File: HBoxLayout.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 (301 lines) | stat: -rw-r--r-- 13,826 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
<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.HBoxLayout"></div>/**
 * @class Ext.layout.HBoxLayout
 * @extends Ext.layout.BoxLayout
 * <p>A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal
 * space between child items containing a numeric <code>flex</code> configuration.</p>
 * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option.
 */
Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
    <div id="cfg-Ext.layout.HBoxLayout-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>top</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned vertically
     * at the <b>top</b> of the container</div></li>
     * <li><b><tt>middle</tt></b> : <div class="sub-desc">child items are aligned vertically in the
     * <b>middle</b> of the container</div></li>
     * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched vertically to fill
     * the height of the container</div></li>
     * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched vertically to
     * the height of the largest item.</div></li>
     */
    align: 'top', // top, middle, stretch, strechmax

    type : 'hbox',

    <div id="cfg-Ext.layout.HBoxLayout-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>left</b> side of container</div></li>
     * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
     * <b>mid-width</b> of container</div></li>
     * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
     * side of container</div></li>
     * </ul></div>
     */
    <div id="cfg-Ext.layout.HBoxLayout-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>horizontally</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 HBox. 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,
            availHeight  = Math.max(0, height - paddingVert),

            isStart      = this.pack == 'start',
            isCenter     = this.pack == 'center',
            isEnd        = this.pack == 'end',

            nonFlexWidth = 0,
            maxHeight    = 0,
            totalFlex    = 0,
            desiredWidth = 0,
            minimumWidth = 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, flexedWidth, 
            horizMargins, vertMargins, stretchHeight;

        //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 width (numeric) requires no calcs
            if (typeof childWidth != 'number') {

                // flex and not 'auto' width
                if (child.flex && !childWidth) {
                    totalFlex += child.flex;

                // Not flexed or 'auto' width or undefined width
                } 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 (!childWidth && canLayout) {
                        child.doLayout();
                    }

                    childSize   = child.getSize();
                    childWidth  = childSize.width;
                    childHeight = childSize.height;
                }
            }

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

            nonFlexWidth += horizMargins + (childWidth || 0);
            desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
            minimumWidth += horizMargins + (child.minWidth || childWidth || 0);

            // Max height for align - force layout of non-laid out subcontainers without a numeric height
            if (typeof childHeight != 'number') {
                if (canLayout) {
                    child.doLayout();
                }
                childHeight = child.getHeight();
            }

            maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);

            //cache the size of each child component. Don't set height or width to 0, keep undefined instead
            boxes.push({
                component: child,
                height   : childHeight || undefined,
                width    : childWidth  || undefined
            });
        }
                
        var shortfall = desiredWidth - width,
            tooNarrow = minimumWidth > width;
            
        //the width available to the flexed items
        var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
        
        if (tooNarrow) {
            for (i = 0; i < visibleCount; i++) {
                boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
            }
        } 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 minWidths = [];
                
                <div id="prop-Ext.layout.HBoxLayout-for"></div>/**
                 * When we have a shortfall but are not tooNarrow, we need to shrink the width of each non-flexed item.
                 * Flexed items are immediately reduced to their minWidth and anything already at minWidth is ignored.
                 * The remaining items are collected into the minWidths array, which is later used to distribute the shortfall.
                 */
                for (var index = 0, length = visibleCount; index < length; index++) {
                    var item     = visibleItems[index],
                        minWidth = item.minWidth || 0;

                    //shrink each non-flex tab by an equal amount to make them all fit. Flexed items are all
                    //shrunk to their minWidth because they're flexible and should be the first to lose width
                    if (item.flex) {
                        boxes[index].width = minWidth;
                    } else {
                        minWidths.push({
                            minWidth : minWidth,
                            available: boxes[index].width - minWidth,
                            index    : index
                        });
                    }
                }
                
                //sort by descending amount of width remaining before minWidth is reached
                minWidths.sort(function(a, b) {
                    return a.available > b.available ? 1 : -1;
                });
                
                /*
                 * Distribute the shortfall (difference between total desired with of all items and actual width available)
                 * between the non-flexed items. We try to distribute the shortfall evenly, but apply it to items with the
                 * smallest difference between their width and minWidth first, so that if reducing the width by the average
                 * amount would make that item less than its minWidth, we carry the remainder over to the next item.
                 */
                for (var i = 0, length = minWidths.length; i < length; i++) {
                    var itemIndex = minWidths[i].index;
                    
                    if (itemIndex == undefined) {
                        continue;
                    }
                        
                    var item      = visibleItems[itemIndex],
                        box       = boxes[itemIndex],
                        oldWidth  = box.width,
                        minWidth  = item.minWidth,
                        newWidth  = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
                        reduction = oldWidth - newWidth;
                    
                    boxes[itemIndex].width = newWidth;
                    shortfall -= reduction;                    
                }
            } else {
                //temporary variables used in the flex width calculations below
                var remainingWidth = availableWidth,
                    remainingFlex  = totalFlex;

                //calculate the widths of each flexed item
                for (i = 0; i < visibleCount; i++) {
                    child = visibleItems[i];
                    calcs = boxes[i];

                    childMargins = child.margins;
                    vertMargins  = childMargins.top + childMargins.bottom;

                    if (isStart && child.flex && !child.width) {
                        flexedWidth     = Math.ceil((child.flex / remainingFlex) * remainingWidth);
                        remainingWidth -= flexedWidth;
                        remainingFlex  -= child.flex;

                        calcs.width = flexedWidth;
                        calcs.dirtySize = true;
                    }
                }
            }
        }
        
        if (isCenter) {
            leftOffset += availableWidth / 2;
        } else if (isEnd) {
            leftOffset += availableWidth;
        }
        
        //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;
            leftOffset  += childMargins.left;
            vertMargins  = childMargins.top + childMargins.bottom;
            
            calcs.left = leftOffset;
            calcs.top  = topOffset + childMargins.top;

            switch (this.align) {
                case 'stretch':
                    stretchHeight = availHeight - vertMargins;
                    calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
                    calcs.dirtySize = true;
                    break;
                case 'stretchmax':
                    stretchHeight = maxHeight - vertMargins;
                    calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
                    calcs.dirtySize = true;
                    break;
                case 'middle':
                    var diff = availHeight - calcs.height - vertMargins;
                    if (diff > 0) {
                        calcs.top = topOffset + vertMargins + (diff / 2);
                    }
            }
            
            leftOffset += calcs.width + childMargins.right;
        }

        return {
            boxes: boxes,
            meta : {
                maxHeight   : maxHeight,
                nonFlexWidth: nonFlexWidth,
                desiredWidth: desiredWidth,
                minimumWidth: minimumWidth,
                shortfall   : desiredWidth - width,
                tooNarrow   : tooNarrow
            }
        };
    }
});

Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;</pre>    
</body>
</html>