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

      0  

    Default Ext.FloatLayout A layout which floats the child Components

    Ext.FloatLayout A layout which floats the child Components


    This layout floats each child item across its available width.

    Like qooxdoo's Flow layout: http://demo.qooxdoo.org/current/demo...yout~Flow.html

    When the next item won't fit in the width, it explicitly styles it with clear: left so that it wraps to position zero which would not happen if just naturally floated.

    Code:
    Ext.layout.FloatLayout = Ext.extend(Ext.layout.ContainerLayout, {
        setContainer: function(ct) {
            Ext.layout.FloatLayout.superclass.setContainer.apply(this, arguments);
            ct.addClass('ux-float-layout-ct');
        },
    
        renderAll: function(ct) {
            this.cr = this.container.getLayoutTarget().getBox(true).right;
            Ext.layout.FloatLayout.superclass.renderAll.apply(this, arguments);
        },
    
        renderItem : function(c, position, target){
            var r = c.rendered,
                e, p, pe, w;
            Ext.layout.FloatLayout.superclass.renderItem.apply(this, arguments);
            e = c.getDomPositionEl();
            if (!r) {
                e.setStyle('float', 'left');
            }
            e.setStyle('clear', 'none');
            w = e.getWidth() + e.getMargins('lr');
            if (p = c.previousSibling()) {
                pe = p.getDomPositionEl();
                if ((pe.getBox().right + pe.getMargins('r') + w) > this.cr) {
                    e.setStyle('clear', 'left');
                }
            }
        },
    
        isValidParent: function() {
            return false;
        }
    });
    Ext.Container.LAYOUTS['float'] = Ext.layout.FloatLayout;


    Post #4 contains correct layout embedded in an example page.

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,251
    Vote Rating
    73
    Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold

      1  

    Default


    ColumnLayout is already a floating layout (simply don't specify a columnWidth).

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

      0  

    Default


    It won't clear items though if you want a layout like http://blog.mozilla.com/webdev/2009/...-inline-block/

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

      0  

    Default


    To see this, run this example page in examples/menu

    Code:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Toolbar with Menus</title>
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../../ext-all-debug.js"></script>
    <script type="text/javascript" src="../ux/FieldLabeler.js"></script>
    <script type="text/javascript" src="../form/states.js"></script>
    <style type="text/css">
    .ux-float-layout-ct {
        position: relative;
    }
    .ux-float-layout-ct .ux-float-layout-sizer {
        background: transparent none;
        border: 0 none;
        padding: 0;
        margin: 0;
        width: 0;
    }
    
    .ux-float-layout-ct .x-box-item {
        position: absolute;
    }
    
    .test-item {
        height: 77px;
        width: 60px;
    }
    
    .show-icons .test-item-inner {
        margin-left: 5px;
        margin-top: 5px;
        background-image: url(http://demo.qooxdoo.org/current/demobrowser/resource/qx/icon/Tango/48/devices/computer.png);
        height:48px;
        width:48px;
    }
    
    .hide-icons .test-item {
        border: 1px solid #99BBE8;
        height: auto;
        margin: 3px;
        padding: 2px 4px;
        width: 40px;
    }
    
    .test-item-desc {
        margin-top: 5px;
        text-align: center;
    }
    
    .x-btn-text-icon em {
        display: block;
        height: 100%;
    }
    
    button.test-button {
        height: 100%!important;
        width: 100%!important;
        background-image: url(http://demo.qooxdoo.org/current/demobrowser/resource/qx/icon/Tango/48/devices/computer.png)!important;
        padding-left: 40px!important;
    }
    
    </style>
    <script type="text/javascript">
    Ext.override(Ext.Element, (function(){
        var pxMatch = /(\d+\.?\d+)px/;
    
        return {
            // private.
            // Return the addressable area of the element using explicit CSS style in preference to offsetHeight/offsetWidth.
            // Optionally subtract padding if contentBox parameter is truthy
            getStyleSize : function(contentBox){
                var doc = document,
                    me = this,
                    d = me.dom,
                    extdom = Ext.lib.Dom,
                    isDoc = (d == doc || d == doc.body),
                    isBB, w, h, tbBorder = 0, lrBorder = 0,
                    tbPadding = 0, lrPadding = 0;
                if (isDoc) {
                    return { width: extdom.getViewWidth(), height: extdom.getViewHeight() };
                }
                isBB = me.isBorderBox();
                tbBorder = me.getBorderWidth('tb');
                lrBorder = me.getBorderWidth('lr');
                tbPadding = me.getPadding('tb');
                lrPadding = me.getPadding('lr');
    
                // Width calcs
                // Try the style first, then offsetWidth
                if (w = me.getStyle('width').match(pxMatch)){
                    if ((w = parseFloat(w[1])) && isBB){
                        // Style includes the padding and border if isBB
                        w -= (lrBorder + lrPadding);
                    }
                    w += lrPadding;
                } else if (w = d.offsetWidth){
                    w -= lrBorder;
                }
                w && contentBox && (w -= lrPadding);
    
                // Height calcs
                // Try the style first, then offsetHeight
                if (h = me.getStyle('height').match(pxMatch)){
                    if ((h = parseFloat(h[1])) && isBB){
                        // Style includes the padding and border if isBB
                        h -= (tbBorder + tbPadding);
                    }
                    h += tbPadding;
                } else if (h = d.offsetHeight){
                    h -= tbBorder;
                }
                h && contentBox && (h -= tbPadding);
    
                return {
                    width : w,
                    height : h
                };
            },
    
            /**
             * <p>Returns the dimensions of the element available to lay content out in.<p>
             * <p>If the element (or any ancestor element) has CSS style <code>display : none</code>, the dimensions will be zero.</p>
             * example:<pre><code>
            var vpSize = Ext.getBody().getViewSize();
    
            // all Windows created afterwards will have a default value of 90% height and 95% width
            Ext.Window.override({
                width: vpSize.width * 0.9,
                height: vpSize.height * 0.95
            });
            // To handle window resizing you would have to hook onto onWindowResize.
            </code></pre>
             * @param {Boolean} contentBox True to return the W3 content box <i>within</i> the padding area of the element. False
             * or omitted to return the full area of the element within the border. See <a href="http://www.w3.org/TR/CSS2/box.html">http://www.w3.org/TR/CSS2/box.html</a>
             * @return {Object} An object containing the elements's area: <code>{width: &lt;element width>, height: &lt;element height>}</code>
             */
            getViewSize : function(contentBox){
                var doc = document,
                    me = this,
                    d = me.dom,
                    extdom = Ext.lib.Dom,
                    isDoc = (d == doc || d == doc.body),
                    ss = Ext.isIE ? me.getStyleSize(contentBox) : null, w, h;
                if (isDoc) {
                    return { width: extdom.getViewWidth(), height: extdom.getViewHeight() };
                }
    
                // Width calcs
                // Try clientWidth, then styleWidth
                if (w = d.clientWidth){
    
    //              IE sometimes overestimates client size
                    Ext.isIE && w > ss.width && (w = ss.width);
    
                    if (contentBox){
                        w -= me.getPadding('lr');
                    }
                } else {
                    if (!ss) ss = me.getStyleSize(contentBox);
                    w = ss.width;
                }
    
                // Height calcs
                // Try clientHeight, then styleHeight
                if (h = d.clientHeight){
    
    //              IE sometimes overestimates client size
                    Ext.isIE && h > ss.height && (h = ss.height);
                    if (contentBox){
                        h -= me.getPadding('tb');
                    }
                } else {
                    if (!ss) ss = me.getStyleSize(contentBox);
                    h = ss.height;
                }
    
                return {
                    width : w,
                    height : h
                };
            }
        };
    })());
    
    /**
     * @class Ext.layout.FloatLayout
     * @extends Ext.layout.BoxLayout
     * <p>A layout that arranges items in a left to right flow similar to using HTML's <code>float: left</code> style.</p>
     * <p>When a Component's width (including its padding) won't fit within the available width of the Container (within its padding)
     * then the Component is wrapped to the beginning of a new line, clearing the tallest item on the current line.</p>
     * <p>Items may be vertically aligned with the row they happen to fall within. A line's height is the height of its tallest child
     * item (including its margins), and vertical alignment take place within this space. Vertical alignment is specified for the layout using the
     * {@link #verticalAlign} config, and may be overriden for a single item by configuring an item with a verticalAlign value.</p>
     * <p>Row content may be aligned within the available width of the Container using the {@link #horizontalAlign} config.</p>
     * <p>Child items may be cleared left or right by configuring a <b>clear</b> value in the item.</p>
     * <p>Row and column spacing may be specified using the {@link #verticalSpacing} and {@link #horizontalSpacing} options.</p>
     * <p>Child items may use <code>columnWidth</code> config to specify a fraction of the available width that the item is to occupy.</p>
     */
    Ext.layout.FloatLayout = Ext.extend(Ext.layout.BoxLayout, {
        /**
         * @cfg {Boolean} animate
         * <p><code>true</code> to animate child items into their calculated positions.</p>
         * <p>Defaults to <code>false</code>.</p>
         */
    
        /**
         * @cfg {String} verticalAlign
         * <p>Vertical alignment of child items within each row. Defaults to 'middle'. Values may be</p>
         * <code>'top'</code>, <code>'middle'</code> or <code>'bottom'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        verticalAlign: 'middle',
    
        /**
         * @cfg {String} horizontalAlign
         * <p>Horizontal alignment of child items within each row. Defaults to 'left'. Values may be</p>
         * <code>'left'</code>, <code>'center'</code>, <code>'right'</code> or <code>'justify'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        horizontalAlign: 'left',
    
        /**
         * @cfg {Number} horizontalSpacing
         * <p>Horizontal space to leave between items.</p>
         */
        horizontalSpacing: 0,
    
        /**
         * @cfg {Number} verticalSpacing
         * <p>Vertical space to leave between rows.</p>
         */
        verticalSpacing: 0,
    
        /**
         * @cfg {Number} rightLimit
         * <p>Max rightmost point to which the right edge of items are allowed to reach before wrapping.</p>
         */
        rightLimit: 0,
    
        targetCls : 'ux-float-layout-ct',
    
        setContainer: function(ct) {
            var ce = ct.getLayoutTarget();
            this.sizer = ce.insertFirst({
                cls: 'ux-float-layout-sizer'
            });
            this.padding = this.parseMargins(this.padding||'0');
            Ext.layout.FloatLayout.superclass.setContainer.apply(this, arguments);
        },
    
        renderAll : function(ct, target){
            Ext.layout.BoxLayout.superclass.renderAll.apply(this, arguments);
        },
    
        onLayout: function() {
            var ct = this.container,
                cte = ct.getLayoutTarget(),
                s = cte.getStyleSize(),
                padding = Ext.apply({}, this.padding);
    
            padding.top = this.getMarginValue(this.padding.top, s.height);
            padding.right = this.getMarginValue(this.padding.right, s.width) - this.horizontalSpacing;
            padding.bottom = this.getMarginValue(this.padding.bottom, s.height) - this.verticalSpacing;
            padding.left = this.getMarginValue(this.padding.left, s.width);
    
            var paddingLeft = padding.left + cte.getPadding('l'),
                paddingTop = padding.top + cte.getPadding('t'),
                rightLimit = s.width -= (padding.right + cte.getPadding('r')),
                bottomLimit = s.height - (padding.bottom + cte.getPadding('b')),
                rowStart = 0,
                rowHeight = 0,
                rowWidth = 0,
                x = paddingLeft,
                y = paddingTop,
                items = this.getRenderedItems(ct),
                l = items.length, i, c, lc, ce, cs, m, rm, r,
                itemPos = [], firstFillItem;
    
    //      We never want to see horizontal scroll bars if possible
            cte.setStyle('overflow-x', 'hidden');
    
    //      Content Width.
            s.width -= paddingLeft;
    
            if (this.rightLimit && this.rightLimit < rightLimit) {
                rightLimit = this.rightLimit;
            }
    
            for (var i = 0, l = items.length; i < l; i++) {
                c = items[i];
                ce = c.getPositionEl();
    
    //          Capure first fill item
                if (c.fillHeight) {
                    c.setHeight('auto');
                    if (!firstFillItem) {
                        firstFillItem = i;
                    }
                }
                cs = c.getSize();
    
    //          Allow floating point allocation of available width
                if (c.columnWidth) {
                    c.setWidth(cs.width = (Math.round(s.width * c.columnWidth) - this.horizontalSpacing));
                }
                if (c.cellHeight) {
                    c.setHeight(cs.height = (Math.round(s.height * c.cellHeight) - this.verticalSpacing));
                }
    
                rm = ce.getMargins('r');
                cs.width += ce.getMargins('lr');
                cs.height += ce.getMargins('tb');
                m = c.margins;
                x += m.left;
                r = x + cs.width;
    
    //          This item won't fit on the row.
                if ((r > rightLimit) || (c.clear == 'left') || (lc && lc.clear == 'right')) {
                    this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
                    x = paddingLeft + m.left;
                    y += rowHeight + this.verticalSpacing;
                    r = x + cs.width + m.right;
                    rowStart = i;
                    rowHeight = 0;
                    rowWidth = 0;
                }
    
                rowHeight = Math.max(rowHeight, cs.height);
                rowWidth += cs.width;
    
    //          We are laying out an autoScroll Container, and this item is going to cause a vertical scrollbar:
    //          Adjust the right padding to account for that scrollbar, and reflow.
                if (ct.autoScroll && !this.reflow && ((y + rowHeight) > bottomLimit)) {
                    r = this.padding.right;
                    this.padding.right += Ext.getScrollBarWidth();
                    this.reflow = true;
                    this.onLayout();
                    delete this.reflow;
                    this.padding.right = r;
                    return;
                }
    
                itemPos.push([x, y]);
                x += cs.width + m.right + this.horizontalSpacing;
                lc = c;
            }
    
    //      Adjust the last row
            this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
    
    //      Stretch the container heightwise.
            this.sizer.setHeight(r = (y + rowHeight - cte.getPadding('t')));
    
            if (firstFillItem) {
                var spare = s.height - r - padding.bottom - padding.top;
                rowHeight = 0;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    ce = c.getPositionEl();
                    cs = c.getSize();
                    cs.height += ce.getMargins('tb');
                    rowHeight = Math.max(rowHeight, cs.height);
                }
                rowHeight += spare;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    if (c.fillHeight) {
                        ce = c.getPositionEl();
                        cs = c.getSize();
                        c.setHeight(rowHeight - ce.getMargins('tb'));
                    }
                }
            } else {
            }
    
    //      Animate child items into place.
            for (var i = 0, l = items.length; i < l; i++) {
                if (this.animate) {
                    Ext.lib.Anim.motion(items[i].getPositionEl().dom, {left: {to: itemPos[i][0]}, top: {to: itemPos[i][1]}}).animate();
                } else {
                    items[i].setPosition(itemPos[i]);
                }
            }
        },
    
        getMarginValue: function(v, s) {
            if (Ext.isNumber(v)) {
                return (v < 1) ? s * v  : v;
            }
            return 0;
        },
    
        parseMargins : function(v){
            if(Ext.isNumber(v)){
                v = v.toString();
            }
            var ms = v.split(' ');
            var len = ms.length;
            if(len == 1){
                ms[1] = ms[2] = ms[3] = ms[0];
            } else if(len == 2){
                ms[2] = ms[0];
                ms[3] = ms[1];
            } else if(len == 3){
                ms[3] = ms[1];
            }
            return {
                top: parseFloat(ms[0], 10) || 0,
                right: parseFloat(ms[1], 10) || 0,
                bottom: parseFloat(ms[2], 10) || 0,
                left: parseFloat(ms[3], 10) || 0
            };
        },
    
    //  Adjust vertical alignment within row.
    //  Adjust horizontal alignment if required.
        adjustRow: function(items, itemPos, rowStart, rowEnd, rowHeight, rowWidth, availWidth) {
            var i, c, h, j = 0, gaps = rowEnd - rowStart, spareWidth, alignmentIncrement = 0;
            rowWidth += gaps * this.horizontalSpacing;
            spareWidth = availWidth - rowWidth;
    
            switch (this.horizontalAlign) {
                case 'middle':
                case 'center':
                    alignmentIncrement = Math.max(spareWidth / 2, 0);
                    break;
                case 'right':
                    alignmentIncrement = Math.max(spareWidth, 0);
                    break;
                case 'justify':
                    if (gaps) {
                        j = Math.max(spareWidth / gaps, 0);
                    }
            }
    
            for (i = rowStart; i <= rowEnd; i++) {
                c = items[i];
                h = c.getHeight() + c.getPositionEl().getMargins('tb');
                itemPos[i][0] += alignmentIncrement;
                alignmentIncrement += j;
                switch (c.verticalAlign || this.verticalAlign) {
                    case 'middle':
                    case 'center':
                        itemPos[i][1] += (rowHeight - h) / 2;
                        break;
                    case 'bottom':
                        itemPos[i][1] += (rowHeight - h);
                }
            }
        },
    
        isValidParent: function(c, e) {
            return c.getPositionEl().dom.parentNode === e.dom;
        }
    });
    Ext.Container.LAYOUTS['float'] = Ext.layout.FloatLayout;
    
    Ext.override(Ext.Element, {
    
    /**
     * Lay out the child elements of this element in a left to right flow similar to using HTML's <code>float: left</code> style.</p>
     * <p>When a Component's width (including its padding) won't fit within the available width of the Container (within its padding)
     * then the Component is wrapped to the beginning of a new line, clearing the tallest item on the current line.</p>
     * <p>Items may be vertically aligned with the row they happen to fall within. A line's height is the height of its tallest child
     * item (including its margins), and vertical alignment take place within this space. Vertical alignment is specified for the layout using the
     * {@link #verticalAlign} config, and may be overriden for a single item by configuring an item with a verticalAlign value.</p>
     * <p>Row content may be aligned within the available width of the Container using the {@link #horizontalAlign} config.</p>
     * <p>Child items may be cleared left or right by configuring a <b>clear</b> value in the item.</p>
     * <p>Row and column spacing may be specified using the {@link #verticalSpacing} and {@link #horizontalSpacing} options.
     */
        doLayout: function(config) {
            this.layout = Ext.apply({
                itemSelector: '/*:not(.ux-float-layout-sizer)',
                animate: false,
                verticalAlign: 'middle',
                horizontalAlign: 'left',
                horizontalSpacing: 0,
                verticalSpacing: 0,
                padding: 0
            }, config);
            this.layout.padding = Ext.layout.ContainerLayout.prototype.parseMargins(this.layout.padding);
    
            var items = this.query(this.layout.itemSelector),
                me = this,
                paddingLeft = this.layout.padding.left + me.getPadding('l'),
                paddingTop = this.layout.padding.top + me.getPadding('t'),
                s = me.getStyleSize(),
                rightLimit = (s.width -= (this.layout.padding.right + me.getPadding('r'))),
                bottomLimit = s.height - (this.layout.padding.bottom + me.getPadding('b')),
                rowStart = 0,
                rowHeight = 0,
                rowWidth = 0,
                x = paddingLeft,
                y = paddingTop,
                l = items.length, i, c, cs, m, r,
                itemPos = [], a;
    
    //      Nothing to lay out.
            if (!items.length) return;
    
            if (!(me.sizer = this.child('.ux-float-layout-sizer'))) {
                me.sizer = me.insertFirst({
                    cls: 'ux-float-layout-sizer'
                });
            }
    
    //      We never want to see horizontal scroll bars if possible
            me.setStyle({
                'overflow-x': 'hidden',
                position: 'relative'
            });
    
    //      Content Width.
            s.width -= paddingLeft;
    
            for (var i = 0, l = items.length; i < l; i++) {
                c = (items[i] = Ext.get(items[i]));
                c.setStyle({
                    position: 'absolute'
                });
                cs = c.getSize();
                m = /*c.margins ||*/ {top: 0, right: 0, bottom: 0, left: 0};
                cs.width += c.getMargins('lr');
                cs.height += c.getMargins('tb');
                r = x + m.left + cs.width + m.right;
    
    //          This item won't fit on the row.
                if ((r > rightLimit) || (c.dom.style.clear == 'left') || ((i > 0) && items[i - 1].dom.style.clear == 'right')) {
                    me.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
                    x = paddingLeft;
                    y += rowHeight + me.layout.verticalSpacing;
                    r = x + m.left + cs.width + m.right;
                    rowStart = i;
                    rowHeight = 0;
                    rowWidth = 0;
                }
    
                rowHeight = Math.max(rowHeight, cs.height);
                rowWidth += cs.width;
    
    //          This item is going to cause a vertical scrollbar:
    //          Adjust the right padding to account for that scrollbar, and reflow.
                if (!me.reflow && ((y + rowHeight) > bottomLimit)) {
                    r = me.layout.padding.right;
                    me.layout.padding.right += Ext.getScrollBarWidth();
                    me.reflow = true;
                    me.doLayout();
                    delete me.reflow;
                    me.layout.padding.right = r;
                    return;
                }
    
                itemPos.push([x, y]);
                x = r + me.layout.horizontalSpacing;
            }
    
    //      Adjust the last row
            me.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
    
    //      Stretch the container heightwise.
            me.sizer.setHeight(y + rowHeight - paddingTop);
    
    //      Animate child items into place.
            for (var i = 0, l = items.length; i < l; i++) {
                if (me.layout.animate) {
                    a = Ext.lib.Anim.motion(items[i].dom, {left: {to: itemPos[i][0]}, top: {to: itemPos[i][1]}});
                    a.animate();
                } else {
                    items[i].setStyle({
                        left: itemPos[i][0] + 'px',
                        top: itemPos[i][1] + 'px'
                    });
                }
            }
        },
    
    //  Adjust vertical alignment within row.
    //  Adjust horizontal alignment if required.
        adjustRow: function(items, itemPos, rowStart, rowEnd, rowHeight, rowWidth, availWidth) {
            var me = this, i, c, h, j = 0, gaps = rowEnd - rowStart, spareWidth, alignmentIncrement = 0;
            rowWidth += gaps * me.layout.horizontalSpacing;
            spareWidth = availWidth - rowWidth;
    
            switch (me.layout.horizontalAlign) {
                case 'middle':
                case 'center':
                    alignmentIncrement = Math.max(spareWidth / 2, 0);
                    break;
                case 'right':
                    alignmentIncrement = Math.max(spareWidth, 0);
                    break;
                case 'justify':
                    if (gaps) {
                        j = Math.max(spareWidth / gaps, 0);
                    }
            }
    
            for (i = rowStart; i <= rowEnd; i++) {
                c = items[i];
                h = c.getHeight() + c.getMargins('tb');
                itemPos[i][0] += alignmentIncrement;
                alignmentIncrement += j;
                switch (c.dom.style.verticalAlign || me.layout.verticalAlign) {
                    case 'middle':
                    case 'center':
                        itemPos[i][1] += (rowHeight - h) / 2;
                        break;
                    case 'bottom':
                        itemPos[i][1] += (rowHeight - h);
                }
            }
        }
    });
    
    Ext.onReady(function(){
        Ext.QuickTips.init();
    
        // Menus can be prebuilt and passed by reference
        var dateMenu = new Ext.menu.DateMenu({
            handler: function(dp, date){
                Ext.example.msg('Date Selected', 'You chose {0}.', date.format('M j, Y'));
            }
        });
    
        var colorMenu = new Ext.menu.ColorMenu({
            handler: function(cm, color){
                Ext.example.msg('Color Selected', 'You chose {0}.', color);
            }
        });
        
        var store = new Ext.data.ArrayStore({
            fields: ['abbr', 'state'],
            data : Ext.exampledata.states // from states.js
        });
    
        var combo = new Ext.form.ComboBox({
            store: store,
            displayField: 'state',
            typeAhead: true,
            mode: 'local',
            triggerAction: 'all',
            emptyText: 'Select a state...',
            selectOnFocus: true,
            width: 135,
            getListParent: function() {
                return this.el.up('.x-menu');
            },
            iconCls: 'no-icon'
        });
    
        var menu = new Ext.menu.Menu({
            id: 'mainMenu',
            style: {
                overflow: 'visible'     // For the Combo popup
            },
            items: [
                combo,                  // A Field in a Menu
                {
                    text: 'I like Ext',
                    checked: true,       // when checked has a boolean value, it is assumed to be a CheckItem
                    checkHandler: onItemCheck
                }, '-', {
                    text: 'Radio Options',
                    menu: {        // <-- submenu by nested config object
                        items: [
                            // stick any markup in a menu
                            '<b class="menu-title">Choose a Theme</b>',
                            {
                                text: 'Aero Glass',
                                checked: true,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }, {
                                text: 'Vista Black',
                                checked: false,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }, {
                                text: 'Gray Theme',
                                checked: false,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }, {
                                text: 'Default Theme',
                                checked: false,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }
                        ]
                    }
                },{
                    text: 'Choose a Date',
                    iconCls: 'calendar',
                    menu: dateMenu // <-- submenu by reference
                },{
                    text: 'Choose a Color',
                    menu: colorMenu // <-- submenu by reference
                }
            ]
        });
    
        var tb = new Ext.Toolbar({
            id: 'tb',
            layout: {
                type: 'float',
                verticalSpacing: 4,
                horizontalSpacing: 4
            }
        });
    
        tb.add({
                text:'Button w/ Menu',
                iconCls: 'bmenu',  // <-- icon
                menu: menu  // assign menu by instance
            }, {
                text: 'Users',
                iconCls: 'user',
                menu: {
                    xtype: 'menu',
                    plain: true,
                    items: {
                        xtype: 'buttongroup',
                        title: 'User options',
                        autoWidth: true,
                        columns: 2,
                        defaults: {
                            xtype: 'button',
                            scale: 'large',
                            width: '100%',
                            iconAlign: 'left'
                        },
                        items: [{
                            text: 'User<br/>manager',
                            iconCls: 'edit'
                        },{
                            iconCls: 'add',
                            width: 'auto',
                            tooltip: 'Add user'
                        },{
                            colspan: 2,
                            text: 'Import',
                            scale: 'small'
                        },{
                            colspan: 2,
                            text: 'Who is online?',
                            scale: 'small'
                        }]
                    }
                }
            },
            new Ext.Toolbar.SplitButton({
                text: 'Split Button',
                handler: onButtonClick,
                tooltip: {text:'This is a an example QuickTip for a toolbar item', title:'Tip Title'},
                iconCls: 'blist',
                // Menus can be built/referenced by using nested menu config objects
                menu : {
                    items: [{
                        text: '<b>Bold</b>', handler: onItemClick
                    }, {
                        text: '<i>Italic</i>', handler: onItemClick
                    }, {
                        text: '<u>Underline</u>', handler: onItemClick
                    }, '-', {
                        text: 'Pick a Color',
                        handler: onItemClick,
                        menu: {
                            items: [
                                new Ext.ColorPalette({
                                    listeners: {
                                        select: function(cp, color){
                                            Ext.example.msg('Color Selected', 'You chose {0}.', color);
                                        }
                                    }
                                }), '-',
                                {
                                    text: 'More Colors...',
                                    handler: onItemClick
                                }
                            ]
                        }
                    }, {
                        text: 'Extellent!',
                        handler: onItemClick
                    }]
                }
            }), '-', {
            text: 'Toggle Me',
            enableToggle: true,
            toggleHandler: onItemToggle,
            pressed: true
        });
    
        menu.addSeparator();
        // Menus have a rich api for
        // adding and removing elements dynamically
        var item = menu.add({
            text: 'Dynamically added Item'
        });
        // items support full Observable API
        item.on('click', onItemClick);
    
        // items can easily be looked up
        menu.add({
            text: 'Disabled Item',
            id: 'disableMe'  // <-- Items can also have an id for easy lookup
            // disabled: true   <-- allowed but for sake of example we use long way below
        });
        // access items by id or index
        menu.items.get('disableMe').disable();
    
        // They can also be referenced by id in or components
        tb.add('-', {
            icon: 'list-items.gif', // icons can also be specified inline
            cls: 'x-btn-icon',
            tooltip: '<b>Quick Tips</b><br/>Icon only button with tooltip'
        }, '-');
        
        var scrollMenu = new Ext.menu.Menu();
        for (var i = 0; i < 50; ++i){
            scrollMenu.add({
                text: 'Item ' + (i + 1)
            });
        }
        
        tb.add(new Ext.form.TextField());
        
        // scrollable menu
        tb.add({
            scale: 'large',
            icon: 'preview.png',
            cls: 'x-btn-text-icon',
            text: 'Scrolling Menu',
            menu: scrollMenu
        });
        
        // add a combobox to the toolbar
        var combo = new Ext.form.ComboBox({
            store: store,
            displayField: 'state',
            typeAhead: true,
            mode: 'local',
            triggerAction: 'all',
            emptyText:'Select a state...',
            selectOnFocus:true,
            width:135
        });
        tb.addField(combo);
    
        tb.add({
            text: 'Another'
        }, {
            text: 'Yet another'
        }, {
            text: 'Still another'
        }, {
            text: 'The last one!'
        });
    
        // sample static data for the store
        var myData = [
            ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
            ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
            ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
            ['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
            ['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
            ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
            ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
            ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
            ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
            ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
            ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
            ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
            ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
            ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
            ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
            ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
            ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
            ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
            ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
            ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
            ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
            ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
            ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
            ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
            ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
            ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
            ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
            ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],            
            ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
        ];
    
        /**
         * Custom function used for column renderer
         * @param {Object} val
         */
        function change(val){
            if(val > 0){
                return '<span style="color:green;">' + val + '</span>';
            }else if(val < 0){
                return '<span style="color:red;">' + val + '</span>';
            }
            return val;
        }
    
        /**
         * Custom function used for column renderer
         * @param {Object} val
         */
        function pctChange(val){
            if(val > 0){
                return '<span style="color:green;">' + val + '%</span>';
            }else if(val < 0){
                return '<span style="color:red;">' + val + '%</span>';
            }
            return val;
        }
    
        // create the data store
        var store = new Ext.data.ArrayStore({
            fields: [
               {name: 'company'},
               {name: 'price', type: 'float'},
               {name: 'change', type: 'float'},
               {name: 'pctChange', type: 'float'},
               {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
            ]
        });
    
        // manually load local data
        store.loadData(myData);
    
        // create the Grid
        var grid = new Ext.grid.GridPanel({
            store: store,
            columns: [
                {id:'company',header: 'Company', width: 160, sortable: true, dataIndex: 'company'},
                {header: 'Price', width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
                {header: 'Change', width: 75, sortable: true, renderer: change, dataIndex: 'change'},
                {header: '% Change', width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
                {header: 'Last Updated', width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
            ],
            stripeRows: true,
            autoExpandColumn: 'company',
            border: false
        });
    
        new Ext.Window({
            title: 'Test Float Toolbar',
            height: 300,
            width: 600,
            tbar: tb,
            layout: 'fit',
            items: grid
        }).show();
    
        // functions to display feedback
        function onButtonClick(btn){
            Ext.example.msg('Button Click','You clicked the "{0}" button.', btn.text);
        }
    
        function onItemClick(item){
            Ext.example.msg('Menu Click', 'You clicked the "{0}" menu item.', item.text);
        }
    
        function onItemCheck(item, checked){
            Ext.example.msg('Item Check', 'You {1} the "{0}" menu item.', item.text, checked ? 'checked' : 'unchecked');
        }
    
        function onItemToggle(item, pressed){
            Ext.example.msg('Button Toggled', 'Button "{0}" was toggled to {1}.', item.text, pressed);
        }
        
        var it = [];
        for (var i = 0; i < 30; i++) {
            it.push({
                xtype: 'box',
                autoEl: {
                    cls: 'test-item',
                    cn: [{
                        cls: 'test-item-inner'
                    }, {
                        cls: 'test-item-desc',
                        html: 'Item ' + (i + 1)
                    }]
                }
            });
        }
    
        w = new Ext.Window({
            title: 'Flow Layout',
            cls: 'show-icons',
            x: 100,
            y: 100,
            width: 314,
            height: 523,
            autoScroll: true,
            layout: {
                type: 'float',
                rightLimit: 500,
                animate: true
            },
            items: it,
            bbar: {
                xtype: 'container',
                layout: {
                    type: 'float',
                    horizontalAlign: 'justify'
                },
                cls: 'x-toolbar',
                style: {
                    overflow: 'hidden',
                    paddingLeft: 0,
                    paddingRight: 0
                },
                defaultType: 'container',
                defaults: {
                    style: {
                        width: '33%'
                    }
                },
                items: [{
                    layout: {
                        type: 'float',
                        padding: '0 0 0 2'
                    },
                    items: {
                        xtype: 'button',
                        text: 'View icons',
                        enableToggle: true,
                        pressed: true,
                        toggleHandler: function(b, state) {
                            if (state) {
                                w.addClass('show-icons');
                                w.removeClass('hide-icons');
                            } else {
                                w.addClass('hide-icons');
                                w.removeClass('show-icons');
                            }
                            w.doLayout();
                        }
                    }
                }, {
                    layout: {
                     type: 'float',
                        horizontalAlign: 'center'
                    },
                    items: {
                        xtype: 'button',
                        text: 'Centre Button'
                    }
                }, {
                    layout: {
                    type: 'float',
                        horizontalAlign: 'right',
                        padding: '0 2 0 0'
                    },
                    items: {
                        xtype: 'button',
                        text: 'Right Button'
                    }
                }]
            }
        }).show();
    
        it = [];
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: '1. First Button',
            width: 140,
            height: 56
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: '2. Second longer Button...',
            width: 200,
            height: 56,
            clear: 'right'
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: '3. Third really, really long Button',
            width: 240,
            height: 100
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: 'Number 4',
            width: 120,
            height: 56,
            verticalAlign: 'bottom'
        });
        it.push({
            xtype: 'button',
            text: '20px Margins around the great big 5th button!',
            width: 240,
            height: 100,
            clear: 'right',
            style: {
                margin: '20px'
            }
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: 'Number 6',
            width: 120,
            height: 56
        });
        it.push({
            xtype: 'button',
            text: '7th a wide, short button',
            width: 120,
            verticalAlign: 'top'
        });
    
        new Ext.Window({
            title: 'Flow Layout',
            x: 500,
            y: 100,
            width: 500,
            height: 400,
            autoScroll: true,
            layout: {
                type: 'float',
                horizontalAlign: 'center',
                animate: true
            },
            items: it
        }).show();
        
        it = [];
        for (i = 0; i < 10; i++) {
            it.push({
                xtype: 'box',
                columnWidth: 0.25,
                html: 'columnWidth:0.25'
            });
        }
        it[4].cellHeight = 0.5;
        it[4].html += ', cellHeight: 0.5';
        it[5].cellHeight = 0.5;
        it[6].cellHeight = 0.5;
        it[6].html += ', cellHeight: 0.5';
        it[5].columnWidth = 0.5;
        it[5].html = 'columnWidth:0.5, cellHeight: 0.5';
        it[9].columnWidth = 0.5;
        it[9].html = 'columnWidth:0.5';
        it[7].fillHeight = true;
        it[7].html += ',<br>fillHeight: true';
    
        new Ext.Window({
            title: 'A Flow layout window using padding: 0.125',
            height: 400, width: 600,
            minWidth: 530,
            x: 200, y: 55,
            autoScroll: true,
            layout: {
                type: 'float',
                horizontalSpacing: 5,
                verticalSpacing: 5,
                verticalAlign: 'top',
                padding: '5 0.125 5 0.125'
            },
            defaultType: 'box',
            defaults: {
                style: {
                    height: '20px',
                    padding: '5px 0 0 5px',
                    backgroundColor: 'red'
                }
            },
            items: it
        }).show();
    
        it = [];
        for (i = 0; i < 10; i++) {
            it.push({ fieldLabel: 'Form item ' + (i + 1)});
        }
        new Ext.Window({
            title: 'A Flow layout form using columnWidth: 0.5',
            cls: 'the-flow-form',
            height: 400, width: 600,
            autoScroll: true,
            layout: {
                type: 'float',
                horizontalSpacing: 5,
                padding: '5 5 1 5'
            },
            defaultType: 'textfield',
            defaults: {
                plugins: [ Ext.ux.FieldLabeler ],
                columnWidth: 0.5
            },
            items: it
        }).show();
    
    });
    </script>
    <link rel="stylesheet" type="text/css" href="menus.css" />
    <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
    </head>
    <body>
    <h1>FloatLayout Toolbar with Menus</h1>
    <p>The js is inline.</p>
    </body>
    </html>
    Then change it to use layout: 'column', and then in Firebug, type

    Code:
    Ext.getCmp("tb").setWidth(500).doLayout();
    You see it does not wrap properly because of uneven heights of the elements:



    When you do this with layout: 'float', you get


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

      0  

    Default


    The layout class:

    Code:
    /**
     * @class Ext.layout.FloatLayout
     * @extends Ext.layout.BoxLayout
     * <p>A layout that arranges items in a left to right flow similar to using HTML's <code>float: left</code> style.</p>
     * <p>When a Component's width (including its padding) won't fit within the available width of the Container (within its padding)
     * then the Component is wrapped to the beginning of a new line, clearing the tallest item on the current line.</p>
     * <p>Items may be vertically aligned with the row they happen to fall within. A line's height is the height of its tallest child
     * item (including its margins), and vertical alignment take place within this space. Vertical alignment is specified for the layout using the
     * {@link #verticalAlign} config, and may be overriden for a single item by configuring an item with a verticalAlign value.</p>
     * <p>Row content may be aligned within the available width of the Container using the {@link #horizontalAlign} config.</p>
     * <p>Child items may be cleared left or right by configuring a <b>clear</b> value in the item.</p>
     * <p>Row and column spacing may be specified using the {@link #verticalSpacing} and {@link #horizontalSpacing} options.</p>
     * <p>Child items may use <code>columnWidth</code> config to specify a fraction of the available width that the item is to occupy.</p>
     */
    Ext.layout.FloatLayout = Ext.extend(Ext.layout.BoxLayout, {
        /**
         * @cfg {Boolean} animate
         * <p><code>true</code> to animate child items into their calculated positions.</p>
         * <p>Defaults to <code>false</code>.</p>
         */
    
        /**
         * @cfg {String} verticalAlign
         * <p>Vertical alignment of child items within each row. Defaults to 'middle'. Values may be</p>
         * <code>'top'</code>, <code>'middle'</code> or <code>'bottom'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        verticalAlign: 'middle',
    
        /**
         * @cfg {String} horizontalAlign
         * <p>Horizontal alignment of child items within each row. Defaults to 'left'. Values may be</p>
         * <code>'left'</code>, <code>'center'</code>, <code>'right'</code> or <code>'justify'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        horizontalAlign: 'left',
    
        /**
         * @cfg {Number} horizontalSpacing
         * <p>Horizontal space to leave between items.</p>
         */
        horizontalSpacing: 0,
    
        /**
         * @cfg {Number} verticalSpacing
         * <p>Vertical space to leave between rows.</p>
         */
        verticalSpacing: 0,
    
        /**
         * @cfg {Number} rightLimit
         * <p>Max rightmost point to which the right edge of items are allowed to reach before wrapping.</p>
         */
        rightLimit: 0,
    
        targetCls : 'ux-float-layout-ct',
    
        setContainer: function(ct) {
            var ce = ct.getLayoutTarget();
            this.sizer = ce.insertFirst({
                cls: 'ux-float-layout-sizer'
            });
            this.padding = this.parseMargins(this.padding||'0');
            Ext.layout.FloatLayout.superclass.setContainer.apply(this, arguments);
        },
    
        renderAll : function(ct, target){
            Ext.layout.BoxLayout.superclass.renderAll.apply(this, arguments);
        },
    
        onLayout: function() {
            var ct = this.container,
                cte = ct.getLayoutTarget(),
                s = cte.getStyleSize(),
                padding = Ext.apply({}, this.padding);
    
            padding.top = this.getMarginValue(this.padding.top, s.height);
            padding.right = this.getMarginValue(this.padding.right, s.width) - this.horizontalSpacing;
            padding.bottom = this.getMarginValue(this.padding.bottom, s.height) - this.verticalSpacing;
            padding.left = this.getMarginValue(this.padding.left, s.width);
    
            var paddingLeft = padding.left + cte.getPadding('l'),
                paddingTop = padding.top + cte.getPadding('t'),
                rightLimit = s.width -= (padding.right + cte.getPadding('r')),
                bottomLimit = s.height - (padding.bottom + cte.getPadding('b')),
                rowStart = 0,
                rowHeight = 0,
                rowWidth = 0,
                x = paddingLeft,
                y = paddingTop,
                items = this.getRenderedItems(ct),
                l = items.length, i, c, lc, ce, cs, m, rm, r,
                itemPos = [], firstFillItem;
    
    //      We never want to see horizontal scroll bars if possible
            cte.setStyle('overflow-x', 'hidden');
    
    //      Content Width.
            s.width -= paddingLeft;
    
            if (this.rightLimit && this.rightLimit < rightLimit) {
                rightLimit = this.rightLimit;
            }
    
            for (var i = 0, l = items.length; i < l; i++) {
                c = items[i];
                ce = c.getPositionEl();
    
    //          Capure first fill item
                if (c.fillHeight) {
                    c.setHeight('auto');
                    if (!firstFillItem) {
                        firstFillItem = i;
                    }
                }
                cs = c.getSize();
    
    //          Allow floating point allocation of available width
                if (c.columnWidth) {
                    c.setWidth(cs.width = (Math.round(s.width * c.columnWidth) - this.horizontalSpacing));
                }
                if (c.cellHeight) {
                    c.setHeight(cs.height = (Math.round(s.height * c.cellHeight) - this.verticalSpacing));
                }
    
                rm = ce.getMargins('r');
                cs.width += ce.getMargins('lr');
                cs.height += ce.getMargins('tb');
                m = c.margins;
                x += m.left;
                r = x + cs.width;
    
    //          This item won't fit on the row.
                if ((r > rightLimit) || (c.clear == 'left') || (lc && lc.clear == 'right')) {
                    this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
                    x = paddingLeft + m.left;
                    y += rowHeight + this.verticalSpacing;
                    r = x + cs.width + m.right;
                    rowStart = i;
                    rowHeight = 0;
                    rowWidth = 0;
                }
    
                rowHeight = Math.max(rowHeight, cs.height);
                rowWidth += cs.width;
    
    //          We are laying out an autoScroll Container, and this item is going to cause a vertical scrollbar:
    //          Adjust the right padding to account for that scrollbar, and reflow.
                if (ct.autoScroll && !this.reflow && ((y + rowHeight) > bottomLimit)) {
                    r = this.padding.right;
                    this.padding.right += Ext.getScrollBarWidth();
                    this.reflow = true;
                    this.onLayout();
                    delete this.reflow;
                    this.padding.right = r;
                    return;
                }
    
                itemPos.push([x, y]);
                x += cs.width + m.right + this.horizontalSpacing;
                lc = c;
            }
    
    //      Adjust the last row
            this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
    
    //      Stretch the container heightwise.
            this.sizer.setHeight(r = (y + rowHeight - cte.getPadding('t')));
    
            if (firstFillItem) {
                var spare = s.height - r - padding.bottom - padding.top;
                rowHeight = 0;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    ce = c.getPositionEl();
                    cs = c.getSize();
                    cs.height += ce.getMargins('tb');
                    rowHeight = Math.max(rowHeight, cs.height);
                }
                rowHeight += spare;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    if (c.fillHeight) {
                        ce = c.getPositionEl();
                        cs = c.getSize();
                        c.setHeight(rowHeight - ce.getMargins('tb'));
                    }
                }
            } else {
            }
    
    //      Animate child items into place.
            for (var i = 0, l = items.length; i < l; i++) {
                if (this.animate) {
                    Ext.lib.Anim.motion(items[i].getPositionEl().dom, {left: {to: itemPos[i][0]}, top: {to: itemPos[i][1]}}).animate();
                } else {
                    items[i].setPosition(itemPos[i]);
                }
            }
        },
    
        getMarginValue: function(v, s) {
            if (Ext.isNumber(v)) {
                return (v < 1) ? s * v  : v;
            }
            return 0;
        },
    
        parseMargins : function(v){
            if(Ext.isNumber(v)){
                v = v.toString();
            }
            var ms = v.split(' ');
            var len = ms.length;
            if(len == 1){
                ms[1] = ms[2] = ms[3] = ms[0];
            } else if(len == 2){
                ms[2] = ms[0];
                ms[3] = ms[1];
            } else if(len == 3){
                ms[3] = ms[1];
            }
            return {
                top: parseFloat(ms[0], 10) || 0,
                right: parseFloat(ms[1], 10) || 0,
                bottom: parseFloat(ms[2], 10) || 0,
                left: parseFloat(ms[3], 10) || 0
            };
        },
    
    //  Adjust vertical alignment within row.
    //  Adjust horizontal alignment if required.
        adjustRow: function(items, itemPos, rowStart, rowEnd, rowHeight, rowWidth, availWidth) {
            var i, c, h, j = 0, gaps = rowEnd - rowStart, spareWidth, alignmentIncrement = 0;
            rowWidth += gaps * this.horizontalSpacing;
            spareWidth = availWidth - rowWidth;
    
            switch (this.horizontalAlign) {
                case 'middle':
                case 'center':
                    alignmentIncrement = Math.max(spareWidth / 2, 0);
                    break;
                case 'right':
                    alignmentIncrement = Math.max(spareWidth, 0);
                    break;
                case 'justify':
                    if (gaps) {
                        j = Math.max(spareWidth / gaps, 0);
                    }
            }
    
            for (i = rowStart; i <= rowEnd; i++) {
                c = items[i];
                h = c.getHeight() + c.getPositionEl().getMargins('tb');
                itemPos[i][0] += alignmentIncrement;
                alignmentIncrement += j;
                switch (c.verticalAlign || this.verticalAlign) {
                    case 'middle':
                    case 'center':
                        itemPos[i][1] += (rowHeight - h) / 2;
                        break;
                    case 'bottom':
                        itemPos[i][1] += (rowHeight - h);
                }
            }
        },
    
        isValidParent: function(c, e) {
            return c.getPositionEl().dom.parentNode === e.dom;
        }
    });
    Ext.Container.LAYOUTS['float'] = Ext.layout.FloatLayout;
    CSS:

    Code:
    .ux-float-layout-ct {
        position: relative;
    }
    .ux-float-layout-ct .ux-float-layout-sizer {
        background: transparent none;
        border: 0 none;
        padding: 0;
        margin: 0;
        width: 0;
    }
    .ux-float-layout-ct .x-box-item {
    	position: absolute;
    }

  6. #6
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,251
    Vote Rating
    73
    Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold Condor is a splendid one to behold

      0  

    Default


    I like the first version better.

    You could also add support for optional float:right and clear:both (based on item config).

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

      0  

    Default


    The float version has problems in IE. Try that newer test page which places the toolbar in a resizeable Window.

    The uneven heights of the rows still caused items on the next row not to be able to flow to the left properly.

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

      0  

    Default


    Example in post #4 updated to use Ext 3.1.1 layout. Currently only available to those with SVN access.

    Items animate into their new positions.

    Items can be aligned within the row they are in. The layout takes a verticalAlign config.

    Also optional horizontalSpacing and verticalSpacing configs to space items out.

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

      0  

    Default


    Example in post #4 updated to show dynamic, animated reflowing in a Window accounting for the appearance of scrollbars, to emulate http://demo.qooxdoo.org/current/demo...yout~Flow.html

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

      0  

    Default


    Now with horizontalAlign setting meaning that each row block may be aligned left, centered, right, or justified (evenly spaced).

    animate: true/false allows optional animation upon reflow.

    Also, each item may use a clear: 'left'/'right' config to force a row break.

    The example page in #4 emulates qooxdoo's Flow layout demo now.

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar