continuing to expand and rework selection stuff. Not finished yet but getting there
authorRichard Fairhurst <richard@systemed.net>
Thu, 19 Nov 2009 02:42:15 +0000 (02:42 +0000)
committerRichard Fairhurst <richard@systemed.net>
Thu, 19 Nov 2009 02:42:15 +0000 (02:42 +0000)
15 files changed:
TODO.txt
net/systemeD/halcyon/EntityUI.as [new file with mode: 0644]
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/NodeUI.as
net/systemeD/halcyon/WayUI.as
net/systemeD/halcyon/styleparser/RuleSet.as
net/systemeD/halcyon/styleparser/StyleChooser.as
net/systemeD/potlatch2/controller/DragWayNode.as
net/systemeD/potlatch2/controller/NoSelection.as
net/systemeD/potlatch2/controller/SelectedPOINode.as [new file with mode: 0644]
net/systemeD/potlatch2/controller/SelectedWay.as
net/systemeD/potlatch2/controller/SelectedWayNode.as [new file with mode: 0644]
potlatch2.mxml
resources/potlatch.css
resources/test.css

index 0b06957..3779f10 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,10 +1,15 @@
 Potlatch 2: main outstanding issues
-(last updated 30th September 2009)
+(last updated 19th November 2009)
 -----------------------------------
 
+== Current issues ==
+
+* Deselecting a way often doesn't remove the nodes (if you've dragged a node, for example)
+* Highlights don't work on nodes
+
+
 == Core drawing ==
 
-* Branching ways
 * Split and merge ways
 * POI drawing (drag and drop/double-click)
 * Undo/redo
diff --git a/net/systemeD/halcyon/EntityUI.as b/net/systemeD/halcyon/EntityUI.as
new file mode 100644 (file)
index 0000000..1cfb1bf
--- /dev/null
@@ -0,0 +1,82 @@
+package net.systemeD.halcyon {
+
+       import flash.display.*;
+       import flash.events.MouseEvent;
+       import flash.text.AntiAliasType;
+       import flash.text.GridFitType;
+
+       public class EntityUI {
+
+               protected var sprites:Array=new Array();                // instances in display list
+        protected var listenSprite:Sprite;                             // clickable sprite to receive events
+               protected var stateClasses:Object=new Object(); // special context-sensitive classes, e.g. :hover
+               protected var layer:int=0;                                              // map layer
+               public var map:Map;                                                             // reference to parent map
+
+               protected const FILLSPRITE:uint=0;
+               protected const CASINGSPRITE:uint=1;
+               protected const STROKESPRITE:uint=2;
+               protected const NAMESPRITE:uint=3;
+               protected const NODESPRITE:uint=4;
+               protected const CLICKSPRITE:uint=5;
+
+               public static const DEFAULT_TEXTFIELD_PARAMS:Object = {
+                       embedFonts: true,
+                       antiAliasType: AntiAliasType.ADVANCED,
+                       gridFitType: GridFitType.NONE
+               };
+
+               public function EntityUI() {
+               }
+
+               // Add object (stroke/fill/roadname) to layer sprite
+               
+               protected function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
+                       var l:DisplayObject=Map(map).getChildAt(map.WAYSPRITE+layer);
+                       var o:DisplayObject=Sprite(l).getChildAt(t);
+                       if (sublayer!=-1) { o=Sprite(o).getChildAt(sublayer); }
+                       Sprite(o).addChild(s);
+                       sprites.push(s);
+            if ( s is Sprite ) {
+                Sprite(s).mouseEnabled = false;
+                Sprite(s).mouseChildren = false;
+            }
+               }
+               
+               public function removeSprites():void {
+                       while (sprites.length>0) {
+                               var d:DisplayObject=sprites.pop(); d.parent.removeChild(d);
+                       }
+               }
+
+               protected function createListenSprite(hitzone:Sprite):void {
+            if ( listenSprite == null ) {
+                listenSprite = new Sprite();
+                listenSprite.addEventListener(MouseEvent.CLICK, mouseEvent);
+                listenSprite.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
+                listenSprite.addEventListener(MouseEvent.MOUSE_OVER, mouseEvent);
+                listenSprite.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
+                listenSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
+                listenSprite.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
+                listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
+            }
+            listenSprite.hitArea = hitzone;
+            addToLayer(listenSprite, CLICKSPRITE);
+            listenSprite.buttonMode = true;
+            listenSprite.mouseEnabled = true;
+               }
+
+        protected function mouseEvent(event:MouseEvent):void {
+        }
+
+        public function setHighlight(stateType:String, isOn:Boolean):void {
+            if ( isOn && stateClasses[stateType] == null ) {
+                stateClasses[stateType] = true;
+            } else if ( !isOn && stateClasses[stateType] != null ) {
+                delete stateClasses[stateType];
+            }
+        }
+
+       }
+
+}
index 1136f2a..5cec07e 100755 (executable)
@@ -84,8 +84,7 @@ package net.systemeD.halcyon {
                public const TILESPRITE:uint=0;
                public const GPSSPRITE:uint=1;
                public const WAYSPRITE:uint=2;
-               public const POISPRITE:uint=13;
-               public const NAMESPRITE:uint=14;
+               public const NAMESPRITE:uint=13;
                
                // ------------------------------------------------------------------------------------------
                // Map constructor function
@@ -107,11 +106,11 @@ package net.systemeD.halcyon {
                // [layer][0]                   - fill
 
                private function createSprites():void {
-                       tileset=new TileSet(this);                                      // 900913 background
-                       addChild(tileset);                                                      //  |
-                       addChild(new Sprite());                                         // GPS
+                       tileset=new TileSet(this);                                      // 0 - 900913 background
+                       addChild(tileset);                                                      //      |
+                       addChild(new Sprite());                                         // 1 - GPS
 
-                       for (var l:int=0; l<13; l++) {                          // 11 layers (11 is +5, 1 is -5)
+                       for (var l:int=0; l<13; l++) {                          // 11 layers (12 is +5, 2 is -5)
                                var s:Sprite = getHitSprite();          //  |
                                s.addChild(getPaintSprite());                   //      | 0 fill
                                s.addChild(getPaintSprite());                   //      | 1 casing
@@ -125,8 +124,7 @@ package net.systemeD.halcyon {
                                s.addChild(getHitSprite());                         //  | 5 entity hit tests
                                addChild(s);                                                    //  |
                        }
-                       addChild(getPaintSprite());                             // 12 - POIs
-                       addChild(getPaintSprite());                             // 13 - shields and POI names
+                       addChild(getPaintSprite());                             // 13 - name sprite
                }
                
                private function removeSprites():void {
@@ -285,12 +283,23 @@ package net.systemeD.halcyon {
                        pois[node.id].redraw();
         }
 
-        public function setHighlight(entity:Entity, stateType:String, isOn:Boolean):void {
+        public function setHighlight(entity:Entity, settings:Object):void {
+                       var stateType:String;
             if ( entity is Way ) {
                 var wayUI:WayUI = ways[entity.id];
-                if ( wayUI != null )
-                    wayUI.setHighlight(stateType, isOn);
-            }
+                if (wayUI==null) { return; }
+                               for (stateType in settings) {
+                       wayUI.setHighlight(stateType, settings[stateType]);
+                               }
+                               wayUI.redraw();
+            } else if (entity is Node) {
+                               var nodeUI:NodeUI = nodes[entity.id];
+                if (nodeUI==null) { return; }
+                               for (stateType in settings) {
+                       nodeUI.setHighlight(stateType, settings[stateType]);
+                               }
+                               nodeUI.redraw();
+                       }
         }
 
         // Handle mouse events on ways/nodes
index b59c65f..59238ea 100644 (file)
@@ -13,29 +13,19 @@ package net.systemeD.halcyon {
        import net.systemeD.halcyon.styleparser.*;
        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;                                         //  |
+               public var loaded:Boolean=false;
                private var iconname:String='';                         // name of icon
                private var heading:Number=0;                           // heading within way
                private var rotation:Number=0;                          // rotation applied to this POI
-               public var loaded:Boolean=false;
-
-               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) {
+               public function NodeUI(node:Node, map:Map, heading:Number=0) {
+                       super();
                        this.map = map;
                        this.node = node;
-                       this.rotation = rotation;
+                       this.heading = heading;
                        node.addEventListener(Connection.NODE_MOVED, nodeMoved);
                }
                
@@ -44,67 +34,62 @@ package net.systemeD.halcyon {
                }
                
                public function redraw(sl:StyleList=null,forceDraw:Boolean=false):Boolean {
+                       // *** forcedraw can be removed
+
                        var tags:Object = node.getTagsCopy();
-                       tags['_heading']=heading;
-                       // ** apply :hover etc.
+
+                       // special tags
+                       if (!node.hasParentWays) { tags[':poi']='yes'; }
+            for (var stateKey:String in stateClasses) {
+                tags[":"+stateKey] = stateKey;
+            }
+
                        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);
-                       }
+                       removeSprites(); iconname='';
+                       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;
-               }
-               
-               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;
-               }
-               
                private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
                        var r:Boolean=false;    // ** rendered
-                       for (var sublayer:uint=0; sublayer<10; sublayer++) {
+                       var w:Number;
+                       var icon:Sprite;
+                       layer=10;
+                       for (var sublayer:int=10; sublayer>=0; sublayer--) {
 
                                if (sl.pointStyles[sublayer]) {
                                        var s:PointStyle=sl.pointStyles[sublayer];
                                        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]) {
+                                               if (s.icon_image=='square') {
+                                                       // draw square
+                                                       icon=new Sprite();
+                                                       addToLayer(icon,STROKESPRITE,sublayer);
+                                                       w=styleIcon(icon,sl,sublayer);
+                                                       icon.graphics.drawRect(0,0,w,w);
+                                                       addHitSprite(w);
+                                                       updatePosition();
+                                                       iconname='_square';
+
+                                               } else if (s.icon_image=='circle') {
+                                                       // draw circle
+                                                       icon=new Sprite();
+                                                       addToLayer(icon,STROKESPRITE,sublayer);
+                                                       w=styleIcon(icon,sl,sublayer);
+                                                       icon.graphics.drawCircle(w,w,w);
+                                                       addHitSprite(w);
+                                                       updatePosition();
+                                                       iconname='_circle';
+
+                                               } else if (map.ruleset.images[s.icon_image]) {
+                                                       // 'load' icon (actually just from library)
                                                        var loader:Loader = new Loader();
-                                                       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedIcon);
+                                                       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { loadedIcon(e,sublayer); } );
                                                        loader.loadBytes(map.ruleset.images[s.icon_image]);
                                                        iconname=s.icon_image;
                                                }
@@ -122,67 +107,73 @@ package net.systemeD.halcyon {
                                }
 
                                if (a) { 
-                                       var l:DisplayObject=map.getChildAt(map.NAMESPRITE);
-                                       if (!name) { name=new Sprite(); Sprite(l).addChild(name); }
+                                       var name:Sprite=new Sprite();
+                                       addToLayer(name,NAMESPRITE);
                                        t.writeNameLabel(name,a,map.lon2coord(node.lon),map.latp2coord(node.latp));
                                }
                        }
                        return r;
                }
 
-               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, sl:StyleList, sublayer:uint):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) {
+                                       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;
                }
 
-               private function loadedIcon(event:Event):void {
-                       createIcon();
+               private function addHitSprite(w:uint):void {
+            var hitzone:Sprite = 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);
+               }
+
+               private function loadedIcon(event:Event,sublayer:uint):void {
+                       var icon:Sprite=new Sprite();
+                       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 mouseEvent(event:MouseEvent):void {
+        override protected function mouseEvent(event:MouseEvent):void {
                        map.entityMouseEvent(event, node);
         }
 
                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;
-               }
+                       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;
 
+                               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));
+                               d.transform.matrix=m;
+                       }
+               }
        }
 }
index 020d104..5cea2a3 100755 (executable)
@@ -4,46 +4,28 @@ package net.systemeD.halcyon {
        import flash.geom.Matrix;
        import flash.geom.Point;
        import flash.geom.Rectangle;
-       import flash.text.AntiAliasType;
-       import flash.text.GridFitType;
        import flash.text.TextField;
        import flash.text.TextFormat;
        import flash.events.*;
        import net.systemeD.halcyon.styleparser.*;
     import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
 
-       public class WayUI {
-        private var way:Way;
+       public class WayUI extends EntityUI {
 
+        private var way:Way;
                public var pathlength:Number;                           // length of path
                public var patharea:Number;                                     // area of path
                public var centroid_x:Number;                           // centroid
                public var centroid_y:Number;                           //  |
-               public var layer:int=0;                                         // map layer
-               public var map:Map;                                                     // reference to parent map
-               public var sprites:Array=new Array();           // instances in display list
                public var heading:Array=new Array();           // angle at each node
-               private var stateClasses:Object = new Object();
         private var hitzone:Sprite;
-        private var listenSprite:Sprite;
-
-               public static const DEFAULT_TEXTFIELD_PARAMS:Object = {
-                       embedFonts: true,
-                       antiAliasType: AntiAliasType.ADVANCED,
-                       gridFitType: GridFitType.NONE
-               };
                public var nameformat:TextFormat;
-               
-               private const FILLSPRITE:uint=0;
-               private const CASINGSPRITE:uint=1;
-               private const STROKESPRITE:uint=2;
-               private const NAMESPRITE:uint=3;
-               private const NODESPRITE:uint=4;
-               private const CLICKSPRITE:uint=5;
 
                private const NODESIZE:uint=6;
 
                public function WayUI(way:Way, map:Map) {
+                       super();
                        this.way = way;
                        this.map = map;
             init();
@@ -131,6 +113,8 @@ package net.systemeD.halcyon {
                // Redraw
 
                public function redraw():void {
+                       removeSprites();
+
             // Copy tags object, and add states
             var tags:Object = way.getTagsCopy();
             for (var stateKey:String in stateClasses) {
@@ -138,11 +122,6 @@ package net.systemeD.halcyon {
             }
                        if (way.isArea()) { tags[':area']='yes'; }
 
-                       // Remove all currently existing sprites
-                       while (sprites.length>0) {
-                               var d:DisplayObject=sprites.pop(); d.parent.removeChild(d);
-                       }
-
                        // Which layer?
                        layer=5;
                        if ( tags['layer'] )
@@ -151,7 +130,7 @@ package net.systemeD.halcyon {
                        // Iterate through each sublayer, drawing any styles on that layer
                        var sl:StyleList=map.ruleset.getStyles(this.way, tags);
                        var drawn:Boolean;
-                       for (var sublayer:uint=0; sublayer<11; sublayer++) {
+                       for (var sublayer:int=10; sublayer>=0; sublayer--) {
                                if (sl.shapeStyles[sublayer]) {
                                        var s:ShapeStyle=sl.shapeStyles[sublayer];
                                        var stroke:Shape, fill:Shape, casing:Shape, roadname:Sprite;
@@ -209,48 +188,29 @@ package net.systemeD.halcyon {
                                // ** ShieldStyle to do
                        }
 
-                       // ** draw icons
-                       // ** this looks like it needs reworking
+                       // Draw icons
+                       // ** there should be huge potential to optimise this - at present we're
+                       //    running getStyles for every node in the way on every redraw
                        var r:Number;
-                       var highlight:Boolean=stateClasses["showNodes"] !=null;
+                       var nodetags:Object;
+                       var highlight:Boolean=stateClasses["showNodes"]; // !=null
                        for (var i:uint = 0; i < way.length; i++) {
                 var node:Node = way.getNode(i);
-                   if (map.pois[node.id]) {
-                                       if (map.pois[node.id].loaded) {
-                                               map.pois[node.id].redraw(null, highlight);
-                                       }
-                               } else if (node.hasTags()) {
-                                       sl=map.ruleset.getStyles(node,node.getTagsHash());
-                                       if (sl.hasStyles()) {
-                                               if (i==0) { r= heading[i]; }
-                                                    else { r=(heading[i]+heading[i-1])/2; }
-                                               map.pois[node.id]=new NodeUI(node,map,r);
-                                               map.pois[node.id].redraw(sl);
-                                               // ** this should be done via the registerPOI/event listener mechanism,
-                                               //    but that needs a bit of reworking so we can pass in a styleList
-                                               //    (otherwise we end up computing the styles twice which is expensive)
-                                       }
-                               } else if (highlight) {
-                                       map.pois[node.id]=new NodeUI(node,map);
-                                       map.pois[node.id].redraw(null, true);
+                               nodetags=node.getTagsCopy();
+                               if (i==0) { nodetags['_heading']= heading[i]; }
+                                    else { nodetags['_heading']=(heading[i]+heading[i-1])/2; }
+                               if (highlight) { nodetags[':selectedway']='yes'; }
+                               sl=map.ruleset.getStyles(node,nodetags);
+                               if (sl.hasStyles()) {
+                                       map.pois[node.id]=new NodeUI(node,map,r);
+                                       map.pois[node.id].redraw(sl);
+                                       // ** this should be done via the registerPOI/event listener mechanism,
+                                       //    but that needs a bit of reworking so we can pass in a styleList
+                                       //    (otherwise we end up computing the styles twice which is expensive)
+                               } else if (map.pois[node.id]) {
+                                       map.pois[node.id].removeSprites();
                                }
                        }
-                       
-//                     // No styles, so add a thin trace
-//                     if (!drawn && map.showall) {
-//                             var def:Sprite = new Sprite();
-//                             def.graphics.lineStyle(0.5, 0x808080, 1, false, "normal");
-//                             solidLine(def.graphics);
-//                             addToLayer(def, STROKESPRITE, 10);
-//                             drawn=true;
-//                     }
-            
-//            if ( stateClasses["showNodes"] != null ) {
-//                var nodes:Sprite = new Sprite();
-//                drawNodes(nodes.graphics);
-//                addToLayer(nodes, NODESPRITE);
-//            }
-
                        if (!drawn) { return; }
                        
             // create a generic "way" hitzone sprite
@@ -259,21 +219,7 @@ package net.systemeD.halcyon {
             solidLine(hitzone.graphics);
             addToLayer(hitzone, CLICKSPRITE);
             hitzone.visible = false;
-
-            if ( listenSprite == null ) {
-                listenSprite = new Sprite();
-                listenSprite.addEventListener(MouseEvent.CLICK, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_OVER, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
-            }
-            listenSprite.hitArea = hitzone;
-            addToLayer(listenSprite, CLICKSPRITE);
-            listenSprite.buttonMode = true;
-            listenSprite.mouseEnabled = true;
+                       createListenSprite(hitzone);
 
                }
                
@@ -440,20 +386,6 @@ package net.systemeD.halcyon {
                        return tf;
                }
                
-               // Add object (stroke/fill/roadname) to layer sprite
-               
-               private function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
-                       var l:DisplayObject=Map(map).getChildAt(map.WAYSPRITE+layer);
-                       var o:DisplayObject=Sprite(l).getChildAt(t);
-                       if (sublayer!=-1) { o=Sprite(o).getChildAt(sublayer); }
-                       Sprite(o).addChild(s);
-                       sprites.push(s);
-            if ( s is Sprite ) {
-                Sprite(s).mouseEnabled = false;
-                Sprite(s).mouseChildren = false;
-            }
-               }
-
                public function getNodeAt(x:Number, y:Number):Node {
                        for (var i:uint = 0; i < way.length; i++) {
                 var node:Node = way.getNode(i);
@@ -466,7 +398,7 @@ package net.systemeD.halcyon {
             return null;
                }
 
-        private function mouseEvent(event:MouseEvent):void {
+        override protected function mouseEvent(event:MouseEvent):void {
             var node:Node = getNodeAt(event.localX, event.localY);
             if ( node == null )
                 map.entityMouseEvent(event, way);
@@ -474,14 +406,5 @@ package net.systemeD.halcyon {
                 map.entityMouseEvent(event, node);
         }
 
-        public function setHighlight(stateType:String, isOn:Boolean):void {
-            if ( isOn && stateClasses[stateType] == null ) {
-                stateClasses[stateType] = true;
-                redraw();
-            } else if ( !isOn && stateClasses[stateType] != null ) {
-                delete stateClasses[stateType];
-                redraw();
-            }
-        }
        }
 }
index 91db022..8e2df5a 100644 (file)
@@ -2,10 +2,12 @@ package net.systemeD.halcyon.styleparser {
 
        import flash.events.*;
        import flash.net.*;
-       import net.systemeD.halcyon.Globals;
        import net.systemeD.halcyon.Map;
        import net.systemeD.halcyon.ImageURLLoader;
     import net.systemeD.halcyon.connection.Entity;
+
+    import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
 //     import bustin.dev.Inspector;
        
        public class RuleSet {
@@ -76,6 +78,7 @@ package net.systemeD.halcyon.styleparser {
                                        else if (style is ShapeStyle  && ShapeStyle(style).fill_image   ) { filename=ShapeStyle(style).fill_image; }
                                        else if (style is ShieldStyle && ShieldStyle(style).shield_image) { filename=ShieldStyle(style).shield_image; }
                                        else { continue; }
+                                       if (filename=='square' || filename=='circle') { continue; }
                                
                                        iconsToLoad++;
                                        var request:URLRequest=new URLRequest(filename);
index 504964c..7183171 100755 (executable)
@@ -31,7 +31,6 @@ package net.systemeD.halcyon.styleparser {
                // Update the current StyleList from this StyleChooser
 
                public function updateStyles(obj:Entity, tags:Object, sl:StyleList):void {
-
                        // Are any of the ruleChains fulfilled?
                        // ** needs to cope with min/max zoom
                        var fulfilled:Boolean=false;
@@ -57,7 +56,7 @@ package net.systemeD.halcyon.styleparser {
                                        continue;
                                }
                                if (a.width) { tags['stroked']='yes'; }
-                               if (a.width || a.fill_color || a.fill_image || a.casing_width) { tags['drawn']='yes'; }
+                               if (a.width || a.fill_color || a.fill_image || a.casing_width || a.icon_image) { tags['drawn']='yes'; }
 
                                r.runEvals(tags);
                                if (a[r.sublayer]) {
index 13c8a43..1955479 100644 (file)
@@ -2,6 +2,7 @@ package net.systemeD.potlatch2.controller {
        import flash.events.*;
     import net.systemeD.potlatch2.EditController;
     import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
 
     public class DragWayNode extends ControllerState {
         private var selectedWay:Way;
@@ -27,16 +28,17 @@ package net.systemeD.potlatch2.controller {
             if (event.type==MouseEvent.MOUSE_UP) {
                                if (dragstate==DRAGGING) {
                                        // mouse-up while dragging, so end drag
-                       return endDrag();
+                       return new SelectedWayNode(selectedWay,draggingNode);
+//                     return endDrag();
                                } else if (event.shiftKey) {
                                        // start new way
                                        var way:Way = controller.connection.createWay({}, [entity, entity]);
                                        return new DrawWay(way, true);
                                } else {
                                        // select node
-                                       // *** haven't done node selection code yet!
+                                       Globals.vars.root.addDebug("- select node from DragWayNode");
                                        dragstate=NOT_DRAGGING;
-                       return new NoSelection();
+                       return new SelectedWayNode(selectedWay,draggingNode);
                                }
 
                        } else if ( event.type == MouseEvent.MOUSE_MOVE) {
@@ -70,10 +72,10 @@ package net.systemeD.potlatch2.controller {
                }
 
         override public function enterState():void {
-            controller.map.setHighlight(selectedWay, "showNodes", true);
+            controller.map.setHighlight(selectedWay, {showNodes: true } );
         }
         override public function exitState():void {
-            controller.map.setHighlight(selectedWay, "showNodes", false);
+            controller.map.setHighlight(selectedWay, {showNodes: false } );
         }
         override public function toString():String {
             return "DragWayNode";
index cdfcc1a..8cbfd2e 100644 (file)
@@ -24,9 +24,9 @@ package net.systemeD.potlatch2.controller {
                                map.dragstate=map.NOT_DRAGGING;
                                return new CreateWay(event);
                        } else if ( event.type == MouseEvent.MOUSE_OVER ) {
-                               controller.map.setHighlight(focus, "hover", true);
+                               controller.map.setHighlight(focus, { hover: true });
                        } else if ( event.type == MouseEvent.MOUSE_OUT ) {
-                               controller.map.setHighlight(focus, "hover", false);
+                               controller.map.setHighlight(focus, { hover: false });
                        } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
                        }
                        return this;
diff --git a/net/systemeD/potlatch2/controller/SelectedPOINode.as b/net/systemeD/potlatch2/controller/SelectedPOINode.as
new file mode 100644 (file)
index 0000000..301cf89
--- /dev/null
@@ -0,0 +1,88 @@
+package net.systemeD.potlatch2.controller {
+       import flash.events.*;
+    import net.systemeD.potlatch2.EditController;
+    import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
+
+       /* **** this is largely unfinished **** */
+
+    public class SelectedPOINode extends ControllerState {
+        protected var selectedNode:Node;
+        protected var initNode:Node;
+        
+        public function SelectedPOINode(node:Node) {
+            initNode = node;
+        }
+        protected function selectNode(node:Node):void {
+            if ( node == selectedNode )
+                return;
+
+            clearSelection();
+            controller.setTagViewer(node);
+            controller.map.setHighlight(node, { selected: true });
+            selectedNode = node;
+            initNode = node;
+        }
+                
+        protected function clearSelection():void {
+            if ( selectedNode != null ) {
+                controller.map.setHighlight(selectedNode, { selected: false });
+                controller.setTagViewer(null);
+                selectedNode = null;
+            }
+        }
+        
+        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
+                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.MOUSE_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
+
+            if ( event.type == MouseEvent.MOUSE_UP ) {
+                               if ( entity is Way ) {
+                    return new SelectedWay(Way(entity));
+                } else if ( focus == null && map.dragstate!=map.DRAGGING ) {
+                    return new NoSelection();
+                               }
+            } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
+//                             if ( entity is Way && focus==selectedWay && event.shiftKey) {
+//                                     // insert node within way (shift-click)
+//                  var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event);
+//                                     d.forceDragStart();
+//                                     return d;
+//                             } else
+                               if ( entity is Node && entity.hasParent(selectedWay) ) {
+                    return new DragWayNode(selectedWay, Node(entity), event);
+                               }
+            }
+
+            return this;
+        }
+
+/*      public function clickOnWay(event:MouseEvent, entity:Entity):ControllerState {
+            if ( entity is Node ) {
+                if ( selectedNode == entity ) {
+                    var i:uint = selectedWay.indexOfNode(selectedNode);
+                    if ( i == 0 )
+                        return new DrawWay(selectedWay, false);
+                    else if ( i == selectedWay.length - 1 )
+                        return new DrawWay(selectedWay, true);
+                } else {
+                    selectNode(entity as Node);
+                }
+            }
+            
+            return this;
+        }
+*/      
+        override public function enterState():void {
+            selectNode(initNode);
+        }
+        override public function exitState():void {
+            clearSelection();
+        }
+
+        override public function toString():String {
+            return "SelectedNode";
+        }
+
+    }
+}
index c535047..9fdf71c 100644 (file)
@@ -6,7 +6,6 @@ package net.systemeD.potlatch2.controller {
 
     public class SelectedWay extends ControllerState {
         protected var selectedWay:Way;
-        protected var selectedNode:Node;
         protected var initWay:Way;
         
         public function SelectedWay(way:Way) {
@@ -19,33 +18,14 @@ package net.systemeD.potlatch2.controller {
 
             clearSelection();
             controller.setTagViewer(way);
-            controller.map.setHighlight(way, "selected", true);
-            controller.map.setHighlight(way, "showNodes", true);
+            controller.map.setHighlight(way, { selected: true, showNodes: true });
             selectedWay = way;
             initWay = way;
         }
 
-        protected function selectNode(node:Node):void {
-            if ( node == selectedNode )
-                return;
-            
-            clearSelectedNode();
-            controller.setTagViewer(node);
-            controller.map.setHighlight(node, "selected", true);
-            selectedNode = node;
-        }
-                
-        protected function clearSelectedNode():void {
-            if ( selectedNode != null ) {
-                controller.map.setHighlight(selectedNode, "selected", false);
-                controller.setTagViewer(selectedWay);
-                selectedNode = null;
-            }
-        }
         protected function clearSelection():void {
             if ( selectedWay != null ) {
-                controller.map.setHighlight(selectedWay, "selected", false);
-                controller.map.setHighlight(selectedWay, "showNodes", false);
+               controller.map.setHighlight(selectedWay, { selected: false, showNodes: false });
                 controller.setTagViewer(null);
                 selectedWay = null;
             }
@@ -61,15 +41,11 @@ package net.systemeD.potlatch2.controller {
                                        Globals.vars.root.addDebug("- start new way");
                     var way:Way = controller.connection.createWay({}, [entity, entity]);
                     return new DrawWay(way, true);
-                               } else if ( entity is Node && entity.hasParent(selectedWay) ) {
-                                       // select node within way
-                                       Globals.vars.root.addDebug("- clicked on place within way");
-                    return clickOnWay(event, entity);
-                } else if ( focus is Way ) {
+                               } else if ( entity is Way ) {
                                        // select way
                                        Globals.vars.root.addDebug("- selected way");
-                    selectWay(focus as Way);
-                } else if ( focus is Node ) {
+                    selectWay(entity as Way);
+                } else if ( entity is Node ) {
                                        // *** select node
                                        Globals.vars.root.addDebug("- selected POI");
                     trace("select poi");
@@ -89,24 +65,8 @@ package net.systemeD.potlatch2.controller {
 
             return this;
         }
-
-        public function clickOnWay(event:MouseEvent, entity:Entity):ControllerState {
-            if ( entity is Node ) {
-                if ( selectedNode == entity ) {
-                    var i:uint = selectedWay.indexOfNode(selectedNode);
-                    if ( i == 0 )
-                        return new DrawWay(selectedWay, false);
-                    else if ( i == selectedWay.length - 1 )
-                        return new DrawWay(selectedWay, true);
-                } else {
-                    selectNode(entity as Node);
-                }
-            }
-            
-            return this;
-        }
         
-        private function addNode(event:MouseEvent):Node {
+        protected function addNode(event:MouseEvent):Node {
             trace("add node");
             var lat:Number = controller.map.coord2lat(event.localY);
             var lon:Number = controller.map.coord2lon(event.localX);
diff --git a/net/systemeD/potlatch2/controller/SelectedWayNode.as b/net/systemeD/potlatch2/controller/SelectedWayNode.as
new file mode 100644 (file)
index 0000000..3525bea
--- /dev/null
@@ -0,0 +1,86 @@
+package net.systemeD.potlatch2.controller {
+       import flash.events.*;
+    import net.systemeD.potlatch2.EditController;
+    import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Globals;
+
+    public class SelectedWayNode extends SelectedWay {
+        protected var selectedNode:Node;
+        protected var initNode:Node;
+        
+        public function SelectedWayNode(way:Way,node:Node) {
+                       Globals.vars.root.addDebug("- SelectedWayNode: constructor");
+                       super (way);
+            initNode = node;
+        }
+        protected function selectNode(way:Way,node:Node):void {
+                       Globals.vars.root.addDebug("- SelectedWayNode: selectNode");
+            if ( way == selectedWay && node == selectedNode )
+                return;
+
+            clearSelection();
+            controller.setTagViewer(node);
+            controller.map.setHighlight(node, { selected: true });
+            controller.map.setHighlight(way, { showNodes: true });
+            selectedWay = way;   initWay  = way;
+            selectedNode = node; initNode = node;
+        }
+                
+        override protected function clearSelection():void {
+            if ( selectedNode != null ) {
+                controller.map.setHighlight(selectedNode, { selected: false });
+               controller.map.setHighlight(selectedWay, { selected: false, showNodes: false });
+                controller.setTagViewer(null);
+                selectedNode = null;
+                               selectedWay = null;
+            }
+        }
+        
+        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
+                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.MOUSE_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
+            var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
+
+            if ( event.type == MouseEvent.MOUSE_UP ) {
+                               if ( entity is Node && event.shiftKey ) {
+                                       // start new way
+                                       Globals.vars.root.addDebug("- SelectedWayNode: start new way");
+                    var way:Way = controller.connection.createWay({}, [entity, entity]);
+                    return new DrawWay(way, true);
+                               } else if ( entity is Node ) {
+                                       // select node within way
+                                       Globals.vars.root.addDebug("- SelectedWayNode: select other node");
+                                       return new SelectedWayNode(selectedWay,Node(entity));
+                } else if ( entity is Way ) {
+                                       // select way
+                                       Globals.vars.root.addDebug("- SelectedWayNode: select way");
+                                       return new SelectedWay(selectedWay);
+                } else if ( focus == null && map.dragstate!=map.DRAGGING ) {
+                                       Globals.vars.root.addDebug("- SelectedWayNode: deselect");
+                    return new NoSelection();
+                               }
+            } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
+                               if ( entity is Way && focus==selectedWay && event.shiftKey) {
+                                       // insert node within way (shift-click)
+                       var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event);
+                                       d.forceDragStart();
+                                       return d;
+                               } else if ( entity is Node && entity.hasParent(selectedWay) ) {
+                                       Globals.vars.root.addDebug("- SelectedWayNode: dragwaynode");
+                    return new DragWayNode(selectedWay, Node(entity), event);
+                               }
+            }
+
+            return this;
+        }
+
+               override public function enterState():void {
+            selectNode(initWay,initNode);
+        }
+
+        override public function toString():String {
+            return "SelectedWayNode";
+        }
+
+    }
+}
index 82545fb..a616bb5 100755 (executable)
@@ -79,7 +79,7 @@
             b.graphics.endFill();
                        _root.addChild(b);
 
-                       // Add Yahoo! background
+/*                     // Add Yahoo! background
                        var yahoo:YahooMap = new YahooMap(); 
                        yahoo.init("f0a.sejV34HnhgIbNSmVHmndXFpijgGeun0fSIMG9428hW_ifF3pYKwbV6r9iaXojl1lU_dakekR", w, h);  
                        yahoo.mapType="satellite";
                                theMap.addEventListener(MapEvent.RESIZE, yahooListener.resizeHandler);
                        }
                        yahoo.addEventListener(YahooMapEvent.MAP_INITIALIZE, yahooListener.yahooInit);
-
+*/
                        // add map
                        theMap=new Map(this.loaderInfo.parameters);
                        theMap.backdrop=b;
 
                        // add debug field
                        var t:TextField=new TextField();
-                       t.width=500; t.height=100; t.border=true;
+                       t.width=500; t.height=150; t.border=true;
                        t.multiline=true;
                        _root.addChild(t);
                        Globals.vars.debug=t;
index bb84087..cd47488 100644 (file)
@@ -64,6 +64,9 @@ way :hover    { z-index: 2; width: 8; color: gray; }
 way :selected { z-index: 2; width: 8; color: yellow; }
 way !:drawn { z-index: 5; width: 0.5; color: gray; }
 
+node :selectedway { z-index: 9; icon-image: square; icon-width: 7; color: red; }
+node !:drawn :poi { z-index: 5; icon-image: circle; icon-width: 4; color: green; casing-color: black; }
+
 /* Descendant selectors provide an easy way to style relations: this example means "any way
    which is part of a relation whose type=route". */
 
index 2a00dc8..2290e74 100644 (file)
@@ -18,7 +18,7 @@ way :area { fill-color: gray; fill-opacity: 0.5; }
 /* A set of fairly standard rules.
    We use z-index to make sure high-priority roads appear above minor ones. */
 
-way[highway=trunk] { z-index: 9; color: green; width: 5; casing-color: black; casing-width: 7; }
+way[highway=trunk] { z-index: 8; color: green; width: 5; casing-color: black; casing-width: 7; }
 way[highway=primary] { z-index: 8; color: red; width: 5; casing-color: black; casing-width: 7; }
 way[highway=secondary] { z-index: 7; color: orange; width: 5; casing-width: 7; text: name; text-color: black; font-size: 9; text-position: line; }
 way[highway=tertiary],way[highway=unclassified] { z-index: 6; color: yellow; width: 5; casing-width: 7; text: name; text-color: black; font-size: 7; text-position: line; }
@@ -59,6 +59,11 @@ way :hover   { z-index: 2; width: 8; color: gray; }
 way :selected { z-index: 2; width: 8; color: yellow; }
 way !:drawn { z-index: 5; width: 0.5; color: gray; }
 
+node :hover                    { z-index: 2;  icon-image: square; icon-width: 10; color: gray; }
+node :selected         { z-index: 2;  icon-image: square; icon-width: 10; color: yellow; }
+node :selectedway      { z-index: 9;  icon-image: square; icon-width: 7;  color: red; }
+node !:drawn :poi      { z-index: 5;  icon-image: circle; icon-width: 4; color: green; casing-color: black; }
+
 /* Descendant selectors provide an easy way to style relations: this example means "any way
    which is part of a relation whose type=route". */