1. #1
    Ext JS Premium Member
    Join Date
    Feb 2009
    Posts
    108
    Vote Rating
    0
    PierceSD is on a distinguished road

      0  

    Default [2.2.1] Border layout resize issues

    [2.2.1] Border layout resize issues


    Not sure if this is a "bug" or "feature request", but I've noticed two issues with BorderLayout and resizing:

    1) The center region's minimum width/height property is ignored when resizing the container.

    2) Sizing the layout's container too small causes odd effects: the regions start to overlap and the split bar gets hidden (but you can still drag it)

    The override below fixes these problems, and adds a couple of improvements (more efficient rendering, region-specific CSS classes). Changes are highlighted in color.

    Code:
    Ext.override(Ext.layout.BorderLayout, {
        onLayout: function(ct, target) {
            if (this.initCollapsed) return; //do not perform layout when initializing collapsed state
    
            var collapsed;
            if (!this.rendered) {
                target.position();
                target.addClass('x-border-layout-ct');
                var items = ct.items.items;
                collapsed = [];
                for (var i = 0, len = items.length; i < len; i++) {
                    var c = items[i];
                    var pos = c.region;
                    if (c.collapsed) {
                        collapsed.push(c);
                    }
                    c.collapsed = false;
                    if (!c.rendered) {
                        c.cls = c.cls ? c.cls + ' x-border-panel': 'x-border-panel';
                        c.cls += ' x-border-panel-' + pos;  //make region-specific styling easier
                        c.render(target, i);
                    }
                    this[pos] = pos != 'center' && c.split ? 
                          new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) : 
                          new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
                    this[pos].render(target, c);
                }
                this.rendered = true;
            }
    
            var size = target.getViewSize();
            if (size.width < 20 || size.height < 20) { // display none?
                if (collapsed) {
                    this.restoreCollapsed = collapsed;
                }
                return;
            } else if (this.restoreCollapsed) {
                collapsed = this.restoreCollapsed;
                delete this.restoreCollapsed;
            }
    
            var w = size.width, h = size.height;
            var centerW = w, centerH = h, centerY = 0,  centerX = 0;
    
            var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
            if (!c && Ext.layout.BorderLayout.WARN !== false) {
                throw 'No center region defined in BorderLayout ' + ct.id;
            }
    
            centerW = Math.max(w - this.getRegionWidths(), c ? c.getMinWidth() : 0);
            centerH = Math.max(h - this.getRegionHeights(), c ? c.getMinHeight() : 0);
    
            if (n && n.isVisible()) {
                var b = n.getSize();
                var m = n.getMargins();
                b.width = w - (m.left + m.right);
                b.x = m.left;
                b.y = m.top;
                centerY = b.height + b.y + m.bottom;
                //centerH -= centerY;
                n.applyLayout(b);
            }
            if (s && s.isVisible()) {
                var b = s.getSize();
                var m = s.getMargins();
                b.width = w - (m.left + m.right);
                b.x = m.left;
                var totalHeight = (b.height + m.top + m.bottom);
                //b.y = h - totalHeight + m.top;
                //centerH -= totalHeight;
                b.y = centerH + (n && n.isVisible() ? n.getSize().height: 0) + m.top;
                s.applyLayout(b);
            }
            if (west && west.isVisible()) {
                var b = west.getSize();
                var m = west.getMargins();
                b.height = centerH - (m.top + m.bottom);
                b.x = m.left;
                b.y = centerY + m.top;
                var totalWidth = (b.width + m.left + m.right);
                centerX += totalWidth;
                //centerW -= totalWidth;
                west.applyLayout(b);
            }
            if (e && e.isVisible()) {
                var b = e.getSize();
                var m = e.getMargins();
                b.height = centerH - (m.top + m.bottom);
                var totalWidth = (b.width + m.left + m.right);
                //b.x = w - totalWidth + m.left;
                b.x = centerW + (west && west.isVisible() ? west.getSize().width: 0) + m.left;
                b.y = centerY + m.top;
                //centerW -= totalWidth;
                e.applyLayout(b);
            }
    
            if (c) {
                var m = c.getMargins();
                var centerBox = {
                    x: centerX + m.left,
                    y: centerY + m.top,
                    width: centerW - (m.left + m.right),
                    height: centerH - (m.top + m.bottom)
                };
                c.applyLayout(centerBox);
            }
            if (collapsed) {
                this.initCollapsed = true;
                for (var i = 0, len = collapsed.length; i < len; i++) {
                    collapsed[i].collapse(false);
                }
                this.initCollapsed = false;
            }
    
            if (Ext.isIE && Ext.isStrict) { // workaround IE strict repainting issue
                target.repaint();
            }
        },
    
        getRegionHeights: function() {
            var h = 0, m, regions = [this.north, this.south];
            Ext.each(regions, function(r) {
                if (r && r.isVisible()) {
                    m = r.getMargins();
                    h += r.getSize().height + m.top + m.bottom;
                }
            }, this);
            return h;
        },
        getRegionWidths: function() {
            var w = 0, m, regions = [this.west, this.east];
            Ext.each(regions, function(r) {
                if (r && r.isVisible()) {
                    m = r.getMargins();
                    w += r.getSize().width + m.left + m.right;
                }
            }, this);
            return w;
        }
    });
    Including this override will cause the layout to resize the center region as small as it will allow. If it is sized any smaller, the overflow gets clipped.

    I've tested in FF3, IE7 and Chrome.
    --Chad Eberle
    Web Application Architect
    Pierce County Software Development
    Pierce County, Washington

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

      0  

    Default


    Ext 3.0 has disabling of layout on hidden or collapsed Containers.

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

      0  

    Default


    I like the 'x-border-panel-' + pos class though!

    You should post a Feature Request for just that.

  4. #4
    Ext JS Premium Member
    Join Date
    Feb 2009
    Posts
    108
    Vote Rating
    0
    PierceSD is on a distinguished road

      0  

    Default


    Quote Originally Posted by Animal View Post
    Ext 3.0 has disabling of layout on hidden or collapsed Containers.
    Good to hear. That isn't really the core issue I was trying to address, though.

    Quote Originally Posted by Animal View Post
    I like the 'x-border-panel-' + pos class though!

    You should post a Feature Request for just that.
    You're right, I'll make a feature request for that separately.
    --Chad Eberle
    Web Application Architect
    Pierce County Software Development
    Pierce County, Washington

  5. #5
    Touch Premium Member
    Join Date
    Jan 2008
    Location
    Quebec, Canada
    Posts
    122
    Vote Rating
    1
    nbourdeau is on a distinguished road

      0  

    Default


    Thank you for this code PierceSD. It is working great (we are using version 3.3.1).
    It is worth noting that the resizing issues are still present in extJS 3 and 4.
    I hope they will fix this soon !

Thread Participants: 2