Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / ColumnLayout.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-grid-ColumnLayout'>/**
19 </span> * @class Ext.grid.ColumnLayout
20  * @extends Ext.layout.container.HBox
21  * @private
22  *
23  * &lt;p&gt;This class is used only by the grid's HeaderContainer docked child.&lt;/p&gt;
24  *
25  * &lt;p&gt;It adds the ability to shrink the vertical size of the inner container element back if a grouped
26  * column header has all its child columns dragged out, and the whole HeaderContainer needs to shrink back down.&lt;/p&gt;
27  *
28  * &lt;p&gt;Also, after every layout, after all headers have attained their 'stretchmax' height, it goes through and calls
29  * &lt;code&gt;setPadding&lt;/code&gt; on the columns so that they lay out correctly.&lt;/p&gt;
30  */
31 Ext.define('Ext.grid.ColumnLayout', {
32     extend: 'Ext.layout.container.HBox',
33     alias: 'layout.gridcolumn',
34     type : 'column',
35
36     reserveOffset: false,
37
38     shrinkToFit: false,
39
40     // Height-stretched innerCt must be able to revert back to unstretched height
41     clearInnerCtOnLayout: true,
42
43     beforeLayout: function() {
44         var me = this,
45             i = 0,
46             items = me.getLayoutItems(),
47             len = items.length,
48             item, returnValue,
49             s;
50
51         // Scrollbar offset defined by width of any vertical scroller in the owning grid
52         if (!Ext.isDefined(me.availableSpaceOffset)) {
53             s = me.owner.up('tablepanel').verticalScroller;
54             me.availableSpaceOffset = s ? s.width-1 : 0;
55         }
56
57         returnValue = me.callParent(arguments);
58
59         // Size to a sane minimum height before possibly being stretched to accommodate grouped headers
60         me.innerCt.setHeight(23);
61
62         // Unstretch child items before the layout which stretches them.
63         for (; i &lt; len; i++) {
64             item = items[i];
65             item.el.setStyle({
66                 height: 'auto'
67             });
68             item.titleContainer.setStyle({
69                 height: 'auto',
70                 paddingTop: '0'
71             });
72             if (item.componentLayout &amp;&amp; item.componentLayout.lastComponentSize) {
73                 item.componentLayout.lastComponentSize.height = item.el.dom.offsetHeight;
74             }
75         }
76         return returnValue;
77     },
78
79     // Override to enforce the forceFit config.
80     calculateChildBoxes: function(visibleItems, targetSize) {
81         var me = this,
82             calculations = me.callParent(arguments),
83             boxes = calculations.boxes,
84             metaData = calculations.meta,
85             len = boxes.length, i = 0, box, item;
86
87         if (targetSize.width &amp;&amp; !me.isHeader) {
88             // If configured forceFit then all columns will be flexed
89             if (me.owner.forceFit) {
90
91                 for (; i &lt; len; i++) {
92                     box = boxes[i];
93                     item = box.component;
94
95                     // Set a sane minWidth for the Box layout to be able to squeeze flexed Headers down to.
96                     item.minWidth = Ext.grid.plugin.HeaderResizer.prototype.minColWidth;
97
98                     // For forceFit, just use allocated width as the flex value, and the proportions
99                     // will end up the same whatever HeaderContainer width they are being forced into.
100                     item.flex = box.width;
101                 }
102
103                 // Recalculate based upon all columns now being flexed instead of sized.
104                 calculations = me.callParent(arguments);
105             }
106             else if (metaData.tooNarrow) {
107                 targetSize.width = metaData.desiredSize;
108             }
109         }
110
111         return calculations;
112     },
113
114     afterLayout: function() {
115         var me = this,
116             owner = me.owner,
117             topGrid,
118             bothHeaderCts,
119             otherHeaderCt,
120             thisHeight,
121             otherHeight,
122             modifiedGrid,
123             i = 0,
124             items,
125             len,
126             headerHeight;
127
128         me.callParent(arguments);
129
130         // Set up padding in items
131         if (!me.owner.hideHeaders) {
132
133             // If this is one HeaderContainer of a pair in a side-by-side locking view, then find the height
134             // of the highest one, and sync the other one to that height.
135             if (owner.lockableInjected) {
136                 topGrid = owner.up('tablepanel').up('tablepanel');
137                 bothHeaderCts = topGrid.query('headercontainer:not([isHeader])');
138                 otherHeaderCt = (bothHeaderCts[0] === owner) ? bothHeaderCts[1] : bothHeaderCts[0];
139
140                 // Both sides must be rendered for this syncing operation to work.
141                 if (!otherHeaderCt.rendered) {
142                     return;
143                 }
144
145                 // Get the height of the highest of both HeaderContainers
146                 otherHeight = otherHeaderCt.layout.getRenderTarget().getViewSize().height;
147                 if (!otherHeight) {
148                     return;
149                 }
150                 thisHeight = this.getRenderTarget().getViewSize().height;
151                 if (!thisHeight) {
152                     return;
153                 }
154
155                 // Prevent recursion back into here when the &quot;other&quot; grid, after adjusting to the new hight of its headerCt, attempts to inform its ownerCt
156                 // Block the upward notification by flagging the top grid's component layout as busy.
157                 topGrid.componentLayout.layoutBusy = true;
158
159                 // Assume that the correct header height is the height of this HeaderContainer
160                 headerHeight = thisHeight;
161
162                 // Synch the height of the smaller HeaderContainer to the height of the highest one.
163                 if (thisHeight &gt; otherHeight) {
164                     otherHeaderCt.layout.align = 'stretch';
165                     otherHeaderCt.setCalculatedSize(otherHeaderCt.getWidth(), owner.getHeight(), otherHeaderCt.ownerCt);
166                     delete otherHeaderCt.layout.align;
167                     modifiedGrid = otherHeaderCt.up('tablepanel');
168                 } else if (otherHeight &gt; thisHeight) {
169                     headerHeight = otherHeight;
170                     this.align = 'stretch';
171                     owner.setCalculatedSize(owner.getWidth(), otherHeaderCt.getHeight(), owner.ownerCt);
172                     delete this.align;
173                     modifiedGrid = owner.up('tablepanel');
174                 }
175                 topGrid.componentLayout.layoutBusy = false;
176
177                 // Gather all Header items across both Grids.
178                 items = bothHeaderCts[0].layout.getLayoutItems().concat(bothHeaderCts[1].layout.getLayoutItems());
179             } else {
180                 headerHeight = this.getRenderTarget().getViewSize().height;
181                 items = me.getLayoutItems();
182             }
183
184             len = items.length;
185             for (; i &lt; len; i++) {
186                 items[i].setPadding(headerHeight);
187             }
188
189             // Size the View within the grid which has had its HeaderContainer entallened (That's a perfectly cromulent word BTW)
190             if (modifiedGrid) {
191                 setTimeout(function() {
192                     modifiedGrid.doLayout();
193                 }, 1);
194             }
195         }
196     },
197
198     // FIX: when flexing we actually don't have enough space as we would
199     // typically because of the scrollOffset on the GridView, must reserve this
200     updateInnerCtSize: function(tSize, calcs) {
201         var me = this,
202             extra;
203
204         // Columns must not account for scroll offset
205         if (!me.isHeader) {
206             me.tooNarrow = calcs.meta.tooNarrow;
207             extra = (me.reserveOffset ? me.availableSpaceOffset : 0);
208
209             if (calcs.meta.tooNarrow) {
210                 tSize.width = calcs.meta.desiredSize + extra;
211             } else {
212                 tSize.width += extra;
213             }
214         }
215
216         return me.callParent(arguments);
217     },
218
219     doOwnerCtLayouts: function() {
220         var ownerCt = this.owner.ownerCt;
221         if (!ownerCt.componentLayout.layoutBusy) {
222             ownerCt.doComponentLayout();
223         }
224     }
225 });</pre>
226 </body>
227 </html>