<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-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.
+ *
+ * One way to create a draw component is:
+ *
+ * @example
+ * 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 {String[]} 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;
- }
- else {
- owner.frameSize = me.frameSize = {
- top: 0,
- left: 0,
- bottom: 0,
- right: 0
- };
- }
- }
- me.callParent(arguments);
- },
+<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,
- beforeLayout : function(width, height, isSetSize, callingContainer) {
+<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 {Object[]} 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:
+ *
+ * - `id` - string - The unique name of the gradient.
+ * - `angle` - number, optional - The angle of the gradient in degrees.
+ * - `stops` - object - An object with numbers as keys (from 0 to 100) and style objects as values
+ *
+ * ## Example
+ *
+ * gradients: [{
+ * id: 'gradientId',
+ * angle: 45,
+ * stops: {
+ * 0: {
+ * color: '#555'
+ * },
+ * 100: {
+ * color: '#ddd'
+ * }
+ * }
+ * }, {
+ * id: 'gradientId2',
+ * angle: 0,
+ * stops: {
+ * 0: {
+ * color: '#590'
+ * },
+ * 20: {
+ * color: '#599'
+ * },
+ * 100: {
+ * color: '#ddd'
+ * }
+ * }
+ * }]
+ *
+ * Then the sprites can use `gradientId` and `gradientId2` by setting the fill attributes to those ids, for example:
+ *
+ * sprite.setAttributes({
+ * fill: 'url(#gradientId)'
+ * }, true);
+ */
+ initComponent: function() {
this.callParent(arguments);
- var me = this,
- owner = me.owner,
- ownerCt = owner.ownerCt,
- layout = owner.layout,
- isVisible = owner.isVisible(true),
- ownerElChild = owner.el.child,
- layoutCollection;
-
- // Cache the size we began with so we can see if there has been any effect.
- me.previousComponentSize = me.lastComponentSize;
+ this.addEvents(
+ 'mousedown',
+ 'mouseup',
+ 'mousemove',
+ 'mouseenter',
+ 'mouseleave',
+ 'click'
+ );
+ },
- //Do not allow autoing of any dimensions which are fixed, unless we are being told to do so by the ownerCt's layout.
- if (!isSetSize && ((!Ext.isNumber(width) && owner.isFixedWidth()) || (!Ext.isNumber(height) && owner.isFixedHeight())) && callingContainer !== ownerCt) {
- me.doContainerLayout();
- return false;
- }
+<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);
- // 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);
+ if (me.createSurface() !== false) {
+ items = me.surface.items;
+
+ 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();
+ }
}
- owner.needsLayout = {
- width: width,
- height: height,
- isSetSize: false
- };
- }
-
- if (isVisible && this.needsLayout(width, height)) {
- return owner.beforeComponentLayout(width, height, isSetSize, callingContainer);
- }
- else {
- return false;
}
},
-<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) {
+ //@private
+ autoSizeSurface: function() {
var me = this,
- 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 {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);
+ 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:
+ *
+ * drawComponent.surface.add(sprite);
*/
- 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
- );
+ createSurface: function() {
+ var surface = Ext.draw.Surface.create(Ext.apply({}, {
+ width: this.width,
+ height: this.height,
+ renderTo: this.el
+ }, this.initialConfig));
+ if (!surface) {
+ // In case we cannot create a surface, return false so we can stop
+ return false;
}
+ this.surface = surface;
- 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')
- }
+ 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,
- curSize = this.lastComponentSize,
- prevSize = this.previousComponentSize,
- widthChange = (prevSize && curSize && curSize.width) ? curSize.width !== prevSize.width : true,
- heightChange = (prevSize && curSize && 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();
- }
- }
- }
+ 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.isAutoDock) {
- 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>