X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..c8256059947f3aa8f5b0a9a2acf55e2142bb4742:/docs/source/BoxLayout.html diff --git a/docs/source/BoxLayout.html b/docs/source/BoxLayout.html index e6c24b1d..e23536ce 100644 --- a/docs/source/BoxLayout.html +++ b/docs/source/BoxLayout.html @@ -1,421 +1,687 @@ - -
-/** - * @class Ext.layout.BoxLayout - * @extends Ext.layout.ContainerLayout - *Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.
- */ -Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, { - /** - * @cfg {Object} defaultMargins - *If the individual contained items do not have a margins - * property specified, 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.
- *Defaults to:
- */ - defaultMargins : {left:0,top:0,right:0,bottom:0}, - /** - * @cfg {String} padding - * Defaults to '0'. Sets the padding to be applied to all child items managed by this - * container's layout. - */ - padding : '0', - // documented in subclasses - pack : 'start', - - // private - monitorResize : true, - scrollOffset : 0, - extraCls : 'x-box-item', - ctCls : 'x-box-layout-ct', - innerCls : 'x-box-inner', - - // private - isValidParent : function(c, target){ - return c.getEl().dom.parentNode == this.innerCt.dom; - }, - - // private - onLayout : function(ct, target){ - var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm; - - if(!this.innerCt){ - target.addClass(this.ctCls); - - // the innerCt prevents wrapping and shuffling while - // the container is resizing - this.innerCt = target.createChild({cls:this.innerCls}); - this.padding = this.parseMargins(this.padding); - } - this.renderAll(ct, this.innerCt); - }, - - // private - renderItem : function(c){ - if(typeof c.margins == 'string'){ - c.margins = this.parseMargins(c.margins); - }else if(!c.margins){ - c.margins = this.defaultMargins; - } - Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments); - }, - - getTargetSize : function(target){ - return (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize(); - }, - - getItems: function(ct){ - var items = []; - ct.items.each(function(c){ - if(c.isVisible()){ - items.push(c); - } - }); - return items; - } - - /** - * @property activeItem - * @hide - */ -}); - -/** - * @class Ext.layout.VBoxLayout - * @extends Ext.layout.BoxLayout - * A layout that arranges items vertically - */ -Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, { - /** - * @cfg {String} align - * Controls how the child items of the container are aligned. Acceptable configuration values for this - * property are: - *- * {top:0, right:0, bottom:0, left:0} - *
- */ - align : 'left', // left, center, stretch, strechmax - /** - * @cfg {String} pack - * Controls how the child items of the container are packed together. Acceptable configuration values - * for this property are: - *- *
- left : Default
- *child items are aligned horizontally - * at the left side of the container- center :
- *child items are aligned horizontally at the - * mid-width of the container- stretch :
- *child items are stretched horizontally to fill - * the width of the container- stretchmax :
- *child items are stretched horizontally to - * the size of the largest item.- */ - /** - * @cfg {Number} flex - * This configuation option is to be applied to child items of the container managed - * by this layout. Each child item with a flex property will be flexed vertically - * according to each item's relative flex value compared to the sum of all items with - * a flex value specified. Any child items that have either a flex = 0 or - * flex = undefined will not be 'flexed' (the initial size will not be changed). - */ - - // private - onLayout : function(ct, target){ - Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target); - - - var cs = this.getItems(ct), cm, ch, margin, - size = this.getTargetSize(target), - w = size.width - target.getPadding('lr') - this.scrollOffset, - h = size.height - target.getPadding('tb'), - l = this.padding.left, t = this.padding.top, - isStart = this.pack == 'start', - isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1, - stretchWidth = w - (this.padding.left + this.padding.right), - extraHeight = 0, - maxWidth = 0, - totalFlex = 0, - flexHeight = 0, - usedHeight = 0; - - Ext.each(cs, function(c){ - cm = c.margins; - totalFlex += c.flex || 0; - ch = c.getHeight(); - margin = cm.top + cm.bottom; - extraHeight += ch + margin; - flexHeight += margin + (c.flex ? 0 : ch); - maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right); - }); - extraHeight = h - extraHeight - this.padding.top - this.padding.bottom; - - var innerCtWidth = maxWidth + this.padding.left + this.padding.right; - switch(this.align){ - case 'stretch': - this.innerCt.setSize(w, h); - break; - case 'stretchmax': - case 'left': - this.innerCt.setSize(innerCtWidth, h); - break; - case 'center': - this.innerCt.setSize(w = Math.max(w, innerCtWidth), h); - break; - } - - var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight), - leftOver = availHeight, - heights = [], - restore = [], - idx = 0, - availableWidth = Math.max(0, w - this.padding.left - this.padding.right); - - - Ext.each(cs, function(c){ - if(isStart && c.flex){ - ch = Math.floor(availHeight * (c.flex / totalFlex)); - leftOver -= ch; - heights.push(ch); - } - }); - - if(this.pack == 'center'){ - t += extraHeight ? extraHeight / 2 : 0; - }else if(this.pack == 'end'){ - t += extraHeight; - } - Ext.each(cs, function(c){ - cm = c.margins; - t += cm.top; - c.setPosition(l + cm.left, t); - if(isStart && c.flex){ - ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0)); - if(isRestore){ - restore.push(c.getWidth()); - } - c.setSize(availableWidth, ch); - }else{ - ch = c.getHeight(); - } - t += ch + cm.bottom; - }); - - idx = 0; - Ext.each(cs, function(c){ - cm = c.margins; - if(this.align == 'stretch'){ - c.setWidth((stretchWidth - (cm.left + cm.right)).constrain( - c.minWidth || 0, c.maxWidth || 1000000)); - }else if(this.align == 'stretchmax'){ - c.setWidth((maxWidth - (cm.left + cm.right)).constrain( - c.minWidth || 0, c.maxWidth || 1000000)); - }else{ - if(this.align == 'center'){ - var diff = availableWidth - (c.getWidth() + cm.left + cm.right); - if(diff > 0){ - c.setPosition(l + cm.left + (diff/2), c.y); - } - } - if(isStart && c.flex){ - c.setWidth(restore[idx++]); - } - } - }, this); - } - /** - * @property activeItem - * @hide - */ -}); - -Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout; - -/** - * @class Ext.layout.HBoxLayout - * @extends Ext.layout.BoxLayout - * A layout that arranges items horizontally - */ -Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, { - /** - * @cfg {String} align - * Controls how the child items of the container are aligned. Acceptable configuration values for this - * property are: - *- *
- start : Default
- *child items are packed together at - * top side of container- center :
- *child items are packed together at - * mid-height of container- end :
- *child items are packed together at bottom - * side of container- *
- top : Default
- *child items are aligned vertically - * at the left side of the container- middle :
- *child items are aligned vertically at the - * mid-height of the container- stretch :
- *child items are stretched vertically to fill - * the height of the container- stretchmax :
- */ - align : 'top', // top, middle, stretch, strechmax - /** - * @cfg {String} pack - * Controls how the child items of the container are packed together. Acceptable configuration values - * for this property are: - *child items are stretched vertically to - * the size of the largest item.- */ - /** - * @cfg {Number} flex - * This configuation option is to be applied to child items of the container managed - * by this layout. Each child item with a flex property will be flexed horizontally - * according to each item's relative flex value compared to the sum of all items with - * a flex value specified. Any child items that have either a flex = 0 or - * flex = undefined will not be 'flexed' (the initial size will not be changed). - */ - - // private - onLayout : function(ct, target){ - Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target); - - var cs = this.getItems(ct), cm, cw, margin, - size = this.getTargetSize(target), - w = size.width - target.getPadding('lr') - this.scrollOffset, - h = size.height - target.getPadding('tb'), - l = this.padding.left, t = this.padding.top, - isStart = this.pack == 'start', - isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1, - stretchHeight = h - (this.padding.top + this.padding.bottom), - extraWidth = 0, - maxHeight = 0, - totalFlex = 0, - flexWidth = 0, - usedWidth = 0; - - Ext.each(cs, function(c){ - cm = c.margins; - totalFlex += c.flex || 0; - cw = c.getWidth(); - margin = cm.left + cm.right; - extraWidth += cw + margin; - flexWidth += margin + (c.flex ? 0 : cw); - maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom); - }); - extraWidth = w - extraWidth - this.padding.left - this.padding.right; - - var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom; - switch(this.align){ - case 'stretch': - this.innerCt.setSize(w, h); - break; - case 'stretchmax': - case 'top': - this.innerCt.setSize(w, innerCtHeight); - break; - case 'middle': - this.innerCt.setSize(w, h = Math.max(h, innerCtHeight)); - break; - } - - - var availWidth = Math.max(0, w - this.padding.left - this.padding.right - flexWidth), - leftOver = availWidth, - widths = [], - restore = [], - idx = 0, - availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom); - - - Ext.each(cs, function(c){ - if(isStart && c.flex){ - cw = Math.floor(availWidth * (c.flex / totalFlex)); - leftOver -= cw; - widths.push(cw); - } - }); - - if(this.pack == 'center'){ - l += extraWidth ? extraWidth / 2 : 0; - }else if(this.pack == 'end'){ - l += extraWidth; - } - Ext.each(cs, function(c){ - cm = c.margins; - l += cm.left; - c.setPosition(l, t + cm.top); - if(isStart && c.flex){ - cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0)); - if(isRestore){ - restore.push(c.getHeight()); - } - c.setSize(cw, availableHeight); - }else{ - cw = c.getWidth(); - } - l += cw + cm.right; - }); - - idx = 0; - Ext.each(cs, function(c){ - var cm = c.margins; - if(this.align == 'stretch'){ - c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain( - c.minHeight || 0, c.maxHeight || 1000000)); - }else if(this.align == 'stretchmax'){ - c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain( - c.minHeight || 0, c.maxHeight || 1000000)); - }else{ - if(this.align == 'middle'){ - var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom); - if(diff > 0){ - c.setPosition(c.x, t + cm.top + (diff/2)); - } - } - if(isStart && c.flex){ - c.setHeight(restore[idx++]); - } - } - }, this); - } - - /** - * @property activeItem - * @hide - */ -}); - + + + +- *
- start : Default
- *child items are packed together at - * left side of container- center :
- *child items are packed together at - * mid-width of container- end :
- *child items are packed together at right - * side of containerThe source code + + + + +/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +/** + * @class Ext.layout.BoxLayout + * @extends Ext.layout.ContainerLayout + *Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.
+ */ +Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, { + /** + * @cfg {Object} defaultMargins + *If the individual contained items do not have a margins + * property specified, 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.
+ *Defaults to:
+ */ + defaultMargins : {left:0,top:0,right:0,bottom:0}, + /** + * @cfg {String} padding + *+ * {top:0, right:0, bottom:0, left:0} + *
Sets the padding to be applied to all child items managed by this layout.
+ *This property must be specified as a string containing + * space-separated, numeric padding values. The order of the sides associated + * with each value matches the way CSS processes padding 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.
+ *Defaults to:
+ */ + padding : '0', + // documented in subclasses + pack : 'start', + + // private + monitorResize : true, + type: 'box', + scrollOffset : 0, + extraCls : 'x-box-item', + targetCls : 'x-box-layout-ct', + innerCls : 'x-box-inner', + + constructor : function(config){ + Ext.layout.BoxLayout.superclass.constructor.call(this, config); + + if (Ext.isString(this.defaultMargins)) { + this.defaultMargins = this.parseMargins(this.defaultMargins); + } + }, + + /** + * @private + * Runs the child box calculations and caches them in childBoxCache. Subclasses can used these cached values + * when laying out + */ + onLayout: function(container, target) { + Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target); + + var items = this.getVisibleItems(container), + tSize = this.getLayoutTargetSize(); + + /** + * @private + * @property layoutTargetLastSize + * @type Object + * Private cache of the last measured size of the layout target. This should never be used except by + * BoxLayout subclasses during their onLayout run. + */ + this.layoutTargetLastSize = tSize; + + /** + * @private + * @property childBoxCache + * @type Array + * Array of the last calculated height, width, top and left positions of each visible rendered component + * within the Box layout. + */ + this.childBoxCache = this.calculateChildBoxes(items, tSize); + + this.updateInnerCtSize(tSize, this.childBoxCache); + this.updateChildBoxes(this.childBoxCache.boxes); + + // Putting a box layout into an overflowed container is NOT correct and will make a second layout pass necessary. + this.handleTargetOverflow(tSize, container, target); + }, + + /** + * Resizes and repositions each child component + * @param {Array} boxes The box measurements + */ + updateChildBoxes: function(boxes) { + for (var i = 0, length = boxes.length; i < length; i++) { + var box = boxes[i], + comp = box.component; + + if (box.dirtySize) { + comp.setSize(box.width, box.height); + } + // Don't set positions to NaN + if (isNaN(box.left) || isNaN(box.top)) { + continue; + } + comp.setPosition(box.left, box.top); + } + }, + + /** + * @private + * Called by onRender just before the child components are sized and positioned. This resizes the innerCt + * to make sure all child items fit within it. We call this before sizing the children because if our child + * items are larger than the previous innerCt size the browser will insert scrollbars and then remove them + * again immediately afterwards, giving a performance hit. + * Subclasses should provide an implementation. + * @param {Object} currentSize The current height and width of the innerCt + * @param {Array} calculations The new box calculations of all items to be laid out + */ + updateInnerCtSize: Ext.emptyFn, + + /** + * @private + * This should be called after onLayout of any BoxLayout subclass. If the target's overflow is not set to 'hidden', + * we need to lay out a second time because the scrollbars may have modified the height and width of the layout + * target. Having a Box layout inside such a target is therefore not recommended. + * @param {Object} previousTargetSize The size and height of the layout target before we just laid out + * @param {Ext.Container} container The container + * @param {Ext.Element} target The target element + */ + handleTargetOverflow: function(previousTargetSize, container, target) { + var overflow = target.getStyle('overflow'); + + if (overflow && overflow != 'hidden' &&!this.adjustmentPass) { + var newTargetSize = this.getLayoutTargetSize(); + if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){ + this.adjustmentPass = true; + this.onLayout(container, target); + } + } + + delete this.adjustmentPass; + }, + + // private + isValidParent : function(c, target){ + return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; + }, + + /** + * @private + * Returns all items that are both rendered and visible + * @return {Array} All matching items + */ + getVisibleItems: function(ct) { + var ct = ct || this.container, + t = ct.getLayoutTarget(), + cti = ct.items.items, + len = cti.length, + + i, c, items = []; + + for (i = 0; i < len; i++) { + if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true){ + items.push(c); + } + } + + return items; + }, + + // private + renderAll : function(ct, target){ + if(!this.innerCt){ + // the innerCt prevents wrapping and shuffling while + // the container is resizing + this.innerCt = target.createChild({cls:this.innerCls}); + this.padding = this.parseMargins(this.padding); + } + Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt); + }, + + getLayoutTargetSize : function(){ + var target = this.container.getLayoutTarget(), ret; + if (target) { + ret = target.getViewSize(); + + // IE in strict mode will return a width of 0 on the 1st pass of getViewSize. + // Use getStyleSize to verify the 0 width, the adjustment pass will then work properly + // with getViewSize + if (Ext.isIE && Ext.isStrict && ret.width == 0){ + ret = target.getStyleSize(); + } + + ret.width -= target.getPadding('lr'); + ret.height -= target.getPadding('tb'); + } + return ret; + }, + + // private + renderItem : function(c){ + if(Ext.isString(c.margins)){ + c.margins = this.parseMargins(c.margins); + }else if(!c.margins){ + c.margins = this.defaultMargins; + } + Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments); + } +}); + +/** + * @class Ext.layout.VBoxLayout + * @extends Ext.layout.BoxLayout + *"0"
A layout that arranges items vertically down a Container. This layout optionally divides available vertical + * space between child items containing a numeric
+ * This layout may also be used to set the widths of child items by configuring it with the {@link #align} option. + */ +Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, { + /** + * @cfg {String} align + * Controls how the child items of the container are aligned. Acceptable configuration values for this + * property are: + *flex
configuration.+ */ + align : 'left', // left, center, stretch, strechmax + type: 'vbox', + + /** + * @cfg {String} pack + * Controls how the child items of the container are packed together. Acceptable configuration values + * for this property are: + *+ *
- left : Default
+ *child items are aligned horizontally + * at the left side of the container- center :
+ *child items are aligned horizontally at the + * mid-width of the container- stretch :
+ *child items are stretched horizontally to fill + * the width of the container- stretchmax :
+ *child items are stretched horizontally to + * the size of the largest item.+ */ + + /** + * @cfg {Number} flex + * This configuation option is to be applied to child items of the container managed + * by this layout. Each child item with a flex property will be flexed vertically + * according to each item's relative flex value compared to the sum of all items with + * a flex value specified. Any child items that have either a flex = 0 or + * flex = undefined will not be 'flexed' (the initial size will not be changed). + */ + + /** + * @private + * See parent documentation + */ + updateInnerCtSize: function(tSize, calcs) { + var innerCtHeight = tSize.height, + innerCtWidth = calcs.meta.maxWidth + this.padding.left + this.padding.right; + + if (this.align == 'stretch') { + innerCtWidth = tSize.width; + } else if (this.align == 'center') { + innerCtWidth = Math.max(tSize.width, innerCtWidth); + } + + //we set the innerCt size first because if our child items are larger than the previous innerCt size + //the browser will insert scrollbars and then remove them again immediately afterwards + this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined); + }, + + /** + * @private + * Calculates the size and positioning of each item in the VBox. This iterates over all of the rendered, + * visible items and returns a height, width, top and left for each, as well as a reference to each. Also + * returns meta data such as maxHeight which are useful when resizing layout wrappers such as this.innerCt. + * @param {Array} visibleItems The array of all rendered, visible items to be calculated for + * @param {Object} targetSize Object containing target size and height + * @return {Object} Object containing box measurements for each child, plus meta data + */ + calculateChildBoxes: function(visibleItems, targetSize) { + var visibleCount = visibleItems.length, + + padding = this.padding, + topOffset = padding.top, + leftOffset = padding.left, + paddingVert = topOffset + padding.bottom, + paddingHoriz = leftOffset + padding.right, + + width = targetSize.width - this.scrollOffset, + height = targetSize.height, + availWidth = Math.max(0, width - paddingHoriz), + + isStart = this.pack == 'start', + isCenter = this.pack == 'center', + isEnd = this.pack == 'end', + + nonFlexHeight= 0, + maxWidth = 0, + totalFlex = 0, + + //used to cache the calculated size and position values for each child item + boxes = [], + + //used in the for loops below, just declared here for brevity + child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight, horizMargins, stretchWidth; + + //gather the total flex of all flexed items and the width taken up by fixed width items + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + childHeight = child.height; + childWidth = child.width; + canLayout = !child.hasLayout && Ext.isFunction(child.doLayout); + + + // Static height (numeric) requires no calcs + if (!Ext.isNumber(childHeight)) { + + // flex and not 'auto' height + if (child.flex && !childHeight) { + totalFlex += child.flex; + + // Not flexed or 'auto' height or undefined height + } else { + //Render and layout sub-containers without a flex or width defined, as otherwise we + //don't know how wide the sub-container should be and cannot calculate flexed widths + if (!childHeight && canLayout) { + child.doLayout(); + } + + childSize = child.getSize(); + childWidth = childSize.width; + childHeight = childSize.height; + } + } + + childMargins = child.margins; + + nonFlexHeight += (childHeight || 0) + childMargins.top + childMargins.bottom; + + // Max width for align - force layout of non-layed out subcontainers without a numeric width + if (!Ext.isNumber(childWidth)) { + if (canLayout) { + child.doLayout(); + } + childWidth = child.getWidth(); + } + + maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right); + + //cache the size of each child component + boxes.push({ + component: child, + height : childHeight || undefined, + width : childWidth || undefined + }); + } + + //the height available to the flexed items + var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert)); + + if (isCenter) { + topOffset += availableHeight / 2; + } else if (isEnd) { + topOffset += availableHeight; + } + + //temporary variables used in the flex height calculations below + var remainingHeight = availableHeight, + remainingFlex = totalFlex; + + //calculate the height of each flexed item, and the left + top positions of every item + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = child.margins; + horizMargins = childMargins.left + childMargins.right; + + topOffset += childMargins.top; + + if (isStart && child.flex && !child.height) { + flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight); + remainingHeight -= flexedHeight; + remainingFlex -= child.flex; + + calcs.height = flexedHeight; + calcs.dirtySize = true; + } + + calcs.left = leftOffset + childMargins.left; + calcs.top = topOffset; + + switch (this.align) { + case 'stretch': + stretchWidth = availWidth - horizMargins; + calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000); + calcs.dirtySize = true; + break; + case 'stretchmax': + stretchWidth = maxWidth - horizMargins; + calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000); + calcs.dirtySize = true; + break; + case 'center': + var diff = availWidth - calcs.width - horizMargins; + if (diff > 0) { + calcs.left = leftOffset + horizMargins + (diff / 2); + } + } + + topOffset += calcs.height + childMargins.bottom; + } + + return { + boxes: boxes, + meta : { + maxWidth: maxWidth + } + }; + } +}); + +Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout; + +/** + * @class Ext.layout.HBoxLayout + * @extends Ext.layout.BoxLayout + *+ *
- start : Default
+ *child items are packed together at + * top side of container- center :
+ *child items are packed together at + * mid-height of container- end :
+ *child items are packed together at bottom + * side of containerA layout that arranges items horizontally across a Container. This layout optionally divides available horizontal + * space between child items containing a numeric
+ * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option. + */ +Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, { + /** + * @cfg {String} align + * Controls how the child items of the container are aligned. Acceptable configuration values for this + * property are: + *flex
configuration.+ *
- top : Default
+ *child items are aligned vertically + * at the top of the container- middle :
+ *child items are aligned vertically in the + * middle of the container- stretch :
+ *child items are stretched vertically to fill + * the height of the container- stretchmax :
+ */ + align: 'top', // top, middle, stretch, strechmax + + type : 'hbox', + + /** + * @private + * See parent documentation + */ + updateInnerCtSize: function(tSize, calcs) { + var innerCtWidth = tSize.width, + innerCtHeight = calcs.meta.maxHeight + this.padding.top + this.padding.bottom; + + if (this.align == 'stretch') { + innerCtHeight = tSize.height; + } else if (this.align == 'middle') { + innerCtHeight = Math.max(tSize.height, innerCtHeight); + } + + this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined); + }, + + /** + * @cfg {String} pack + * Controls how the child items of the container are packed together. Acceptable configuration values + * for this property are: + *child items are stretched vertically to + * the height of the largest item.+ */ + /** + * @cfg {Number} flex + * This configuation option is to be applied to child items of the container managed + * by this layout. Each child item with a flex property will be flexed horizontally + * according to each item's relative flex value compared to the sum of all items with + * a flex value specified. Any child items that have either a flex = 0 or + * flex = undefined will not be 'flexed' (the initial size will not be changed). + */ + + /** + * @private + * Calculates the size and positioning of each item in the HBox. This iterates over all of the rendered, + * visible items and returns a height, width, top and left for each, as well as a reference to each. Also + * returns meta data such as maxHeight which are useful when resizing layout wrappers such as this.innerCt. + * @param {Array} visibleItems The array of all rendered, visible items to be calculated for + * @param {Object} targetSize Object containing target size and height + * @return {Object} Object containing box measurements for each child, plus meta data + */ + calculateChildBoxes: function(visibleItems, targetSize) { + var visibleCount = visibleItems.length, + + padding = this.padding, + topOffset = padding.top, + leftOffset = padding.left, + paddingVert = topOffset + padding.bottom, + paddingHoriz = leftOffset + padding.right, + + width = targetSize.width - this.scrollOffset, + height = targetSize.height, + availHeight = Math.max(0, height - paddingVert), + + isStart = this.pack == 'start', + isCenter = this.pack == 'center', + isEnd = this.pack == 'end', + // isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1, + + nonFlexWidth = 0, + maxHeight = 0, + totalFlex = 0, + + //used to cache the calculated size and position values for each child item + boxes = [], + + //used in the for loops below, just declared here for brevity + child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, vertMargins, stretchHeight; + + //gather the total flex of all flexed items and the width taken up by fixed width items + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + childHeight = child.height; + childWidth = child.width; + canLayout = !child.hasLayout && Ext.isFunction(child.doLayout); + + // Static width (numeric) requires no calcs + if (!Ext.isNumber(childWidth)) { + + // flex and not 'auto' width + if (child.flex && !childWidth) { + totalFlex += child.flex; + + // Not flexed or 'auto' width or undefined width + } else { + //Render and layout sub-containers without a flex or width defined, as otherwise we + //don't know how wide the sub-container should be and cannot calculate flexed widths + if (!childWidth && canLayout) { + child.doLayout(); + } + + childSize = child.getSize(); + childWidth = childSize.width; + childHeight = childSize.height; + } + } + + childMargins = child.margins; + + nonFlexWidth += (childWidth || 0) + childMargins.left + childMargins.right; + + // Max height for align - force layout of non-layed out subcontainers without a numeric height + if (!Ext.isNumber(childHeight)) { + if (canLayout) { + child.doLayout(); + } + childHeight = child.getHeight(); + } + + maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom); + + //cache the size of each child component + boxes.push({ + component: child, + height : childHeight || undefined, + width : childWidth || undefined + }); + } + + //the width available to the flexed items + var availableWidth = Math.max(0, (width - nonFlexWidth - paddingHoriz)); + + if (isCenter) { + leftOffset += availableWidth / 2; + } else if (isEnd) { + leftOffset += availableWidth; + } + + //temporary variables used in the flex width calculations below + var remainingWidth = availableWidth, + remainingFlex = totalFlex; + + //calculate the widths of each flexed item, and the left + top positions of every item + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = child.margins; + vertMargins = childMargins.top + childMargins.bottom; + + leftOffset += childMargins.left; + + if (isStart && child.flex && !child.width) { + flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth); + remainingWidth -= flexedWidth; + remainingFlex -= child.flex; + + calcs.width = flexedWidth; + calcs.dirtySize = true; + } + + calcs.left = leftOffset; + calcs.top = topOffset + childMargins.top; + + switch (this.align) { + case 'stretch': + stretchHeight = availHeight - vertMargins; + calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000); + calcs.dirtySize = true; + break; + case 'stretchmax': + stretchHeight = maxHeight - vertMargins; + calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000); + calcs.dirtySize = true; + break; + case 'middle': + var diff = availHeight - calcs.height - vertMargins; + if (diff > 0) { + calcs.top = topOffset + vertMargins + (diff / 2); + } + } + leftOffset += calcs.width + childMargins.right; + } + + return { + boxes: boxes, + meta : { + maxHeight: maxHeight + } + }; + } +}); + Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout; - - + + \ No newline at end of file+ *
- start : Default
+ *child items are packed together at + * left side of container- center :
+ *child items are packed together at + * mid-width of container- end :
+ *child items are packed together at right + * side of container