First cut at styling TIGER data via an option. Needs lots of propagation of uid and...
[potlatch2.git] / net / systemeD / halcyon / NodeUI.as
index b59c65ff12afc807941cf23c2797940186450e13..eb9e608bf8c380f1b97363f47475ec191a4a62fb 100644 (file)
@@ -8,181 +8,176 @@ package net.systemeD.halcyon {
        import flash.text.TextFormat;
        import flash.geom.Matrix;
        import flash.geom.Point;
-    import net.systemeD.halcyon.connection.Node;
-    import net.systemeD.halcyon.connection.Connection;
        import net.systemeD.halcyon.styleparser.*;
+    import net.systemeD.halcyon.connection.*;
        import net.systemeD.halcyon.Globals;
        
-       public class NodeUI extends Object {
+       public class NodeUI extends EntityUI {
                
-        private var node:Node;
-               public var map:Map;                                                     // reference to parent map
-               public var icon:Sprite;                                         // instance in display list
-               public var name:Sprite;                                         //  |
-               private var iconname:String='';                         // name of icon
+               public var loaded:Boolean=false;
+               private var iconnames:Object={};                        // name of icon on each sublayer
                private var heading:Number=0;                           // heading within way
                private var rotation:Number=0;                          // rotation applied to this POI
-               public var loaded:Boolean=false;
+               private static const NO_LAYER:int=-99999;
 
-               public static const DEFAULT_TEXTFIELD_PARAMS:Object = {
-//                     embedFonts: true,
-                       antiAliasType: AntiAliasType.ADVANCED,
-                       gridFitType: GridFitType.NONE
-               };
-//             [Embed(source="fonts/DejaVuSans.ttf", fontFamily="DejaVu", fontWeight="normal", mimeType="application/x-font-truetype")]
-//             public static var DejaVu:Class;
-
-               public function NodeUI(node:Node, map:Map, rotation:Number=0) {
-                       this.map = map;
-                       this.node = node;
-                       this.rotation = rotation;
-                       node.addEventListener(Connection.NODE_MOVED, nodeMoved);
+               public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, layer:int=NO_LAYER, stateClasses:Object=null) {
+                       super(node,paint);
+                       if (layer==NO_LAYER) { this.layer=paint.maxlayer; } else { this.layer=layer; }
+                       this.heading = heading;
+                       if (stateClasses) {
+                               for (var state:String in stateClasses) {
+                                       if (stateClasses[state]) { this.stateClasses[state]=stateClasses[state]; }
+                               }
+                       }
+            entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
+                       entity.addEventListener(Connection.NODE_MOVED, nodeMoved);
+                       entity.addEventListener(Connection.NODE_DELETED, nodeDeleted);
+            attachRelationListeners();
+                       redraw();
                }
                
                public function nodeMoved(event:Event):void {
                    updatePosition();
                }
-               
-               public function redraw(sl:StyleList=null,forceDraw:Boolean=false):Boolean {
-                       var tags:Object = node.getTagsCopy();
-                       tags['_heading']=heading;
-                       // ** apply :hover etc.
-                       if (!sl) { sl=map.ruleset.getStyles(this.node,tags); }
-
-                       var inWay:Boolean=node.hasParentWays;
-                       var hasStyles:Boolean=sl.hasStyles();
-                       
-                       removePrevious();
-                       if (!hasStyles && !inWay) {
-                               // No styles, not in way; usually return, but render as green circle if showall set
-                               if (!map.showall) { return false; }
-                               return renderAsCircle();
-                       } else if (!hasStyles && inWay) {
-                               // No styles, in way; so render as highlight
-                               // *** needs to be blue/red depending on mouse-over
-                               if (forceDraw) {
-                                       return renderAsSquare();
-                               } else {
-                                       return false;
-                               }
-                       } else {
-                               // Styled, so render properly
-                               return renderFromStyle(sl,tags);
-                       }
-               }
 
-               private function renderAsSquare():Boolean {
-                       createIcon();
-                       icon.graphics.beginFill(0xFF0000);
-                       icon.graphics.drawRect(0,0,6,6);        // ** NODESIZE
-                       loaded=true;
-                       updatePosition();
-                       iconname='_square';
-                       return true;
+               public function nodeDeleted(event:Event):void {
+                       removeSprites();
                }
-               
-               private function renderAsCircle():Boolean {
-                       createIcon();
-                       icon.graphics.lineStyle(1,0,1);
-                       icon.graphics.beginFill(0x00FF00);
-                       icon.graphics.drawCircle(4,4,4);        // ** NODESIZE
-                       loaded=true;
-                       updatePosition();
-                       iconname='_circle';
-                       return true;
+
+               override public function doRedraw():Boolean {
+                       if (!paint.ready) { return false; }
+                       if (entity.deleted) { return false; }
+
+                       var tags:Object = entity.getTagsCopy();
+                       tags=applyStateClasses(tags);
+                       if (!entity.hasParentWays) { tags[':poi']='yes'; }
+            if (entity.hasInterestingTags()) { tags[':hasTags']='yes'; }
+                       if (!styleList || !styleList.isValidAt(paint.map.scale)) {
+                               styleList=paint.ruleset.getStyles(entity,tags,paint.map.scale); 
+                       }
+
+                       var inWay:Boolean=entity.hasParentWays;
+                       var hasStyles:Boolean=styleList.hasStyles();
+                       
+                       removeSprites(); iconnames={};
+                       return renderFromStyle(tags);
                }
-               
-               private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
-                       var r:Boolean=false;    // ** rendered
-                       for (var sublayer:uint=0; sublayer<10; sublayer++) {
 
-                               if (sl.pointStyles[sublayer]) {
-                                       var s:PointStyle=sl.pointStyles[sublayer];
+               private function renderFromStyle(tags:Object):Boolean {
+                       var r:Boolean=false;                    // ** rendered
+                       var maxwidth:Number=4;                  // biggest width
+                       var w:Number;
+                       var icon:Sprite;
+                       interactive=false;
+                       for each (var sublayer:Number in styleList.sublayers) {
+
+                               if (styleList.pointStyles[sublayer]) {
+                                       var s:PointStyle=styleList.pointStyles[sublayer];
+                                       interactive||=s.interactive;
                                        r=true;
                                        if (s.rotation) { rotation=s.rotation; }
-                                       if (s.icon_image!=iconname) {
-                                               // 'load' icon (actually just from library)
-                                               if (map.ruleset.images[s.icon_image]) {
-                                                       var loader:Loader = new Loader();
+                                       if (s.icon_image!=iconnames[sublayer]) {
+                                               if (s.icon_image=='square') {
+                                                       // draw square
+                                                       icon=new Sprite();
+                                                       addToLayer(icon,STROKESPRITE,sublayer);
+                                                       w=styleIcon(icon,sublayer);
+                                                       icon.graphics.drawRect(0,0,w,w);
+                                                       if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
+                                                       iconnames[sublayer]='_square';
+
+                                               } else if (s.icon_image=='circle') {
+                                                       // draw circle
+                                                       icon=new Sprite();
+                                                       addToLayer(icon,STROKESPRITE,sublayer);
+                                                       w=styleIcon(icon,sublayer);
+                                                       icon.graphics.drawCircle(w,w,w);
+                                                       if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
+                                                       iconnames[sublayer]='_circle';
+
+                                               } else if (paint.ruleset.images[s.icon_image]) {
+                                                       // 'load' icon (actually just from library)
+                                                       var loader:ExtendedLoader = new ExtendedLoader();
+                                                       loader.info['sublayer']=sublayer;
                                                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedIcon);
-                                                       loader.loadBytes(map.ruleset.images[s.icon_image]);
-                                                       iconname=s.icon_image;
+                                                       loader.loadBytes(paint.ruleset.images[s.icon_image]);
+                                                       iconnames[sublayer]=s.icon_image;
                                                }
-                                       } else {
-                                               // already loaded, so just reposition
-                                               updatePosition();
                                        }
                                }
 
                                // name sprite
-                               var a:String, t:TextStyle;
-                               if (sl.textStyles[sublayer]) {
-                                       t=sl.textStyles[sublayer];
+                               var a:String='', t:TextStyle;
+                               if (styleList.textStyles[sublayer]) {
+                                       t=styleList.textStyles[sublayer];
+                                       interactive||=t.interactive;
                                        a=tags[t.text];
                                }
 
                                if (a) { 
-                                       var l:DisplayObject=map.getChildAt(map.NAMESPRITE);
-                                       if (!name) { name=new Sprite(); Sprite(l).addChild(name); }
-                                       t.writeNameLabel(name,a,map.lon2coord(node.lon),map.latp2coord(node.latp));
+                                       var name:Sprite=new Sprite();
+                                       addToLayer(name,NAMESPRITE);
+                                       t.writeNameLabel(name,a,0,0);
                                }
                        }
-                       return r;
+                       if (!r) { return false; }
+                       if (interactive) { addHitSprite(maxwidth); }
+                       updatePosition();
+                       return true;
                }
 
-               private function removePrevious():void {
-                       var l:DisplayObject;
-                       
-                       if (icon) {
-                               l=map.getChildAt(map.POISPRITE);
-                               Sprite(l).removeChild(icon);
-                               icon=null;
-                               iconname='';
-                       }
-                       if (name) {
-                               l=map.getChildAt(map.NAMESPRITE);
-                               Sprite(l).removeChild(name);
-                               name=null;
+
+               private function styleIcon(icon:Sprite, sublayer:Number):Number {
+                       loaded=true;
+
+                       // get colours
+                       if (styleList.shapeStyles[sublayer]) {
+                               var s:ShapeStyle=styleList.shapeStyles[sublayer];
+                               if (!isNaN(s.color)) { icon.graphics.beginFill(s.color);
+                                       }
+                               if (s.casing_width || !isNaN(s.casing_color)) {
+                                       icon.graphics.lineStyle(s.casing_width ? s.casing_width : 1,
+                                                                                       s.casing_color ? s.casing_color : 0,
+                                                                                       s.casing_opacity ? s.casing_opacity : 1);
+                               }
                        }
+
+                       // return width
+                       return styleList.pointStyles[sublayer].icon_width;
+               }
+
+               private function addHitSprite(w:uint):void {
+            hitzone = new Sprite();
+            hitzone.graphics.lineStyle(4, 0x000000, 1, false, "normal", CapsStyle.ROUND, JointStyle.ROUND);
+                       hitzone.graphics.beginFill(0);
+                       hitzone.graphics.drawRect(0,0,w,w);
+                       hitzone.visible = false;
+                       setListenSprite();
                }
 
                private function loadedIcon(event:Event):void {
-                       createIcon();
+                       var icon:Sprite=new Sprite();
+                       var sublayer:Number=event.target.loader.info['sublayer'];
+                       addToLayer(icon,STROKESPRITE,sublayer);
                        icon.addChild(Bitmap(event.target.content));
+                       addHitSprite(icon.width);
                        loaded=true;
                        updatePosition();
                }
 
-               private function createIcon():void {
-                       icon = new Sprite();
-                       var l:DisplayObject=map.getChildAt(map.POISPRITE);
-                       Sprite(l).addChild(icon);
-            icon.addEventListener(MouseEvent.CLICK, mouseEvent);
-            icon.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
-            icon.addEventListener(MouseEvent.MOUSE_OVER, mouseEvent);
-            icon.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
-            icon.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
-            icon.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
-            icon.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
-            icon.buttonMode = true;
-            icon.mouseEnabled = true;
-               }
+               private function updatePosition():void {
+                       if (!loaded) { return; }
 
-        private function mouseEvent(event:MouseEvent):void {
-                       map.entityMouseEvent(event, node);
-        }
+                       for (var i:uint=0; i<sprites.length; i++) {
+                               var d:DisplayObject=sprites[i];
+                               d.x=0; d.y=0; d.rotation=0;
 
-               private function updatePosition():void {
-                       if (!loaded || !icon) { return; }
-                       icon.x=0; icon.y=0; icon.rotation=0;
-
-                       var m:Matrix=new Matrix();
-//                     m.identity();
-                       m.translate(-icon.width/2,-icon.height/2);
-                       m.rotate(rotation);
-                       m.translate(map.lon2coord(node.lon),map.latp2coord(node.latp));
-                       icon.transform.matrix=m;
+                               var m:Matrix=new Matrix();
+                               m.translate(-d.width/2,-d.height/2);
+                               m.rotate(rotation);
+                               m.translate(paint.map.lon2coord(Node(entity).lon),paint.map.latp2coord(Node(entity).latp));
+                               d.transform.matrix=m;
+                       }
                }
-
        }
 }