<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
</script>
</head>
<body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-draw-Component'>/**
-</span> * @class Ext.draw.Component
- * @extends Ext.Component
+ <pre class="prettyprint lang-js"><span id='Ext-layout-component-Component'>/**
+</span> * @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 */
-<span id='Ext-draw-Component-cfg-enginePriority'> /**
-</span> * @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,
-<span id='Ext-draw-Component-cfg-viewBox'> /**
-</span> * @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;
-<span id='Ext-draw-Component-cfg-autoSize'> /**
-</span> * @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,
-
-<span id='Ext-draw-Component-cfg-gradients'> /**
-</span> * @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'
- );
- },
-
-<span id='Ext-draw-Component-method-onRender'> /**
-</span> * @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() {
+<span id='Ext-layout-component-Component-method-needsLayout'> /**
+</span> * 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);
+ },
+
+<span id='Ext-layout-component-Component-method-setElementSize'> /**
+</span> * 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);
},
-<span id='Ext-draw-Component-method-createSurface'> /**
-</span> * 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>
+<span id='Ext-layout-component-Component-method-getTarget'> /**
+</span> * Returns the owner component's resize element.
+ * @return {Ext.Element}
+ */
+ getTarget : function() {
+ return this.owner.el;
+ },
+
+<span id='Ext-layout-component-Component-method-getRenderTarget'> /**
+</span> * <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;
+ },
+
+<span id='Ext-layout-component-Component-method-setTargetSize'> /**
+</span> * 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;
-<span id='Ext-draw-Component-method-onDestroy'> /**
-</span> * @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);
+ }
});
</pre>
</body>