source: EDIS/trunk/java/tracking-ui-core/src/main/flex/gov/va/med/edp/widget/Spinner.as@ 1227

Last change on this file since 1227 was 1227, checked in by George Lilly, 13 years ago

initial load of EDIS 1.0

File size: 6.5 KB
Line 
1package gov.va.med.edp.widget {
2
3 import flash.events.TimerEvent;
4
5 import flash.utils.Timer;
6
7
8
9 import mx.core.UIComponent;
10
11 import mx.events.FlexEvent;
12
13 import mx.styles.CSSStyleDeclaration;
14
15 import mx.styles.StyleManager;
16
17
18
19
20
21 [Style(name="tickColor",type="uint",format="Color",inherit="no")]
22
23 public class Spinner extends UIComponent {
24
25 private static var STYLE_TICK_COLOR:String = "tickColor";
26
27 private var tickColorChanged:Boolean;
28
29
30
31 private static var classConstructed:Boolean = classConstruct();
32
33
34
35 // Make sure we create the ticks the first time updateDisplayList is called
36
37 private var creation:Boolean = true;
38
39
40
41
42
43 private var fadeTimer:Timer;
44
45 private var _isPlaying:Boolean;
46
47
48
49 private var _numTicks:int = 12;
50
51 private var numTicksChanged:Boolean;
52
53
54
55 private var _size:Number = 30;
56
57 private var sizeChanged:Boolean;
58
59
60
61 private var _tickWidth:Number = 3;
62
63 private var tickWidthChanged:Boolean;
64
65
66
67 private var _speed:int = 1000;
68
69 [Bindable] public var fadeSpeed:int = 600;
70
71
72
73 public var autoPlay:Boolean = true;
74
75
76
77
78
79 public function Spinner() {
80
81 super();
82
83
84
85 addEventListener(FlexEvent.CREATION_COMPLETE, handleCreationComplete);
86
87 }
88
89
90
91
92
93 private function handleCreationComplete(e:FlexEvent):void {
94
95 removeEventListener(FlexEvent.CREATION_COMPLETE, handleCreationComplete);
96
97 if (autoPlay) {
98
99 play();
100
101 }
102
103 }
104
105
106
107
108
109 /**
110
111 * Set the height and width based on the size of the spinner. This should be more robust, but oh well.
112
113 */
114
115 override protected function measure():void {
116
117 super.measure();
118
119
120
121 width = _size;
122
123 height = _size;
124
125 }
126
127
128
129
130
131 /**
132
133 * Override the updateDisplayList method
134
135 */
136
137 override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
138
139 if (tickColorChanged || numTicksChanged || sizeChanged || tickWidthChanged || creation) {
140
141 creation = false;
142
143 // Find out whether it's playing so we can restart it later if we need to
144
145 var wasPlaying:Boolean = _isPlaying;
146
147
148
149 // stop the spinning
150
151 stop();
152
153
154
155 // Remove all children
156
157 for (var i:int = numChildren - 1; i >= 0; i--) {
158
159 removeChildAt(i);
160
161 }
162
163
164
165 // Re-create the children
166
167 var radius:Number = size / 2;
168
169 var angle:Number = 2 * Math.PI / _numTicks; // The angle between each tick
170
171 var tickWidth:Number = (_tickWidth != -1) ? _tickWidth : size / 10;
172
173 var tickColor:uint = getStyle(STYLE_TICK_COLOR);
174
175
176
177 var currentAngle:Number = 0;
178
179 for (var j:int = 0; j < _numTicks; j++) {
180
181
182
183 var xStart:Number = radius + Math.sin(currentAngle) * ((_numTicks + 2) * tickWidth / 2 / Math.PI);
184
185 var yStart:Number = radius - Math.cos(currentAngle) * ((_numTicks + 2) * tickWidth / 2 / Math.PI);
186
187 var xEnd:Number = radius + Math.sin(currentAngle) * (radius - tickWidth);
188
189 var yEnd:Number = radius - Math.cos(currentAngle) * (radius - tickWidth);
190
191
192
193 var t:Tick = new Tick(xStart, yStart, xEnd, yEnd, tickWidth, tickColor);
194
195 t.alpha = 0.1;
196
197
198
199 this.addChild(t);
200
201
202
203 currentAngle += angle;
204
205 }
206
207
208
209 // Start the spinning again if it was playing when this function was called.
210
211 if (wasPlaying) {
212
213 play();
214
215 }
216
217
218
219 tickColorChanged = false;
220
221 numTicksChanged = false;
222
223 sizeChanged = false;
224
225 tickWidthChanged = false;
226
227 }
228
229 }
230
231
232
233
234
235 private static function classConstruct():Boolean {
236
237 if (!StyleManager.getStyleDeclaration("Spinner")) {
238
239 // If there is no CSS definition for StyledRectangle,
240
241 // then create one and set the default value.
242
243 var newStyleDeclaration:CSSStyleDeclaration = new CSSStyleDeclaration();
244
245 newStyleDeclaration.setStyle(STYLE_TICK_COLOR, 0x000000);
246
247 StyleManager.setStyleDeclaration("Spinner", newStyleDeclaration, true);
248
249 }
250
251 return true;
252
253 }
254
255
256
257 override public function styleChanged(styleProp:String):void {
258
259 if (styleProp == STYLE_TICK_COLOR) {
260
261 tickColorChanged = true;
262
263 invalidateDisplayList();
264
265 }
266
267 }
268
269
270
271
272
273 /**
274
275 * Begin the circular fading of the ticks.
276
277 */
278
279 public function play():void {
280
281 if (! _isPlaying) {
282
283 fadeTimer = new Timer(speed / _numTicks, 0);
284
285 // Anonymous functions are especially useful as simple event handlers
286
287 fadeTimer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void {
288
289 var tickNum:int = int(fadeTimer.currentCount % _numTicks);
290
291
292
293 if (numChildren > tickNum) {
294
295 var tick:Tick = getChildAt(tickNum) as Tick;
296
297 tick.fade(fadeSpeed != 1 ? fadeSpeed : speed * 6 / 10);
298
299 }
300
301 });
302
303 fadeTimer.start();
304
305 _isPlaying = true;
306
307 }
308
309 }
310
311
312
313 /**
314
315 * Stop the spinning.
316
317 */
318
319 public function stop():void {
320
321 if (fadeTimer != null && fadeTimer.running) {
322
323 _isPlaying = false;
324
325 fadeTimer.stop();
326
327 }
328
329 }
330
331
332
333 /**
334
335 * The overall diameter of the spinner; also the height and width.
336
337 */
338
339 [Bindable]
340
341 public function set size(value:Number):void {
342
343 if (value != _size) {
344
345 _size = value;
346
347 sizeChanged = true;
348
349 invalidateDisplayList();
350
351 invalidateSize();
352
353 }
354
355 }
356
357
358
359 public function get size():Number {
360
361 return _size;
362
363 }
364
365
366
367 /**
368
369 * The number of 'spokes' on the spinner.
370
371 */
372
373 [Bindable]
374
375 public function set numTicks(value:int):void {
376
377 if (value != _numTicks) {
378
379 _numTicks = value;
380
381 numTicksChanged = true;
382
383 invalidateDisplayList();
384
385 }
386
387 }
388
389
390
391 public function get numTicks():int {
392
393 return _numTicks;
394
395 }
396
397
398
399 /**
400
401 * The width of the 'spokes' on the spinner.
402
403 */
404
405 [Bindable]
406
407 public function set tickWidth(value:int):void {
408
409 if (value != _tickWidth) {
410
411 _tickWidth = value;
412
413 tickWidthChanged = true;
414
415 invalidateDisplayList();
416
417 }
418
419 }
420
421
422
423 public function get tickWidth():int {
424
425 return _tickWidth;
426
427 }
428
429
430
431 /**
432
433 * The duration (in milliseconds) that it takes for the spinner to make one revolution.
434
435 */
436
437 [Bindable]
438
439 public function set speed(value:int):void {
440
441 if (value != _speed) {
442
443 _speed = value;
444
445 fadeTimer.stop();
446
447 fadeTimer.delay = value / _numTicks;
448
449 fadeTimer.start();
450
451 }
452
453 }
454
455
456
457 public function get speed():int {
458
459 return _speed;
460
461 }
462
463
464
465
466
467 public function get isPlaying():Boolean {
468
469 return _isPlaying;
470
471 }
472
473 }
474
475}
Note: See TracBrowser for help on using the repository browser.