various click-handling improvements/fixes
authorRichard Fairhurst <richard@systemed.net>
Wed, 18 Nov 2009 02:30:41 +0000 (02:30 +0000)
committerRichard Fairhurst <richard@systemed.net>
Wed, 18 Nov 2009 02:30:41 +0000 (02:30 +0000)
12 files changed:
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/MapEvent.as
net/systemeD/halcyon/WayUI.as
net/systemeD/halcyon/connection/AMFConnection.as
net/systemeD/halcyon/connection/Connection.as
net/systemeD/halcyon/connection/XMLConnection.as
net/systemeD/potlatch2/controller/ControllerState.as
net/systemeD/potlatch2/controller/CreateWay.as
net/systemeD/potlatch2/controller/DragWayNode.as
net/systemeD/potlatch2/controller/DrawWay.as
net/systemeD/potlatch2/controller/NoSelection.as
net/systemeD/potlatch2/controller/SelectedWay.as

index d99d97e..1136f2a 100755 (executable)
@@ -64,11 +64,14 @@ package net.systemeD.halcyon {
                public var mapwidth:uint;                                               // width (Flash pixels)
                public var mapheight:uint;                                              // height (Flash pixels)
 
-               private var dragging:Boolean=false;                             // dragging map?
+               public var dragstate:uint=NOT_DRAGGING;                 // dragging map
                private var lastxmouse:Number;                                  //  |
                private var lastymouse:Number;                                  //  |
-               private var firstxmouse:Number;                                 //  |
-               private var firstymouse:Number;                                 //  |
+               private var downX:Number;                                               //  |
+               private var downY:Number;                                               //  |
+               public const NOT_DRAGGING:uint=0;                               //  |
+               public const NOT_MOVED:uint=1;                                  //  |
+               public const DRAGGING:uint=2;                                   //  |
                
                public var initparams:Object;                                   // object containing 
 
@@ -83,7 +86,7 @@ package net.systemeD.halcyon {
                public const WAYSPRITE:uint=2;
                public const POISPRITE:uint=13;
                public const NAMESPRITE:uint=14;
-
+               
                // ------------------------------------------------------------------------------------------
                // Map constructor function
 
@@ -365,22 +368,29 @@ package net.systemeD.halcyon {
                // Mouse events
                
                public function mouseDownHandler(event:MouseEvent):void {
-                       dragging=true;
-                       lastxmouse=firstxmouse=mouseX;
-                       lastymouse=firstymouse=mouseY;
+                       dragstate=NOT_MOVED;
+                       lastxmouse=downX=mouseX;
+                       lastymouse=downY=mouseY;
                }
         
                public function mouseUpHandler(event:MouseEvent):void {
-                       if (!dragging) { return; }
-                       dragging=false;
-                       updateCoords(x,y);
-                       if (Math.abs(firstxmouse-mouseX)>4 || Math.abs(firstymouse-mouseY)>4) {
+                       if (dragstate==DRAGGING) {
+                               updateCoords(x,y);
                                download();
                        }
+                       dragstate=NOT_DRAGGING;
                }
         
                public function mouseMoveHandler(event:MouseEvent):void {
-                       if (!dragging) { return; }
+                       if (dragstate==NOT_DRAGGING) {
+                               return;
+                       }
+                       
+                       if (dragstate==NOT_MOVED && Math.abs(downX - mouseX) < 3 && Math.abs(downY - mouseY) < 3) {
+                               return;
+                       }
+                       
+                       dragstate=DRAGGING;
                        x+=mouseX-lastxmouse;
                        y+=mouseY-lastymouse;
                        lastxmouse=mouseX; lastymouse=mouseY;
index 15cee92..a6dfb31 100644 (file)
@@ -7,6 +7,7 @@ package net.systemeD.halcyon {
                public static const DOWNLOAD:String = "download";
                public static const RESIZE:String = "resize";
                public static const MOVE:String = "move";
+               public static const CLICK:String = "click";
 
                public var params:Object;
 
index 3d23747..020d104 100755 (executable)
@@ -11,7 +11,6 @@ package net.systemeD.halcyon {
        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;
index 99d8525..5bfe705 100755 (executable)
@@ -43,8 +43,9 @@ package net.systemeD.halcyon.connection {
                        readConnection.call("whichways",new Responder(gotBbox, error),left,bottom,right,top);
                }
                
-               override public function sendEvent(e:*):void {
-                       eventTarget.addEvent(e);
+               override public function sendEvent(e:*,queue:Boolean):void {
+                       if (queue) { eventTarget.addEvent(e); }
+                             else { dispatchEvent(e); }
                }
 
         private function gotBbox(r:Object):void {
@@ -100,7 +101,7 @@ package net.systemeD.halcyon.connection {
                     var lon:Number = Number(p[1]);
                     var tags:Object = p[3];
                     node = new Node(id, version, tags, true, lat, lon);
-                    setNode(node);
+                    setNode(node,true);
                 }
                 registerPOI(node);
                        }
@@ -148,7 +149,7 @@ package net.systemeD.halcyon.connection {
                 } else if (!node.loaded) {
                                        node.update(nodeVersion, nodeTags, true, lat, lon);
                                }
-                setNode(node);
+                setNode(node,true);
                 nodes.push(node);
                        }
 
@@ -157,7 +158,7 @@ package net.systemeD.halcyon.connection {
                        } else {
                                way.update(version, tags, true, nodes);
                        }
-               setWay(way);
+               setWay(way,true);
                        gotRequest(id+"way");
                }
 
@@ -191,15 +192,15 @@ package net.systemeD.halcyon.connection {
                                switch (type) {
                                        case 'Node':
                                                e=getNode(memid);
-                                               if (e==null) { e=new Node(memid,0,{},false,0,0); setNode(Node(e)); }
+                                               if (e==null) { e=new Node(memid,0,{},false,0,0); setNode(Node(e),true); }
                                                break;
                                        case 'Way':
                                                e=getWay(memid);
-                                               if (e==null) { e=new Way(memid,0,{},false,[]); setWay(Way(e)); }
+                                               if (e==null) { e=new Way(memid,0,{},false,[]); setWay(Way(e),true); }
                                                break;
                                        case 'Relation':
                                                e=getRelation(memid);
-                                               if (e==null) { e=new Relation(memid,0,{},false,[]); setRelation(Relation(e)); }
+                                               if (e==null) { e=new Relation(memid,0,{},false,[]); setRelation(Relation(e),true); }
                                                break;
                                }
                                members.push(new RelationMember(e,role));
@@ -209,7 +210,7 @@ package net.systemeD.halcyon.connection {
                        } else {
                                relation.update(version,tags,true,members);
                        }
-            setRelation(relation);
+            setRelation(relation,true);
                        gotRequest(id+"rel");
                }
                
index 384afeb..6bed36e 100755 (executable)
@@ -76,19 +76,19 @@ package net.systemeD.halcyon.connection {
             return negativeID--;
         }
 
-        protected function setNode(node:Node):void {
+        protected function setNode(node:Node,queue:Boolean):void {
             nodes[node.id] = node;
-            if (node.loaded) { sendEvent(new EntityEvent(NEW_NODE, node)); }
+            if (node.loaded) { sendEvent(new EntityEvent(NEW_NODE, node),queue); }
         }
 
-        protected function setWay(way:Way):void {
+        protected function setWay(way:Way,queue:Boolean):void {
             ways[way.id] = way;
-            if (way.loaded) { sendEvent(new EntityEvent(NEW_WAY, way)); }
+            if (way.loaded) { sendEvent(new EntityEvent(NEW_WAY, way),queue); }
         }
 
-        protected function setRelation(relation:Relation):void {
+        protected function setRelation(relation:Relation,queue:Boolean):void {
             relations[relation.id] = relation;
-            if (relation.loaded) { sendEvent(new EntityEvent(NEW_RELATION, relation)); }
+            if (relation.loaded) { sendEvent(new EntityEvent(NEW_RELATION, relation),queue); }
         }
 
         protected function renumberNode(oldID:Number, node:Node):void {
@@ -106,14 +106,15 @@ package net.systemeD.halcyon.connection {
             delete relations[oldID];
         }
 
-               public function sendEvent(e:*):void {
+               public function sendEvent(e:*,queue:Boolean):void {
+                       // queue is only used for AMFConnection
                        dispatchEvent(e);
                }
 
         public function registerPOI(node:Node):void {
             if ( pois.indexOf(node) < 0 ) {
                 pois.push(node);
-                sendEvent(new EntityEvent(NEW_POI, node));
+                sendEvent(new EntityEvent(NEW_POI, node),false);
             }
         }
 
@@ -126,7 +127,7 @@ package net.systemeD.halcyon.connection {
 
         protected function setActiveChangeset(changeset:Changeset):void {
             this.changeset = changeset;
-            sendEvent(new EntityEvent(NEW_CHANGESET, changeset));
+            sendEvent(new EntityEvent(NEW_CHANGESET, changeset),false);
         }
         
         public function getNode(id:Number):Node {
@@ -143,19 +144,19 @@ package net.systemeD.halcyon.connection {
 
         public function createNode(tags:Object, lat:Number, lon:Number):Node {
             var node:Node = new Node(nextNegative, 0, tags, true, lat, lon);
-            setNode(node);
+            setNode(node,false);
             return node;
         }
 
         public function createWay(tags:Object, nodes:Array):Way {
             var way:Way = new Way(nextNegative, 0, tags, true, nodes.concat());
-            setWay(way);
+            setWay(way,false);
             return way;
         }
 
         public function createRelation(tags:Object, members:Array):Relation {
             var relation:Relation = new Relation(nextNegative, 0, tags, true, members.concat());
-            setRelation(relation);
+            setRelation(relation,false);
             return relation;
         }
 
index 5e46b82..dbe9fdb 100644 (file)
@@ -60,7 +60,7 @@ package net.systemeD.halcyon.connection {
                     var lat:Number = Number(nodeData.@lat);
                     var lon:Number = Number(nodeData.@lon);
                     tags = parseTags(nodeData.tag);
-                    setNode(new Node(id, version, tags, true, lat, lon));
+                    setNode(new Node(id, version, tags, true, lat, lon),false);
                 }
             }
 
@@ -74,7 +74,7 @@ package net.systemeD.halcyon.connection {
                     for each(var nd:XML in data.nd)
                         nodes.push(getNode(Number(nd.@ref)));
                     tags = parseTags(data.tag);
-                    setWay(new Way(id, version, tags,true,  nodes));
+                    setWay(new Way(id, version, tags,true,  nodes),false);
                 }
             }
             
index fa1b0d5..7d6c5ca 100644 (file)
@@ -1,5 +1,6 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
+    import net.systemeD.halcyon.Map;
     import net.systemeD.halcyon.connection.*;
     import net.systemeD.potlatch2.EditController;
 
@@ -26,9 +27,17 @@ package net.systemeD.potlatch2.controller {
         public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
             return this;
         }
-        
+
+               public function get map():Map {
+                       return controller.map;
+               }
+
         public function enterState():void {}
         public function exitState():void {}
 
+               public function toString():String {
+                       return "(No state)";
+               }
+
     }
 }
index ccc43bc..91862e2 100644 (file)
@@ -60,5 +60,9 @@ package net.systemeD.potlatch2.controller {
             elastic.removeSprites();
             elastic = null;
         }
+
+        override public function toString():String {
+            return "CreateWay";
+        }
     }
 }
index fc0b0a8..13c8a43 100644 (file)
@@ -2,49 +2,59 @@ 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;
         private var draggingNode:Node;
         private var isDraggingStarted:Boolean = false;
+
         private var downX:Number;
         private var downY:Number;
+               private var dragstate:uint=NOT_MOVED;
+               private const NOT_DRAGGING:uint=0;
+               private const NOT_MOVED:uint=1;
+               private const DRAGGING:uint=2;
         
-        public function DragWayNode(way:Way, node:Node, mouseDown:MouseEvent) {
+        public function DragWayNode(way:Way, node:Node, event:MouseEvent) {
             selectedWay = way;
             draggingNode = node;
-            downX = mouseDown.localX;
-            downY = mouseDown.localY;
+            downX = event.localX;
+            downY = event.localY;
         }
  
-        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
-            if ( event.type == MouseEvent.MOUSE_UP ) {
-                               Globals.vars.root.addDebug("dragwaynode - mouse-up");
-                return endDrag();
-                       }
-            
-            if ( !isDragging(event) ) {
-                               Globals.vars.root.addDebug("dragwaynode - not dragging");
-                return this;
-                       }
+       override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
+
+            if (event.type==MouseEvent.MOUSE_UP) {
+                               if (dragstate==DRAGGING) {
+                                       // mouse-up while dragging, so end drag
+                       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!
+                                       dragstate=NOT_DRAGGING;
+                       return new NoSelection();
+                               }
 
-            if ( event.type == MouseEvent.MOUSE_MOVE ) {
+                       } else if ( event.type == MouseEvent.MOUSE_MOVE) {
+                               // dragging
+                               if (dragstate==NOT_DRAGGING) {
+                                       return this;
+                               } else if (dragstate==NOT_MOVED && Math.abs(downX - event.localX) < 3 && Math.abs(downY - event.localY) < 3) {
+                                       return this;
+                               }
+                               dragstate=DRAGGING;
                 return dragTo(event);
+
                        } else {
+                               // event not handled
                 return this;
                        }
         }
 
-        private function isDragging(event:MouseEvent):Boolean {
-            if ( isDraggingStarted )
-                return true;
-            
-            isDraggingStarted = Math.abs(downX - event.localX) > 3 ||
-                                Math.abs(downY - event.localY) > 3;
-            return isDraggingStarted;
-        }
-        
         private function endDrag():ControllerState {
             return previousState;
         }
@@ -55,11 +65,18 @@ package net.systemeD.potlatch2.controller {
             return this;
         }
         
+               public function forceDragStart():void {
+                       dragstate=NOT_MOVED;
+               }
+
         override public function enterState():void {
             controller.map.setHighlight(selectedWay, "showNodes", true);
         }
         override public function exitState():void {
             controller.map.setHighlight(selectedWay, "showNodes", false);
         }
+        override public function toString():String {
+            return "DragWayNode";
+        }
     }
 }
index 4c1a412..f5da8ce 100644 (file)
@@ -1,83 +1,85 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
        import flash.geom.*;
-    import net.systemeD.potlatch2.EditController;
-    import net.systemeD.halcyon.connection.*;
-    import net.systemeD.halcyon.Elastic;
+       import net.systemeD.potlatch2.EditController;
+       import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Elastic;
 
-    public class DrawWay extends SelectedWay {
-        private var elastic:Elastic;
-        private var editEnd:Boolean;
-        
-        public function DrawWay(way:Way, editEnd:Boolean) {
-            super(way);
-            
-            this.editEnd = editEnd;
-        }
-        
-        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
-            var mouse:Point;
-            var node:Node;
-            var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
-            if ( event.type == MouseEvent.CLICK ) {
-                if ( focus == null ) {
-                    node = createAndAddNode(event);
-                    resetElastic(node);
-                } else if ( focus is Node ) {
-                    appendNode(focus as Node);
-                } else if ( focus is Way ) {
-                    node = createAndAddNode(event);
-                    Way(focus).insertNodeAtClosestPosition(node, true);
-                    resetElastic(node);
-                }
-            } else if ( event.type == MouseEvent.MOUSE_MOVE ) {
-                mouse = new Point(
-                          controller.map.coord2lon(event.localX),
-                          controller.map.coord2latp(event.localY));
-                elastic.end = mouse;
-            }
+       public class DrawWay extends SelectedWay {
+               private var elastic:Elastic;
+               private var editEnd:Boolean;
+               
+               public function DrawWay(way:Way, editEnd:Boolean) {
+                       super(way);
+                       this.editEnd = editEnd;
+               }
+               
+               override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
+                       var mouse:Point;
+                       var node:Node;
+                       var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
+                       if ( event.type == MouseEvent.CLICK ) {
+                               if ( focus == null ) {
+                                       node = createAndAddNode(event);
+                                       resetElastic(node);
+                               } else if ( focus is Node ) {
+                                       appendNode(focus as Node);
+                               } else if ( focus is Way ) {
+                                       node = createAndAddNode(event);
+                                       Way(focus).insertNodeAtClosestPosition(node, true);
+                                       resetElastic(node);
+                               }
+                       } else if ( event.type == MouseEvent.MOUSE_MOVE ) {
+                               mouse = new Point(
+                                                 controller.map.coord2lon(event.localX),
+                                                 controller.map.coord2latp(event.localY));
+                               elastic.end = mouse;
+                       }
 
-            return this;
-        }
-        
-        protected function resetElastic(node:Node):void {
-            var mouse:Point = new Point(node.lon, node.latp);
-            elastic.start = mouse;
-            elastic.end = mouse;
-        }
+                       return this;
+               }
+               
+               protected function resetElastic(node:Node):void {
+                       var mouse:Point = new Point(node.lon, node.latp);
+                       elastic.start = mouse;
+                       elastic.end = mouse;
+               }
 
-        override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
-            if ( event.keyCode == 13 || event.keyCode == 27 )
-                return new SelectedWay(selectedWay);
-            return this;
-        }
+               override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
+                       if ( event.keyCode == 13 || event.keyCode == 27 )
+                               return new SelectedWay(selectedWay);
+                       return this;
+               }
 
-        public function createAndAddNode(event:MouseEvent):Node {
-            var lat:Number = controller.map.coord2lat(event.localY);
-            var lon:Number = controller.map.coord2lon(event.localX);
-            var node:Node = controller.connection.createNode({}, lat, lon);
-            appendNode(node);
-            return node;
-        }
-        
-        protected function appendNode(node:Node):void {
-            if ( editEnd )
-                selectedWay.appendNode(node);
-            else
-                selectedWay.insertNode(0, node);
-        }
-        
-        override public function enterState():void {
-            super.enterState();
-            
-            var node:Node = selectedWay.getNode(editEnd ? selectedWay.length - 1 : 0);
-            var start:Point = new Point(node.lon, node.latp);
-            elastic = new Elastic(controller.map, start, start);
-        }
-        override public function exitState():void {
-            super.exitState();
-            elastic.removeSprites();
-            elastic = null;
-        }
-    }
+               public function createAndAddNode(event:MouseEvent):Node {
+                       var lat:Number = controller.map.coord2lat(event.localY);
+                       var lon:Number = controller.map.coord2lon(event.localX);
+                       var node:Node = controller.connection.createNode({}, lat, lon);
+                       appendNode(node);
+                       return node;
+               }
+               
+               protected function appendNode(node:Node):void {
+                       if ( editEnd )
+                               selectedWay.appendNode(node);
+                       else
+                               selectedWay.insertNode(0, node);
+               }
+               
+               override public function enterState():void {
+                       super.enterState();
+                       
+                       var node:Node = selectedWay.getNode(editEnd ? selectedWay.length - 1 : 0);
+                       var start:Point = new Point(node.lon, node.latp);
+                       elastic = new Elastic(controller.map, start, start);
+               }
+               override public function exitState():void {
+                       super.exitState();
+                       elastic.removeSprites();
+                       elastic = null;
+               }
+               override public function toString():String {
+                       return "DrawWay";
+               }
+       }
 }
index 32e26a8..cdfcc1a 100644 (file)
@@ -1,40 +1,53 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
-    import net.systemeD.potlatch2.EditController;
-    import net.systemeD.halcyon.connection.*;
+       import net.systemeD.potlatch2.EditController;
+       import net.systemeD.halcyon.connection.*;
+       import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.Globals;
 
-    public class NoSelection extends ControllerState {
-        public function NoSelection() {
-        }
+       public class NoSelection extends ControllerState {
+
+               public function NoSelection() {
+               }
  
-        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
-            var focus:Entity = getTopLevelFocusEntity(entity);
-            if ( event.type == MouseEvent.CLICK )
-                if ( focus is Way )
-                    return new SelectedWay(focus as Way);
-                else if ( focus is Node )
-                    trace("select poi");
-                else if ( focus == null )
-                    return new CreateWay(event);
-            else if ( event.type == MouseEvent.MOUSE_OVER )
-                controller.map.setHighlight(focus, "hover", true);
-            else if ( event.type == MouseEvent.MOUSE_OUT )
-                controller.map.setHighlight(focus, "hover", false);
-                
-            return this;
-        }
-        
-        public static function getTopLevelFocusEntity(entity:Entity):Entity {
-            if ( entity is Node ) {
-                for each (var parent:Entity in entity.parentWays) {
-                    return parent;
-                }
-                return entity;
-            } else if ( entity is Way ) {
-                return entity;
-            } else {
-                return null;
-            }
-        }
-    }
+               override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
+                       var focus:Entity = getTopLevelFocusEntity(entity);
+
+                       if ( event.type == MouseEvent.CLICK ) {
+                               if ( focus is Way ) {
+                                       return new SelectedWay(focus as Way);
+                               } else if ( focus is Node ) {
+                                       // *** select node
+                                       Globals.vars.root.addDebug("- selected POI");
+                               }
+                       } else if (event.type==MouseEvent.MOUSE_UP && focus==null && map.dragstate!=map.DRAGGING) {
+                               map.dragstate=map.NOT_DRAGGING;
+                               return new CreateWay(event);
+                       } else if ( event.type == MouseEvent.MOUSE_OVER ) {
+                               controller.map.setHighlight(focus, "hover", true);
+                       } else if ( event.type == MouseEvent.MOUSE_OUT ) {
+                               controller.map.setHighlight(focus, "hover", false);
+                       } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
+                       }
+                       return this;
+               }
+               
+               public static function getTopLevelFocusEntity(entity:Entity):Entity {
+                       if ( entity is Node ) {
+                               for each (var parent:Entity in entity.parentWays) {
+                                       return parent;
+                               }
+                               return entity;
+                       } else if ( entity is Way ) {
+                               return entity;
+                       } else {
+                               return null;
+                       }
+               }
+
+               override public function toString():String {
+                       return "NoSelection";
+               }
+
+       }
 }
index 6dfb25e..c535047 100644 (file)
@@ -53,37 +53,36 @@ package net.systemeD.potlatch2.controller {
         
         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 (entity) {
-                               Globals.vars.root.addDebug("entered SelectedWay pme "+event.type+":"+entity.getType());
-                       } else {
-                               Globals.vars.root.addDebug("entered SelectedWay pme "+event.type+":null");
-                       }
-                       
-            if ( event.type == MouseEvent.CLICK ) {
-                               Globals.vars.root.addDebug("- is click");
+
+            if ( event.type == MouseEvent.MOUSE_UP ) {
                                if ( entity is Node && event.shiftKey ) {
+                                       // start new way
                                        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)) || focus == selectedWay ) {
+                               } 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 ) {
+                                       // select way
                                        Globals.vars.root.addDebug("- selected way");
                     selectWay(focus as Way);
                 } else if ( focus is Node ) {
+                                       // *** select node
                                        Globals.vars.root.addDebug("- selected POI");
                     trace("select poi");
-                } else if ( focus == null ) {
-                                       Globals.vars.root.addDebug("- no selection");
+                } else if ( focus == null && map.dragstate!=map.DRAGGING ) {
                     return new NoSelection();
                                }
             } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
-                               Globals.vars.root.addDebug("- is mousedown");
-                if ( entity is Node && entity.hasParent(selectedWay) ) {
-                                       Globals.vars.root.addDebug("- started dragging");
+                               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);
                                }
             }
@@ -92,31 +91,28 @@ package net.systemeD.potlatch2.controller {
         }
 
         public function clickOnWay(event:MouseEvent, entity:Entity):ControllerState {
-            if ( entity is Way && event.shiftKey ) {
-                addNode(event);
-            } else {
-                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);
-                    }
+            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):void {
+        private function addNode(event:MouseEvent):Node {
             trace("add node");
             var lat:Number = controller.map.coord2lat(event.localY);
             var lon:Number = controller.map.coord2lon(event.localX);
             var node:Node = controller.connection.createNode({}, lat, lon);
             selectedWay.insertNodeAtClosestPosition(node, true);
+                       return node;
         }
         
         override public function enterState():void {
@@ -125,5 +121,10 @@ package net.systemeD.potlatch2.controller {
         override public function exitState():void {
             clearSelection();
         }
+
+        override public function toString():String {
+            return "SelectedWay";
+        }
+
     }
 }