]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * @class Ext.draw.modifier.Highlight\r | |
3 | * @extends Ext.draw.modifier.Modifier\r | |
4 | *\r | |
5 | * Highlight is a modifier that will override sprite attributes\r | |
6 | * with {@link Ext.draw.modifier.Highlight#highlightStyle highlightStyle} attributes\r | |
7 | * when sprite's `highlighted` attribute is true.\r | |
8 | */\r | |
9 | Ext.define('Ext.draw.modifier.Highlight', {\r | |
10 | extend: 'Ext.draw.modifier.Modifier',\r | |
11 | alias: 'modifier.highlight',\r | |
12 | \r | |
13 | config: {\r | |
14 | \r | |
15 | /**\r | |
16 | * @cfg {Boolean} enabled 'true' if the highlight is applied.\r | |
17 | */\r | |
18 | enabled: false,\r | |
19 | \r | |
20 | /**\r | |
21 | * @cfg {Object} highlightStyle The style attributes of the highlight modifier.\r | |
22 | */\r | |
23 | highlightStyle: null\r | |
24 | },\r | |
25 | \r | |
26 | preFx: true,\r | |
27 | \r | |
28 | applyHighlightStyle: function (style, oldStyle) {\r | |
29 | oldStyle = oldStyle || {};\r | |
30 | if (this.getSprite()) {\r | |
31 | Ext.apply(oldStyle, this.getSprite().self.def.normalize(style));\r | |
32 | } else {\r | |
33 | Ext.apply(oldStyle, style);\r | |
34 | }\r | |
35 | return oldStyle;\r | |
36 | },\r | |
37 | \r | |
38 | /**\r | |
39 | * @inheritdoc\r | |
40 | */\r | |
41 | prepareAttributes: function (attr) {\r | |
42 | if (!attr.hasOwnProperty('highlightOriginal')) {\r | |
43 | attr.highlighted = false;\r | |
44 | attr.highlightOriginal = Ext.Object.chain(attr);\r | |
45 | attr.highlightOriginal.prototype = attr;\r | |
46 | // A list of attributes that should be removed from a sprite instance\r | |
47 | // when it is unhighlighted.\r | |
48 | attr.highlightOriginal.removeFromInstance = {};\r | |
49 | }\r | |
50 | if (this._previous) {\r | |
51 | this._previous.prepareAttributes(attr.highlightOriginal);\r | |
52 | }\r | |
53 | },\r | |
54 | \r | |
55 | updateSprite: function (sprite, oldSprite) {\r | |
56 | if (sprite) {\r | |
57 | if (this.getHighlightStyle()) {\r | |
58 | this._highlightStyle = sprite.self.def.normalize(this.getHighlightStyle());\r | |
59 | }\r | |
60 | this.setHighlightStyle(sprite.config.highlight);\r | |
61 | }\r | |
62 | \r | |
63 | // Add highlight related attributes to sprite's attribute definition.\r | |
64 | // TODO: Unfortunately this will affect all sprites of the same type,\r | |
65 | // TODO: even those without the highlight modifier.\r | |
66 | sprite.self.def.setConfig({\r | |
67 | defaults: {\r | |
68 | highlighted: false\r | |
69 | },\r | |
70 | processors: {\r | |
71 | highlighted: 'bool'\r | |
72 | }\r | |
73 | });\r | |
74 | this.setSprite(sprite);\r | |
75 | },\r | |
76 | \r | |
77 | /**\r | |
78 | * Filter out modifier changes that override highlightStyle or source attributes.\r | |
79 | * @param {Object} attr The source attributes.\r | |
80 | * @param {Object} changes The modifier changes.\r | |
81 | * @return {*} The filtered changes.\r | |
82 | */\r | |
83 | filterChanges: function (attr, changes) {\r | |
84 | var me = this,\r | |
85 | highlightOriginal = attr.highlightOriginal,\r | |
86 | style = me.getHighlightStyle(),\r | |
87 | name;\r | |
88 | if (attr.highlighted) {\r | |
89 | // TODO: Remove changes that match highlightStyle attribute names.\r | |
90 | // TODO: Backup such changes to highlightOriginal before removing.\r | |
91 | for (name in changes) {\r | |
92 | if (style.hasOwnProperty(name)) {\r | |
93 | // If sprite is highlighted, then stash the changes\r | |
94 | // to the `highlightStyle` attributes made by lower level modifiers\r | |
95 | // to apply them later when sprite is unhighlighted.\r | |
96 | highlightOriginal[name] = changes[name];\r | |
97 | delete changes[name];\r | |
98 | }\r | |
99 | }\r | |
100 | }\r | |
101 | \r | |
102 | // TODO: Remove changes (except the 'highlighted' flag) that match the original values. Why?\r | |
103 | for (name in changes) {\r | |
104 | if (name !== 'highlighted' && highlightOriginal[name] === changes[name]) {\r | |
105 | delete changes[name];\r | |
106 | }\r | |
107 | }\r | |
108 | \r | |
109 | return changes;\r | |
110 | },\r | |
111 | \r | |
112 | /**\r | |
113 | * @inheritdoc\r | |
114 | */\r | |
115 | pushDown: function (attr, changes) {\r | |
116 | var highlightStyle = this.getHighlightStyle(),\r | |
117 | highlightOriginal = attr.highlightOriginal,\r | |
118 | removeFromInstance = highlightOriginal.removeFromInstance,\r | |
119 | highlighted, name, tplAttr, timer;\r | |
120 | \r | |
121 | if (changes.hasOwnProperty('highlighted')) {\r | |
122 | highlighted = changes.highlighted;\r | |
123 | // Hide `highlighted` and `highlightStyle` from underlying modifiers.\r | |
124 | delete changes.highlighted;\r | |
125 | \r | |
126 | if (this._previous) {\r | |
127 | changes = this._previous.pushDown(highlightOriginal, changes);\r | |
128 | }\r | |
129 | changes = this.filterChanges(attr, changes);\r | |
130 | \r | |
131 | if (highlighted !== attr.highlighted) {\r | |
132 | if (highlighted) {\r | |
133 | // Switching ON.\r | |
134 | // At this time, original should be empty.\r | |
135 | for (name in highlightStyle) {\r | |
136 | // Remember the values of attributes to revert back to them on unhighlight.\r | |
137 | if (name in changes) {\r | |
138 | // Remember value set by lower level modifiers.\r | |
139 | highlightOriginal[name] = changes[name];\r | |
140 | } else {\r | |
141 | // Remember the original value.\r | |
142 | \r | |
143 | // If this is a sprite instance and it doesn't have its own\r | |
144 | // 'name' attribute, (i.e. inherits template's attribute value)\r | |
145 | // than we have to get the value for the 'name' attribute from\r | |
146 | // the template's 'animationOriginal' object instead of its\r | |
147 | // 'attr' object (which is the prototype of the instance),\r | |
148 | // because the 'name' attribute of the template may be animating.\r | |
149 | // Check out the prepareAttributes method of the Animation\r | |
150 | // modifier for more details on the 'animationOriginal' object.\r | |
151 | \r | |
152 | tplAttr = attr.template && attr.template.ownAttr;\r | |
153 | if (tplAttr && !attr.prototype.hasOwnProperty(name)) {\r | |
154 | removeFromInstance[name] = true;\r | |
155 | highlightOriginal[name] = tplAttr.animationOriginal[name];\r | |
156 | } else {\r | |
157 | \r | |
158 | // Even if a sprite instance has its own property, it may\r | |
159 | // still have to be removed from the instance after\r | |
160 | // unhighlighting is done.\r | |
161 | // Consider a situation where an instance doesn't originally\r | |
162 | // have its own attribute (that is used for highlighting and\r | |
163 | // unhighlighting). It will however have that attribute as\r | |
164 | // its own when the highlight/unhighlight animation is in\r | |
165 | // progress, until the attribute is removed from the instance\r | |
166 | // when the unhighlighting is done.\r | |
167 | // So in a scenario where the instance is highlighted, then\r | |
168 | // unhighlighted (i.e. starts animating back to its original\r | |
169 | // value) and then highlighted again before the unhighlight\r | |
170 | // animation is done, we should still mark the attribute\r | |
171 | // for removal from the instance, if it was our original\r | |
172 | // intention. To tell if it was, we can check the timer\r | |
173 | // for the attribute and see if the 'remove' flag is set.\r | |
174 | \r | |
175 | timer = highlightOriginal.timers[name];\r | |
176 | if (timer && timer.remove) {\r | |
177 | removeFromInstance[name] = true;\r | |
178 | }\r | |
179 | highlightOriginal[name] = attr[name];\r | |
180 | }\r | |
181 | }\r | |
182 | if (highlightOriginal[name] !== highlightStyle[name]) {\r | |
183 | changes[name] = highlightStyle[name];\r | |
184 | }\r | |
185 | }\r | |
186 | } else {\r | |
187 | // Switching OFF.\r | |
188 | for (name in highlightStyle) {\r | |
189 | if (!(name in changes)) {\r | |
190 | changes[name] = highlightOriginal[name];\r | |
191 | }\r | |
192 | delete highlightOriginal[name];\r | |
193 | }\r | |
194 | changes.removeFromInstance = changes.removeFromInstance || {};\r | |
195 | // Let the higher lever animation modifier know which attributes\r | |
196 | // should be removed from instance when the animation is done.\r | |
197 | Ext.apply(changes.removeFromInstance, removeFromInstance);\r | |
198 | highlightOriginal.removeFromInstance = {};\r | |
199 | }\r | |
200 | changes.highlighted = highlighted;\r | |
201 | }\r | |
202 | } else {\r | |
203 | if (this._previous) {\r | |
204 | changes = this._previous.pushDown(highlightOriginal, changes);\r | |
205 | }\r | |
206 | changes = this.filterChanges(attr, changes);\r | |
207 | }\r | |
208 | \r | |
209 | return changes;\r | |
210 | },\r | |
211 | \r | |
212 | /**\r | |
213 | * @inheritdoc\r | |
214 | */\r | |
215 | popUp: function (attr, changes) {\r | |
216 | changes = this.filterChanges(attr, changes);\r | |
217 | Ext.draw.modifier.Modifier.prototype.popUp.call(this, attr, changes);\r | |
218 | }\r | |
219 | });\r |