3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.grid.ColumnLayout
17 * @extends Ext.layout.container.HBox
20 * <p>This class is used only by the grid's HeaderContainer docked child.</p>
22 * <p>It adds the ability to shrink the vertical size of the inner container element back if a grouped
23 * column header has all its child columns dragged out, and the whole HeaderContainer needs to shrink back down.</p>
25 * <p>Also, after every layout, after all headers have attained their 'stretchmax' height, it goes through and calls
26 * <code>setPadding</code> on the columns so that they lay out correctly.</p>
28 Ext.define('Ext.grid.ColumnLayout', {
29 extend: 'Ext.layout.container.HBox',
30 alias: 'layout.gridcolumn',
37 // Height-stretched innerCt must be able to revert back to unstretched height
38 clearInnerCtOnLayout: true,
40 beforeLayout: function() {
43 items = me.getLayoutItems(),
48 // Scrollbar offset defined by width of any vertical scroller in the owning grid
49 if (!Ext.isDefined(me.availableSpaceOffset)) {
50 s = me.owner.up('tablepanel').verticalScroller;
51 me.availableSpaceOffset = s ? s.width-1 : 0;
54 returnValue = me.callParent(arguments);
56 // Size to a sane minimum height before possibly being stretched to accommodate grouped headers
57 me.innerCt.setHeight(23);
59 // Unstretch child items before the layout which stretches them.
60 for (; i < len; i++) {
65 item.titleContainer.setStyle({
69 if (item.componentLayout && item.componentLayout.lastComponentSize) {
70 item.componentLayout.lastComponentSize.height = item.el.dom.offsetHeight;
76 // Override to enforce the forceFit config.
77 calculateChildBoxes: function(visibleItems, targetSize) {
79 calculations = me.callParent(arguments),
80 boxes = calculations.boxes,
81 metaData = calculations.meta,
82 len = boxes.length, i = 0, box, item;
84 if (targetSize.width && !me.isHeader) {
85 // If configured forceFit then all columns will be flexed
86 if (me.owner.forceFit) {
88 for (; i < len; i++) {
92 // Set a sane minWidth for the Box layout to be able to squeeze flexed Headers down to.
93 item.minWidth = Ext.grid.plugin.HeaderResizer.prototype.minColWidth;
95 // For forceFit, just use allocated width as the flex value, and the proportions
96 // will end up the same whatever HeaderContainer width they are being forced into.
97 item.flex = box.width;
100 // Recalculate based upon all columns now being flexed instead of sized.
101 calculations = me.callParent(arguments);
103 else if (metaData.tooNarrow) {
104 targetSize.width = metaData.desiredSize;
111 afterLayout: function() {
125 me.callParent(arguments);
127 // Set up padding in items
128 if (!me.owner.hideHeaders) {
130 // If this is one HeaderContainer of a pair in a side-by-side locking view, then find the height
131 // of the highest one, and sync the other one to that height.
132 if (owner.lockableInjected) {
133 topGrid = owner.up('tablepanel').up('tablepanel');
134 bothHeaderCts = topGrid.query('headercontainer:not([isHeader])');
135 otherHeaderCt = (bothHeaderCts[0] === owner) ? bothHeaderCts[1] : bothHeaderCts[0];
137 // Both sides must be rendered for this syncing operation to work.
138 if (!otherHeaderCt.rendered) {
142 // Get the height of the highest of both HeaderContainers
143 otherHeight = otherHeaderCt.layout.getRenderTarget().getViewSize().height;
147 thisHeight = this.getRenderTarget().getViewSize().height;
152 // Prevent recursion back into here when the "other" grid, after adjusting to the new hight of its headerCt, attempts to inform its ownerCt
153 // Block the upward notification by flagging the top grid's component layout as busy.
154 topGrid.componentLayout.layoutBusy = true;
156 // Assume that the correct header height is the height of this HeaderContainer
157 headerHeight = thisHeight;
159 // Synch the height of the smaller HeaderContainer to the height of the highest one.
160 if (thisHeight > otherHeight) {
161 otherHeaderCt.layout.align = 'stretch';
162 otherHeaderCt.setCalculatedSize(otherHeaderCt.getWidth(), owner.getHeight(), otherHeaderCt.ownerCt);
163 delete otherHeaderCt.layout.align;
164 modifiedGrid = otherHeaderCt.up('tablepanel');
165 } else if (otherHeight > thisHeight) {
166 headerHeight = otherHeight;
167 this.align = 'stretch';
168 owner.setCalculatedSize(owner.getWidth(), otherHeaderCt.getHeight(), owner.ownerCt);
170 modifiedGrid = owner.up('tablepanel');
172 topGrid.componentLayout.layoutBusy = false;
174 // Gather all Header items across both Grids.
175 items = bothHeaderCts[0].layout.getLayoutItems().concat(bothHeaderCts[1].layout.getLayoutItems());
177 headerHeight = this.getRenderTarget().getViewSize().height;
178 items = me.getLayoutItems();
182 for (; i < len; i++) {
183 items[i].setPadding(headerHeight);
186 // Size the View within the grid which has had its HeaderContainer entallened (That's a perfectly cromulent word BTW)
188 setTimeout(function() {
189 modifiedGrid.doLayout();
195 // FIX: when flexing we actually don't have enough space as we would
196 // typically because of the scrollOffset on the GridView, must reserve this
197 updateInnerCtSize: function(tSize, calcs) {
201 // Columns must not account for scroll offset
203 me.tooNarrow = calcs.meta.tooNarrow;
204 extra = (me.reserveOffset ? me.availableSpaceOffset : 0);
206 if (calcs.meta.tooNarrow) {
207 tSize.width = calcs.meta.desiredSize + extra;
209 tSize.width += extra;
213 return me.callParent(arguments);
216 doOwnerCtLayouts: function() {
217 var ownerCt = this.owner.ownerCt;
218 if (!ownerCt.componentLayout.layoutBusy) {
219 ownerCt.doComponentLayout();