3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4 <title>The source code</title>
5 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <body onload="prettyPrint();">
9 <pre class="prettyprint lang-js">/*!
10 * Ext JS Library 3.3.1
11 * Copyright(c) 2006-2010 Sencha Inc.
12 * licensing@sencha.com
13 * http://www.sencha.com/license
15 <div id="cls-Ext.layout.HBoxLayout"></div>/**
16 * @class Ext.layout.HBoxLayout
17 * @extends Ext.layout.BoxLayout
18 * <p>A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal
19 * space between child items containing a numeric <code>flex</code> configuration.</p>
20 * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option.
22 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
23 <div id="cfg-Ext.layout.HBoxLayout-align"></div>/**
25 * Controls how the child items of the container are aligned. Acceptable configuration values for this
27 * <div class="mdetail-params"><ul>
28 * <li><b><tt>top</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned vertically
29 * at the <b>top</b> of the container</div></li>
30 * <li><b><tt>middle</tt></b> : <div class="sub-desc">child items are aligned vertically in the
31 * <b>middle</b> of the container</div></li>
32 * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched vertically to fill
33 * the height of the container</div></li>
34 * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched vertically to
35 * the height of the largest item.</div></li>
37 align: 'top', // top, middle, stretch, strechmax
41 <div id="cfg-Ext.layout.HBoxLayout-pack"></div>/**
43 * Controls how the child items of the container are packed together. Acceptable configuration values
44 * for this property are:
45 * <div class="mdetail-params"><ul>
46 * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
47 * <b>left</b> side of container</div></li>
48 * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
49 * <b>mid-width</b> of container</div></li>
50 * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
51 * side of container</div></li>
54 <div id="cfg-Ext.layout.HBoxLayout-flex"></div>/**
56 * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
57 * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>horizontally</b>
58 * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
59 * a <tt>flex</tt> value specified. Any child items that have either a <tt>flex = 0</tt> or
60 * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
65 * Calculates the size and positioning of each item in the HBox. This iterates over all of the rendered,
66 * visible items and returns a height, width, top and left for each, as well as a reference to each. Also
67 * returns meta data such as maxHeight which are useful when resizing layout wrappers such as this.innerCt.
68 * @param {Array} visibleItems The array of all rendered, visible items to be calculated for
69 * @param {Object} targetSize Object containing target size and height
70 * @return {Object} Object containing box measurements for each child, plus meta data
72 calculateChildBoxes: function(visibleItems, targetSize) {
73 var visibleCount = visibleItems.length,
75 padding = this.padding,
76 topOffset = padding.top,
77 leftOffset = padding.left,
78 paddingVert = topOffset + padding.bottom,
79 paddingHoriz = leftOffset + padding.right,
81 width = targetSize.width - this.scrollOffset,
82 height = targetSize.height,
83 availHeight = Math.max(0, height - paddingVert),
85 isStart = this.pack == 'start',
86 isCenter = this.pack == 'center',
87 isEnd = this.pack == 'end',
95 //used to cache the calculated size and position values for each child item
98 //used in the for loops below, just declared here for brevity
99 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
100 horizMargins, vertMargins, stretchHeight;
102 //gather the total flex of all flexed items and the width taken up by fixed width items
103 for (i = 0; i < visibleCount; i++) {
104 child = visibleItems[i];
105 childHeight = child.height;
106 childWidth = child.width;
107 canLayout = !child.hasLayout && typeof child.doLayout == 'function';
109 // Static width (numeric) requires no calcs
110 if (typeof childWidth != 'number') {
112 // flex and not 'auto' width
113 if (child.flex && !childWidth) {
114 totalFlex += child.flex;
116 // Not flexed or 'auto' width or undefined width
118 //Render and layout sub-containers without a flex or width defined, as otherwise we
119 //don't know how wide the sub-container should be and cannot calculate flexed widths
120 if (!childWidth && canLayout) {
124 childSize = child.getSize();
125 childWidth = childSize.width;
126 childHeight = childSize.height;
130 childMargins = child.margins;
131 horizMargins = childMargins.left + childMargins.right;
133 nonFlexWidth += horizMargins + (childWidth || 0);
134 desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
135 minimumWidth += horizMargins + (child.minWidth || childWidth || 0);
137 // Max height for align - force layout of non-laid out subcontainers without a numeric height
138 if (typeof childHeight != 'number') {
142 childHeight = child.getHeight();
145 maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
147 //cache the size of each child component. Don't set height or width to 0, keep undefined instead
150 height : childHeight || undefined,
151 width : childWidth || undefined
155 var shortfall = desiredWidth - width,
156 tooNarrow = minimumWidth > width;
158 //the width available to the flexed items
159 var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
162 for (i = 0; i < visibleCount; i++) {
163 boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
166 //all flexed items should be sized to their minimum width, other items should be shrunk down until
167 //the shortfall has been accounted for
171 <div id="prop-Ext.layout.HBoxLayout-for"></div>/**
172 * When we have a shortfall but are not tooNarrow, we need to shrink the width of each non-flexed item.
173 * Flexed items are immediately reduced to their minWidth and anything already at minWidth is ignored.
174 * The remaining items are collected into the minWidths array, which is later used to distribute the shortfall.
176 for (var index = 0, length = visibleCount; index < length; index++) {
177 var item = visibleItems[index],
178 minWidth = item.minWidth || 0;
180 //shrink each non-flex tab by an equal amount to make them all fit. Flexed items are all
181 //shrunk to their minWidth because they're flexible and should be the first to lose width
183 boxes[index].width = minWidth;
187 available: boxes[index].width - minWidth,
193 //sort by descending amount of width remaining before minWidth is reached
194 minWidths.sort(function(a, b) {
195 return a.available > b.available ? 1 : -1;
199 * Distribute the shortfall (difference between total desired with of all items and actual width available)
200 * between the non-flexed items. We try to distribute the shortfall evenly, but apply it to items with the
201 * smallest difference between their width and minWidth first, so that if reducing the width by the average
202 * amount would make that item less than its minWidth, we carry the remainder over to the next item.
204 for (var i = 0, length = minWidths.length; i < length; i++) {
205 var itemIndex = minWidths[i].index;
207 if (itemIndex == undefined) {
211 var item = visibleItems[itemIndex],
212 box = boxes[itemIndex],
213 oldWidth = box.width,
214 minWidth = item.minWidth,
215 newWidth = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
216 reduction = oldWidth - newWidth;
218 boxes[itemIndex].width = newWidth;
219 shortfall -= reduction;
222 //temporary variables used in the flex width calculations below
223 var remainingWidth = availableWidth,
224 remainingFlex = totalFlex;
226 //calculate the widths of each flexed item
227 for (i = 0; i < visibleCount; i++) {
228 child = visibleItems[i];
231 childMargins = child.margins;
232 vertMargins = childMargins.top + childMargins.bottom;
234 if (isStart && child.flex && !child.width) {
235 flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth);
236 remainingWidth -= flexedWidth;
237 remainingFlex -= child.flex;
239 calcs.width = flexedWidth;
240 calcs.dirtySize = true;
247 leftOffset += availableWidth / 2;
249 leftOffset += availableWidth;
252 //finally, calculate the left and top position of each item
253 for (i = 0; i < visibleCount; i++) {
254 child = visibleItems[i];
257 childMargins = child.margins;
258 leftOffset += childMargins.left;
259 vertMargins = childMargins.top + childMargins.bottom;
261 calcs.left = leftOffset;
262 calcs.top = topOffset + childMargins.top;
264 switch (this.align) {
266 stretchHeight = availHeight - vertMargins;
267 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
268 calcs.dirtySize = true;
271 stretchHeight = maxHeight - vertMargins;
272 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
273 calcs.dirtySize = true;
276 var diff = availHeight - calcs.height - vertMargins;
278 calcs.top = topOffset + vertMargins + (diff / 2);
282 leftOffset += calcs.width + childMargins.right;
288 maxHeight : maxHeight,
289 nonFlexWidth: nonFlexWidth,
290 desiredWidth: desiredWidth,
291 minimumWidth: minimumWidth,
292 shortfall : desiredWidth - width,
293 tooNarrow : tooNarrow
299 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;</pre>