PageRenderTime 1447ms CodeModel.GetById 10ms app.highlight 47ms RepoModel.GetById 1ms app.codeStats 0ms

/ext-4.0.7/src/layout/component/Component.js

https://bitbucket.org/srogerf/javascript
JavaScript | 289 lines | 184 code | 39 blank | 66 comment | 60 complexity | 471fd859f781d4459c81a5eed6097a86 MD5 | raw file
  1/*
  2
  3This file is part of Ext JS 4
  4
  5Copyright (c) 2011 Sencha Inc
  6
  7Contact:  http://www.sencha.com/contact
  8
  9GNU General Public License Usage
 10This 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.
 11
 12If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
 13
 14*/
 15/**
 16 * @class Ext.layout.component.Component
 17 * @extends Ext.layout.Layout
 18 *
 19 * This class is intended to be extended or created via the {@link Ext.Component#componentLayout layout}
 20 * configuration property.  See {@link Ext.Component#componentLayout} for additional details.
 21 *
 22 * @private
 23 */
 24Ext.define('Ext.layout.component.Component', {
 25
 26    /* Begin Definitions */
 27
 28    extend: 'Ext.layout.Layout',
 29
 30    /* End Definitions */
 31
 32    type: 'component',
 33
 34    monitorChildren: true,
 35
 36    initLayout : function() {
 37        var me = this,
 38            owner = me.owner,
 39            ownerEl = owner.el;
 40
 41        if (!me.initialized) {
 42            if (owner.frameSize) {
 43                me.frameSize = owner.frameSize;
 44            }
 45            else {
 46                owner.frameSize = me.frameSize = {
 47                    top: 0,
 48                    left: 0,
 49                    bottom: 0,
 50                    right: 0
 51                };
 52            }
 53        }
 54        me.callParent(arguments);
 55    },
 56
 57    beforeLayout : function(width, height, isSetSize, callingContainer) {
 58        this.callParent(arguments);
 59
 60        var me = this,
 61            owner = me.owner,
 62            ownerCt = owner.ownerCt,
 63            layout = owner.layout,
 64            isVisible = owner.isVisible(true),
 65            ownerElChild = owner.el.child,
 66            layoutCollection;
 67
 68        // Cache the size we began with so we can see if there has been any effect.
 69        me.previousComponentSize = me.lastComponentSize;
 70
 71        // Do not allow autoing of any dimensions which are fixed
 72        if (!isSetSize
 73            && ((!Ext.isNumber(width) && owner.isFixedWidth()) ||
 74                (!Ext.isNumber(height) && owner.isFixedHeight()))
 75            // unless we are being told to do so by the ownerCt's layout
 76            && callingContainer && callingContainer !== ownerCt) {
 77            
 78            me.doContainerLayout();
 79            return false;
 80        }
 81
 82        // If an ownerCt is hidden, add my reference onto the layoutOnShow stack.  Set the needsLayout flag.
 83        // If the owner itself is a directly hidden floater, set the needsLayout object on that for when it is shown.
 84        if (!isVisible && (owner.hiddenAncestor || owner.floating)) {
 85            if (owner.hiddenAncestor) {
 86                layoutCollection = owner.hiddenAncestor.layoutOnShow;
 87                layoutCollection.remove(owner);
 88                layoutCollection.add(owner);
 89            }
 90            owner.needsLayout = {
 91                width: width,
 92                height: height,
 93                isSetSize: false
 94            };
 95        }
 96
 97        if (isVisible && this.needsLayout(width, height)) {
 98            return owner.beforeComponentLayout(width, height, isSetSize, callingContainer);
 99        }
100        else {
101            return false;
102        }
103    },
104
105    /**
106    * Check if the new size is different from the current size and only
107    * trigger a layout if it is necessary.
108    * @param {Number} width The new width to set.
109    * @param {Number} height The new height to set.
110    */
111    needsLayout : function(width, height) {
112        var me = this,
113            widthBeingChanged,
114            heightBeingChanged;
115            me.lastComponentSize = me.lastComponentSize || {
116                width: -Infinity,
117                height: -Infinity
118            };
119
120        // If autoWidthing, or an explicitly different width is passed, then the width is being changed.
121        widthBeingChanged  = !Ext.isDefined(width)  || me.lastComponentSize.width  !== width;
122
123        // If autoHeighting, or an explicitly different height is passed, then the height is being changed.
124        heightBeingChanged = !Ext.isDefined(height) || me.lastComponentSize.height !== height;
125
126
127        // isSizing flag added to prevent redundant layouts when going up the layout chain
128        return !me.isSizing && (me.childrenChanged || widthBeingChanged || heightBeingChanged);
129    },
130
131    /**
132    * Set the size of any element supporting undefined, null, and values.
133    * @param {Number} width The new width to set.
134    * @param {Number} height The new height to set.
135    */
136    setElementSize: function(el, width, height) {
137        if (width !== undefined && height !== undefined) {
138            el.setSize(width, height);
139        }
140        else if (height !== undefined) {
141            el.setHeight(height);
142        }
143        else if (width !== undefined) {
144            el.setWidth(width);
145        }
146    },
147
148    /**
149     * Returns the owner component's resize element.
150     * @return {Ext.Element}
151     */
152     getTarget : function() {
153         return this.owner.el;
154     },
155
156    /**
157     * <p>Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.</p>
158     * May be overridden in Component layout managers which implement an inner element.
159     * @return {Ext.Element}
160     */
161    getRenderTarget : function() {
162        return this.owner.el;
163    },
164
165    /**
166    * Set the size of the target element.
167    * @param {Number} width The new width to set.
168    * @param {Number} height The new height to set.
169    */
170    setTargetSize : function(width, height) {
171        var me = this;
172        me.setElementSize(me.owner.el, width, height);
173
174        if (me.owner.frameBody) {
175            var targetInfo = me.getTargetInfo(),
176                padding = targetInfo.padding,
177                border = targetInfo.border,
178                frameSize = me.frameSize;
179
180            me.setElementSize(me.owner.frameBody,
181                Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width,
182                Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height
183            );
184        }
185
186        me.autoSized = {
187            width: !Ext.isNumber(width),
188            height: !Ext.isNumber(height)
189        };
190
191        me.lastComponentSize = {
192            width: width,
193            height: height
194        };
195    },
196
197    getTargetInfo : function() {
198        if (!this.targetInfo) {
199            var target = this.getTarget(),
200                body = this.owner.getTargetEl();
201
202            this.targetInfo = {
203                padding: {
204                    top: target.getPadding('t'),
205                    right: target.getPadding('r'),
206                    bottom: target.getPadding('b'),
207                    left: target.getPadding('l')
208                },
209                border: {
210                    top: target.getBorderWidth('t'),
211                    right: target.getBorderWidth('r'),
212                    bottom: target.getBorderWidth('b'),
213                    left: target.getBorderWidth('l')
214                },
215                bodyMargin: {
216                    top: body.getMargin('t'),
217                    right: body.getMargin('r'),
218                    bottom: body.getMargin('b'),
219                    left: body.getMargin('l')
220                }
221            };
222        }
223        return this.targetInfo;
224    },
225
226    // Start laying out UP the ownerCt's layout when flagged to do so.
227    doOwnerCtLayouts: function() {
228        var owner = this.owner,
229            ownerCt = owner.ownerCt,
230            ownerCtComponentLayout, ownerCtContainerLayout,
231            curSize = this.lastComponentSize,
232            prevSize = this.previousComponentSize,
233            widthChange  = (prevSize && curSize && Ext.isNumber(curSize.width )) ? curSize.width  !== prevSize.width  : true,
234            heightChange = (prevSize && curSize && Ext.isNumber(curSize.height)) ? curSize.height !== prevSize.height : true;
235
236        // If size has not changed, do not inform upstream layouts
237        if (!ownerCt || (!widthChange && !heightChange)) {
238            return;
239        }
240
241        ownerCtComponentLayout = ownerCt.componentLayout;
242        ownerCtContainerLayout = ownerCt.layout;
243
244        if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
245            if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) {
246
247                // If the owning Container may be adjusted in any of the the dimension which have changed, perform its Component layout
248                if (((widthChange && !ownerCt.isFixedWidth()) || (heightChange && !ownerCt.isFixedHeight()))) {
249                    // Set the isSizing flag so that the upstream Container layout (called after a Component layout) can omit this component from sizing operations
250                    this.isSizing = true;
251                    ownerCt.doComponentLayout();
252                    this.isSizing = false;
253                }
254                // Execute upstream Container layout
255                else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) {
256                    ownerCtContainerLayout.layout();
257                }
258            }
259        }
260    },
261
262    doContainerLayout: function() {
263        var me = this,
264            owner = me.owner,
265            ownerCt = owner.ownerCt,
266            layout = owner.layout,
267            ownerCtComponentLayout;
268
269        // Run the container layout if it exists (layout for child items)
270        // **Unless automatic laying out is suspended, or the layout is currently running**
271        if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy && !layout.isAutoDock) {
272            layout.layout();
273        }
274
275        // Tell the ownerCt that it's child has changed and can be re-layed by ignoring the lastComponentSize cache.
276        if (ownerCt && ownerCt.componentLayout) {
277            ownerCtComponentLayout = ownerCt.componentLayout;
278            if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
279                ownerCtComponentLayout.childrenChanged = true;
280            }
281        }
282    },
283
284    afterLayout : function(width, height, isSetSize, layoutOwner) {
285        this.doContainerLayout();
286        this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner);
287    }
288});
289