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.layout.component.Component
17 * @extends Ext.layout.Layout
19 * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Component#componentLayout layout}</b></tt>
20 * configuration property. See <tt><b>{@link Ext.Component#componentLayout}</b></tt> for additional details.</p>
23 Ext.define('Ext.layout.component.Component', {
25 /* Begin Definitions */
27 extend: 'Ext.layout.Layout',
33 monitorChildren: true,
35 initLayout : function() {
40 if (!me.initialized) {
41 if (owner.frameSize) {
42 me.frameSize = owner.frameSize;
45 owner.frameSize = me.frameSize = {
53 me.callParent(arguments);
56 beforeLayout : function(width, height, isSetSize, callingContainer) {
57 this.callParent(arguments);
61 ownerCt = owner.ownerCt,
62 layout = owner.layout,
63 isVisible = owner.isVisible(true),
64 ownerElChild = owner.el.child,
67 // Cache the size we began with so we can see if there has been any effect.
68 me.previousComponentSize = me.lastComponentSize;
70 //Do not allow autoing of any dimensions which are fixed, unless we are being told to do so by the ownerCt's layout.
71 if (!isSetSize && ((!Ext.isNumber(width) && owner.isFixedWidth()) || (!Ext.isNumber(height) && owner.isFixedHeight())) && callingContainer !== ownerCt) {
72 me.doContainerLayout();
76 // If an ownerCt is hidden, add my reference onto the layoutOnShow stack. Set the needsLayout flag.
77 // If the owner itself is a directly hidden floater, set the needsLayout object on that for when it is shown.
78 if (!isVisible && (owner.hiddenAncestor || owner.floating)) {
79 if (owner.hiddenAncestor) {
80 layoutCollection = owner.hiddenAncestor.layoutOnShow;
81 layoutCollection.remove(owner);
82 layoutCollection.add(owner);
91 if (isVisible && this.needsLayout(width, height)) {
92 return owner.beforeComponentLayout(width, height, isSetSize, callingContainer);
100 * Check if the new size is different from the current size and only
101 * trigger a layout if it is necessary.
102 * @param {Mixed} width The new width to set.
103 * @param {Mixed} height The new height to set.
105 needsLayout : function(width, height) {
109 me.lastComponentSize = me.lastComponentSize || {
114 // If autoWidthing, or an explicitly different width is passed, then the width is being changed.
115 widthBeingChanged = !Ext.isDefined(width) || me.lastComponentSize.width !== width;
117 // If autoHeighting, or an explicitly different height is passed, then the height is being changed.
118 heightBeingChanged = !Ext.isDefined(height) || me.lastComponentSize.height !== height;
121 // isSizing flag added to prevent redundant layouts when going up the layout chain
122 return !me.isSizing && (me.childrenChanged || widthBeingChanged || heightBeingChanged);
126 * Set the size of any element supporting undefined, null, and values.
127 * @param {Mixed} width The new width to set.
128 * @param {Mixed} height The new height to set.
130 setElementSize: function(el, width, height) {
131 if (width !== undefined && height !== undefined) {
132 el.setSize(width, height);
134 else if (height !== undefined) {
135 el.setHeight(height);
137 else if (width !== undefined) {
143 * Returns the owner component's resize element.
144 * @return {Ext.core.Element}
146 getTarget : function() {
147 return this.owner.el;
151 * <p>Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.</p>
152 * May be overridden in Component layout managers which implement an inner element.
153 * @return {Ext.core.Element}
155 getRenderTarget : function() {
156 return this.owner.el;
160 * Set the size of the target element.
161 * @param {Mixed} width The new width to set.
162 * @param {Mixed} height The new height to set.
164 setTargetSize : function(width, height) {
166 me.setElementSize(me.owner.el, width, height);
168 if (me.owner.frameBody) {
169 var targetInfo = me.getTargetInfo(),
170 padding = targetInfo.padding,
171 border = targetInfo.border,
172 frameSize = me.frameSize;
174 me.setElementSize(me.owner.frameBody,
175 Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width,
176 Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height
181 width: !Ext.isNumber(width),
182 height: !Ext.isNumber(height)
185 me.lastComponentSize = {
191 getTargetInfo : function() {
192 if (!this.targetInfo) {
193 var target = this.getTarget(),
194 body = this.owner.getTargetEl();
198 top: target.getPadding('t'),
199 right: target.getPadding('r'),
200 bottom: target.getPadding('b'),
201 left: target.getPadding('l')
204 top: target.getBorderWidth('t'),
205 right: target.getBorderWidth('r'),
206 bottom: target.getBorderWidth('b'),
207 left: target.getBorderWidth('l')
210 top: body.getMargin('t'),
211 right: body.getMargin('r'),
212 bottom: body.getMargin('b'),
213 left: body.getMargin('l')
217 return this.targetInfo;
220 // Start laying out UP the ownerCt's layout when flagged to do so.
221 doOwnerCtLayouts: function() {
222 var owner = this.owner,
223 ownerCt = owner.ownerCt,
224 ownerCtComponentLayout, ownerCtContainerLayout,
225 curSize = this.lastComponentSize,
226 prevSize = this.previousComponentSize,
227 widthChange = (prevSize && curSize && curSize.width) ? curSize.width !== prevSize.width : true,
228 heightChange = (prevSize && curSize && curSize.height) ? curSize.height !== prevSize.height : true;
231 // If size has not changed, do not inform upstream layouts
232 if (!ownerCt || (!widthChange && !heightChange)) {
236 ownerCtComponentLayout = ownerCt.componentLayout;
237 ownerCtContainerLayout = ownerCt.layout;
239 if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
240 if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) {
242 // If the owning Container may be adjusted in any of the the dimension which have changed, perform its Component layout
243 if (((widthChange && !ownerCt.isFixedWidth()) || (heightChange && !ownerCt.isFixedHeight()))) {
244 // Set the isSizing flag so that the upstream Container layout (called after a Component layout) can omit this component from sizing operations
245 this.isSizing = true;
246 ownerCt.doComponentLayout();
247 this.isSizing = false;
249 // Execute upstream Container layout
250 else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) {
251 ownerCtContainerLayout.layout();
257 doContainerLayout: function() {
260 ownerCt = owner.ownerCt,
261 layout = owner.layout,
262 ownerCtComponentLayout;
264 // Run the container layout if it exists (layout for child items)
265 // **Unless automatic laying out is suspended, or the layout is currently running**
266 if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy && !layout.isAutoDock) {
270 // Tell the ownerCt that it's child has changed and can be re-layed by ignoring the lastComponentSize cache.
271 if (ownerCt && ownerCt.componentLayout) {
272 ownerCtComponentLayout = ownerCt.componentLayout;
273 if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
274 ownerCtComponentLayout.childrenChanged = true;
279 afterLayout : function(width, height, isSetSize, layoutOwner) {
280 this.doContainerLayout();
281 this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner);