First cut at styling TIGER data via an option. Needs lots of propagation of uid and...
[potlatch2.git] / net / systemeD / halcyon / NodeUI.as
index 59238ea4f9eb6482ddebf0c8fbf078997d9fa5c7..eb9e608bf8c380f1b97363f47475ec191a4a62fb 100644 (file)
@@ -8,146 +8,156 @@ 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 EntityUI {
                
-        private var node:Node;
                public var loaded:Boolean=false;
-               private var iconname:String='';                         // name of icon
+               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
+               private static const NO_LAYER:int=-99999;
 
-               public function NodeUI(node:Node, map:Map, heading:Number=0) {
-                       super();
-                       this.map = map;
-                       this.node = node;
+               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;
-                       node.addEventListener(Connection.NODE_MOVED, nodeMoved);
+                       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 {
-                       // *** forcedraw can be removed
 
-                       var tags:Object = node.getTagsCopy();
+               public function nodeDeleted(event:Event):void {
+                       removeSprites();
+               }
 
-                       // special tags
-                       if (!node.hasParentWays) { tags[':poi']='yes'; }
-            for (var stateKey:String in stateClasses) {
-                tags[":"+stateKey] = stateKey;
-            }
+               override public function doRedraw():Boolean {
+                       if (!paint.ready) { return false; }
+                       if (entity.deleted) { return false; }
 
-                       if (!sl) { sl=map.ruleset.getStyles(this.node,tags); }
+                       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=node.hasParentWays;
-                       var hasStyles:Boolean=sl.hasStyles();
+                       var inWay:Boolean=entity.hasParentWays;
+                       var hasStyles:Boolean=styleList.hasStyles();
                        
-                       removeSprites(); iconname='';
-                       return renderFromStyle(sl,tags);
+                       removeSprites(); iconnames={};
+                       return renderFromStyle(tags);
                }
 
-               private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
-                       var r:Boolean=false;    // ** rendered
+               private function renderFromStyle(tags:Object):Boolean {
+                       var r:Boolean=false;                    // ** rendered
+                       var maxwidth:Number=4;                  // biggest width
                        var w:Number;
                        var icon:Sprite;
-                       layer=10;
-                       for (var sublayer:int=10; sublayer>=0; sublayer--) {
+                       interactive=false;
+                       for each (var sublayer:Number in styleList.sublayers) {
 
-                               if (sl.pointStyles[sublayer]) {
-                                       var s:PointStyle=sl.pointStyles[sublayer];
+                               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) {
+                                       if (s.icon_image!=iconnames[sublayer]) {
                                                if (s.icon_image=='square') {
                                                        // draw square
                                                        icon=new Sprite();
                                                        addToLayer(icon,STROKESPRITE,sublayer);
-                                                       w=styleIcon(icon,sl,sublayer);
+                                                       w=styleIcon(icon,sublayer);
                                                        icon.graphics.drawRect(0,0,w,w);
-                                                       addHitSprite(w);
-                                                       updatePosition();
-                                                       iconname='_square';
+                                                       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,sl,sublayer);
+                                                       w=styleIcon(icon,sublayer);
                                                        icon.graphics.drawCircle(w,w,w);
-                                                       addHitSprite(w);
-                                                       updatePosition();
-                                                       iconname='_circle';
+                                                       if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
+                                                       iconnames[sublayer]='_circle';
 
-                                               } else if (map.ruleset.images[s.icon_image]) {
+                                               } else if (paint.ruleset.images[s.icon_image]) {
                                                        // 'load' icon (actually just from library)
-                                                       var loader:Loader = new Loader();
-                                                       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { loadedIcon(e,sublayer); } );
-                                                       loader.loadBytes(map.ruleset.images[s.icon_image]);
-                                                       iconname=s.icon_image;
+                                                       var loader:ExtendedLoader = new ExtendedLoader();
+                                                       loader.info['sublayer']=sublayer;
+                                                       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedIcon);
+                                                       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 name:Sprite=new Sprite();
                                        addToLayer(name,NAMESPRITE);
-                                       t.writeNameLabel(name,a,map.lon2coord(node.lon),map.latp2coord(node.latp));
+                                       t.writeNameLabel(name,a,0,0);
                                }
                        }
-                       return r;
+                       if (!r) { return false; }
+                       if (interactive) { addHitSprite(maxwidth); }
+                       updatePosition();
+                       return true;
                }
 
 
-               private function styleIcon(icon:Sprite, sl:StyleList, sublayer:uint):Number {
+               private function styleIcon(icon:Sprite, sublayer:Number):Number {
                        loaded=true;
 
                        // get colours
-                       if (sl.shapeStyles[sublayer]) {
-                               var s:ShapeStyle=sl.shapeStyles[sublayer];
-                               if (s.color) { icon.graphics.beginFill(s.color); }
-                               if (s.casing_width || s.casing_color!=false) {
+                       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);
-                                       // ** this appears to give casing to things that shouldn't have it
-                                       // Globals.vars.root.addDebug("casing: "+(s.casing_width ? s.casing_width : 1)+","+(s.casing_color ? s.casing_color : 0)+","+(s.casing_opacity ? s.casing_opacity : 1)); 
                                }
                        }
 
                        // return width
-                       return sl.pointStyles[sublayer].icon_width ? sl.pointStyles[sublayer].icon_width : 4;
+                       return styleList.pointStyles[sublayer].icon_width;
                }
 
                private function addHitSprite(w:uint):void {
-            var hitzone:Sprite = new Sprite();
+            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);
-            addToLayer(hitzone, CLICKSPRITE);
-            hitzone.visible = false;
-                       createListenSprite(hitzone);
+                       hitzone.visible = false;
+                       setListenSprite();
                }
 
-               private function loadedIcon(event:Event,sublayer:uint):void {
+               private function loadedIcon(event:Event):void {
                        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);
@@ -155,15 +165,9 @@ package net.systemeD.halcyon {
                        updatePosition();
                }
 
-        override protected function mouseEvent(event:MouseEvent):void {
-                       map.entityMouseEvent(event, node);
-        }
-
                private function updatePosition():void {
                        if (!loaded) { return; }
 
-                       // ** this won't work with text objects. They have a different .x and .y
-                       //    and (obviously) don't need to be rotated. Needs fixing
                        for (var i:uint=0; i<sprites.length; i++) {
                                var d:DisplayObject=sprites[i];
                                d.x=0; d.y=0; d.rotation=0;
@@ -171,7 +175,7 @@ package net.systemeD.halcyon {
                                var m:Matrix=new Matrix();
                                m.translate(-d.width/2,-d.height/2);
                                m.rotate(rotation);
-                               m.translate(map.lon2coord(node.lon),map.latp2coord(node.latp));
+                               m.translate(paint.map.lon2coord(Node(entity).lon),paint.map.latp2coord(Node(entity).latp));
                                d.transform.matrix=m;
                        }
                }