Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: auto-arranging Ext.Window panels (tiled/horizontal/vertical)

  1. #1
    Ext User
    Join Date
    Nov 2008
    Posts
    6
    Vote Rating
    0
      0  

    Default auto-arranging Ext.Window panels (tiled/horizontal/vertical)

    Hi all,

    I had a look at extjs today and it seems very good, however my first project with it was to try to replicate a client app that requires being able to "tile" the panels plus maximise and minimise the panels - much like what you can do in MS excel with worksheets

    This suggested that I use Ext.Windows panels that can be maximised/minimised etc, I have not got to the point where it looks like I am going to have to write a handler to auto arrange the windows into 2x2 or 3x3 and call it whenever the window is resized. the effect I want to achieve is something like this;
    http://blog.windowsvistamagazine.co....ed-windows.jpg

    Has this been done before? or should I be looking to write a function for this?

    Thanks,

    Tom

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    119
      0  

    Default

    I don't think this has has done before.

    ps. This is something you would need to add to Ext.WindowGroup.

  3. #3
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,615
    Vote Rating
    54
      0  

    Default

    I assume you are using the desktop as a basis for this? That gives you minimize to a toolbar and restore and resize.

    Then a tile function is not hard to add.

    Try this tweaked version of desktop.js. It offers a context menu to arrange the windows, and you can set xTickSize and xTickSize in it to affect drag/drop ticks and resize increments, and tiling spacing/increments:

    Code:
    Ext.Desktop = function(app){
        this.taskbar = new Ext.ux.TaskBar(app);
        this.xTickSize = this.yTickSize = 1;
        var taskbar = this.taskbar;
    
        var desktopEl = Ext.get('x-desktop');
        var taskbarEl = Ext.get('ux-taskbar');
        var shortcuts = Ext.get('x-shortcuts');
    
        var windows = new Ext.WindowGroup();
        var activeWindow;
            
        function minimizeWin(win){
            win.minimized = true;
            win.hide();
        }
    
        function markActive(win){
            if(activeWindow && activeWindow != win){
                markInactive(activeWindow);
            }
            taskbar.setActiveButton(win.taskButton);
            activeWindow = win;
            Ext.fly(win.taskButton.el).addClass('active-win');
            win.minimized = false;
        }
    
        function markInactive(win){
            if(win == activeWindow){
                activeWindow = null;
                Ext.fly(win.taskButton.el).removeClass('active-win');
            }
        }
    
        function removeWin(win){
            taskbar.removeTaskButton(win.taskButton);
            layout();
        }
    
        function layout(){
            desktopEl.setHeight(Ext.lib.Dom.getViewHeight()-taskbarEl.getHeight());
        }
        Ext.EventManager.onWindowResize(layout);
    
        this.layout = layout;
    
        this.createWindow = function(config, cls){
            var win = new (cls||Ext.Window)(
                Ext.applyIf(config||{}, {
                    renderTo: desktopEl,
                    manager: windows,
                    minimizable: true,
                    maximizable: true
                })
            );
            win.dd.xTickSize = this.xTickSize;
            win.dd.yTickSize = this.yTickSize;
            win.resizer.widthIncrement = this.xTickSize;
            win.resizer.heightIncrement = this.yTickSize;
            win.render(desktopEl);
            win.taskButton = taskbar.addTaskButton(win);
    
            win.cmenu = new Ext.menu.Menu({
                items: [
    
                ]
            });
    
            win.animateTarget = win.taskButton.el;
            
            win.on({
                'activate': {
                    fn: markActive
                },
                'beforeshow': {
                    fn: markActive
                },
                'deactivate': {
                    fn: markInactive
                },
                'minimize': {
                    fn: minimizeWin
                },
                'close': {
                    fn: removeWin
                }
            });
            layout();
            return win;
        };
    
        this.getManager = function(){
            return windows;
        };
    
        this.getWindow = function(id){
            return windows.get(id);
        };
    
        this.getWinWidth = function(){
            var width = Ext.lib.Dom.getViewWidth();
            return width < 200 ? 200 : width;
        };
    
        this.getWinHeight = function(){
            var height = (Ext.lib.Dom.getViewHeight()-taskbarEl.getHeight());
            return height < 100 ? 100 : height;
        };
    
        this.getWinX = function(width){
            return (Ext.lib.Dom.getViewWidth() - width) / 2
        };
    
        this.getWinY = function(height){
            return (Ext.lib.Dom.getViewHeight()-taskbarEl.getHeight() - height) / 2;
        };
    
        this.setTickSize = function(xTickSize, yTickSize) {
            this.xTickSize = xTickSize;
            if (arguments.length == 1) {
                this.yTickSize = xTickSize;
            } else {
                this.yTickSize = yTickSize;
            }
            windows.each(function(win) {
                win.dd.xTickSize = this.xTickSize;
                win.dd.yTickSize = this.yTickSize;
                win.resizer.widthIncrement = this.xTickSize;
                win.resizer.heightIncrement = this.yTickSize;
            }, this);
        };
    
        this.cascade = function() {
            var xTick = Math.max(this.xTickSize, 20);
            var yTick = Math.max(this.yTickSize, 20);
            var x = xTick;
            var y = yTick;
            windows.each(function(win) {
                if (win.isVisible() && !win.maximized) {
                    win.setPosition(x, y);
                    x += xTick;
                    y += yTick;
                }
            }, this);
        };
    
        this.tile = function() {
            var availWidth = desktopEl.getWidth(true);
            var x = this.xTickSize;
            var y = this.yTickSize;
            var nextY = y;
            windows.each(function(win) {
                if (win.isVisible() && !win.maximized) {
                    var w = win.el.getWidth();
    
    //              Wrap to next row if we are not at the line start and this Window will go off the end
                    if ((x > this.xTickSize) && (x + w > availWidth)) {
                        x = this.xTickSize;
                        y = nextY;
                    }
    
                    win.setPosition(x, y);
                    x += w + this.xTickSize;
                    nextY = Math.max(nextY, y + win.el.getHeight() + this.yTickSize);
                }
            }, this);
        };
    
        this.contextMenu = new Ext.menu.Menu({
            items: [{
                text: 'Tile',
                handler: this.tile,
                scope: this
            }, {
                text: 'Cascade',
                handler: this.cascade,
                scope: this
            }]
        });
        desktopEl.on('contextmenu', function(e) {
            e.stopEvent();
            this.contextMenu.showAt(e.getXY());
        }, this);
    
        layout();
    
        if(shortcuts){
            shortcuts.on('click', function(e, t){
                if(t = e.getTarget('dt', shortcuts)){
                    e.stopEvent();
                    var module = app.getModule(t.id.replace('-shortcut', ''));
                    if(module){
                        module.createWindow();
                    }
                }
            });
        }
    };

  4. #4
    Ext User
    Join Date
    Nov 2008
    Posts
    6
    Vote Rating
    0
      0  

    Default

    ah right, thats almost bang on what I was after. Thanks.

    Now I have another question - I was using the portal example, and trying to add resizable windows to it, but it seems that using the Desktop example is the way to go.

    However I still want to have a navigation menu in the west "pane"/"region" of the screen, and have my application child windows tiled into the "center" region.

    What is the best way to achieve that, I'm thinking of splitting the x-desktop div into 2 areas so the tile context menu arranges the Windows into the "center" div of the x-desktop - but somehow I am wondering if I should be using another object for this?

    Any ideas?

    Many Thanks,

    Tom

  5. #5
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,615
    Vote Rating
    54
      0  

    Default

    You'll have to enhance the Desktop class to be an Ext.Container which manages the div #desktop using layout:'border'

    You'll have to add a handler to Ext.EventManager.onWindowResize to call doLayout which will arrange the west/center split.

  6. #6
    Ext User
    Join Date
    Nov 2008
    Posts
    6
    Vote Rating
    0
      0  

    Default

    So I have got a bit further, and now I am stuck. Is this the right way to proceeed;


    1) I have my Desktop class

    Code:
    Ext.Desktop = function(app){
    ...
    }
    2) I am extending it to include the Container functionality;

    Code:
    Ext.extend(Ext.Desktop, Ext.Container, {
    
    });
    3) I am calling the Container contructor in the Ext.desktop constructor, and passing in the Container config parameters;

    Code:
       Ext.Desktop = function(app){
        
         Ext.Desktop.superclass.constructor.call({
        layout: 'border',
        el: 'x-desktop',
        title: 'Results',
    });
    4) I have added a handler to onWindowResize in Ext.Desktop

    Code:
    Ext.EventManager.onWindowResize(doLayout);
    I'm gettng;

    Code:
    this.addEvents is not a function
    file:///G:/Projects/windowing/ext-2.2/ext-all.js
    Line 58

  7. #7
    Ext User
    Join Date
    Nov 2008
    Posts
    6
    Vote Rating
    0
      0  

    Default

    OK, well I created a "DesktopContainer" object similar to how the TaskBar was done with a;

    Code:
    Ext.DesktopContainer = Ext.extend(Ext.Container, {
        initComponent : function() {
            Ext.DesktopContainer.superclass.initComponent.call(this);
    ...
    
    }
    and created an init function in the extended class to create a new container;

    Code:
    Ext.extend(Ext.Desktop, Ext.util.Observable, {
        init : function(){
                var container = new Ext.DesktopContainer({
                el: 'x-desktop',
                layout:'border',
                hideBorders: true,
    and Desktop now inits itself;

    Code:
    Ext.Desktop = function(app){
        
    this.init();
    I still can't get the windows to render into the container frames, they go to x-desktop...

    Thanks,

    Tom

  8. #8
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,615
    Vote Rating
    54
      0  

    Default

    Desktop should extend Container IMNSHO.

    Persevere down that route.

  9. #9
    Ext User
    Join Date
    Jul 2007
    Location
    Florida
    Posts
    9,996
    Vote Rating
    8
      0  

    Default

    For what it's worth I'm currently down a road of using Ext.ux.View instead of calling it Ext.Desktop. Ext.ux.View is implemented to support different 'view' layouts, one of which will be a "desktop" view.

    At the moment Ext.ux.View extends Ext.Viewport, but I had already planned to look at going a step farther and extending Ext.Container like Animal suggested. I haven't fully explored to see what penalties/benefits these two alternatives present, but Viewport was the easier to implement initially.

    I've gone the Ext.ux.View route because my thought is that I can dynamically alter the view easier this way, whether it will be a "desktop" GUI or the more typical "web layout" typically seen around.

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,615
    Vote Rating
    54
      0  

    Default

    Viewport extends Container if you look, so you are basically extending Container.

    Viewport just hardcodes that it's el is document.body, and attaches a resize listener to the Window in order to fire its own resize event and trigger the cascade of layouts.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •