File: VBoxLayout.html

package info (click to toggle)
libjs-extjs 3.4.0%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, jessie, jessie-kfreebsd, stretch
  • size: 53,188 kB
  • ctags: 3,384
  • sloc: php: 819; xml: 537; python: 60; sql: 44; makefile: 35
file content (304 lines) | stat: -rw-r--r-- 13,723 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
  <title>The source code</title>
    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
</head>
<body  onload="prettyPrint();">
    <pre class="prettyprint lang-js">/*!
 * Ext JS Library 3.4.0
 * Copyright(c) 2006-2011 Sencha Inc.
 * licensing@sencha.com
 * http://www.sencha.com/license
 */
<div id="cls-Ext.layout.VBoxLayout"></div>/**
 * @class Ext.layout.VBoxLayout
 * @extends Ext.layout.BoxLayout
 * <p>A layout that arranges items vertically down a Container. This layout optionally divides available vertical
 * space between child items containing a numeric <code>flex</code> configuration.</p>
 * 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, {
    <div id="cfg-Ext.layout.VBoxLayout-align"></div>/**
     * @cfg {String} align
     * Controls how the child items of the container are aligned. Acceptable configuration values for this
     * property are:
     * <div class="mdetail-params"><ul>
     * <li><b><tt>left</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned horizontally
     * at the <b>left</b> side of the container</div></li>
     * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are aligned horizontally at the
     * <b>mid-width</b> of the container</div></li>
     * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched horizontally to fill
     * the width of the container</div></li>
     * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched horizontally to
     * the size of the largest item.</div></li>
     * </ul></div>
     */
    align : 'left', // left, center, stretch, strechmax
    type: 'vbox',

    <div id="cfg-Ext.layout.VBoxLayout-pack"></div>/**
     * @cfg {String} pack
     * Controls how the child items of the container are packed together. Acceptable configuration values
     * for this property are:
     * <div class="mdetail-params"><ul>
     * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
     * <b>top</b> side of container</div></li>
     * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
     * <b>mid-height</b> of container</div></li>
     * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>bottom</b>
     * side of container</div></li>
     * </ul></div>
     */

    <div id="cfg-Ext.layout.VBoxLayout-flex"></div>/**
     * @cfg {Number} flex
     * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
     * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>vertically</b>
     * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
     * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
     * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
     */

    /**
     * @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,
            desiredHeight= 0,
            minimumHeight= 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, vertMargins, stretchWidth, length;

        //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 && typeof child.doLayout == 'function';

            // Static height (numeric) requires no calcs
            if (typeof childHeight != 'number') {

                // 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;
            vertMargins  = childMargins.top + childMargins.bottom;

            nonFlexHeight += vertMargins + (childHeight || 0);
            desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
            minimumHeight += vertMargins + (child.minHeight || childHeight || 0);

            // Max width for align - force layout of non-layed out subcontainers without a numeric width
            if (typeof childWidth != 'number') {
                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
            });
        }
                
        var shortfall = desiredHeight - height,
            tooNarrow = minimumHeight > height;

        //the height available to the flexed items
        var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
        
        if (tooNarrow) {
            for (i = 0, length = visibleCount; i < length; i++) {
                boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
            }
        } else {
            //all flexed items should be sized to their minimum width, other items should be shrunk down until
            //the shortfall has been accounted for
            if (shortfall > 0) {
                var minHeights = [];

                <div id="prop-Ext.layout.VBoxLayout-for"></div>/**
                 * When we have a shortfall but are not tooNarrow, we need to shrink the height of each non-flexed item.
                 * Flexed items are immediately reduced to their minHeight and anything already at minHeight is ignored.
                 * The remaining items are collected into the minHeights array, which is later used to distribute the shortfall.
                 */
                for (var index = 0, length = visibleCount; index < length; index++) {
                    var item      = visibleItems[index],
                        minHeight = item.minHeight || 0;

                    //shrink each non-flex tab by an equal amount to make them all fit. Flexed items are all
                    //shrunk to their minHeight because they're flexible and should be the first to lose height
                    if (item.flex) {
                        boxes[index].height = minHeight;
                    } else {
                        minHeights.push({
                            minHeight: minHeight, 
                            available: boxes[index].height - minHeight,
                            index    : index
                        });
                    }
                }

                //sort by descending minHeight value
                minHeights.sort(function(a, b) {
                    return a.available > b.available ? 1 : -1;
                });

                /*
                 * Distribute the shortfall (difference between total desired with of all items and actual height available)
                 * between the non-flexed items. We try to distribute the shortfall evenly, but apply it to items with the
                 * smallest difference between their height and minHeight first, so that if reducing the height by the average
                 * amount would make that item less than its minHeight, we carry the remainder over to the next item.
                 */
                for (var i = 0, length = minHeights.length; i < length; i++) {
                    var itemIndex = minHeights[i].index;

                    if (itemIndex == undefined) {
                        continue;
                    }

                    var item      = visibleItems[itemIndex],
                        box       = boxes[itemIndex],
                        oldHeight  = box.height,
                        minHeight  = item.minHeight,
                        newHeight  = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
                        reduction = oldHeight - newHeight;

                    boxes[itemIndex].height = newHeight;
                    shortfall -= reduction;
                }
            } else {
                //temporary variables used in the flex height calculations below
                var remainingHeight = availableHeight,
                    remainingFlex   = totalFlex;
                
                //calculate the height of each flexed item
                for (i = 0; i < visibleCount; i++) {
                    child = visibleItems[i];
                    calcs = boxes[i];

                    childMargins = child.margins;
                    horizMargins = childMargins.left + childMargins.right;

                    if (isStart && child.flex && !child.height) {
                        flexedHeight     = Math.ceil((child.flex / remainingFlex) * remainingHeight);
                        remainingHeight -= flexedHeight;
                        remainingFlex   -= child.flex;

                        calcs.height = flexedHeight;
                        calcs.dirtySize = true;
                    }
                }
            }
        }

        if (isCenter) {
            topOffset += availableHeight / 2;
        } else if (isEnd) {
            topOffset += availableHeight;
        }

        //finally, calculate the left and top position of each item
        for (i = 0; i < visibleCount; i++) {
            child = visibleItems[i];
            calcs = boxes[i];

            childMargins = child.margins;
            topOffset   += childMargins.top;
            horizMargins = childMargins.left + childMargins.right;
            

            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,
                nonFlexHeight: nonFlexHeight,
                desiredHeight: desiredHeight,
                minimumHeight: minimumHeight,
                shortfall    : desiredHeight - height,
                tooNarrow    : tooNarrow
            }
        };
    }
});

Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
</pre>    
</body>
</html>