4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-layout-container-Box'>/**
19 </span> * @class Ext.layout.container.Box
20 * @extends Ext.layout.container.Container
21 * <p>Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.</p>
24 Ext.define('Ext.layout.container.Box', {
26 /* Begin Definitions */
28 alias: ['layout.box'],
29 extend: 'Ext.layout.container.Container',
30 alternateClassName: 'Ext.layout.BoxLayout',
33 'Ext.layout.container.boxOverflow.None',
34 'Ext.layout.container.boxOverflow.Menu',
35 'Ext.layout.container.boxOverflow.Scroller',
37 'Ext.dd.DragDropManager'
42 <span id='Ext-layout-container-Box-cfg-animate'> /**
43 </span> * @cfg {Boolean/Number/Object} animate
44 * <p>If truthy, child Component are <i>animated</i> into position whenever the Container
45 * is layed out. If this option is numeric, it is used as the animation duration in milliseconds.</p>
46 * <p>May be set as a property at any time.</p>
49 <span id='Ext-layout-container-Box-cfg-defaultMargins'> /**
50 </span> * @cfg {Object} defaultMargins
51 * <p>If the individual contained items do not have a <tt>margins</tt>
52 * property specified or margin specified via CSS, the default margins from this property will be
53 * applied to each item.</p>
54 * <br><p>This property may be specified as an object containing margins
55 * to apply in the format:</p><pre><code>
58 right: (right margin),
59 bottom: (bottom margin),
61 }</code></pre>
62 * <p>This property may also be specified as a string containing
63 * space-separated, numeric margin values. The order of the sides associated
64 * with each value matches the way CSS processes margin values:</p>
65 * <div class="mdetail-params"><ul>
66 * <li>If there is only one value, it applies to all sides.</li>
67 * <li>If there are two values, the top and bottom borders are set to the
68 * first value and the right and left are set to the second.</li>
69 * <li>If there are three values, the top is set to the first value, the left
70 * and right are set to the second, and the bottom is set to the third.</li>
71 * <li>If there are four values, they apply to the top, right, bottom, and
72 * left, respectively.</li>
73 * </ul></div>
82 <span id='Ext-layout-container-Box-cfg-padding'> /**
83 </span> * @cfg {String} padding
84 * <p>Sets the padding to be applied to all child items managed by this layout.</p>
85 * <p>This property must be specified as a string containing
86 * space-separated, numeric padding values. The order of the sides associated
87 * with each value matches the way CSS processes padding values:</p>
88 * <div class="mdetail-params"><ul>
89 * <li>If there is only one value, it applies to all sides.</li>
90 * <li>If there are two values, the top and bottom borders are set to the
91 * first value and the right and left are set to the second.</li>
92 * <li>If there are three values, the top is set to the first value, the left
93 * and right are set to the second, and the bottom is set to the third.</li>
94 * <li>If there are four values, they apply to the top, right, bottom, and
95 * left, respectively.</li>
96 * </ul></div>
99 // documented in subclasses
102 <span id='Ext-layout-container-Box-cfg-pack'> /**
103 </span> * @cfg {String} pack
104 * Controls how the child items of the container are packed together. Acceptable configuration values
105 * for this property are:
106 * <div class="mdetail-params"><ul>
107 * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
108 * <b>left</b> side of container</div></li>
109 * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
110 * <b>mid-width</b> of container</div></li>
111 * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
112 * side of container</div></li>
113 * </ul></div>
115 <span id='Ext-layout-container-Box-cfg-flex'> /**
116 </span> * @cfg {Number} flex
117 * This configuration option is to be applied to <b>child <tt>items</tt></b> of the container managed
118 * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>horizontally</b>
119 * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
120 * a <tt>flex</tt> value specified. Any child items that have either a <tt>flex = 0</tt> or
121 * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
126 itemCls: Ext.baseCSSPrefix + 'box-item',
127 targetCls: Ext.baseCSSPrefix + 'box-layout-ct',
128 innerCls: Ext.baseCSSPrefix + 'box-inner',
130 bindToOwnerCtContainer: true,
132 // availableSpaceOffset is used to adjust the availableWidth, typically used
133 // to reserve space for a scrollbar
134 availableSpaceOffset: 0,
136 // whether or not to reserve the availableSpaceOffset in layout calculations
139 <span id='Ext-layout-container-Box-cfg-shrinkToFit'> /**
140 </span> * @cfg {Boolean} shrinkToFit
141 * True (the default) to allow fixed size components to shrink (limited to their
142 * minimum size) to avoid overflow. False to preserve fixed sizes even if they cause
147 <span id='Ext-layout-container-Box-cfg-clearInnerCtOnLayout'> /**
148 </span> * @cfg {Boolean} clearInnerCtOnLayout
150 clearInnerCtOnLayout: false,
152 flexSortFn: function (a, b) {
153 var maxParallelPrefix = 'max' + this.parallelPrefixCap,
154 infiniteValue = Infinity;
155 a = a.component[maxParallelPrefix] || infiniteValue;
156 b = b.component[maxParallelPrefix] || infiniteValue;
157 // IE 6/7 Don't like Infinity - Infinity...
158 if (!isFinite(a) && !isFinite(b)) {
164 // Sort into *descending* order.
165 minSizeSortFn: function(a, b) {
166 return b.available - a.available;
169 constructor: function(config) {
172 me.callParent(arguments);
174 // The sort function needs access to properties in this, so must be bound.
175 me.flexSortFn = Ext.Function.bind(me.flexSortFn, me);
177 me.initOverflowHandler();
180 <span id='Ext-layout-container-Box-method-getChildBox'> /**
182 * Returns the current size and positioning of the passed child item.
183 * @param {Ext.Component} child The child Component to calculate the box for
184 * @return {Object} Object containing box measurements for the child. Properties are left,top,width,height.
186 getChildBox: function(child) {
187 child = child.el || this.owner.getComponent(child).el;
188 var size = child.getBox(false, true);
197 <span id='Ext-layout-container-Box-method-calculateChildBox'> /**
199 * Calculates the size and positioning of the passed child item.
200 * @param {Ext.Component} child The child Component to calculate the box for
201 * @return {Object} Object containing box measurements for the child. Properties are left,top,width,height.
203 calculateChildBox: function(child) {
205 boxes = me.calculateChildBoxes(me.getVisibleItems(), me.getLayoutTargetSize()).boxes,
209 child = me.owner.getComponent(child);
210 for (; i < ln; i++) {
211 if (boxes[i].component === child) {
217 <span id='Ext-layout-container-Box-method-calculateChildBoxes'> /**
219 * Calculates the size and positioning of each item in the box. This iterates over all of the rendered,
220 * visible items and returns a height, width, top and left for each, as well as a reference to each. Also
221 * returns meta data such as maxSize which are useful when resizing layout wrappers such as this.innerCt.
222 * @param {Array} visibleItems The array of all rendered, visible items to be calculated for
223 * @param {Object} targetSize Object containing target size and height
224 * @return {Object} Object containing box measurements for each child, plus meta data
226 calculateChildBoxes: function(visibleItems, targetSize) {
230 infiniteValue = Infinity,
233 parallelPrefix = me.parallelPrefix,
234 parallelPrefixCap = me.parallelPrefixCap,
235 perpendicularPrefix = me.perpendicularPrefix,
236 perpendicularPrefixCap = me.perpendicularPrefixCap,
237 parallelMinString = 'min' + parallelPrefixCap,
238 perpendicularMinString = 'min' + perpendicularPrefixCap,
239 perpendicularMaxString = 'max' + perpendicularPrefixCap,
241 parallelSize = targetSize[parallelPrefix] - me.scrollOffset,
242 perpendicularSize = targetSize[perpendicularPrefix],
243 padding = me.padding,
244 parallelOffset = padding[me.parallelBefore],
245 paddingParallel = parallelOffset + padding[me.parallelAfter],
246 perpendicularOffset = padding[me.perpendicularLeftTop],
247 paddingPerpendicular = perpendicularOffset + padding[me.perpendicularRightBottom],
248 availPerpendicularSize = mmax(0, perpendicularSize - paddingPerpendicular),
250 innerCtBorderWidth = me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB),
252 isStart = me.pack == 'start',
253 isCenter = me.pack == 'center',
254 isEnd = me.pack == 'end',
256 constrain = Ext.Number.constrain,
257 visibleCount = visibleItems.length,
267 i, child, childParallel, childPerpendicular, childMargins, childSize, minParallel, tmpObj, shortfall,
268 tooNarrow, availableSpace, minSize, item, length, itemIndex, box, oldSize, newSize, reduction, diff,
269 flexedBoxes, remainingSpace, remainingFlex, flexedSize, parallelMargins, calcs, offset,
270 perpendicularMargins, stretchSize;
272 //gather the total flex of all flexed items and the width taken up by fixed width items
273 for (i = 0; i < visibleCount; i++) {
274 child = visibleItems[i];
275 childPerpendicular = child[perpendicularPrefix];
276 if (!child.flex || !(me.align == 'stretch' || me.align == 'stretchmax')) {
277 if (child.componentLayout.initialized !== true) {
278 me.layoutItem(child);
282 childMargins = child.margins;
283 parallelMargins = childMargins[me.parallelBefore] + childMargins[me.parallelAfter];
285 // Create the box description object for this child item.
288 margins: childMargins
291 // flex and not 'auto' width
293 totalFlex += child.flex;
294 childParallel = undefinedValue;
296 // Not flexed or 'auto' width or undefined width
298 if (!(child[parallelPrefix] && childPerpendicular)) {
299 childSize = child.getSize();
301 childParallel = child[parallelPrefix] || childSize[parallelPrefix];
302 childPerpendicular = childPerpendicular || childSize[perpendicularPrefix];
305 nonFlexSize += parallelMargins + (childParallel || 0);
306 desiredSize += parallelMargins + (child.flex ? child[parallelMinString] || 0 : childParallel);
307 minimumSize += parallelMargins + (child[parallelMinString] || childParallel || 0);
309 // Max height for align - force layout of non-laid out subcontainers without a numeric height
310 if (typeof childPerpendicular != 'number') {
311 // Clear any static sizing and revert to flow so we can get a proper measurement
312 // child['set' + perpendicularPrefixCap](null);
313 childPerpendicular = child['get' + perpendicularPrefixCap]();
316 // Track the maximum perpendicular size for use by the stretch and stretchmax align config values.
317 // Ensure that the tracked maximum perpendicular size takes into account child min[Width|Height] settings!
318 maxSize = mmax(maxSize, mmax(childPerpendicular, child[perpendicularMinString]||0) + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]);
320 tmpObj[parallelPrefix] = childParallel || undefinedValue;
321 tmpObj.dirtySize = child.componentLayout.lastComponentSize ? (tmpObj[parallelPrefix] !== child.componentLayout.lastComponentSize[parallelPrefix]) : false;
322 tmpObj[perpendicularPrefix] = childPerpendicular || undefinedValue;
326 // Only calculate parallel overflow indicators if we are not auto sizing
328 shortfall = desiredSize - parallelSize;
329 tooNarrow = minimumSize > parallelSize;
332 //the space available to the flexed items
333 availableSpace = mmax(0, parallelSize - nonFlexSize - paddingParallel - (me.reserveOffset ? me.availableSpaceOffset : 0));
336 for (i = 0; i < visibleCount; i++) {
338 minSize = visibleItems[i][parallelMinString] || visibleItems[i][parallelPrefix] || box[parallelPrefix];
339 box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize;
340 box[parallelPrefix] = minSize;
344 //all flexed items should be sized to their minimum size, other items should be shrunk down until
345 //the shortfall has been accounted for
346 if (shortfall > 0) {
348 * When we have a shortfall but are not tooNarrow, we need to shrink the width of each non-flexed item.
349 * Flexed items are immediately reduced to their minWidth and anything already at minWidth is ignored.
350 * The remaining items are collected into the minWidths array, which is later used to distribute the shortfall.
352 for (i = 0; i < visibleCount; i++) {
353 item = visibleItems[i];
354 minSize = item[parallelMinString] || 0;
356 //shrink each non-flex tab by an equal amount to make them all fit. Flexed items are all
357 //shrunk to their minSize because they're flexible and should be the first to lose size
360 box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize;
361 box[parallelPrefix] = minSize;
362 } else if (me.shrinkToFit) {
365 available: boxes[i][parallelPrefix] - minSize,
371 //sort by descending amount of width remaining before minWidth is reached
372 Ext.Array.sort(minSizes, me.minSizeSortFn);
375 * Distribute the shortfall (difference between total desired size of all items and actual size available)
376 * between the non-flexed items. We try to distribute the shortfall evenly, but apply it to items with the
377 * smallest difference between their size and minSize first, so that if reducing the size by the average
378 * amount would make that item less than its minSize, we carry the remainder over to the next item.
380 for (i = 0, length = minSizes.length; i < length; i++) {
381 itemIndex = minSizes[i].index;
383 if (itemIndex == undefinedValue) {
386 item = visibleItems[itemIndex];
387 minSize = minSizes[i].minSize;
389 box = boxes[itemIndex];
390 oldSize = box[parallelPrefix];
391 newSize = mmax(minSize, oldSize - math.ceil(shortfall / (length - i)));
392 reduction = oldSize - newSize;
394 box.dirtySize = box.dirtySize || box[parallelPrefix] != newSize;
395 box[parallelPrefix] = newSize;
396 shortfall -= reduction;
398 tooNarrow = (shortfall > 0);
401 remainingSpace = availableSpace;
402 remainingFlex = totalFlex;
405 // Create an array containing *just the flexed boxes* for allocation of remainingSpace
406 for (i = 0; i < visibleCount; i++) {
407 child = visibleItems[i];
408 if (isStart && child.flex) {
409 flexedBoxes.push(boxes[Ext.Array.indexOf(visibleItems, child)]);
412 // The flexed boxes need to be sorted in ascending order of maxSize to work properly
413 // so that unallocated space caused by maxWidth being less than flexed width
414 // can be reallocated to subsequent flexed boxes.
415 Ext.Array.sort(flexedBoxes, me.flexSortFn);
417 // Calculate the size of each flexed item, and attempt to set it.
418 for (i = 0; i < flexedBoxes.length; i++) {
419 calcs = flexedBoxes[i];
420 child = calcs.component;
421 childMargins = calcs.margins;
423 flexedSize = math.ceil((child.flex / remainingFlex) * remainingSpace);
425 // Implement maxSize and minSize check
426 flexedSize = Math.max(child['min' + parallelPrefixCap] || 0, math.min(child['max' + parallelPrefixCap] || infiniteValue, flexedSize));
428 // Remaining space has already had all parallel margins subtracted from it, so just subtract consumed size
429 remainingSpace -= flexedSize;
430 remainingFlex -= child.flex;
432 calcs.dirtySize = calcs.dirtySize || calcs[parallelPrefix] != flexedSize;
433 calcs[parallelPrefix] = flexedSize;
439 parallelOffset += availableSpace / 2;
442 parallelOffset += availableSpace;
445 // Fix for left and right docked Components in a dock component layout. This is for docked Headers and docked Toolbars.
446 // Older Microsoft browsers do not size a position:absolute element's width to match its content.
447 // So in this case, in the updateInnerCtSize method we may need to adjust the size of the owning Container's element explicitly based upon
448 // the discovered max width. So here we put a calculatedWidth property in the metadata to facilitate this.
449 if (me.owner.dock && (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) && !me.owner.width && me.direction == 'vertical') {
451 calculatedWidth = maxSize + me.owner.el.getPadding('lr') + me.owner.el.getBorderWidth('lr');
452 if (me.owner.frameSize) {
453 calculatedWidth += me.owner.frameSize.left + me.owner.frameSize.right;
455 // If the owning element is not sized, calculate the available width to center or stretch in based upon maxSize
456 availPerpendicularSize = Math.min(availPerpendicularSize, targetSize.width = maxSize + padding.left + padding.right);
459 //finally, calculate the left and top position of each item
460 for (i = 0; i < visibleCount; i++) {
461 child = visibleItems[i];
464 childMargins = calcs.margins;
466 perpendicularMargins = childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom];
468 // Advance past the "before" margin
469 parallelOffset += childMargins[me.parallelBefore];
471 calcs[me.parallelBefore] = parallelOffset;
472 calcs[me.perpendicularLeftTop] = perpendicularOffset + childMargins[me.perpendicularLeftTop];
474 if (me.align == 'stretch') {
475 stretchSize = constrain(availPerpendicularSize - perpendicularMargins, child[perpendicularMinString] || 0, child[perpendicularMaxString] || infiniteValue);
476 calcs.dirtySize = calcs.dirtySize || calcs[perpendicularPrefix] != stretchSize;
477 calcs[perpendicularPrefix] = stretchSize;
479 else if (me.align == 'stretchmax') {
480 stretchSize = constrain(maxSize - perpendicularMargins, child[perpendicularMinString] || 0, child[perpendicularMaxString] || infiniteValue);
481 calcs.dirtySize = calcs.dirtySize || calcs[perpendicularPrefix] != stretchSize;
482 calcs[perpendicularPrefix] = stretchSize;
484 else if (me.align == me.alignCenteringString) {
485 // When calculating a centered position within the content box of the innerCt, the width of the borders must be subtracted from
486 // the size to yield the space available to center within.
487 // The updateInnerCtSize method explicitly adds the border widths to the set size of the innerCt.
488 diff = mmax(availPerpendicularSize, maxSize) - innerCtBorderWidth - calcs[perpendicularPrefix];
490 calcs[me.perpendicularLeftTop] = perpendicularOffset + Math.round(diff / 2);
494 // Advance past the box size and the "after" margin
495 parallelOffset += (calcs[parallelPrefix] || 0) + childMargins[me.parallelAfter];
501 calculatedWidth: calculatedWidth,
503 nonFlexSize: nonFlexSize,
504 desiredSize: desiredSize,
505 minimumSize: minimumSize,
506 shortfall: shortfall,
512 onRemove: function(comp){
513 this.callParent(arguments);
514 if (this.overflowHandler) {
515 this.overflowHandler.onRemove(comp);
519 <span id='Ext-layout-container-Box-method-initOverflowHandler'> /**
522 initOverflowHandler: function() {
523 var handler = this.overflowHandler;
525 if (typeof handler == 'string') {
531 var handlerType = 'None';
532 if (handler && handler.type !== undefined) {
533 handlerType = handler.type;
536 var constructor = Ext.layout.container.boxOverflow[handlerType];
537 if (constructor[this.type]) {
538 constructor = constructor[this.type];
541 this.overflowHandler = Ext.create('Ext.layout.container.boxOverflow.' + handlerType, this, handler);
544 <span id='Ext-layout-container-Box-method-onLayout'> /**
546 * Runs the child box calculations and caches them in childBoxCache. Subclasses can used these cached values
549 onLayout: function() {
551 // Clear the innerCt size so it doesn't influence the child items.
552 if (this.clearInnerCtOnLayout === true && this.adjustmentPass !== true) {
553 this.innerCt.setSize(null, null);
557 targetSize = me.getLayoutTargetSize(),
558 items = me.getVisibleItems(),
559 calcs = me.calculateChildBoxes(items, targetSize),
562 handler, method, results;
564 if (me.autoSize && calcs.meta.desiredSize) {
565 targetSize[me.parallelPrefix] = calcs.meta.desiredSize;
568 //invoke the overflow handler, if one is configured
569 if (meta.shortfall > 0) {
570 handler = me.overflowHandler;
571 method = meta.tooNarrow ? 'handleOverflow': 'clearOverflow';
573 results = handler[method](calcs, targetSize);
576 if (results.targetSize) {
577 targetSize = results.targetSize;
580 if (results.recalculate) {
581 items = me.getVisibleItems();
582 calcs = me.calculateChildBoxes(items, targetSize);
587 me.overflowHandler.clearOverflow();
590 <span id='Ext-layout-container-Box-property-layoutTargetLastSize'> /**
592 * @property layoutTargetLastSize
594 * Private cache of the last measured size of the layout target. This should never be used except by
595 * BoxLayout subclasses during their onLayout run.
597 me.layoutTargetLastSize = targetSize;
599 <span id='Ext-layout-container-Box-property-childBoxCache'> /**
601 * @property childBoxCache
603 * Array of the last calculated height, width, top and left positions of each visible rendered component
604 * within the Box layout.
606 me.childBoxCache = calcs;
608 me.updateInnerCtSize(targetSize, calcs);
609 me.updateChildBoxes(boxes);
610 me.handleTargetOverflow(targetSize);
613 animCallback: Ext.emptyFn,
615 <span id='Ext-layout-container-Box-method-updateChildBoxes'> /**
616 </span> * Resizes and repositions each child component
617 * @param {Object[]} boxes The box measurements
619 updateChildBoxes: function(boxes) {
622 length = boxes.length,
624 dd = Ext.dd.DDM.getDDById(me.innerCt.id), // Any DD active on this layout's element (The BoxReorderer plugin does this.)
625 oldBox, newBox, changed, comp, boxAnim, animCallback;
627 for (; i < length; i++) {
629 comp = newBox.component;
631 // If a Component is being drag/dropped, skip positioning it.
632 // Accomodate the BoxReorderer plugin: Its current dragEl must not be positioned by the layout
633 if (dd && (dd.getDragEl() === comp.el.dom)) {
639 oldBox = me.getChildBox(comp);
641 // If we are animating, we build up an array of Anim config objects, one for each
642 // child Component which has any changed box properties. Those with unchanged
643 // properties are not animated.
645 // Animate may be a config object containing callback.
646 animCallback = me.animate.callback || me.animate;
648 layoutAnimation: true, // Component Target handler must use set*Calculated*Size
654 // Only set from and to properties when there's a change.
655 // Perform as few Component setter methods as possible.
656 // Temporarily set the property values that we are not animating
657 // so that doComponentLayout does not auto-size them.
658 if (!isNaN(newBox.width) && (newBox.width != oldBox.width)) {
660 // boxAnim.from.width = oldBox.width;
661 boxAnim.to.width = newBox.width;
663 if (!isNaN(newBox.height) && (newBox.height != oldBox.height)) {
665 // boxAnim.from.height = oldBox.height;
666 boxAnim.to.height = newBox.height;
668 if (!isNaN(newBox.left) && (newBox.left != oldBox.left)) {
670 // boxAnim.from.left = oldBox.left;
671 boxAnim.to.left = newBox.left;
673 if (!isNaN(newBox.top) && (newBox.top != oldBox.top)) {
675 // boxAnim.from.top = oldBox.top;
676 boxAnim.to.top = newBox.top;
679 animQueue.push(boxAnim);
682 if (newBox.dirtySize) {
683 if (newBox.width !== oldBox.width || newBox.height !== oldBox.height) {
684 me.setItemSize(comp, newBox.width, newBox.height);
687 // Don't set positions to NaN
688 if (isNaN(newBox.left) || isNaN(newBox.top)) {
691 comp.setPosition(newBox.left, newBox.top);
695 // Kick off any queued animations
696 length = animQueue.length;
699 // A function which cleans up when a Component's animation is done.
700 // The last one to finish calls the callback.
701 var afterAnimate = function(anim) {
702 // When we've animated all changed boxes into position, clear our busy flag and call the callback.
705 me.animCallback(anim);
706 me.layoutBusy = false;
707 if (Ext.isFunction(animCallback)) {
713 var beforeAnimate = function() {
714 me.layoutBusy = true;
717 // Start each box animation off
718 for (i = 0, length = animQueue.length; i < length; i++) {
719 boxAnim = animQueue[i];
721 // Clean up the Component after. Clean up the *layout* after the last animation finishes
722 boxAnim.listeners.afteranimate = afterAnimate;
724 // The layout is busy during animation, and may not be called, so set the flag when the first animation begins
726 boxAnim.listeners.beforeanimate = beforeAnimate;
728 if (me.animate.duration) {
729 boxAnim.duration = me.animate.duration;
731 comp = boxAnim.target;
732 delete boxAnim.target;
733 // Stop any currently running animation
734 comp.stopAnimation();
735 comp.animate(boxAnim);
740 <span id='Ext-layout-container-Box-method-updateInnerCtSize'> /**
742 * Called by onRender just before the child components are sized and positioned. This resizes the innerCt
743 * to make sure all child items fit within it. We call this before sizing the children because if our child
744 * items are larger than the previous innerCt size the browser will insert scrollbars and then remove them
745 * again immediately afterwards, giving a performance hit.
746 * Subclasses should provide an implementation.
747 * @param {Object} currentSize The current height and width of the innerCt
748 * @param {Object} calculations The new box calculations of all items to be laid out
750 updateInnerCtSize: function(tSize, calcs) {
754 padding = me.padding,
756 height = tSize.height,
761 if (me.direction == 'horizontal') {
762 innerCtWidth = width;
763 innerCtHeight = meta.maxSize + padding.top + padding.bottom + me.innerCt.getBorderWidth('tb');
765 if (align == 'stretch') {
766 innerCtHeight = height;
768 else if (align == 'middle') {
769 innerCtHeight = mmax(height, innerCtHeight);
772 innerCtHeight = height;
773 innerCtWidth = meta.maxSize + padding.left + padding.right + me.innerCt.getBorderWidth('lr');
775 if (align == 'stretch') {
776 innerCtWidth = width;
778 else if (align == 'center') {
779 innerCtWidth = mmax(width, innerCtWidth);
782 me.getRenderTarget().setSize(innerCtWidth || undefined, innerCtHeight || undefined);
784 // If a calculated width has been found (and this only happens for auto-width vertical docked Components in old Microsoft browsers)
785 // then, if the Component has not assumed the size of its content, set it to do so.
786 if (meta.calculatedWidth && me.owner.el.getWidth() > meta.calculatedWidth) {
787 me.owner.el.setWidth(meta.calculatedWidth);
790 if (me.innerCt.dom.scrollTop) {
791 me.innerCt.dom.scrollTop = 0;
795 <span id='Ext-layout-container-Box-method-handleTargetOverflow'> /**
797 * This should be called after onLayout of any BoxLayout subclass. If the target's overflow is not set to 'hidden',
798 * we need to lay out a second time because the scrollbars may have modified the height and width of the layout
799 * target. Having a Box layout inside such a target is therefore not recommended.
800 * @param {Object} previousTargetSize The size and height of the layout target before we just laid out
801 * @param {Ext.container.Container} container The container
802 * @param {Ext.Element} target The target element
803 * @return True if the layout overflowed, and was reflowed in a secondary onLayout call.
805 handleTargetOverflow: function(previousTargetSize) {
806 var target = this.getTarget(),
807 overflow = target.getStyle('overflow'),
810 if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
811 newTargetSize = this.getLayoutTargetSize();
812 if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height) {
813 this.adjustmentPass = true;
819 delete this.adjustmentPass;
823 isValidParent : function(item, target, position) {
824 // Note: Box layouts do not care about order within the innerCt element because it's an absolutely positioning layout
825 // We only care whether the item is a direct child of the innerCt element.
826 var itemEl = item.el ? item.el.dom : Ext.getDom(item);
827 return (itemEl && this.innerCt && itemEl.parentNode === this.innerCt.dom) || false;
830 // Overridden method from AbstractContainer.
831 // Used in the base AbstractLayout.beforeLayout method to render all items into.
832 getRenderTarget: function() {
834 // the innerCt prevents wrapping and shuffling while the container is resizing
835 this.innerCt = this.getTarget().createChild({
839 this.padding = Ext.util.Format.parseBox(this.padding);
845 renderItem: function(item, target) {
846 this.callParent(arguments);
848 itemEl = item.getEl(),
849 style = itemEl.dom.style,
850 margins = item.margins || item.margin;
852 // Parse the item's margin/margins specification
854 if (Ext.isString(margins) || Ext.isNumber(margins)) {
855 margins = Ext.util.Format.parseBox(margins);
857 Ext.applyIf(margins, {top: 0, right: 0, bottom: 0, left: 0});
860 margins = Ext.apply({}, me.defaultMargins);
863 // Add any before/after CSS margins to the configured margins, and zero the CSS margins
864 margins.top += itemEl.getMargin('t');
865 margins.right += itemEl.getMargin('r');
866 margins.bottom += itemEl.getMargin('b');
867 margins.left += itemEl.getMargin('l');
868 margins.height = margins.top + margins.bottom;
869 margins.width = margins.left + margins.right;
870 style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '0';
872 // Item must reference calculated margins.
873 item.margins = margins;
876 <span id='Ext-layout-container-Box-method-destroy'> /**
879 destroy: function() {
880 Ext.destroy(this.innerCt, this.overflowHandler);
881 this.callParent(arguments);