PDA

View Full Version : "Window" extension of BasicDialog



Animal
20 Nov 2006, 10:15 AM
An extension of the BasicDialog class which functions more like a desktop window.

It takes a "parent" config property which specifies a container. When modality is specified, the mask only masks the container. When constraintoviewport is specified, the Window is constrained to its container.

Currently, minimizable requires that a "toolbar" property be specified in which to create a Task Button to use to restore.

Maximizing sizes to the viewport if no parent specified, or the parent.


YAHOO.ext.Window = function(el, config){
YAHOO.ext.Window.superclass.constructor.call(this, el, config);

this.titleEl = document.createElement("div");
this.titleEl.className = "ydlg-title"
if(!this.header){
this.header = dh.append(this.el.dom, {tag: 'div', cls:'ydlg-hd'}, true);
}
else {
while(this.header.dom.firstChild)
this.titleEl.appendChild(this.header.dom.firstChild);
}

// wrap any title elements in a float:left div, oppsite to the close/maximize/minimize buttons
this.header.dom.appendChild(this.titleEl);
this.titleEl = YAHOO.ext.Element.get(this.titleEl)

// Add a float:right tool area for header buttons
this.tools = dh.append(this.header.dom, {tag:'span', cls:'ydlg-tools'}, true);

// Add specified header buttons at the opposite end to the title
if(this.closable !== false){
this.el.addClass('ydlg-closable');
this.close.addClass("ydlg-hd-button");
this.tools.dom.appendChild(this.close.dom);
this.on("hide", function()
{
this.taskButton.el.dom.parentNode.removeChild(this.taskButton.el.dom);
}, this, true);
}
if(this.maximizable !== false){
this.el.addClass('ydlg-maximizable');
this.maximizeButton = dh.append(this.tools.dom, {tag: 'div', cls:'ydlg-hd-button ydlg-maximize'}, true);
this.maximizeButton.mon('click', this.maximize, this, true);
}
if(this.minimizable !== false){
this.el.addClass('ydlg-minimizable');
this.minimizeButton = dh.append(this.tools.dom, {tag: 'div', cls:'ydlg-hd-button ydlg-minimize'}, true);
this.minimizeButton.mon('click', this.minimize, this, true);
this.taskButton = this.toolbar.addButton(
{
text: this.titleEl.getText().ellipse(20),
style:{width:"auto"},
click: this.toggleMinimize.createDelegate(this)
});
}

// Acquire the parent Element
if (this.parent)
{
this.parent = YAHOO.ext.Element.get(this.parent);

// Size and position any modal mask to just the parent Element
if(this.modal){
this.parent.dom.insertBefore(this.mask.dom, this.parent.dom.firstChild);
this.mask.setHeight(this.parent.getHeight());
this.mask.setWidth(this.parent.getWidth());
}
}

this.dialogList.add(this.id, this);
this.el.setStyle({zIndex:10000 + this.dialogList.getCount()});
this.el.mon("mousedown", this.toFront.createDelegate(this));

};

YAHOO.extendX(YAHOO.ext.Window, YAHOO.ext.BasicDialog, {

dialogList: new YAHOO.ext.util.MixedCollection(),

/**
* @ignore
* Rotate this Dialog to the top in the dialog z order stack.
*/
toFront: function()
{
this.dialogList.each(function(dialog)
{
var z = dialog.el.getStyle("zIndex");
if (dialog == this) z = 10000 + this.dialogList.getCount(); else z--;
dialog.el.setStyle({zIndex: z});
}, this);
},

toggleMinimize: function()
{
if (this.minimized) {
this.restoreFromButton();
}
else {
this.minimize();
}
},

maximize: function()
{
var p = this.parent ?
this.parent.getBox() :
{x:0, y:0, width:YAHOO.util.Dom.getViewportWidth(), height:YAHOO.util.Dom.getViewportHeight()};
this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
this.proxy.show();
this.proxy.setBounds(p.x, p.y, p.width, p.height, true, .35, function()
{
this.proxy.hide();
this.el.setBounds(p.x, p.y, p.width, p.height);
this.onResize();
}.createDelegate(this));
},

/**
* @method minimize
* Minimizes the dialog.
* @param {Function} callback Function to call when the dialog is minimized
*/
minimize: function(callback)
{
if(this.shadow){
this.shadow.hide();
}
this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
var b = this.taskButton.el.getBox();
this.proxy.show();
this.el.setDisplayed(false);
this.el.hide();
this.proxy.setBounds(b.x, b.y, b.width, b.height, true, .35, function()
{
this.proxy.hide();
if (typeof callback == "function")
callback();
}.createDelegate(this));
this.minimized = true;
},

/**
* @method restoreFromButton
* Expands the dialog from its taskButton.
*/
restoreFromButton : function(){
if(!this.el.isVisible()){
var b = this.taskButton.el.getBox();
this.proxy.setLocation(b.x, b.y);
this.proxy.setSize(b.width, b.height);
this.proxy.show();
this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height, true, .35, this.showEl.createDelegate(this));
}
this.minimized = false;
},

adjustViewport : function(width, height){
if (!this.parent)
YAHOO.ext.Window.superclass.prototype.apply(adjustViewport, arguments);
},

startMove : function(){
if(this.constraintoviewport != false){
this.dd.resetConstraints();
var viewBox = this.parent ?
this.parent.getBox(false) :
{x:0, y:0, width:YAHOO.util.Dom.getViewportWidth(), height:YAHOO.util.Dom.getViewportHeight()};
var topSpace = this.xy[1] - viewBox.y;
var leftSpace = this.xy[0] - viewBox.x;
this.dd.setXConstraint(leftSpace, viewBox.width - leftSpace - this.el.getWidth() - (this.shadow ? this.shadowOffset : 0));
this.dd.setYConstraint(topSpace, viewBox.height - topSpace - this.el.getHeight() - (this.shadow ? this.shadowOffset : 0));
}
},

setTitle: function(text)
{
this.titleEl.dom.innerHTML = text;
},

beforeShow : function(){
YAHOO.util.Event.on(document, 'keydown', this.keyDownDelegate);

if (this.fixedcenter) {
this.el.beginMeasure();
this.xy = this.el.center(this.parent);
this.el.endMeasure();
}
if(this.modal){
YAHOO.util.Dom.addClass(this.parent ? this.parent.dom : document.body, 'masked');
if (this.parent)
this.mask.setBounds(this.parent.getBox());
else
this.mask.setSize(YAHOO.util.Dom.getViewportWidth(), YAHOO.util.Dom.getViewportHeight());
this.mask.show();
}
},

beforeHide : function(){
YAHOO.util.Event.removeListener(document, 'keydown', this.keyDownDelegate);
if(this.modal){
this.mask.hide();
YAHOO.util.Dom.removeClass(this.parent ? this.parent.dom : document.body, 'masked');
}
},
});

CSS required:



.ydlg .ydlg-title {
float:left;
color:#fff;
white-space:nowrap;
}

.ydlg .ydlg-tools {
position:absolute;
top:6px;
right:4px;
}
.ydlg .ydlg-hd-button {
float:right;
height:15px;
width:15px;
margin:0px;
padding:0px;
line-height:1px;
font-size:1px;
background-repeat:no-repeat;
cursor:pointer;
visibility:inherit;
}
.ydlg .ydlg-close {
background-image:url(../images/basic-dialog/close.gif);
}
.ydlg .ydlg-maximize {
background-image:url(../images/basic-dialog/maximize.gif);
}
.ydlg .ydlg-minimize {
background-image:url(../images/basic-dialog/minimize.gif);
}

Animal
21 Nov 2006, 12:11 AM
Sorry, that code uses these extras:

Jack's version of this will be in the next release:


/**
* Centers the Element in either the viewport, or another Element.
* @method center
* @param {String/HTMLElement/YAHOO.ext.Element} centerIn (optional) The element in which to center this.
*/
YAHOO.ext.Element.prototype.center = function(centerIn) {
var box = centerIn ?
YAHOO.ext.Element.get(centerIn).getBox() :
{
x: document.documentElement.scrollLeft || document.body.scrollLeft,
y: document.documentElement.scrollTop || document.body.scrollTop,
width: YAHOO.util.Dom.getClientWidth(),
height: YAHOO.util.Dom.getClientHeight()
};
this.setXY([ box.x + (box.width / 2) - (this.getWidth() / 2),
box.y + (box.height / 2) - (this.getHeight() / 2) ]);
};


This could be quite useful:


/**
* Returns normalized text from within any Element.
elements are converted into whitespace.
* @method getText
* @param {String/HTMLElement} el (optional) The DOM element from which to extract text.
*/
YAHOO.ext.Element.prototype.getText = function(el)
{
var dom = el ? YAHOO.util.Dom.get(el) : this.dom;
if (dom.nodeType == 3)
return dom.data;
else if (dom.nodeType == 1 && dom.tagName.equalsIgnoreCase("br"))
return " ";

var result = "";
for (var i = 0, c = dom.childNodes, l = c.length; i < l; i++)
{
result += fcl.util.getText(c[i]);
}
return result.normalize();
};


And I use these a lot:


/**
* Remove leading and trailing whitespace.
*/
String.prototype.normalize = function()
{
return /^\s*([^\s]*)?\s*/.exec(this)[1] || "";
};

/**
* Case insensitive String equality test
*/
String.prototype.equalsIgnoreCase = function(other)
{
return (this.toLowerCase() == other.toLowerCase())
}

jack.slocum
21 Nov 2006, 4:09 AM
It sounds great. Is it possible you put up an example page and/or send me an example page :)so I can see it? :)

Animal
21 Nov 2006, 4:39 AM
If you go to http://80.177.128.44:8080/aspicio/form/Lister.jsp?type=CountrySubEntity

and log in using nigelw/p

Then go to http://80.177.128.44:8080/aspicio/TestLayout.html

Clicking in the title bar will create a new YAHOO.ext.Window.

You can create as many as you want. You'll see they are constrained to the content div (under the title bar) if they were modal, the mask would also only cover the content area.

There are a few little problems such as after resizing, maximize doesn't start the maximizing proxy from the correct [xy] coords, but it's a good start.

Perhaps adding a parent config option should be added to BasicDialog? I think adding the option of adding your own header buttons in addition to "close"/"hide" (bit of a dichotomy there) would be a good thing.

Animal
21 Nov 2006, 5:02 AM
This should work now: https://secure0.forward-comp.co.uk/aspicio/TestLayout.html

jack.slocum
21 Nov 2006, 8:18 AM
How do I get windows? Iclick "new" and it says loading but then nothing happens.

Animal
21 Nov 2006, 8:24 AM
Just click in the blue "The Title!" area...

It's really a crappy, cobbled up testbed for all sorts of ideas, so it's a bit messy.

jack.slocum
21 Nov 2006, 8:30 AM
That's sweet man. One thing, can the maximize button clicked a second time restore the last size (before maximize)? :D I really like how that looks and I think I am inspired to do something with it. :twisted:

Animal
21 Nov 2006, 8:34 AM
Yes, I suppose it could. That would entail storing the dimensions, swapping the button's class to be "ydlg-restore", setting up the CSS and the gif for that.

I'll take a look....

Animal
21 Nov 2006, 9:19 AM
OK, the version at https://secure0.forward-comp.co.uk/aspicio/TestLayout.html now has a maximizeRestoreButton.

I thought the proxy element was 1 zIndex higher than the real element, but on restore from maximized, you don't see the proxy shrinking. There's just a 0.35 second wait and then "bloop!" it's restored. I am setting the proxy to the correct size and asking it to shrink and only resizing the real element in the completion callback.

I don't know why it's not working!

jack.slocum
21 Nov 2006, 10:57 AM
That looks sweet.

I forgot to update the resizer z-index, I just did that too. I check it in in a few minutes, after I update a couple other things.

jack.slocum
21 Nov 2006, 12:11 PM
I just committed the update to BasicDialog. It now has 8 way resizing too. :)

arnair
21 Nov 2006, 2:34 PM
Animal - pro'ly not a good idea for everyone on the forum to hit your link, but I couldn't resist taking a look. Just wanted to second Jack's comment on that - it looks pretty awesome, can't wait to use it...

genius551v
23 Nov 2006, 6:22 AM
En mi pais decimos q una persona es un ANIMAL cuando hizo algo muy malo o cuando es muy bueno en algo, jajaja que hironia que una misma palabra se pueda utilizar para dos cosas opuestas, pero asi son muchas cosas en mi bello pais.

En este caso puedo decir que eres un ANIMAL pero diciendote QUE BUENO LO QUE HICISTE!

se ve maravilloso, gracias por compartir.

(English...i try... :wink: )

In my country we say to a person is an ANIMAL when he made something very bad or when he is very very good in something, jajaja that ironic that a same word can be used for two opposed things, but this is many things in my beautiful country.

In this case I can say that you are an ANIMAL becouse THAT GOOD WHAT YOU DID! looks wonderful, thanks to share.

8)

Animal
23 Nov 2006, 9:02 AM
:lol:

In a fit of vanity, I named myself after the big guy who's putting the hurt on his competitors here: http://www.first-contact.demon.co.uk/cycling2/yates1.html

brian.moeskau
24 Nov 2006, 6:56 PM
The window functionality looks great. FYI -- trying it in FF 1.5 Mac, when I minimize and restore, the restored window is not visible. I can see the minimize / restore animations coming from the toolbar, but the window itself never reappears. Happens no matter how many windows I create.

digerata
30 Nov 2006, 12:29 PM
That was happening to me as well with Firefox 2.0 on Windows.

moraes
29 Dec 2006, 8:59 PM
The 'maximize' part of this code still works like a charm for the current BasicDialog version. Very nice, I was looking for something like this. Thanks! :-)

dselkirk
31 Dec 2006, 3:55 PM
Fairly new to YUI but having been enjoying it. Been tinkering with the window extension and have done some of my own improvements. Removed the minimize function and streamlined alot of the code. Its been tested with a customized aero theme so i'm not certain how well it will work with the others. Being new to this I would appreciate some feed back.

script:


YAHOO.ext.Window = function(el, config){
YAHOO.ext.Window.superclass.constructor.call(this, el, config);
this.el = getEl(el);
if(this.maximizable){
this.el.addClass('ydlg-maximizable');
this.maximizeRestoreButton = YAHOO.ext.DomHelper.append(this.el.dom, {tag: 'div', cls:'ydlg-maximize'}, true);
this.maximizeRestoreButton.mon('click', this.toggleMaximize, this, true);
this.maximizeRestoreButton.mon('mouseover', this.toggleMouseover, this, true);
this.maximizeRestoreButton.mon('mouseout', this.toggleMouseout, this, true);
this.el.mon('dblclick', this.toggleMaximize, this, true);
}
};

YAHOO.extendX(YAHOO.ext.Window, YAHOO.ext.BasicDialog, {

resetState: function(){
this.toggleMouseout();
this.maximizeRestoreButton.removeClass("ydlg-restore");
this.maximizeRestoreButton.addClass("ydlg-maximize");
},

animShow: function(){
this.resetState();
YAHOO.ext.BasicDialog.superclass.animShow.call(this);
},

showEl: function(){
this.resetState();
YAHOO.ext.BasicDialog.superclass.showEl.call(this);
},

toggleMouseover: function(){
if (this.maximizeRestoreButton.hasClass("ydlg-maximize"))
this.maximizeRestoreButton.addClass('ydlg-maximize-over');
else
this.maximizeRestoreButton.addClass('ydlg-restore-over');
},

toggleMouseout: function(){
this.maximizeRestoreButton.removeClass('ydlg-maximize-over');
this.maximizeRestoreButton.removeClass('ydlg-restore-over');
},

toggleMaximize: function(){
this.refreshSize();
this.toggleMouseout();
if (this.maximizeRestoreButton.hasClass("ydlg-maximize")){
this.restoreSize = this.size;
this.restoreXy = this.xy;
var p = this.parent ?
this.parent.getBox() :
{x:0, y:0, width:YAHOO.util.Dom.getViewportWidth(), height:YAHOO.util.Dom.getViewportHeight()};
this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
this.proxy.show();
this.proxy.setBounds(p.x, p.y, p.width, p.height, true, .35, function(){
this.proxy.hide();
this.el.setBounds(p.x, p.y, p.width, p.height);
this.maximizeRestoreButton.removeClass("ydlg-maximize");
this.maximizeRestoreButton.addClass("ydlg-restore");
this.onResize();
}.createDelegate(this));
}else{
this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
this.proxy.show();
this.proxy.setBounds(this.restoreXy[0], this.restoreXy[1], this.restoreSize.width, this.restoreSize.height, true, .35, function(){
this.proxy.hide();
this.el.setBounds(this.restoreXy[0], this.restoreXy[1], this.restoreSize.width, this.restoreSize.height);
this.maximizeRestoreButton.removeClass("ydlg-restore");
this.maximizeRestoreButton.addClass("ydlg-maximize");
this.onResize();
}.createDelegate(this));
}
},
});

// Override the constructor with our extended version
YAHOO.ext.BasicDialog = YAHOO.ext.Window;


style:


.ydlg .ydlg-maximize, .ydlg .ydlg-restore {
position: absolute;
width:21px;
height:20px;
top:5px;
right:26px;
background-repeat: no-repeat;
opacity:.85;-moz-opacity:.85;filter:alpha(opacity=80);
zoom:1;
}
.ydlg .ydlg-maximize {
background-image:url(/cms/manager/images/basic-dialog/maximize.gif);
}
.ydlg .ydlg-maximize-over {
background-image:url(/cms/manager/images/basic-dialog/maximize-over.gif);
}
.ydlg .ydlg-restore {
background-image:url(/cms/manager/images/basic-dialog/restore.gif);
}
.ydlg .ydlg-restore-over {
background-image:url(/cms/manager/images/basic-dialog/restore-over.gif);
}

jack.slocum
31 Dec 2006, 4:34 PM
That looks short and clean dselkirk. I may have to take it and drop it in the codebase. :) A couple things I would change:

Add maximized var to track if it's maximized instead of using the buttons class. Add isMaximized() function.

Add that info to the state/restoreState so it doesn't try to use stale dimensions.

Add events.

Hide/show the shadow on maximize/restore.

Thanks for posting.

dselkirk
31 Dec 2006, 8:20 PM
Thx, I'm glad you like it. I've posted an updated version with the requested changes. The demo is utilizing a custom theme which is not complete. Cheers.

http://don.atomicmotion.com/window.htm

jack.slocum
31 Dec 2006, 10:48 PM
Looks good. The new separate themes should make create new ones easier.

brian.moeskau
31 Dec 2006, 11:42 PM
Looks cool. One minor niggle -- when you mouse just under the max/restore/close buttons, you get the resize cursor for a couple of pixels. Ideally the buttons would fit directly against the bottom border of the title bar (just like in the OS). When you are moving the curosr to the buttons it creates a brief cursor flash that is not good. Other than that, it's really nice!

dselkirk
1 Jan 2007, 7:25 AM
its been updated. just a slight height adjustment in the .ydlg-close, .ydlg-maximize and .ydlg-restore classes.

moraes
2 Jan 2007, 9:12 PM
Great, dselkirk. I started to use it and it works perfectly. I only had to tweak the CSS and images to fit my dialogs, and it is done.

rehman_922
22 Jan 2007, 11:20 PM
Great job,
how to make this as modal dailog,how to get retrun value from modal dailog

MD
25 Mar 2007, 3:49 PM
Is the parent container parameter and maximize included in the latest Alpha 3 rev 4? In the docs, I'm still seeing the older params in the example.

genius551v
26 Mar 2007, 6:23 AM
the link is broken... :(

dselkirk
2 Apr 2007, 12:10 PM
My apologies for the broken link. It has been restored. I have also done a quick rebuild for Beta 1. Certainly not perfect but functional.

http://don.atomicmotion.com/window.htm

Cheers

Animal
2 Apr 2007, 11:56 PM
This looks great.

I hope Jack will incorporate this work, and extend BasicDialog to have a parent element which resizing and dragging is constrained into, and to maximize to its parent element.

kitepad
3 Apr 2007, 8:30 AM
My apologies for the broken link. It has been restored. I have also done a quick rebuild for Beta 1. Certainly not perfect but functional.

http://don.atomicmotion.com/window.htm

Cheers

Hi,

I'm a newbie for JavaScript, can you post a new version base on Ext 1.0 beta1.

Very thanks.

kitepad
3 Apr 2007, 8:55 AM
My apologies for the broken link. It has been restored. I have also done a quick rebuild for Beta 1. Certainly not perfect but functional.

http://don.atomicmotion.com/window.htm

Cheers


Hi,

I'm a newbie for JavaScript, can you post a new version base on Ext 1.0 beta1.

Very thanks.
Hi,
When I use this window with a Flash, if I maximize it, flash cann't be hide. If I don't maximize it, it's display correctly and keep top on flash.

dselkirk
3 Apr 2007, 11:19 AM
you may need to apply the wmode=transparent parameter to the flash to prevent overlaps. Also varying on how you load your flash you may need to handle the resize event to update your elements.

kitepad
3 Apr 2007, 6:55 PM
you may need to apply the wmode=transparent parameter to the flash to prevent overlaps. Also varying on how you load your flash you may need to handle the resize event to update your elements.

Sorry, I think my descriptions is confused you. My scenario is:
1. Create two window with tab.
2. First window's tab host a Flash chart.
3. Second window's tab host a Grid.
4. Second window's Grid has a event handler to handle "celldblclick".
5. Event handler will open a modal dialog to display somethings.
6. When Dialog is opend, it's right, dialog will be top on Flash.
7. If I maximize this dialog, it's occupy all area of viewport, but Flash chart of first window still display.

Attachment are my screenshot:
1.Gif: First window
2.Gif: Using BasicDialog
3.Gif: Using Ext.Window
20

21

22

kitepad
3 Apr 2007, 7:53 PM
Hi,

Solved. Problem is in maximize function:
Original: if(this.shim) this.shim.show();

I think shim should be always show when window is maximized.
In my samples, because I don't use shim:true options when I create window.

kitepad
4 Apr 2007, 9:58 PM
I have modified Ext.Window implementation to add tab play support.
When you use Ext.PlayerDialog, you need add a config parameter with dialog constructor: player:true. A player button will be added into title bar. You can click this button to start play/stop your tab.

If you want to use Ext.PlayerDialog, you need to modify ext-all.css,
change .x-dlg-toolbox style's width from 40px to 100px. then add following style classes in your .css file:

.x-dlg .x-dlg-play {
background-image:url(../images/aero/basic-dialog/play.gif);
}
.x-dlg .x-dlg-play-over {
background-image:url(../images/aero/basic-dialog/play-over.gif);
}
.x-dlg-stop .x-dlg-play {
background-image:url(../images/aero/basic-dialog/stop.gif);
}
.x-dlg-stop .x-dlg-stop-over {
background-image:url(../images/aero/basic-dialog/stop-over.gif);
}
.x-dlg .x-dlg-play, .x-dlg .x-dlg-stop {
float:right;
height:19px;
width:21px;
margin:0;
margin-left:2px;
padding:0;
line-height:1px;
font-size:1px;
background-repeat:no-repeat;
cursor:pointer;
visibility:inherit;
}

Then include following .js file:
Ext.PlayerDialog = function(el, config){
Ext.PlayerDialog.superclass.constructor.call(this, el, config);
this.el.addClass("x-dlg-collapsed");
this.collapseBtn.removeListener("click", this.collapseClick);
this.collapseBtn.on("click", this.maximizeClick, this);
this.header.mon('dblclick', this.toggle, this, true);
this.events['maximize'] = new YAHOO.util.CustomEvent('maximize');
this.events['restore'] = new YAHOO.util.CustomEvent('restore');
//Add a tab player support
this.playing = false;

if(this.player !== false) {
this.playBtn = this.toolbox.createChild({cls:"x-dlg-play"});
this.playBtn.on("click", this.playerClick,this);
this.playBtn.addClassOnOver("x-dlg-play-over");
}

};

Ext.extend(Ext.PlayerDialog, Ext.BasicDialog, {

isMaximized: function() { return this.maximized; },

resetState: function(){
if(this.maximized) this.collapse();
},

playerClick : function(){
if(this.playing) {
this.el.removeClass("x-dlg-stop");
this.playBtn.removeClass("x-dlg-stop-over");
this.playBtn.addClassOnOver("x-dlg-play-over");
this.stop();
this.playing = false;
}else {
this.el.addClass("x-dlg-stop");
this.playBtn.removeClass("x-dlg-play-over");
this.playBtn.addClassOnOver("x-dlg-stop-over");
this.play();
this.playing = true;
}
},

play : function(){
var tabs = this.getTabs();
if(tabs.getCount() > 1) {
tabs.el.getUpdateManager().addListener("beforeupdate",function(el,url,params){
var size = tabs.getCount();
var i = 0;
for(i=0;i<size;i++)
{
var tab = tabs.getTab(i);
if(tab.isActive())
break;
}
i = i + 1;
if(i < size)
tabs.activate(i);
else
tabs.activate(0);

return false;
});
tabs.el.getUpdateManager().startAutoRefresh(10,null,null,null,false);
}
},

stop : function(){
var tabs = this.getTabs();
if(tabs.getCount() > 1) {
tabs.el.getUpdateManager().removeListener("beforeupdate",function(el,url,params){
var size = tabs.getCount();
var i = 0;
for(i=0;i<size;i++)
{
var tab = tabs.getTab(i);
if(tab.isActive())
break;
}
i = i + 1;
if(i < size)
tabs.activate(i);
else
tabs.activate(0);

return false;
});
tabs.el.getUpdateManager().stopAutoRefresh();
}
},

animShow: function(){
this.resetState();
Ext.PlayerDialog.superclass.animShow.call(this);
},

showEl: function(){
this.resetState();
Ext.PlayerDialog.superclass.showEl.call(this);
},

toggle: function(){
this.maximized=!this.maximized;
this.maximized?this.collapse():this.maximize();
},

maximizeClick: function(){
this.maximized?this.collapse():this.maximize();
},

maximize : function(){
if(!this.maximized){
this.maximized = true;
this.el.removeClass("x-dlg-collapsed");
this.restore = this.el.getBox();
var box = this.parent?this.parent.getBox():{x:0,y:0,width:Ext.lib.Dom.getViewWidth(true), height:Ext.lib.Dom.getViewHeight(true)};
if(this.shadow) this.shadow.hide();
//if(this.shim)
this.shim.show();
this.resizeTo(box.width,box.height);
this.fireEvent('expand', this);
}
},

collapse : function(){
if(this.maximized){
this.maximized = false;
this.el.addClass("x-dlg-collapsed");
this.resizeTo(this.restore.width, this.restore.height, this.restore.x, this.restore.y);
if(this.shadow) this.shadow.show(this.el);
if(this.shim) this.shim.show();
this.fireEvent('collapse', this);
}
},

resizeTo : function(w,h,x,y){
x=x|0;
y=y|0;
this.size = this.el.getSize();
this.xy = this.el.getXY();
this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
this.proxy.show();

this.proxy.setBounds(x, y, w, h, true, .35, function(){
this.proxy.hide();
this.xy[0] = x;
this.xy[1] = y;
this.size = {width: w, height: h};
this.el.setBounds(x, y, w, h);
this.syncBodyHeight();
if(this.fixedcenter){
this.center();
}
if(this.isVisible()){
this.constrainXY();
this.adjustAssets();
}
this.fireEvent("resize", this, w, h);
}.createDelegate(this));

return this;
}

});
// Override the constructor with our extended version
//Ext.BasicDialog = Ext.PlayerDialog;

Caolga
5 Apr 2007, 4:24 PM
Hello,
Animal said:
An extension of the BasicDialog class which functions more like a desktop window.

It takes a "parent" config property which specifies a container. When modality is specified, the mask only masks the container. When constraintoviewport is specified, the Window is constrained to its container.

This is my implementation, but the container must be a ContentPanel (because we can catch the 'resize' event and then resize the mask when it's modal) with fitToFrame=true (yes, for the 'resize' event). To specify the ContentPanel, use 'parentContentPanel' in the config object.

If you don't specify the 'parentContentPanel', this class functions exactly like a BasicDialog.
Indeed there is only very little code which changes.

Maybe the BasicBialog should be like that ;)
Tell me what you think about... maybe I am wrong

In comment the old code from BasicDialog.


Ext.Window = function(el, config){
Ext.Window.superclass.constructor.call(this, el, config);

if(this.parentContentPanel) {
this.parent = this.parentContentPanel.getEl();
Ext.EventManager.removeResizeListener(this.adjustViewport, this);
this.parentContentPanel.on('resize', this.adjustParentViewport, this, true);
this.parent.dom.insertBefore(this.el.dom, this.parent.dom.firstChild);
if(this.modal)
this.parent.dom.insertBefore(this.mask.dom, this.parent.dom.firstChild);
}
};

Ext.extend(Ext.Window, Ext.BasicDialog, {
/* New usefull method! */
getCenterXY: function() {
var p = this.parent;
return (p?[p.getX()+Math.ceil(p.getWidth()/2)-Math.ceil(this.el.getWidth()/2), p.getY()+Math.ceil(p.getHeight()/2)-Math.ceil(this.el.getHeight()/2)]:this.el.getCenterXY(true));
},

/* New usefull method! */
getParentWidth: function(contentWidth) {
return (this.parent?this.parent.getWidth(contentWidth):Ext.lib.Dom.getViewWidth(contentWidth));
},

/* New usefull method! */
getParentHeight: function(contentHeight) {
return (this.parent?this.parent.getHeight(contentHeight):Ext.lib.Dom.getViewHeight(contentHeight));
},

/* New usefull method! */
getParentSize: function(contentSize) {
return [this.getParentWidth(contentSize), this.getParentHeight(contentSize)];
},

/* New usefull method! */
getParentXY: function() {
return (this.parent?this.parent.getXY():[0,0]);
},

/* Redefinition with some little modifications */
beforeShow : function(){
this.expand();
if(this.fixedcenter){
//this.xy = this.el.getCenterXY(true);
this.xy = this.getCenterXY();
}
if(this.modal){
Ext.get(document.body).addClass("x-body-masked");
//this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
this.mask.setSize(this.getParentWidth(), this.getParentHeight());
this.mask.show();
}
this.constrainXY();
},

/* Redefinition with some little modifications */
constrainXY : function(){
if(this.constraintoviewport !== false){
/*
if(!this.viewSize){
if(this.container){
var s = this.container.getSize();
this.viewSize = [s.width, s.height];
}else{
this.viewSize = [Ext.lib.Dom.getViewWidth(),Ext.lib.Dom.getViewHeight()];
}
}
var s = Ext.get(this.container||document).getScroll();
*/
if(!this.viewSize || !this.viewXY){
this.viewSize = this.getParentSize();
this.viewXY = this.getParentXY(); // viewXY for offset if viewport != document.body
}
var s = Ext.get(this.parent||document).getScroll();

var x = this.xy[0], y = this.xy[1];
var w = this.size.width, h = this.size.height;
var vw = this.viewSize[0], vh = this.viewSize[1];
var vx = this.viewXY[0], vy = this.viewXY[1]; // not in BasicDialog.js

// only move it if it needs it
var moved = false;
// first validate right/bottom
// vx and vy added!
if(x + w > vx+vw+s.left){
x = vx + vw - w;
moved = true;
}
if(y + h > vy+vh+s.top){
y = vy + vh - h;
moved = true;
}
// then make sure top/left isn't negative
if(x < vx + s.left){
x = vx + s.left;
moved = true;
}
if(y < vy + s.top){
y = vy + s.top;
moved = true;
}
if(moved){
// cache xy
this.xy = [x, y];
if(this.isVisible()){
this.el.setLocation(x, y);
this.adjustAssets();
}
}
}
},

/*
* New method but almost same as adjustViewport in BasicDialog.js l.673!
* New parameter: cp, because ContentPanel's resize event send it! (ContentPanel.js l.85)
*/
adjustParentViewport : function(cp, w, h){
// these following 4 lines are in BasicDialog.js, but why? Maybe not necessary
if(!w || !h){
w = /*Ext.lib.Dom.getViewWidth()*/this.getParentWidth();
h = /*Ext.lib.Dom.getViewHeight()*/this.getParentHeight();
}
// cache the size
this.viewSize = [w, h];
if(this.modal && this.el.isVisible()){
//this.mask.setSize(w, h); // first make sure the mask isn't causing overflow
//this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
this.mask.hide(); // prevent overflow,
this.mask.setSize(w, h);
this.mask.show();
}
if(this.isVisible()){
this.constrainXY();
}
},

/* Redefinition with some little modifications */
startMove : function(){
if(this.proxyDrag){
this.proxy.show();
}
if(this.constraintoviewport !== false){
//this.dd.constrainTo(document.body, {right: this.shadowOffset, bottom: this.shadowOffset});
this.dd.constrainTo(this.parent||document.body, {right: this.shadowOffset, bottom: this.shadowOffset, left: this.shadowOffset, top: this.shadowOffset});
}
}
});

Caolga
6 Apr 2007, 1:35 PM
Sorry,

This new version fix a bug in constraintXY method and clip the ContentPanel for prevent the scroll possibility (only if it is modal and parentContentPanel is specified).:)


Ext.Window = function(el, config){
Ext.Window.superclass.constructor.call(this, el, config);

if (this.parentContentPanel) {
this.parent = this.parentContentPanel.getEl();
Ext.EventManager.removeResizeListener(this.adjustViewport, this);
this.parentContentPanel.on('resize', this.adjustParentViewport, this, true);
this.parent.dom.insertBefore(this.el.dom, this.parent.dom.firstChild);
if(this.modal) {
this.parent.dom.insertBefore(this.mask.dom, this.parent.dom.firstChild);
// for clipping (prevent scroll if modal)
this.parentScroller = this.parent.findParent('div.x-layout-tabs-body', document.body, true);
}
}
};

Ext.extend(Ext.Window, Ext.BasicDialog, {
/* New usefull method! */
getCenterXY: function() {
var p = this.parent;
return (p?[p.getX()+Math.ceil(p.getWidth()/2)-Math.ceil(this.el.getWidth()/2), p.getY()+Math.ceil(p.getHeight()/2)-Math.ceil(this.el.getHeight()/2)]:this.el.getCenterXY(true));
},

/* New usefull method! */
getParentWidth: function(contentWidth) {
return (this.parent?this.parent.getWidth(contentWidth):Ext.lib.Dom.getViewWidth(contentWidth));
},

/* New usefull method! */
getParentHeight: function(contentHeight) {
return (this.parent?this.parent.getHeight(contentHeight):Ext.lib.Dom.getViewHeight(contentHeight));
},

/* New usefull method! */
getParentSize: function(contentSize) {
return [this.getParentWidth(contentSize), this.getParentHeight(contentSize)];
},

/* New usefull method! */
getParentXY: function() {
return (this.parent?this.parent.getXY():[0,0]);
},

/* Redefinition with some little modifications */
beforeShow : function(){
this.expand();
if(this.fixedcenter){
//this.xy = this.el.getCenterXY(true);
this.xy = this.getCenterXY();
}
if(this.modal){
Ext.get(document.body).addClass("x-body-masked");
//this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
this.mask.setSize(this.getParentWidth(), this.getParentHeight());
this.mask.show();
}
// if parentContentPanel and modal stop scroll if any
if(this.parentScroller)
this.parentScroller.clip();

this.constrainXY();
},

/* Redefinition with some little modifications */
constrainXY : function(){
if(this.constraintoviewport !== false){
/*
if(!this.viewSize){
if(this.container){
var s = this.container.getSize();
this.viewSize = [s.width, s.height];
}else{
this.viewSize = [Ext.lib.Dom.getViewWidth(),Ext.lib.Dom.getViewHeight()];
}
}
var s = Ext.get(this.container||document).getScroll();
*/


this.viewSize = this.getParentSize();
this.viewXY = this.getParentXY(); // viewXY for offset if viewport != document.body
var s = Ext.get(this.parent||document).getScroll();

var x = this.xy[0], y = this.xy[1];
var w = this.size.width, h = this.size.height;
var vw = this.viewSize[0], vh = this.viewSize[1];
var vx = this.viewXY[0], vy = this.viewXY[1]; // not in BasicDialog.js

// only move it if it needs it
var moved = false;
// first validate right/bottom
// vx and vy and shadowOffset added!
if(x + w + this.shadowOffset > vx + vw + s.left){
x = vx + vw - w - this.shadowOffset;
moved = true;
}
if(y + h + this.shadowOffset > vy + vh + s.top){
y = vy + vh - h - this.shadowOffset;
moved = true;
}
// then make sure top/left isn't negative
if(x - this.shadowOffset < vx){
x = vx + this.shadowOffset;
moved = true;
}
if(y - this.shadowOffset < vy){
y = vy + this.shadowOffset;
moved = true;
}
if(moved){
// cache xy
this.xy = [x, y];
if(this.isVisible()){
this.el.setLocation(x, y);
this.adjustAssets();
}
}
}
},

/*
* New method but almost same as adjustViewport in BasicDialog.js l.673!
* New parameter: cp, because ContentPanel's resize event send it! (ContentPanel.js l.85)
*/
adjustParentViewport : function(cp, w, h){
// these following 4 lines are in BasicDialog.js, but why? Maybe not necessary
if(!w || !h){
w = /*Ext.lib.Dom.getViewWidth()*/this.getParentWidth();
h = /*Ext.lib.Dom.getViewHeight()*/this.getParentHeight();
}
// cache the size
this.viewSize = [w, h];
if(this.modal && this.el.isVisible()){
//this.mask.setSize(w, h); // first make sure the mask isn't causing overflow
//this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
this.mask.hide(); // prevent overflow,
this.mask.setSize(w, h);
this.mask.show();
}
if(this.isVisible()){
this.constrainXY();
}
},

/* Redefinition with some little modifications */
startMove : function(){
if(this.proxyDrag){
this.proxy.show();
}
if(this.constraintoviewport !== false){
//this.dd.constrainTo(document.body, {right: this.shadowOffset, bottom: this.shadowOffset});
this.dd.constrainTo(this.parent||document.body, {right: this.shadowOffset, bottom: this.shadowOffset, left: this.shadowOffset, top: this.shadowOffset});
}
},

/* Redefinition with some little modifications */
hide : function(callback){
if (this.fireEvent("beforehide", this) === false){
return;
}
if(this.shadow){
this.shadow.hide();
}
if(this.shim) {
this.shim.hide();
}
if(this.animateTarget){
this.animHide(callback);
}else{
this.el.hide();
this.hideEl(callback);
}
// if parentContentPanel and modal restore scroll if any
if(this.parentScroller)
this.parentScroller.unclip();
return this;
}
});

jay@moduscreate.com
12 Apr 2007, 5:08 AM
this is sick. good work dude.

jay@moduscreate.com
20 Apr 2007, 9:23 AM
you may need to apply the wmode=transparent parameter to the flash to prevent overlaps. Also varying on how you load your flash you may need to handle the resize event to update your elements.



link is down dude, can you set it back up and i'll host it permanently.

thanks.

jack.slocum
22 Apr 2007, 4:21 AM
The code looks good. One change: you can probably kill the whole getCenterXY function and put in:

return this.el.getAlignToXY(this.parent||document, 'c-c');

Caolga
23 Apr 2007, 1:35 AM
Of course you are right Jack :)
But the result is unfortunately not yet perfect! For example when the parent width is not enough...

zaps
23 Apr 2007, 11:38 PM
once minimize the window is not restore properly it is hidden