select and move POI nodes, and a handful of smaller fixes too
[potlatch2.git] / net / systemeD / potlatch2 / controller / DrawWay.as
1 package net.systemeD.potlatch2.controller {
2         import flash.events.*;
3         import flash.geom.*;
4         import net.systemeD.potlatch2.EditController;
5         import net.systemeD.halcyon.connection.*;
6         import net.systemeD.halcyon.Elastic;
7         import net.systemeD.halcyon.Globals;
8
9         public class DrawWay extends SelectedWay {
10                 private var elastic:Elastic;
11                 private var editEnd:Boolean;
12                 private var leaveNodeSelected:Boolean;
13                 private var lastClick:Entity=null;
14                 private var lastClickTime:Date;
15                 
16                 public function DrawWay(way:Way, editEnd:Boolean, leaveNodeSelected:Boolean) {
17                         super(way);
18                         this.editEnd = editEnd;
19                         this.leaveNodeSelected = leaveNodeSelected;
20                 }
21                 
22                 override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
23                         var mouse:Point;
24                         var node:Node;
25                         var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
26
27                         if ( event.type == MouseEvent.MOUSE_UP ) {
28                                 if ( entity == null ) {
29                                         node = createAndAddNode(event);
30                                         resetElastic(node);
31                                         lastClick=node;
32                                 } else if ( entity is Node ) {
33                                         if (entity==lastClick && (new Date().getTime()-lastClickTime.getTime())<1000) {
34                                                 return stopDrawing();
35                                         } else {
36                                                 appendNode(entity as Node);
37                                                 controller.map.setHighlight(focus, { showNodesHover: false });
38                                                 controller.map.setHighlight(selectedWay, { showNodes: true });
39                                                 resetElastic(entity as Node);
40                                                 lastClick=entity;
41                                         }
42                                 } else if ( entity is Way ) {
43                                         node = createAndAddNode(event);
44                                         Way(entity).insertNodeAtClosestPosition(node, true);
45                                         resetElastic(node);
46                                         lastClick=node;
47                                 }
48                                 lastClickTime=new Date();
49                         } else if ( event.type == MouseEvent.MOUSE_MOVE ) {
50                                 mouse = new Point(
51                                                   controller.map.coord2lon(event.localX),
52                                                   controller.map.coord2latp(event.localY));
53                                 elastic.end = mouse;
54                         } else if ( event.type == MouseEvent.MOUSE_OVER && focus!=selectedWay) {
55                                 controller.map.setHighlight(focus, { showNodesHover: true });
56                         } else if ( event.type == MouseEvent.MOUSE_OUT  && focus!=selectedWay) {
57                                 controller.map.setHighlight(focus, { showNodesHover: false });
58                                 controller.map.setHighlight(selectedWay, { showNodes: true });
59                                 // ** this call to setHighlight(selectedWay) is necessary in case the hovered way (blue nodes)
60                                 // shares any nodes with the selected way (red nodes): if they do, they'll be wiped out by the
61                                 // first call.
62                                 // Ultimately we should fix this by referring to 'way :selected nodes' instead of 'nodes :selectedway'.
63                                 // But this will do for now.
64                                 // We could do with an optional way of calling WayUI.redraw to only do the nodes, which would be a
65                                 // useful optimisation.
66                         }
67
68                         return this;
69                 }
70                 
71                 protected function resetElastic(node:Node):void {
72                         var mouse:Point = new Point(node.lon, node.latp);
73                         elastic.start = mouse;
74                         elastic.end = mouse;
75                 }
76
77                 override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
78                         if ( event.keyCode == 13 || event.keyCode == 27 ) { return stopDrawing(); }
79                         return this;
80                 }
81                 
82                 protected function stopDrawing():ControllerState {
83                         if ( selectedWay.length<2) {
84                                 // ** probably needs to call a proper 'delete way' method
85                                 controller.map.setHighlight(selectedWay, { showNodes: false });
86                                 delete controller.map.ways[selectedWay.id];
87                                 return new NoSelection();
88                         } else if ( leaveNodeSelected ) {
89                             return new SelectedWayNode(selectedWay, selectedWay.getNode(editEnd ? selectedWay.length - 1 : 0));
90                         } else {
91                             return new SelectedWay(selectedWay);
92                         }
93                         return this;
94                 }
95
96                 public function createAndAddNode(event:MouseEvent):Node {
97                         var lat:Number = controller.map.coord2lat(event.localY);
98                         var lon:Number = controller.map.coord2lon(event.localX);
99                         var node:Node = controller.connection.createNode({}, lat, lon);
100                         appendNode(node);
101                         return node;
102                 }
103                 
104                 protected function appendNode(node:Node):void {
105                         if ( editEnd )
106                                 selectedWay.appendNode(node);
107                         else
108                                 selectedWay.insertNode(0, node);
109                 }
110                 
111                 override public function enterState():void {
112                         super.enterState();
113                         
114                         var node:Node = selectedWay.getNode(editEnd ? selectedWay.length - 1 : 0);
115                         var start:Point = new Point(node.lon, node.latp);
116                         elastic = new Elastic(controller.map, start, start);
117                         Globals.vars.root.addDebug("**** -> "+this);
118                 }
119                 override public function exitState():void {
120                         super.exitState();
121                         elastic.removeSprites();
122                         elastic = null;
123                         Globals.vars.root.addDebug("**** <- "+this);
124                 }
125                 override public function toString():String {
126                         return "DrawWay";
127                 }
128         }
129 }