Animated spinner to make loading/saving more obvious
authorRichard Fairhurst <richard@systemeD.net>
Sun, 4 Mar 2012 14:23:42 +0000 (14:23 +0000)
committerRichard Fairhurst <richard@systemeD.net>
Sun, 4 Mar 2012 14:23:42 +0000 (14:23 +0000)
net/systemeD/controls/Spinner.as [new file with mode: 0644]
potlatch2.mxml

diff --git a/net/systemeD/controls/Spinner.as b/net/systemeD/controls/Spinner.as
new file mode 100644 (file)
index 0000000..038aefa
--- /dev/null
@@ -0,0 +1,68 @@
+package net.systemeD.controls {
+       import flash.events.TimerEvent;
+       import flash.events.Event;
+       import flash.display.Sprite;
+       import flash.display.Shape;
+       import flash.utils.Timer;
+       import flash.filters.GlowFilter;
+       
+       // Adapted from http://www.stevensacks.net/2008/10/01/as3-apple-style-preloader/
+
+       public class Spinner extends Sprite {
+               private var timer:Timer;
+               private var slices:int;
+               private var radius:int;
+
+               public function Spinner(slices:int = 12, radius:int = 6) {
+                       super();
+                       this.slices = slices;
+                       this.radius = radius;
+                       draw();
+
+                       var filter:GlowFilter=new GlowFilter(0xFFFFFF,1,4,4,6);
+                       this.filters = [filter];
+               }
+
+               public function start():void {
+                       visible=true;
+                       if (timer) return;
+                       timer = new Timer(65);
+                       timer.addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
+                       timer.start();
+               }
+
+               public function stop():void {
+                       visible=false;
+                       if (!timer) return;
+                       timer.reset();
+                       timer.removeEventListener(TimerEvent.TIMER, onTimer);
+                       timer = null;
+               }
+
+               private function onTimer(event:TimerEvent):void {
+                       rotation = (rotation + (360 / slices)) % 360;
+               }
+               
+               private function draw():void {
+                       var i:int = slices;
+                       var degrees:int = 360 / slices;
+                       while (i--) {
+                               var slice:Shape = getSlice();
+                               slice.alpha = Math.max(0.2, 1 - (0.1 * i));
+                               var radianAngle:Number = (degrees * i) * Math.PI / 180;
+                               slice.rotation = -degrees * i;
+                               slice.x = Math.sin(radianAngle) * radius;
+                               slice.y = Math.cos(radianAngle) * radius;
+                               addChild(slice);
+                       }
+               }
+
+               private function getSlice():Shape {
+                       var slice:Shape = new Shape();
+                       slice.graphics.beginFill(0x666666);
+                       slice.graphics.drawRoundRect(-1, 0, 2, 6, 12, 12);
+                       slice.graphics.endFill();
+                       return slice;
+               }
+       }
+}
index 2c51c57..b365c7d 100644 (file)
                import net.systemeD.potlatch2.utils.*;
         import net.systemeD.potlatch2.mygpx.*;
                import net.systemeD.controls.FloatingAlert;
+               import net.systemeD.controls.Spinner;
                import mx.managers.PopUpManager;
                import flash.system.Security;
                import flash.net.*;
 
                private var savecount:uint=0;
                private var loadcount:uint=0;
+               private var spinner:Spinner;
                private var saveLabel:String='Save';
                private var saveTimer:Timer;
 
             // Auto-load vector backgrounds from config
             theMap.addEventListener(MapEvent.INITIALISED, function(e:Event):void { VectorBackgrounds.instance().init(theMap); });
 
+                       // Add loading 'spinner' indicator
+                       spinner=new Spinner();
+                       _root.addChild(spinner);
+                       spinner.x=dataWorking.x-20;
+                       spinner.y=dataWorking.y+dataWorking.height/2;
+
                        // Set start position of map
                        // ** FIXME: if lat/lon/zoom aren't supplied, we need to keep the map in a non-loading state 
                        //           until the user has decided where to start editing (e.g. when the first GPX loads)
                        else if (savecount>0)           { t="Saving data..."; }
                        else                            { t=""; }
                        dataWorking.text=t.replace("#",(loadcount>1) ? (" ("+loadcount+")") : "");
-                       dataWorking.visible=(dataWorking.text!="");
+
+                       var previousState:Boolean=dataWorking.visible;
+                       var newState:Boolean=(dataWorking.text!="");
+                       if (!previousState && newState) spinner.start();
+                       if (previousState && !newState) spinner.stop();
+                       dataWorking.visible=newState;
                }
         private function onDataDirty(event:Event):void {
                        saveButton.enabled=true;