2 * @class Ext.layout.component.Component
3 * @extends Ext.layout.Layout
5 * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Component#componentLayout layout}</b></tt>
6 * configuration property. See <tt><b>{@link Ext.Component#componentLayout}</b></tt> for additional details.</p>
9 Ext.define('Ext.layout.component.Component', {
11 /* Begin Definitions */
13 extend: 'Ext.layout.Layout',
19 monitorChildren: true,
21 initLayout : function() {
26 if (!me.initialized) {
27 if (owner.frameSize) {
28 me.frameSize = owner.frameSize;
31 owner.frameSize = me.frameSize = {
39 me.callParent(arguments);
42 beforeLayout : function(width, height, isSetSize, layoutOwner) {
43 this.callParent(arguments);
47 ownerCt = owner.ownerCt,
48 layout = owner.layout,
49 isVisible = owner.isVisible(true),
50 ownerElChild = owner.el.child,
54 * Do not layout calculatedSized components for fixedLayouts unless the ownerCt == layoutOwner
55 * fixedLayouts means layouts which are never auto/auto in the sizing that comes from their ownerCt.
56 * Currently 3 layouts MAY be auto/auto (Auto, Border, and Box)
57 * The reason for not allowing component layouts is to stop component layouts from things such as Updater and
60 if (!isSetSize && !(Ext.isNumber(width) && Ext.isNumber(height)) && ownerCt && ownerCt.layout && ownerCt.layout.fixedLayout && ownerCt != layoutOwner) {
61 me.doContainerLayout();
65 // If an ownerCt is hidden, add my reference onto the layoutOnShow stack. Set the needsLayout flag.
66 // If the owner itself is a directly hidden floater, set the needsLayout object on that for when it is shown.
67 if (!isVisible && (owner.hiddenAncestor || owner.floating)) {
68 if (owner.hiddenAncestor) {
69 layoutCollection = owner.hiddenAncestor.layoutOnShow;
70 layoutCollection.remove(owner);
71 layoutCollection.add(owner);
80 if (isVisible && this.needsLayout(width, height)) {
82 me.rawHeight = height;
83 return owner.beforeComponentLayout(width, height, isSetSize, layoutOwner);
91 * Check if the new size is different from the current size and only
92 * trigger a layout if it is necessary.
93 * @param {Mixed} width The new width to set.
94 * @param {Mixed} height The new height to set.
96 needsLayout : function(width, height) {
97 this.lastComponentSize = this.lastComponentSize || {
101 return (this.childrenChanged || this.lastComponentSize.width !== width || this.lastComponentSize.height !== height);
105 * Set the size of any element supporting undefined, null, and values.
106 * @param {Mixed} width The new width to set.
107 * @param {Mixed} height The new height to set.
109 setElementSize: function(el, width, height) {
110 if (width !== undefined && height !== undefined) {
111 el.setSize(width, height);
113 else if (height !== undefined) {
114 el.setHeight(height);
116 else if (width !== undefined) {
122 * Returns the owner component's resize element.
123 * @return {Ext.core.Element}
125 getTarget : function() {
126 return this.owner.el;
130 * <p>Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.</p>
131 * May be overridden in Component layout managers which implement an inner element.
132 * @return {Ext.core.Element}
134 getRenderTarget : function() {
135 return this.owner.el;
139 * Set the size of the target element.
140 * @param {Mixed} width The new width to set.
141 * @param {Mixed} height The new height to set.
143 setTargetSize : function(width, height) {
145 me.setElementSize(me.owner.el, width, height);
147 if (me.owner.frameBody) {
148 var targetInfo = me.getTargetInfo(),
149 padding = targetInfo.padding,
150 border = targetInfo.border,
151 frameSize = me.frameSize;
153 me.setElementSize(me.owner.frameBody,
154 Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width,
155 Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height
160 width: !Ext.isNumber(width),
161 height: !Ext.isNumber(height)
164 me.lastComponentSize = {
170 getTargetInfo : function() {
171 if (!this.targetInfo) {
172 var target = this.getTarget(),
173 body = this.owner.getTargetEl();
177 top: target.getPadding('t'),
178 right: target.getPadding('r'),
179 bottom: target.getPadding('b'),
180 left: target.getPadding('l')
183 top: target.getBorderWidth('t'),
184 right: target.getBorderWidth('r'),
185 bottom: target.getBorderWidth('b'),
186 left: target.getBorderWidth('l')
189 top: body.getMargin('t'),
190 right: body.getMargin('r'),
191 bottom: body.getMargin('b'),
192 left: body.getMargin('l')
196 return this.targetInfo;
199 // Start laying out UP the ownerCt's layout when flagged to do so.
200 doOwnerCtLayouts: function() {
201 var owner = this.owner,
202 ownerCt = owner.ownerCt,
203 ownerCtComponentLayout, ownerCtContainerLayout;
209 ownerCtComponentLayout = ownerCt.componentLayout;
210 ownerCtContainerLayout = ownerCt.layout;
212 if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
213 if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) {
214 // AutoContainer Layout and Dock with auto in some dimension
215 if (ownerCtContainerLayout.bindToOwnerCtComponent === true) {
216 ownerCt.doComponentLayout();
219 else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) {
220 ownerCtContainerLayout.layout();
226 doContainerLayout: function() {
229 ownerCt = owner.ownerCt,
230 layout = owner.layout,
231 ownerCtComponentLayout;
233 // Run the container layout if it exists (layout for child items)
234 // **Unless automatic laying out is suspended, or the layout is currently running**
235 if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy) {
239 // Tell the ownerCt that it's child has changed and can be re-layed by ignoring the lastComponentSize cache.
240 if (ownerCt && ownerCt.componentLayout) {
241 ownerCtComponentLayout = ownerCt.componentLayout;
242 if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
243 ownerCtComponentLayout.childrenChanged = true;
248 afterLayout : function(width, height, isSetSize, layoutOwner) {
249 this.doContainerLayout();
250 this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner);