refactoring and some bugfixes
[potlatch2.git] / net / systemeD / potlatch2 / controller / DragWayNode.as
1 package net.systemeD.potlatch2.controller {
2         import flash.events.*;
3     import net.systemeD.potlatch2.EditController;
4     import net.systemeD.halcyon.connection.*;
5         import net.systemeD.halcyon.Globals;
6         import net.systemeD.halcyon.WayUI;
7
8     public class DragWayNode extends ControllerState {
9         private var draggingNode:Node;
10                 private var draggingIndex:int;
11         private var isDraggingStarted:Boolean = false;
12                 private var isNew:Boolean = false;
13
14         private var downX:Number;
15         private var downY:Number;
16                 private var originalLat:Number;
17                 private var originalLon:Number;
18                 private var dragstate:uint=NOT_MOVED;
19                 private const NOT_DRAGGING:uint=0;
20                 private const NOT_MOVED:uint=1;
21                 private const DRAGGING:uint=2;
22                 
23                 private var parentWay:Way;
24                 private var initEvent:MouseEvent;
25         
26         public function DragWayNode(way:Way, index:int, event:MouseEvent, newNode:Boolean) {
27                         parentWay=way;
28                         draggingIndex=index;
29             downX = event.localX;
30             downY = event.localY;
31                         isNew = newNode;
32                         initEvent=event;
33                         // the rest of the init will be done during enterState, because we need the controller to be initialised
34         }
35
36         private function addNode(selectedWay:Way,event:MouseEvent):int {
37                         // find which other ways are under the mouse
38                         var ways:Array=[]; var w:Way;
39                         for each (var wayui:WayUI in controller.map.paint.wayuis) {
40                                 w=wayui.hitTest(event.stageX, event.stageY);
41                                 if (w && w!=selectedWay) { ways.push(w); }
42                         }
43
44             var lat:Number = controller.map.coord2lat(event.localY);
45             var lon:Number = controller.map.coord2lon(event.localX);
46             var undo:CompositeUndoableAction = new CompositeUndoableAction("Insert node");
47             var node:Node = controller.connection.createNode({}, lat, lon, undo.push);
48             var index:int = selectedWay.insertNodeAtClosestPosition(node, true, undo.push);
49                         for each (w in ways) { w.insertNodeAtClosestPosition(node, true, undo.push); }
50             MainUndoStack.getGlobalStack().addAction(undo);
51                         return index;
52         }
53
54  
55        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
56
57             if (event.type==MouseEvent.MOUSE_UP) {
58                                 if (dragstate==DRAGGING) {
59                                         // mouse-up while dragging, so end drag
60                         return new SelectedWayNode(parentWay,draggingIndex);
61                                 } else if (event.shiftKey && !isNew) {
62                                         // start new way
63                                         var way:Way = controller.connection.createWay({}, [entity],
64                                             MainUndoStack.getGlobalStack().addAction);
65                                         return new DrawWay(way, true, false);
66                                 } else if (event.shiftKey && isNew) {
67                         return new SelectedWayNode(parentWay,draggingIndex);
68                                 } else {
69                                         // select node
70                                         dragstate=NOT_DRAGGING;
71                         return SelectedWayNode.selectOrEdit(parentWay, draggingIndex);
72                                 }
73
74                         } else if ( event.type == MouseEvent.MOUSE_MOVE) {
75                                 // dragging
76                                 if (dragstate==NOT_DRAGGING) {
77                                         return this;
78                                 } else if (dragstate==NOT_MOVED && Math.abs(downX - event.localX) < 3 && Math.abs(downY - event.localY) < 3) {
79                                         return this;
80                                 }
81                                 dragstate=DRAGGING;
82                 return dragTo(event);
83
84                         } else {
85                                 // event not handled
86                 return this;
87                         }
88         }
89
90                 override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
91                         if (event.keyCode==27) {
92                                 draggingNode.setLatLon( originalLat, originalLon, MainUndoStack.getGlobalStack().addAction );
93                 return new SelectedWayNode(parentWay,draggingIndex);
94                         }
95                         return this;
96                 }
97
98         private function dragTo(event:MouseEvent):ControllerState {
99                         draggingNode.setLatLon( controller.map.coord2lat(event.localY),
100                                     controller.map.coord2lon(event.localX),
101                                     MainUndoStack.getGlobalStack().addAction );
102             return this;
103         }
104         
105                 public function forceDragStart():void {
106                         dragstate=NOT_MOVED;
107                 }
108                 
109                 override public function get selectedWay():Way {
110                         return parentWay;
111                 }
112
113         override public function enterState():void {
114                         if (isNew && draggingIndex==-1) { draggingIndex=addNode(parentWay,initEvent); }
115             draggingNode = parentWay.getNode(draggingIndex);
116                         originalLat = draggingNode.lat;
117                         originalLon = draggingNode.lon;
118
119                         controller.map.setHighlightOnNodes(parentWay, { selectedway: true } );
120                         controller.map.setHighlight(draggingNode, { selected: true } );
121                         Globals.vars.root.addDebug("**** -> "+this);
122         }
123         override public function exitState(newState:ControllerState):void {
124                         controller.map.setHighlightOnNodes(parentWay, { selectedway: false } );
125                         controller.map.setHighlight(draggingNode, { selected: false } );
126                         Globals.vars.root.addDebug("**** <- "+this);
127         }
128         override public function toString():String {
129             return "DragWayNode";
130         }
131     }
132 }