1. #1
    Sencha Premium Member bpjohnson's Avatar
    Join Date
    Jun 2007
    Location
    Atlanta, GA
    Posts
    47
    Vote Rating
    6
    bpjohnson is on a distinguished road

      0  

    Post Cascading Windows

    Cascading Windows


    [Edit: Animal offered a very nice riff on the same theme further down in this thread.]

    Ever notice how, by default, new Ext Windows are created in the center of their containing element? I thought it'd be nice to have the first window start at the top left, and each subsequent window start down and to the right a bit, like in most OSes. Hence this plugin.

    To call a window that will cascade:

    PHP Code:
    win = new Ext.Window({
                    
    layout:'fit',
                    
    width:500,
                    
    height:300,
                    
    closeAction:'hide',
                    
    plaintrue,
                    
    plugins: [ new Ext.ux.plugins.CascadeWindows() ],
                    
    offSetX15,
                    
    offSetY: -15,
                    
    items: [{title'Hello World'html'lorem ipsum'}],
                });

    win.show(); 
    The offSetX and offSetY options set how far down and over each window is created. If you don't specify them, the defaults are 15px. Oh, and I should note that cascading is relative to the window's windowgroup, defaulting to the global Ext.WindowMgr if one hasn't been specified.

    And here's the plugin code:

    PHP Code:
    Ext.namespace('Ext.ux.plugins');

    Ext.ux.plugins.CascadeWindows = function(config) {
        
    Ext.apply(thisconfig);
    };

    Ext.extend(Ext.ux.plugins.CascadeWindowsExt.util.Observable, {
        
    init:function(win) {
            
    Ext.apply(win, {
                
    onRender:win.onRender.createSequence(function(ctposition) {
                var 
    mgr = (this.manager)?this.manager:Ext.WindowMgr;
                var 
    ctr this.container;
                var 
    size = { widththis.width,
                     
    heightthis.height };
                var 
    ctSize this.getEl().getAlignToXY(ctr.id"tl-br");
                var 
    offSetX = (this.offSetX)?this.offSetX:15;
                var 
    offSetY = (this.offsetY)?this.offsetY:-15;
                if (
    mgr.cascaded) {
                
    mgr.cascaded += 1;
                } else {
                
    mgr.cascaded 1;
                }
                if (
    mgr.cascaded == 1) {
                
    mgr.lastXY this.getEl().getAlignToXY(ctr.id"tl-tl?", [offSetX,offSetY]);
                } else {
                
    mgr.lastXY[0] += 40;
                
    mgr.lastXY[1] += 25;
                var 
    testBR = {bottom: (size.height mgr.lastXY[1]),
                          
    right: (size.width mgr.lastXY[0]) };
                if (
    testBR.bottom ctSize[1]) {
                    
    mgr.lastXY[1] = 0;
                }
                if (
    testBR.right ctSize[0]) {
                    
    mgr.lastXY[0] = 15;
                }
                }
                
    this.cascaded true;
                
    this.origPos = [];
                
    this.origPos[0] = mgr.lastXY[0];
                
    this.origPos[1] = mgr.lastXY[1];
                
    this.setPosition(mgr.lastXY[0], mgr.lastXY[1]);
            }),
            
    cascade: function(e) {
                
    this.setPosition(this.origPos[0], this.origPos[1]);
                }
           });
        } 
    // end of function init
    }); // end of extend 

  2. #2
    franckxx
    Guest

    Default


    Hi bpjohnson,

    It's interesting, have your got online demo ?
    it's can be usefull, thx !

  3. #3
    Ext User
    Join Date
    Mar 2007
    Posts
    18
    Vote Rating
    0
    zzo is on a distinguished road

      0  

    Default thanks!

    thanks!


    Works great with the Desktop app... just added:

    PHP Code:
                    ,plugins: [ new Ext.ux.plugins.CascadeWindows() ] 
    to createWindow in Desktop.js

    thanks!
    Mark

    PS Note it's NOT 'CascadingWindows' ...

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    57
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    This adds a config option cascadeOnFirstShow which is a pixel offset to cascade any new Window down and right from it's previous sibling:

    Code:
    Ext.override(Ext.Window, {
        beforeShow : function(){
            delete this.el.lastXY;
            delete this.el.lastLT;
            if(this.x === undefined || this.y === undefined){
                var xy = this.el.getAlignToXY(this.container, 'c-c');
                var pos = this.el.translatePoints(xy[0], xy[1]);
                this.x = this.x === undefined? pos.left : this.x;
                this.y = this.y === undefined? pos.top : this.y;
                if (this.cascadeOnFirstShow) {
                    var prev;
                    this.manager.each(function(w) {
                        if (w == this) {
                            if (prev) {
                            	var o = (typeof this.cascadeOnFirstShow == 'number') ? this.cascadeOnFirstShow : 20;
                                var p = prev.getPosition();
                                this.x = p[0] + o;
                                this.y = p[1] + o;
                            }
                            return false;
                        }
                        if (w.isVisible()) prev = w;
                    }, this);
                }
            }
            this.el.setLeftTop(this.x, this.y);
    
            if(this.expandOnShow){
                this.expand(false);
            }
    
            if(this.modal){
                Ext.getBody().addClass("x-body-masked");
                this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
                this.mask.show();
            }
        }
    });

  5. #5
    Sencha Premium Member bpjohnson's Avatar
    Join Date
    Jun 2007
    Location
    Atlanta, GA
    Posts
    47
    Vote Rating
    6
    bpjohnson is on a distinguished road

      0  

    Default


    Quote Originally Posted by zzo View Post
    Works great with the Desktop app... just added:

    PHP Code:
                    ,plugins: [ new Ext.ux.plugins.CascadeWindows() ] 
    to createWindow in Desktop.js

    thanks!
    Mark

    PS Note it's NOT 'CascadingWindows' ...
    Thanks for pointing that out. I guess I should proofread after coffee and not before. I've fixed the example in the first post.

  6. #6
    Sencha Premium Member bpjohnson's Avatar
    Join Date
    Jun 2007
    Location
    Atlanta, GA
    Posts
    47
    Vote Rating
    6
    bpjohnson is on a distinguished road

      0  

    Default


    Quote Originally Posted by Animal View Post
    This adds a config option cascadeOnFirstShow which is a pixel offset to cascade any new Window down and right from it's previous sibling:

    Okay, that's pretty dang cool. Thanks for showing me a different and somewhat less BFI way of doing things.

    I'm still a bit fuzzy on when to override versus extend or plug-in, so I guess I have some more reading to do...

    B

  7. #7
    Sencha - Community Support Team jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    DC Area =)
    Posts
    16,364
    Vote Rating
    81
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    Override replaces a method/property
    Extend copies an existing object, extends and/or overrides methods/properties.

  8. #8
    Sencha Premium Member bpjohnson's Avatar
    Join Date
    Jun 2007
    Location
    Atlanta, GA
    Posts
    47
    Vote Rating
    6
    bpjohnson is on a distinguished road

      0  

    Default


    Quote Originally Posted by djliquidice View Post
    Override replaces a method/property
    Extend copies an existing object, extends and/or overrides methods/properties.
    Thanks for the info! That much I felt fairly clear on; my lack of clarity more revolves around when does one use an override versus an extend (it seems to me when you still want the original to work as advertised) and when does one use an override or extension versus a plug-in?

    But it seems that this has been talked to death in other threads. If only some enterprising person would comb through the vast store of knowledge that is the forums and perhaps write an abstract for the wiki... Sadly I lack the gumption.

    B

  9. #9
    Sencha - Community Support Team jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    DC Area =)
    Posts
    16,364
    Vote Rating
    81
    jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all jay@moduscreate.com is a name known to all

      0  

    Default


    An override will apply to your code globally. Instead of an extension, where you have to do a search and replace in your code where you are using that class.

    Good overrides will fix code and/or add to functionality w/out being cumbersome. Case in point, something i published the other day: Here You can specify groups of visible columns in your code. If the columnViews object doesn't exist, it's as if the override never existed... with one exception, the added 'show all' button.

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    57
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Here it is as a plugin:

    Code:
    Ext.ux.WindowCascade = Ext.extend(Object, {
        constructor: function(offset) {
        	this.offset = offset;
        },
    
        init: function(client) {
        	client.beforeShow = Ext.Window.prototype.beforeShow.createInterceptor(this.beforeShow);
        },
    
        beforeShow: function() {
        	if ((this.x == undefined) && (this.y == undefined)) {
        	    var prev;
        	    this.manager.each(function(w) {
        	        if (w == this) {
        	            if (prev) {
        	            	var o = this.offset || 20;
        	                var p = prev.getPosition();
        	                this.x = p[0] + o;
        	                this.y = p[1] + o;
        	            }
        	            return false;
        	        }
        	        if (w.isVisible()) prev = w;
        	    }, this);
        	}
        }
    });