Upgrade to ExtJS 3.1.1 - Released 02/08/2010
[extjs.git] / docs / source / BoxLayout.html
1 <html>\r
2 <head>\r
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    \r
4   <title>The source code</title>\r
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
7 </head>\r
8 <body  onload="prettyPrint();">\r
9     <pre class="prettyprint lang-js"><div id="cls-Ext.layout.BoxLayout"></div>/**
10  * @class Ext.layout.BoxLayout
11  * @extends Ext.layout.ContainerLayout
12  * <p>Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.</p>
13  */
14 Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
15     <div id="cfg-Ext.layout.BoxLayout-defaultMargins"></div>/**
16      * @cfg {Object} defaultMargins
17      * <p>If the individual contained items do not have a <tt>margins</tt>
18      * property specified, the default margins from this property will be
19      * applied to each item.</p>
20      * <br><p>This property may be specified as an object containing margins
21      * to apply in the format:</p><pre><code>
22 {
23     top: (top margin),
24     right: (right margin),
25     bottom: (bottom margin),
26     left: (left margin)
27 }</code></pre>
28      * <p>This property may also be specified as a string containing
29      * space-separated, numeric margin values. The order of the sides associated
30      * with each value matches the way CSS processes margin values:</p>
31      * <div class="mdetail-params"><ul>
32      * <li>If there is only one value, it applies to all sides.</li>
33      * <li>If there are two values, the top and bottom borders are set to the
34      * first value and the right and left are set to the second.</li>
35      * <li>If there are three values, the top is set to the first value, the left
36      * and right are set to the second, and the bottom is set to the third.</li>
37      * <li>If there are four values, they apply to the top, right, bottom, and
38      * left, respectively.</li>
39      * </ul></div>
40      * <p>Defaults to:</p><pre><code>
41      * {top:0, right:0, bottom:0, left:0}
42      * </code></pre>
43      */
44     defaultMargins : {left:0,top:0,right:0,bottom:0},
45     <div id="cfg-Ext.layout.BoxLayout-padding"></div>/**
46      * @cfg {String} padding
47      * <p>Sets the padding to be applied to all child items managed by this layout.</p>
48      * <p>This property must be specified as a string containing
49      * space-separated, numeric padding values. The order of the sides associated
50      * with each value matches the way CSS processes padding values:</p>
51      * <div class="mdetail-params"><ul>
52      * <li>If there is only one value, it applies to all sides.</li>
53      * <li>If there are two values, the top and bottom borders are set to the
54      * first value and the right and left are set to the second.</li>
55      * <li>If there are three values, the top is set to the first value, the left
56      * and right are set to the second, and the bottom is set to the third.</li>
57      * <li>If there are four values, they apply to the top, right, bottom, and
58      * left, respectively.</li>
59      * </ul></div>
60      * <p>Defaults to: <code>"0"</code></p>
61      */
62     padding : '0',
63     // documented in subclasses
64     pack : 'start',
65
66     // private
67     monitorResize : true,
68     type: 'box',
69     scrollOffset : 0,
70     extraCls : 'x-box-item',
71     targetCls : 'x-box-layout-ct',
72     innerCls : 'x-box-inner',
73
74     constructor : function(config){
75         Ext.layout.BoxLayout.superclass.constructor.call(this, config);
76         if(Ext.isString(this.defaultMargins)){
77             this.defaultMargins = this.parseMargins(this.defaultMargins);
78         }
79     },
80
81     // private
82     isValidParent : function(c, target){
83         return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
84     },
85
86     // private
87     renderAll : function(ct, target){
88         if(!this.innerCt){
89             // the innerCt prevents wrapping and shuffling while
90             // the container is resizing
91             this.innerCt = target.createChild({cls:this.innerCls});
92             this.padding = this.parseMargins(this.padding);
93         }
94         Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
95     },
96
97     onLayout : function(ct, target){
98         this.renderAll(ct, target);
99     },
100
101     getLayoutTargetSize : function(){
102         var target = this.container.getLayoutTarget(), ret;
103         if (target) {
104             ret = target.getViewSize();
105             ret.width -= target.getPadding('lr');
106             ret.height -= target.getPadding('tb');
107         }
108         return ret;
109     },
110
111     // private
112     renderItem : function(c){
113         if(Ext.isString(c.margins)){
114             c.margins = this.parseMargins(c.margins);
115         }else if(!c.margins){
116             c.margins = this.defaultMargins;
117         }
118         Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
119     }
120 });
121
122 <div id="cls-Ext.layout.VBoxLayout"></div>/**
123  * @class Ext.layout.VBoxLayout
124  * @extends Ext.layout.BoxLayout
125  * <p>A layout that arranges items vertically down a Container. This layout optionally divides available vertical
126  * space between child items containing a numeric <code>flex</code> configuration.</p>
127  * This layout may also be used to set the widths of child items by configuring it with the {@link #align} option.
128  */
129 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
130     <div id="cfg-Ext.layout.VBoxLayout-align"></div>/**
131      * @cfg {String} align
132      * Controls how the child items of the container are aligned. Acceptable configuration values for this
133      * property are:
134      * <div class="mdetail-params"><ul>
135      * <li><b><tt>left</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned horizontally
136      * at the <b>left</b> side of the container</div></li>
137      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are aligned horizontally at the
138      * <b>mid-width</b> of the container</div></li>
139      * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched horizontally to fill
140      * the width of the container</div></li>
141      * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched horizontally to
142      * the size of the largest item.</div></li>
143      * </ul></div>
144      */
145     align : 'left', // left, center, stretch, strechmax
146     type: 'vbox',
147     <div id="cfg-Ext.layout.VBoxLayout-pack"></div>/**
148      * @cfg {String} pack
149      * Controls how the child items of the container are packed together. Acceptable configuration values
150      * for this property are:
151      * <div class="mdetail-params"><ul>
152      * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
153      * <b>top</b> side of container</div></li>
154      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
155      * <b>mid-height</b> of container</div></li>
156      * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>bottom</b>
157      * side of container</div></li>
158      * </ul></div>
159      */
160     <div id="cfg-Ext.layout.VBoxLayout-flex"></div>/**
161      * @cfg {Number} flex
162      * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
163      * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>vertically</b>
164      * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
165      * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
166      * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
167      */
168
169     // private
170     onLayout : function(ct, target){
171         Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);
172
173         var cs = this.getRenderedItems(ct), csLen = cs.length,
174             c, i, cm, ch, margin, cl, diff, aw, availHeight,
175             size = this.getLayoutTargetSize(),
176             w = size.width,
177             h = size.height - this.scrollOffset,
178             l = this.padding.left,
179             t = this.padding.top,
180             isStart = this.pack == 'start',
181             extraHeight = 0,
182             maxWidth = 0,
183             totalFlex = 0,
184             usedHeight = 0,
185             idx = 0,
186             heights = [],
187             restore = [];
188
189         // Do only width calculations and apply those first, as they can affect height
190         for (i = 0 ; i < csLen; i++) {
191             c = cs[i];
192             cm = c.margins;
193             margin = cm.top + cm.bottom;
194             // Max height for align
195             maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
196         }
197
198         var innerCtWidth = maxWidth + this.padding.left + this.padding.right;
199         switch(this.align){
200             case 'stretch':
201                 this.innerCt.setSize(w, h);
202                 break;
203             case 'stretchmax':
204             case 'left':
205                 this.innerCt.setSize(innerCtWidth, h);
206                 break;
207             case 'center':
208                 this.innerCt.setSize(w = Math.max(w, innerCtWidth), h);
209                 break;
210         }
211
212         var availableWidth = Math.max(0, w - this.padding.left - this.padding.right);
213         // Apply widths
214         for (i = 0 ; i < csLen; i++) {
215             c = cs[i];
216             cm = c.margins;
217             if(this.align == 'stretch'){
218                 c.setWidth(((w - (this.padding.left + this.padding.right)) - (cm.left + cm.right)).constrain(
219                     c.minWidth || 0, c.maxWidth || 1000000));
220             }else if(this.align == 'stretchmax'){
221                 c.setWidth((maxWidth - (cm.left + cm.right)).constrain(
222                     c.minWidth || 0, c.maxWidth || 1000000));
223             }else if(isStart && c.flex){
224                 c.setWidth();
225             }
226
227         }
228
229         // Height calculations
230         for (i = 0 ; i < csLen; i++) {
231             c = cs[i];
232             // Total of all the flex values
233             totalFlex += c.flex || 0;
234             // Don't run height calculations on flexed items
235             if (!c.flex) {
236                 // Render and layout sub-containers without a flex or height, once
237                 if (!c.height && !c.hasLayout && c.doLayout) {
238                     c.doLayout();
239                 }
240                 ch = c.getHeight();
241             } else {
242                 ch = 0;
243             }
244
245             cm = c.margins;
246             // Determine how much height is available to flex
247             extraHeight += ch + cm.top + cm.bottom;
248         }
249         // Final avail height calc
250         availHeight = Math.max(0, (h - extraHeight - this.padding.top - this.padding.bottom));
251
252         var leftOver = availHeight;
253         for (i = 0 ; i < csLen; i++) {
254             c = cs[i];
255             if(isStart && c.flex){
256                 ch = Math.floor(availHeight * (c.flex / totalFlex));
257                 leftOver -= ch;
258                 heights.push(ch);
259             }
260         }
261         if(this.pack == 'center'){
262             t += availHeight ? availHeight / 2 : 0;
263         }else if(this.pack == 'end'){
264             t += availHeight;
265         }
266         idx = 0;
267         // Apply heights
268         for (i = 0 ; i < csLen; i++) {
269             c = cs[i];
270             cm = c.margins;
271             t += cm.top;
272             aw = availableWidth;
273             cl = l + cm.left // default left pos
274
275             // Adjust left pos for centering
276             if(this.align == 'center'){
277                 if((diff = availableWidth - (c.getWidth() + cm.left + cm.right)) > 0){
278                     cl += (diff/2);
279                     aw -= diff;
280                 }
281             }
282
283             c.setPosition(cl, t);
284             if(isStart && c.flex){
285                 ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0));
286                 c.setSize(aw, ch);
287             }else{
288                 ch = c.getHeight();
289             }
290             t += ch + cm.bottom;
291         }
292         // Putting a box layout into an overflowed container is NOT correct and will make a second layout pass necessary.
293         if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
294             var ts = this.getLayoutTargetSize();
295             if (ts.width != size.width || ts.height != size.height){
296                 this.adjustmentPass = true;
297                 this.onLayout(ct, target);
298             }
299         }
300         delete this.adjustmentPass;
301     }
302 });
303
304 Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
305
306 <div id="cls-Ext.layout.HBoxLayout"></div>/**
307  * @class Ext.layout.HBoxLayout
308  * @extends Ext.layout.BoxLayout
309  * <p>A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal
310  * space between child items containing a numeric <code>flex</code> configuration.</p>
311  * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option.
312  */
313 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
314     <div id="cfg-Ext.layout.HBoxLayout-align"></div>/**
315      * @cfg {String} align
316      * Controls how the child items of the container are aligned. Acceptable configuration values for this
317      * property are:
318      * <div class="mdetail-params"><ul>
319      * <li><b><tt>top</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned vertically
320      * at the <b>top</b> of the container</div></li>
321      * <li><b><tt>middle</tt></b> : <div class="sub-desc">child items are aligned vertically in the
322      * <b>middle</b> of the container</div></li>
323      * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched vertically to fill
324      * the height of the container</div></li>
325      * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched vertically to
326      * the height of the largest item.</div></li>
327      */
328     align : 'top', // top, middle, stretch, strechmax
329     type: 'hbox',
330     <div id="cfg-Ext.layout.HBoxLayout-pack"></div>/**
331      * @cfg {String} pack
332      * Controls how the child items of the container are packed together. Acceptable configuration values
333      * for this property are:
334      * <div class="mdetail-params"><ul>
335      * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
336      * <b>left</b> side of container</div></li>
337      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
338      * <b>mid-width</b> of container</div></li>
339      * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
340      * side of container</div></li>
341      * </ul></div>
342      */
343     <div id="cfg-Ext.layout.HBoxLayout-flex"></div>/**
344      * @cfg {Number} flex
345      * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
346      * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>horizontally</b>
347      * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
348      * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
349      * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
350      */
351
352     // private
353     onLayout : function(ct, target){
354         Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
355
356         var cs = this.getRenderedItems(ct), csLen = cs.length,
357             c, i, cm, cw, ch, diff, availWidth,
358             size = this.getLayoutTargetSize(),
359             w = size.width - this.scrollOffset,
360             h = size.height,
361             l = this.padding.left,
362             t = this.padding.top,
363             isStart = this.pack == 'start',
364             isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
365             extraWidth = 0,
366             maxHeight = 0,
367             totalFlex = 0,
368             usedWidth = 0;
369
370         for (i = 0 ; i < csLen; i++) {
371             c = cs[i];
372             // Total of all the flex values
373             totalFlex += c.flex || 0;
374             // Don't run width calculations on flexed items
375             if (!c.flex) {
376                 // Render and layout sub-containers without a flex or width, once
377                 if (!c.width && !c.hasLayout && c.doLayout) {
378                     c.doLayout();
379                 }
380                 cw = c.getWidth();
381             } else {
382                 cw = 0;
383             }
384             cm = c.margins;
385             // Determine how much width is available to flex
386             extraWidth += cw + cm.left + cm.right;
387             // Max height for align
388             maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
389         }
390         // Final avail width calc
391         availWidth = Math.max(0, (w - extraWidth - this.padding.left - this.padding.right));
392
393         var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
394         switch(this.align){
395             case 'stretch':
396                 this.innerCt.setSize(w, h);
397                 break;
398             case 'stretchmax':
399             case 'top':
400                 this.innerCt.setSize(w, innerCtHeight);
401                 break;
402             case 'middle':
403                 this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
404                 break;
405         }
406
407         var leftOver = availWidth,
408             widths = [],
409             restore = [],
410             idx = 0,
411             availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom);
412
413         for (i = 0 ; i < csLen; i++) {
414             c = cs[i];
415             if(isStart && c.flex){
416                 cw = Math.floor(availWidth * (c.flex / totalFlex));
417                 leftOver -= cw;
418                 widths.push(cw);
419             }
420         }
421
422         if(this.pack == 'center'){
423             l += availWidth ? availWidth / 2 : 0;
424         }else if(this.pack == 'end'){
425             l += availWidth;
426         }
427         for (i = 0 ; i < csLen; i++) {
428             c = cs[i];
429             cm = c.margins;
430             l += cm.left;
431             c.setPosition(l, t + cm.top);
432             if(isStart && c.flex){
433                 cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0));
434                 if(isRestore){
435                     restore.push(c.getHeight());
436                 }
437                 c.setSize(cw, availableHeight);
438             }else{
439                 cw = c.getWidth();
440             }
441             l += cw + cm.right;
442         }
443
444         idx = 0;
445         for (i = 0 ; i < csLen; i++) {
446             c = cs[i];
447             cm = c.margins;
448             ch = c.getHeight();
449             if(isStart && c.flex){
450                 ch = restore[idx++];
451             }
452             if(this.align == 'stretch'){
453                 c.setHeight(((h - (this.padding.top + this.padding.bottom)) - (cm.top + cm.bottom)).constrain(
454                     c.minHeight || 0, c.maxHeight || 1000000));
455             }else if(this.align == 'stretchmax'){
456                 c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
457                     c.minHeight || 0, c.maxHeight || 1000000));
458             }else{
459                 if(this.align == 'middle'){
460                     diff = availableHeight - (ch + cm.top + cm.bottom);
461                     ch = t + cm.top + (diff/2);
462                     if(diff > 0){
463                         c.setPosition(c.x, ch);
464                     }
465                 }
466                 if(isStart && c.flex){
467                     c.setHeight(ch);
468                 }
469             }
470         }
471         // Putting a box layout into an overflowed container is NOT correct and will make a second layout pass necessary.
472         if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
473             var ts = this.getLayoutTargetSize();
474             if (ts.width != size.width || ts.height != size.height){
475                 this.adjustmentPass = true;
476                 this.onLayout(ct, target);
477             }
478         }
479         delete this.adjustmentPass;
480     }
481 });
482
483 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
484 </pre>    \r
485 </body>\r
486 </html>