PDA

View Full Version : "Window" extension of BasicDialog


Animal
11-20-2006, 01:15 PM
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
11-21-2006, 03: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
11-21-2006, 07: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
11-21-2006, 07: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
11-21-2006, 08:02 AM
This should work now: https://secure0.forward-comp.co.uk/aspicio/TestLayout.html

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

Animal
11-21-2006, 11: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
11-21-2006, 11: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
11-21-2006, 11: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
11-21-2006, 12:19 PM
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
11-21-2006, 01:57 PM
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
11-21-2006, 03:11 PM
I just committed the update to BasicDialog. It now has 8 way resizing too. :)

arnair
11-21-2006, 05: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
11-23-2006, 09: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
11-23-2006, 12:02 PM
: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
11-24-2006, 09: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
11-30-2006, 03:29 PM
That was happening to me as well with Firefox 2.0 on Windows.

moraes
12-29-2006, 11: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
12-31-2006, 06: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
12-31-2006, 07: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
12-31-2006, 11: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
01-01-2007, 01:48 AM
Looks good. The new separate themes should make create new ones easier.

brian.moeskau
01-01-2007, 02:42 AM
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
01-01-2007, 10:25 AM
its been updated. just a slight height adjustment in the .ydlg-close, .ydlg-maximize and .ydlg-restore classes.

moraes
01-03-2007, 12:12 AM
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
01-23-2007, 02:20 AM
Great job,
how to make this as modal dailog,how to get retrun value from modal dailog

MD
03-25-2007, 07: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
03-26-2007, 10:23 AM
the link is broken... :(

dselkirk
04-02-2007, 04: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
04-03-2007, 03:56 AM
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
04-03-2007, 12:30 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

Hi,

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

Very thanks.

kitepad
04-03-2007, 12:55 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

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
04-03-2007, 03:19 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.

kitepad
04-03-2007, 10: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
04-03-2007, 11: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
04-05-2007, 01:58 AM
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
04-05-2007, 08: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
04-06-2007, 05: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;
}
});

jgarcia@tdg-i.com
04-12-2007, 09:08 AM
this is sick. good work dude.

jgarcia@tdg-i.com
04-20-2007, 01:23 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.



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

thanks.

jack.slocum
04-22-2007, 08: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
04-23-2007, 05: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
04-24-2007, 03:38 AM
once minimize the window is not restore properly it is hidden