X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..HEAD:/docs/source/Component5.html diff --git a/docs/source/Component5.html b/docs/source/Component5.html index 74549452..25c9fa7b 100644 --- a/docs/source/Component5.html +++ b/docs/source/Component5.html @@ -3,8 +3,8 @@
/** - * @class Ext.draw.Component - * @extends Ext.Component +/** + * @class Ext.layout.component.Component + * @extends Ext.layout.Layout * - * The Draw Component is a surface in which sprites can be rendered. The Draw Component - * manages and holds a `Surface` instance: an interface that has - * an SVG or VML implementation depending on the browser capabilities and where - * Sprites can be appended. - * {@img Ext.draw.Component/Ext.draw.Component.png Ext.draw.Component component} - * One way to create a draw component is: - * - * var drawComponent = Ext.create('Ext.draw.Component', { - * viewBox: false, - * items: [{ - * type: 'circle', - * fill: '#79BB3F', - * radius: 100, - * x: 100, - * y: 100 - * }] - * }); - * - * Ext.create('Ext.Window', { - * width: 215, - * height: 235, - * layout: 'fit', - * items: [drawComponent] - * }).show(); - * - * In this case we created a draw component and added a sprite to it. - * The *type* of the sprite is *circle* so if you run this code you'll see a yellow-ish - * circle in a Window. When setting `viewBox` to `false` we are responsible for setting the object's position and - * dimensions accordingly. - * - * You can also add sprites by using the surface's add method: - * - * drawComponent.surface.add({ - * type: 'circle', - * fill: '#79BB3F', - * radius: 100, - * x: 100, - * y: 100 - * }); - * - * For more information on Sprites, the core elements added to a draw component's surface, - * refer to the Ext.draw.Sprite documentation. + * This class is intended to be extended or created via the {@link Ext.Component#componentLayout layout} + * configuration property. See {@link Ext.Component#componentLayout} for additional details. + * + * @private */ -Ext.define('Ext.draw.Component', { +Ext.define('Ext.layout.component.Component', { /* Begin Definitions */ - alias: 'widget.draw', - - extend: 'Ext.Component', - - requires: [ - 'Ext.draw.Surface', - 'Ext.layout.component.Draw' - ], + extend: 'Ext.layout.Layout', /* End Definitions */ - /** - * @cfg {Array} enginePriority - * Defines the priority order for which Surface implementation to use. The first - * one supported by the current environment will be used. - */ - enginePriority: ['Svg', 'Vml'], - - baseCls: Ext.baseCSSPrefix + 'surface', + type: 'component', - componentLayout: 'draw', + monitorChildren: true, - /** - * @cfg {Boolean} viewBox - * Turn on view box support which will scale and position items in the draw component to fit to the component while - * maintaining aspect ratio. Note that this scaling can override other sizing settings on yor items. Defaults to true. - */ - viewBox: true, + initLayout : function() { + var me = this, + owner = me.owner, + ownerEl = owner.el; - /** - * @cfg {Boolean} autoSize - * Turn on autoSize support which will set the bounding div's size to the natural size of the contents. Defaults to false. - */ - autoSize: false, - - /** - * @cfg {Array} gradients (optional) Define a set of gradients that can be used as `fill` property in sprites. - * The gradients array is an array of objects with the following properties: - * - * <ul> - * <li><strong>id</strong> - string - The unique name of the gradient.</li> - * <li><strong>angle</strong> - number, optional - The angle of the gradient in degrees.</li> - * <li><strong>stops</strong> - object - An object with numbers as keys (from 0 to 100) and style objects - * as values</li> - * </ul> - * - - For example: - - <pre><code> - gradients: [{ - id: 'gradientId', - angle: 45, - stops: { - 0: { - color: '#555' - }, - 100: { - color: '#ddd' - } + if (!me.initialized) { + if (owner.frameSize) { + me.frameSize = owner.frameSize; } - }, { - id: 'gradientId2', - angle: 0, - stops: { - 0: { - color: '#590' - }, - 20: { - color: '#599' - }, - 100: { - color: '#ddd' - } + else { + owner.frameSize = me.frameSize = { + top: 0, + left: 0, + bottom: 0, + right: 0 + }; } - }] - </code></pre> - - Then the sprites can use `gradientId` and `gradientId2` by setting the fill attributes to those ids, for example: - - <pre><code> - sprite.setAttributes({ - fill: 'url(#gradientId)' - }, true); - </code></pre> - - */ + } + me.callParent(arguments); + }, - initComponent: function() { + beforeLayout : function(width, height, isSetSize, callingContainer) { this.callParent(arguments); - this.addEvents( - 'mousedown', - 'mouseup', - 'mousemove', - 'mouseenter', - 'mouseleave', - 'click' - ); - }, - - /** - * @private - * - * Create the Surface on initial render - */ - onRender: function() { var me = this, - viewBox = me.viewBox, - autoSize = me.autoSize, - bbox, items, width, height, x, y; - me.callParent(arguments); + owner = me.owner, + ownerCt = owner.ownerCt, + layout = owner.layout, + isVisible = owner.isVisible(true), + ownerElChild = owner.el.child, + layoutCollection; - me.createSurface(); + // Cache the size we began with so we can see if there has been any effect. + me.previousComponentSize = me.lastComponentSize; - items = me.surface.items; + // Do not allow autoing of any dimensions which are fixed + if (!isSetSize + && ((!Ext.isNumber(width) && owner.isFixedWidth()) || + (!Ext.isNumber(height) && owner.isFixedHeight())) + // unless we are being told to do so by the ownerCt's layout + && callingContainer && callingContainer !== ownerCt) { + + me.doContainerLayout(); + return false; + } - if (viewBox || autoSize) { - bbox = items.getBBox(); - width = bbox.width; - height = bbox.height; - x = bbox.x; - y = bbox.y; - if (me.viewBox) { - me.surface.setViewBox(x, y, width, height); - } - else { - // AutoSized - me.autoSizeSurface(); + // If an ownerCt is hidden, add my reference onto the layoutOnShow stack. Set the needsLayout flag. + // If the owner itself is a directly hidden floater, set the needsLayout object on that for when it is shown. + if (!isVisible && (owner.hiddenAncestor || owner.floating)) { + if (owner.hiddenAncestor) { + layoutCollection = owner.hiddenAncestor.layoutOnShow; + layoutCollection.remove(owner); + layoutCollection.add(owner); } + owner.needsLayout = { + width: width, + height: height, + isSetSize: false + }; + } + + if (isVisible && this.needsLayout(width, height)) { + return owner.beforeComponentLayout(width, height, isSetSize, callingContainer); + } + else { + return false; } }, - //@private - autoSizeSurface: function() { + /** + * Check if the new size is different from the current size and only + * trigger a layout if it is necessary. + * @param {Number} width The new width to set. + * @param {Number} height The new height to set. + */ + needsLayout : function(width, height) { var me = this, - items = me.surface.items, - bbox = items.getBBox(), - width = bbox.width, - height = bbox.height; - items.setAttributes({ - translate: { - x: -bbox.x, - //Opera has a slight offset in the y axis. - y: -bbox.y + (+Ext.isOpera) - } - }, true); - if (me.rendered) { - me.setSize(width, height); - me.surface.setSize(width, height); + widthBeingChanged, + heightBeingChanged; + me.lastComponentSize = me.lastComponentSize || { + width: -Infinity, + height: -Infinity + }; + + // If autoWidthing, or an explicitly different width is passed, then the width is being changed. + widthBeingChanged = !Ext.isDefined(width) || me.lastComponentSize.width !== width; + + // If autoHeighting, or an explicitly different height is passed, then the height is being changed. + heightBeingChanged = !Ext.isDefined(height) || me.lastComponentSize.height !== height; + + + // isSizing flag added to prevent redundant layouts when going up the layout chain + return !me.isSizing && (me.childrenChanged || widthBeingChanged || heightBeingChanged); + }, + + /** + * Set the size of any element supporting undefined, null, and values. + * @param {Number} width The new width to set. + * @param {Number} height The new height to set. + */ + setElementSize: function(el, width, height) { + if (width !== undefined && height !== undefined) { + el.setSize(width, height); } - else { - me.surface.setSize(width, height); + else if (height !== undefined) { + el.setHeight(height); + } + else if (width !== undefined) { + el.setWidth(width); } - me.el.setSize(width, height); }, - /** - * Create the Surface instance. Resolves the correct Surface implementation to - * instantiate based on the 'enginePriority' config. Once the Surface instance is - * created you can use the handle to that instance to add sprites. For example: - * - <pre><code> - drawComponent.surface.add(sprite); - </code></pre> + /** + * Returns the owner component's resize element. + * @return {Ext.Element} + */ + getTarget : function() { + return this.owner.el; + }, + + /** + * <p>Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.</p> + * May be overridden in Component layout managers which implement an inner element. + * @return {Ext.Element} */ - createSurface: function() { - var surface = Ext.draw.Surface.create(Ext.apply({}, { - width: this.width, - height: this.height, - renderTo: this.el - }, this.initialConfig)); - this.surface = surface; - - function refire(eventName) { - return function(e) { - this.fireEvent(eventName, e); + getRenderTarget : function() { + return this.owner.el; + }, + + /** + * Set the size of the target element. + * @param {Number} width The new width to set. + * @param {Number} height The new height to set. + */ + setTargetSize : function(width, height) { + var me = this; + me.setElementSize(me.owner.el, width, height); + + if (me.owner.frameBody) { + var targetInfo = me.getTargetInfo(), + padding = targetInfo.padding, + border = targetInfo.border, + frameSize = me.frameSize; + + me.setElementSize(me.owner.frameBody, + Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width, + Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height + ); + } + + me.autoSized = { + width: !Ext.isNumber(width), + height: !Ext.isNumber(height) + }; + + me.lastComponentSize = { + width: width, + height: height + }; + }, + + getTargetInfo : function() { + if (!this.targetInfo) { + var target = this.getTarget(), + body = this.owner.getTargetEl(); + + this.targetInfo = { + padding: { + top: target.getPadding('t'), + right: target.getPadding('r'), + bottom: target.getPadding('b'), + left: target.getPadding('l') + }, + border: { + top: target.getBorderWidth('t'), + right: target.getBorderWidth('r'), + bottom: target.getBorderWidth('b'), + left: target.getBorderWidth('l') + }, + bodyMargin: { + top: body.getMargin('t'), + right: body.getMargin('r'), + bottom: body.getMargin('b'), + left: body.getMargin('l') + } }; } + return this.targetInfo; + }, - surface.on({ - scope: this, - mouseup: refire('mouseup'), - mousedown: refire('mousedown'), - mousemove: refire('mousemove'), - mouseenter: refire('mouseenter'), - mouseleave: refire('mouseleave'), - click: refire('click') - }); + // Start laying out UP the ownerCt's layout when flagged to do so. + doOwnerCtLayouts: function() { + var owner = this.owner, + ownerCt = owner.ownerCt, + ownerCtComponentLayout, ownerCtContainerLayout, + curSize = this.lastComponentSize, + prevSize = this.previousComponentSize, + widthChange = (prevSize && curSize && Ext.isNumber(curSize.width )) ? curSize.width !== prevSize.width : true, + heightChange = (prevSize && curSize && Ext.isNumber(curSize.height)) ? curSize.height !== prevSize.height : true; + + // If size has not changed, do not inform upstream layouts + if (!ownerCt || (!widthChange && !heightChange)) { + return; + } + + ownerCtComponentLayout = ownerCt.componentLayout; + ownerCtContainerLayout = ownerCt.layout; + + if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { + if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) { + + // If the owning Container may be adjusted in any of the the dimension which have changed, perform its Component layout + if (((widthChange && !ownerCt.isFixedWidth()) || (heightChange && !ownerCt.isFixedHeight()))) { + // Set the isSizing flag so that the upstream Container layout (called after a Component layout) can omit this component from sizing operations + this.isSizing = true; + ownerCt.doComponentLayout(); + this.isSizing = false; + } + // Execute upstream Container layout + else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) { + ownerCtContainerLayout.layout(); + } + } + } }, + doContainerLayout: function() { + var me = this, + owner = me.owner, + ownerCt = owner.ownerCt, + layout = owner.layout, + ownerCtComponentLayout; - /** - * @private - * - * Clean up the Surface instance on component destruction - */ - onDestroy: function() { - var surface = this.surface; - if (surface) { - surface.destroy(); + // Run the container layout if it exists (layout for child items) + // **Unless automatic laying out is suspended, or the layout is currently running** + if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy && !layout.isAutoDock) { + layout.layout(); } - this.callParent(arguments); - } + // Tell the ownerCt that it's child has changed and can be re-layed by ignoring the lastComponentSize cache. + if (ownerCt && ownerCt.componentLayout) { + ownerCtComponentLayout = ownerCt.componentLayout; + if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { + ownerCtComponentLayout.childrenChanged = true; + } + } + }, + + afterLayout : function(width, height, isSetSize, layoutOwner) { + this.doContainerLayout(); + this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner); + } });