</script>
</head>
<body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-layout-component-Component'>/**
-</span> * @class Ext.layout.component.Component
- * @extends Ext.layout.Layout
- * @private
- * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Component#componentLayout layout}</b></tt>
- * configuration property. See <tt><b>{@link Ext.Component#componentLayout}</b></tt> for additional details.</p>
+ <pre class="prettyprint lang-js"><span id='Ext-draw-Component'>/**
+</span> * @class Ext.draw.Component
+ * @extends Ext.Component
+ *
+ * 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.
*/
-
-Ext.define('Ext.layout.component.Component', {
+Ext.define('Ext.draw.Component', {
/* Begin Definitions */
- extend: 'Ext.layout.Layout',
+ alias: 'widget.draw',
+
+ extend: 'Ext.Component',
+
+ requires: [
+ 'Ext.draw.Surface',
+ 'Ext.layout.component.Draw'
+ ],
/* End Definitions */
- type: 'component',
+<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'],
- monitorChildren: true,
+ baseCls: Ext.baseCSSPrefix + 'surface',
- initLayout : function() {
- var me = this,
- owner = me.owner,
- ownerEl = owner.el;
+ componentLayout: 'draw',
- if (!me.initialized) {
- if (owner.frameSize) {
- me.frameSize = owner.frameSize;
+<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,
+
+<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'
+ }
}
- else {
- owner.frameSize = me.frameSize = {
- top: 0,
- left: 0,
- bottom: 0,
- right: 0
- };
+ }, {
+ id: 'gradientId2',
+ angle: 0,
+ stops: {
+ 0: {
+ color: '#590'
+ },
+ 20: {
+ color: '#599'
+ },
+ 100: {
+ color: '#ddd'
+ }
}
- }
- me.callParent(arguments);
- },
+ }]
+ </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>
+
+ */
- beforeLayout : function(width, height, isSetSize, layoutOwner) {
+ initComponent: function() {
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,
- owner = me.owner,
- ownerCt = owner.ownerCt,
- layout = owner.layout,
- isVisible = owner.isVisible(true),
- ownerElChild = owner.el.child,
- layoutCollection;
+ viewBox = me.viewBox,
+ autoSize = me.autoSize,
+ bbox, items, width, height, x, y;
+ me.callParent(arguments);
- /*
- * Do not layout calculatedSized components for fixedLayouts unless the ownerCt == layoutOwner
- * fixedLayouts means layouts which are never auto/auto in the sizing that comes from their ownerCt.
- * Currently 3 layouts MAY be auto/auto (Auto, Border, and Box)
- * The reason for not allowing component layouts is to stop component layouts from things such as Updater and
- * form Validation.
- */
- if (!isSetSize && !(Ext.isNumber(width) && Ext.isNumber(height)) && ownerCt && ownerCt.layout && ownerCt.layout.fixedLayout && ownerCt != layoutOwner) {
- me.doContainerLayout();
- return false;
- }
+ me.createSurface();
- // 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
- };
- }
+ items = me.surface.items;
- if (isVisible && this.needsLayout(width, height)) {
- me.rawWidth = width;
- me.rawHeight = height;
- return owner.beforeComponentLayout(width, height, isSetSize, layoutOwner);
- }
- else {
- 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();
+ }
}
},
-<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 {Mixed} width The new width to set.
- * @param {Mixed} height The new height to set.
- */
- needsLayout : function(width, height) {
- this.lastComponentSize = this.lastComponentSize || {
- width: -Infinity,
- height: -Infinity
- };
- return (this.childrenChanged || this.lastComponentSize.width !== width || this.lastComponentSize.height !== height);
- },
-
-<span id='Ext-layout-component-Component-method-setElementSize'> /**
-</span> * Set the size of any element supporting undefined, null, and values.
- * @param {Mixed} width The new width to set.
- * @param {Mixed} height The new height to set.
- */
- setElementSize: function(el, width, height) {
- if (width !== undefined && height !== undefined) {
- el.setSize(width, height);
- }
- else if (height !== undefined) {
- el.setHeight(height);
+ //@private
+ autoSizeSurface: function() {
+ 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);
}
- else if (width !== undefined) {
- el.setWidth(width);
+ else {
+ me.surface.setSize(width, height);
}
+ me.el.setSize(width, height);
},
-<span id='Ext-layout-component-Component-method-getTarget'> /**
-</span> * Returns the owner component's resize element.
- * @return {Ext.core.Element}
+<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>
*/
- 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.core.Element}
- */
- getRenderTarget : function() {
- return this.owner.el;
- },
-
-<span id='Ext-layout-component-Component-method-setTargetSize'> /**
-</span> * Set the size of the target element.
- * @param {Mixed} width The new width to set.
- * @param {Mixed} 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')
- }
+ 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);
};
}
- return this.targetInfo;
- },
-
- // Start laying out UP the ownerCt's layout when flagged to do so.
- doOwnerCtLayouts: function() {
- var owner = this.owner,
- ownerCt = owner.ownerCt,
- ownerCtComponentLayout, ownerCtContainerLayout;
-
- if (!ownerCt) {
- return;
- }
- ownerCtComponentLayout = ownerCt.componentLayout;
- ownerCtContainerLayout = ownerCt.layout;
-
- if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
- if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) {
- // AutoContainer Layout and Dock with auto in some dimension
- if (ownerCtContainerLayout.bindToOwnerCtComponent === true) {
- ownerCt.doComponentLayout();
- }
- // Box Layouts
- else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) {
- ownerCtContainerLayout.layout();
- }
- }
- }
+ surface.on({
+ scope: this,
+ mouseup: refire('mouseup'),
+ mousedown: refire('mousedown'),
+ mousemove: refire('mousemove'),
+ mouseenter: refire('mouseenter'),
+ mouseleave: refire('mouseleave'),
+ click: refire('click')
+ });
},
- doContainerLayout: function() {
- var me = this,
- owner = me.owner,
- ownerCt = owner.ownerCt,
- layout = owner.layout,
- ownerCtComponentLayout;
- // 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.layout();
- }
-
- // 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;
- }
+<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();
}
- },
-
- afterLayout : function(width, height, isSetSize, layoutOwner) {
- this.doContainerLayout();
- this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner);
+ this.callParent(arguments);
}
+
});
</pre>
</body>