| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-layout-container-Fit'>/**</span> * This is a base class for layouts that contain a single item that automatically expands to fill the layout's * container. This class is intended to be extended or created via the layout:'fit' * {@link Ext.container.Container#layout} config, and should generally not need to be created directly via the new keyword. * * Fit layout does not have any direct config options (other than inherited ones). To fit a panel to a container using * Fit layout, simply set `layout: 'fit'` on the container and add a single panel to it. * *     @example *     Ext.create('Ext.panel.Panel', { *         title: 'Fit Layout', *         width: 300, *         height: 150, *         layout:'fit', *         items: { *             title: 'Inner Panel', *             html: 'This is the inner panel content', *             bodyPadding: 20, *             border: false *         }, *         renderTo: Ext.getBody() *     }); * * If the container has multiple items, all of the items will all be equally sized. This is usually not * desired, so to avoid this, place only a **single** item in the container. This sizing of all items * can be used to provide a background {@link Ext.Img image} that is "behind" another item * such as a {@link Ext.view.View dataview} if you also absolutely position the items. */Ext.define('Ext.layout.container.Fit', {    /* Begin Definitions */    extend: 'Ext.layout.container.Container',    alternateClassName: 'Ext.layout.FitLayout',    alias: 'layout.fit',    /* End Definitions */    itemCls: Ext.baseCSSPrefix + 'fit-item',    targetCls: Ext.baseCSSPrefix + 'layout-fit',    type: 'fit',   <span id='Ext-layout-container-Fit-cfg-defaultMargins'>    /**</span>     * @cfg {Object} defaultMargins     * If the individual contained items do not have a margins property specified or margin specified via CSS, the     * default margins from this property will be applied to each item.     *     * This property may be specified as an object containing margins to apply in the format:     *     *     {     *         top: (top margin),     *         right: (right margin),     *         bottom: (bottom margin),     *         left: (left margin)     *     }     *     * This property may also be specified as a string containing space-separated, numeric margin values. The order of     * the sides associated with each value matches the way CSS processes margin values:     *     *   - If there is only one value, it applies to all sides.     *   - If there are two values, the top and bottom borders are set to the first value and the right and left are     *     set to the second.     *   - If there are three values, the top is set to the first value, the left and right are set to the second,     *     and the bottom is set to the third.     *   - If there are four values, they apply to the top, right, bottom, and left, respectively.     *     */    defaultMargins: {        top: 0,        right: 0,        bottom: 0,        left: 0    },    manageMargins: true,    sizePolicies: {        0: { setsWidth: 0, setsHeight: 0 },        1: { setsWidth: 1, setsHeight: 0 },        2: { setsWidth: 0, setsHeight: 1 },        3: { setsWidth: 1, setsHeight: 1 }    },    getItemSizePolicy: function (item, ownerSizeModel) {        // this layout's sizePolicy is derived from its owner's sizeModel:        var sizeModel = ownerSizeModel || this.owner.getSizeModel(),            mode = (sizeModel.width.shrinkWrap ? 0 : 1) |                   (sizeModel.height.shrinkWrap ? 0 : 2);       return this.sizePolicies[mode];    },    beginLayoutCycle: function (ownerContext, firstCycle) {        var me = this,            // determine these before the lastSizeModels get updated:            resetHeight = me.lastHeightModel && me.lastHeightModel.calculated,            resetWidth = me.lastWidthModel && me.lastWidthModel.calculated,            resetSizes = resetWidth || resetHeight,            maxChildMinHeight = 0, maxChildMinWidth = 0,            c, childItems, i, item, length, margins, minHeight, minWidth, style, undef;        me.callParent(arguments);        // Clear any dimensions which we set before calculation, in case the current        // settings affect the available size. This particularly effects self-sizing        // containers such as fields, in which the target element is naturally sized,        // and should not be stretched by a sized child item.        if (resetSizes && ownerContext.targetContext.el.dom.tagName.toUpperCase() != 'TD') {            resetSizes = resetWidth = resetHeight = false;        }        childItems = ownerContext.childItems;        length = childItems.length;        for (i = 0; i < length; ++i) {            item = childItems[i];            // On the firstCycle, we determine the max of the minWidth/Height of the items            // since these can cause the container to grow scrollbars despite our attempts            // to fit the child to the container.            if (firstCycle) {                c = item.target;                minHeight = c.minHeight;                minWidth = c.minWidth;                if (minWidth || minHeight) {                    margins = item.marginInfo || item.getMarginInfo();                    // if the child item has undefined minWidth/Height, these will become                    // NaN by adding the margins...                    minHeight += margins.height;                    minWidth += margins.height;                    // if the child item has undefined minWidth/Height, these comparisons                    // will evaluate to false... that is, "0 < NaN" == false...                    if (maxChildMinHeight < minHeight) {                        maxChildMinHeight = minHeight;                    }                    if (maxChildMinWidth < minWidth) {                        maxChildMinWidth = minWidth;                    }                }            }            if (resetSizes) {                style = item.el.dom.style;                if (resetHeight) {                    style.height = '';                }                if (resetWidth) {                    style.width = '';                }            }        }        if (firstCycle) {            ownerContext.maxChildMinHeight = maxChildMinHeight;            ownerContext.maxChildMinWidth = maxChildMinWidth;        }        // Cache the overflowX/Y flags, but make them false in shrinkWrap mode (since we        // won't be triggering overflow in that case) and false if we have no minSize (so        // no child to trigger an overflow).        c = ownerContext.target;        ownerContext.overflowX = (!ownerContext.widthModel.shrinkWrap &&                                    ownerContext.maxChildMinWidth &&                                   (c.autoScroll || c.overflowX)) || undef;        ownerContext.overflowY = (!ownerContext.heightModel.shrinkWrap &&                                   ownerContext.maxChildMinHeight &&                                   (c.autoScroll || c.overflowY)) || undef;    },    calculate : function (ownerContext) {        var me = this,            childItems = ownerContext.childItems,            length = childItems.length,            containerSize = me.getContainerSize(ownerContext),            info = {                length: length,                ownerContext: ownerContext,                targetSize: containerSize            },            shrinkWrapWidth = ownerContext.widthModel.shrinkWrap,            shrinkWrapHeight = ownerContext.heightModel.shrinkWrap,            overflowX = ownerContext.overflowX,            overflowY = ownerContext.overflowY,            scrollbars, scrollbarSize, padding, i, contentWidth, contentHeight;        if (overflowX || overflowY) {            // If we have children that have minHeight/Width, we may be forced to overflow            // and gain scrollbars. If so, we want to remove their space from the other            // axis so that we fit things inside the scrollbars rather than under them.            scrollbars = me.getScrollbarsNeeded(                    overflowX && containerSize.width, overflowY && containerSize.height,                    ownerContext.maxChildMinWidth, ownerContext.maxChildMinHeight);            if (scrollbars) {                scrollbarSize = Ext.getScrollbarSize();                if (scrollbars & 1) { // if we need the hscrollbar, remove its height                    containerSize.height -= scrollbarSize.height;                }                if (scrollbars & 2) { // if we need the vscrollbar, remove its width                    containerSize.width -= scrollbarSize.width;                }            }        }        // Size the child items to the container (if non-shrinkWrap):        for (i = 0; i < length; ++i) {            info.index = i;            me.fitItem(childItems[i], info);        }                if (shrinkWrapHeight || shrinkWrapWidth) {            padding = ownerContext.targetContext.getPaddingInfo();                        if (shrinkWrapWidth) {                if (overflowY && !containerSize.gotHeight) {                    // if we might overflow vertically and don't have the container height,                    // we don't know if we will need a vscrollbar or not, so we must wait                    // for that height so that we can determine the contentWidth...                    me.done = false;                } else {                    contentWidth = info.contentWidth + padding.width;                    // the scrollbar flag (if set) will indicate that an overflow exists on                    // the horz(1) or vert(2) axis... if not set, then there could never be                    // an overflow...                    if (scrollbars & 2) { // if we need the vscrollbar, add its width                        contentWidth += scrollbarSize.width;                    }                    if (!ownerContext.setContentWidth(contentWidth)) {                        me.done = false;                    }                }            }            if (shrinkWrapHeight) {                if (overflowX && !containerSize.gotWidth) {                    // if we might overflow horizontally and don't have the container width,                    // we don't know if we will need a hscrollbar or not, so we must wait                    // for that width so that we can determine the contentHeight...                    me.done = false;                } else {                    contentHeight = info.contentHeight + padding.height;                    // the scrollbar flag (if set) will indicate that an overflow exists on                    // the horz(1) or vert(2) axis... if not set, then there could never be                    // an overflow...                    if (scrollbars & 1) { // if we need the hscrollbar, add its height                        contentHeight += scrollbarSize.height;                    }                    if (!ownerContext.setContentHeight(contentHeight)) {                        me.done = false;                    }                }            }        }    },    fitItem: function (itemContext, info) {        var me = this;        if (itemContext.invalid) {            me.done = false;            return;        }        info.margins = itemContext.getMarginInfo();        info.needed = info.got = 0;        me.fitItemWidth(itemContext, info);        me.fitItemHeight(itemContext, info);        // If not all required dimensions have been satisfied, we're not done.        if (info.got != info.needed) {            me.done = false;        }    },    fitItemWidth: function (itemContext, info) {        var contentWidth, width;        // Attempt to set only dimensions that are being controlled, not shrinkWrap dimensions        if (info.ownerContext.widthModel.shrinkWrap) {            // contentWidth must include the margins to be consistent with setItemWidth            width = itemContext.getProp('width') + info.margins.width;            // because we add margins, width will be NaN or a number (not undefined)            contentWidth = info.contentWidth;            if (contentWidth === undefined) {                info.contentWidth = width;            } else {                info.contentWidth = Math.max(contentWidth, width);            }        } else if (itemContext.widthModel.calculated) {            ++info.needed;            if (info.targetSize.gotWidth) {                ++info.got;                this.setItemWidth(itemContext, info);            }        }        this.positionItemX(itemContext, info);    },    fitItemHeight: function (itemContext, info) {        var contentHeight, height;        if (info.ownerContext.heightModel.shrinkWrap) {            // contentHeight must include the margins to be consistent with setItemHeight            height = itemContext.getProp('height') + info.margins.height;            // because we add margins, height will be NaN or a number (not undefined)            contentHeight = info.contentHeight;            if (contentHeight === undefined) {                info.contentHeight = height;            } else {                info.contentHeight = Math.max(contentHeight, height);            }        } else if (itemContext.heightModel.calculated) {            ++info.needed;            if (info.targetSize.gotHeight) {                ++info.got;                this.setItemHeight(itemContext, info);            }        }        this.positionItemY(itemContext, info);    },    positionItemX: function (itemContext, info) {        var margins = info.margins;        // Adjust position to account for configured margins or if we have multiple items        // (all items should overlap):        if (info.index || margins.left) {            itemContext.setProp('x', margins.left);        }        if (margins.width) {            // Need the margins for shrink-wrapping but old IE sometimes collapses the left margin into the padding            itemContext.setProp('margin-right', margins.width);        }    },    positionItemY: function (itemContext, info) {        var margins = info.margins;        if (info.index || margins.top) {            itemContext.setProp('y', margins.top);        }        if (margins.height) {            // Need the margins for shrink-wrapping but old IE sometimes collapses the top margin into the padding            itemContext.setProp('margin-bottom', margins.height);        }    },    setItemHeight: function (itemContext, info) {        itemContext.setHeight(info.targetSize.height - info.margins.height);    },    setItemWidth: function (itemContext, info) {        itemContext.setWidth(info.targetSize.width - info.margins.width);    }});</pre></body></html>
 |