Upgrade to ExtJS 3.1.0 - Released 12/16/2009
[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     scrollOffset : 0,
69     extraCls : 'x-box-item',
70     targetCls : 'x-box-layout-ct',
71     innerCls : 'x-box-inner',
72
73     constructor : function(config){
74         Ext.layout.BoxLayout.superclass.constructor.call(this, config);
75         if(Ext.isString(this.defaultMargins)){
76             this.defaultMargins = this.parseMargins(this.defaultMargins);
77         }
78     },
79
80     // private
81     isValidParent : function(c, target){
82         return c.getPositionEl().dom.parentNode == this.innerCt.dom;
83     },
84
85     // private
86     onLayout : function(ct, target){
87         var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;
88
89         if(!this.innerCt){
90             // the innerCt prevents wrapping and shuffling while
91             // the container is resizing
92             this.innerCt = target.createChild({cls:this.innerCls});
93             this.padding = this.parseMargins(this.padding);
94         }
95         this.renderAll(ct, this.innerCt);
96     },
97
98     // private
99     renderItem : function(c){
100         if(Ext.isString(c.margins)){
101             c.margins = this.parseMargins(c.margins);
102         }else if(!c.margins){
103             c.margins = this.defaultMargins;
104         }
105         Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
106     },
107
108     // deprecate
109     getTargetSize : function(target){
110         return (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize(true);
111     },
112
113     getItems: function(ct){
114         var items = [];
115         ct.items.each(function(c){
116             if(c.isVisible()){
117                 items.push(c);
118             }
119         });
120         return items;
121     }
122 });
123
124 <div id="cls-Ext.layout.VBoxLayout"></div>/**
125  * @class Ext.layout.VBoxLayout
126  * @extends Ext.layout.BoxLayout
127  * <p>A layout that arranges items vertically down a Container. This layout optionally divides available vertical
128  * space between child items containing a numeric <code>flex</code> configuration.</p>
129  * This layout may also be used to set the widths of child items by configuring it with the {@link #align} option.
130  */
131 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
132     <div id="cfg-Ext.layout.VBoxLayout-align"></div>/**
133      * @cfg {String} align
134      * Controls how the child items of the container are aligned. Acceptable configuration values for this
135      * property are:
136      * <div class="mdetail-params"><ul>
137      * <li><b><tt>left</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned horizontally
138      * at the <b>left</b> side of the container</div></li>
139      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are aligned horizontally at the
140      * <b>mid-width</b> of the container</div></li>
141      * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched horizontally to fill
142      * the width of the container</div></li>
143      * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched horizontally to
144      * the size of the largest item.</div></li>
145      * </ul></div>
146      */
147     align : 'left', // left, center, stretch, strechmax
148     <div id="cfg-Ext.layout.VBoxLayout-pack"></div>/**
149      * @cfg {String} pack
150      * Controls how the child items of the container are packed together. Acceptable configuration values
151      * for this property are:
152      * <div class="mdetail-params"><ul>
153      * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
154      * <b>top</b> side of container</div></li>
155      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
156      * <b>mid-height</b> of container</div></li>
157      * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>bottom</b>
158      * side of container</div></li>
159      * </ul></div>
160      */
161     <div id="cfg-Ext.layout.VBoxLayout-flex"></div>/**
162      * @cfg {Number} flex
163      * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
164      * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>vertically</b>
165      * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
166      * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
167      * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
168      */
169
170     // private
171     onLayout : function(ct, target){
172         Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);
173
174         var cs = this.getItems(ct), cm, ch, margin, cl, diff, aw,
175             size = target.getViewSize(true),
176             w = size.width,
177             h = size.height - this.scrollOffset,
178             l = this.padding.left, t = this.padding.top,
179             isStart = this.pack == 'start',
180             stretchWidth = w - (this.padding.left + this.padding.right),
181             extraHeight = 0,
182             maxWidth = 0,
183             totalFlex = 0,
184             flexHeight = 0,
185             usedHeight = 0,
186             idx = 0,
187             heights = [],
188             restore = [],
189             c,
190             csLen = cs.length;
191
192         // Do only width calculations and apply those first, as they can affect height
193         for (i = 0 ; i < csLen; i++) {
194             c = cs[i];
195             cm = c.margins;
196             margin = cm.top + cm.bottom;
197             maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
198         }
199
200         var innerCtWidth = maxWidth + this.padding.left + this.padding.right;
201         switch(this.align){
202             case 'stretch':
203                 this.innerCt.setSize(w, h);
204                 break;
205             case 'stretchmax':
206             case 'left':
207                 this.innerCt.setSize(innerCtWidth, h);
208                 break;
209             case 'center':
210                 this.innerCt.setSize(w = Math.max(w, innerCtWidth), h);
211                 break;
212         }
213
214         var availableWidth = Math.max(0, w - this.padding.left - this.padding.right);
215         // Apply widths
216         for (i = 0 ; i < csLen; i++) {
217             c = cs[i];
218             cm = c.margins;
219             if(this.align == 'stretch'){
220                 c.setWidth((stretchWidth - (cm.left + cm.right)).constrain(
221                     c.minWidth || 0, c.maxWidth || 1000000));
222             }else if(this.align == 'stretchmax'){
223                 c.setWidth((maxWidth - (cm.left + cm.right)).constrain(
224                     c.minWidth || 0, c.maxWidth || 1000000));
225             }else if(isStart && c.flex){
226                 c.setWidth();
227             }
228
229         }
230
231         // Do height calculations
232         for (i = 0 ; i < csLen; i++) {
233             c = cs[i];
234             cm = c.margins;
235             totalFlex += c.flex || 0;
236             ch = c.getHeight();
237             margin = cm.top + cm.bottom;
238             extraHeight += ch + margin;
239             flexHeight += margin + (c.flex ? 0 : ch);
240         }
241         extraHeight = h - extraHeight - this.padding.top - this.padding.bottom;
242
243         var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight),
244             leftOver = availHeight;
245         for (i = 0 ; i < csLen; i++) {
246             c = cs[i];
247             if(isStart && c.flex){
248                 ch = Math.floor(availHeight * (c.flex / totalFlex));
249                 leftOver -= ch;
250                 heights.push(ch);
251             }
252         }
253         if(this.pack == 'center'){
254             t += extraHeight ? extraHeight / 2 : 0;
255         }else if(this.pack == 'end'){
256             t += extraHeight;
257         }
258         idx = 0;
259         // Apply heights
260         for (i = 0 ; i < csLen; i++) {
261             c = cs[i];
262             cm = c.margins;
263             t += cm.top;
264             aw = availableWidth;
265             cl = l + cm.left // default left pos
266
267 //          Adjust left pos for centering
268             if(this.align == 'center'){
269                 if((diff = availableWidth - (c.getWidth() + cm.left + cm.right)) > 0){
270                     cl += (diff/2);
271                     aw -= diff;
272                 }
273             }
274
275             c.setPosition(cl, t);
276             if(isStart && c.flex){
277                 ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0));
278                 c.setSize(aw, ch);
279             }else{
280                 ch = c.getHeight();
281             }
282             t += ch + cm.bottom;
283         }
284     }
285 });
286
287 Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
288
289 <div id="cls-Ext.layout.HBoxLayout"></div>/**
290  * @class Ext.layout.HBoxLayout
291  * @extends Ext.layout.BoxLayout
292  * <p>A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal
293  * space between child items containing a numeric <code>flex</code> configuration.</p>
294  * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option.
295  */
296 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
297     <div id="cfg-Ext.layout.HBoxLayout-align"></div>/**
298      * @cfg {String} align
299      * Controls how the child items of the container are aligned. Acceptable configuration values for this
300      * property are:
301      * <div class="mdetail-params"><ul>
302      * <li><b><tt>top</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned vertically
303      * at the <b>top</b> of the container</div></li>
304      * <li><b><tt>middle</tt></b> : <div class="sub-desc">child items are aligned vertically in the
305      * <b>middle</b> of the container</div></li>
306      * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched vertically to fill
307      * the height of the container</div></li>
308      * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched vertically to
309      * the height of the largest item.</div></li>
310      */
311     align : 'top', // top, middle, stretch, strechmax
312     <div id="cfg-Ext.layout.HBoxLayout-pack"></div>/**
313      * @cfg {String} pack
314      * Controls how the child items of the container are packed together. Acceptable configuration values
315      * for this property are:
316      * <div class="mdetail-params"><ul>
317      * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
318      * <b>left</b> side of container</div></li>
319      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
320      * <b>mid-width</b> of container</div></li>
321      * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
322      * side of container</div></li>
323      * </ul></div>
324      */
325     <div id="cfg-Ext.layout.HBoxLayout-flex"></div>/**
326      * @cfg {Number} flex
327      * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
328      * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>horizontally</b>
329      * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
330      * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
331      * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
332      */
333
334     // private
335     onLayout : function(ct, target){
336         Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
337
338         var cs = this.getItems(ct), cm, cw, margin, ch, diff,
339             size = target.getViewSize(true),
340             w = size.width - this.scrollOffset,
341             h = size.height,
342             l = this.padding.left, t = this.padding.top,
343             isStart = this.pack == 'start',
344             isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
345             stretchHeight = h - (this.padding.top + this.padding.bottom),
346             extraWidth = 0,
347             maxHeight = 0,
348             totalFlex = 0,
349             flexWidth = 0,
350             usedWidth = 0;
351
352         Ext.each(cs, function(c){
353             cm = c.margins;
354             totalFlex += c.flex || 0;
355             cw = c.getWidth();
356             margin = cm.left + cm.right;
357             extraWidth += cw + margin;
358             flexWidth += margin + (c.flex ? 0 : cw);
359             maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
360         });
361         extraWidth = w - extraWidth - this.padding.left - this.padding.right;
362
363         var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
364         switch(this.align){
365             case 'stretch':
366                 this.innerCt.setSize(w, h);
367                 break;
368             case 'stretchmax':
369             case 'top':
370                 this.innerCt.setSize(w, innerCtHeight);
371                 break;
372             case 'middle':
373                 this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
374                 break;
375         }
376
377
378         var availWidth = Math.max(0, w - this.padding.left - this.padding.right - flexWidth),
379             leftOver = availWidth,
380             widths = [],
381             restore = [],
382             idx = 0,
383             availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom);
384
385
386         Ext.each(cs, function(c){
387             if(isStart && c.flex){
388                 cw = Math.floor(availWidth * (c.flex / totalFlex));
389                 leftOver -= cw;
390                 widths.push(cw);
391             }
392         });
393
394         if(this.pack == 'center'){
395             l += extraWidth ? extraWidth / 2 : 0;
396         }else if(this.pack == 'end'){
397             l += extraWidth;
398         }
399         Ext.each(cs, function(c){
400             cm = c.margins;
401             l += cm.left;
402             c.setPosition(l, t + cm.top);
403             if(isStart && c.flex){
404                 cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0));
405                 if(isRestore){
406                     restore.push(c.getHeight());
407                 }
408                 c.setSize(cw, availableHeight);
409             }else{
410                 cw = c.getWidth();
411             }
412             l += cw + cm.right;
413         });
414
415         idx = 0;
416         Ext.each(cs, function(c){
417             cm = c.margins;
418             ch = c.getHeight();
419             if(isStart && c.flex){
420                 ch = restore[idx++];
421             }
422             if(this.align == 'stretch'){
423                 c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain(
424                     c.minHeight || 0, c.maxHeight || 1000000));
425             }else if(this.align == 'stretchmax'){
426                 c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
427                     c.minHeight || 0, c.maxHeight || 1000000));
428             }else{
429                 if(this.align == 'middle'){
430                     diff = availableHeight - (ch + cm.top + cm.bottom);
431                     ch = t + cm.top + (diff/2);
432                     if(diff > 0){
433                         c.setPosition(c.x, ch);
434                     }
435                 }
436                 if(isStart && c.flex){
437                     c.setHeight(ch);
438                 }
439             }
440         }, this);
441     }
442 });
443
444 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
445 </pre>    \r
446 </body>\r
447 </html>