Experimental "create multipolygon" feature.
[potlatch2.git] / net / systemeD / potlatch2 / controller / DragSelection.as
1 package net.systemeD.potlatch2.controller {
2         import flash.events.*;
3         import flash.geom.Point;
4     import flash.ui.Keyboard;
5     import net.systemeD.potlatch2.EditController;
6     import net.systemeD.halcyon.connection.*;
7     import net.systemeD.halcyon.connection.actions.*;
8
9     /** The state of moving a selection around with the mouse. */
10     public class DragSelection extends ControllerState {
11         private var isDraggingStarted:Boolean = false;
12                 private var enterTime:Number;
13
14         private var downX:Number;
15         private var downY:Number;
16                 private var dragstate:uint=NOT_MOVED;
17                 /** Not used? */
18                 private const NOT_DRAGGING:uint=0;
19                 
20                 /** "Dragging" but hasn't actually moved yet. */
21                 private const NOT_MOVED:uint=1;
22                 
23                 /** While moving. */
24                 private const DRAGGING:uint=2;
25         
26         /** Start the drag by recording the dragged way, where it started, and when. */
27         public function DragSelection(sel:Array, event:MouseEvent) {
28             selection = sel.concat();
29             downX = event.localX;
30             downY = event.localY;
31                         enterTime = (new Date()).getTime();
32         }
33  
34        /** Handle dragging and end drag events. Filters out very short or quick drags. */
35        override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
36             if (event.type==MouseEvent.MOUSE_UP) {
37                 if (dragstate==DRAGGING) { 
38                                         var undo:CompositeUndoableAction = new CompositeUndoableAction("Move items");
39                                         var lonDelta:Number = controller.map.coord2lon(downX)-controller.map.coord2lon(event.localX);
40                                         var latDelta:Number = controller.map.coord2lat(downY)-controller.map.coord2lat(event.localY);
41                                         var moved:Object = {};
42                                         for each (var entity:Entity in selection) {
43                                                 if (entity is Node) {
44                                                         var node:Node=Node(entity);
45                                                         node.setLatLon(node.lat-latDelta, node.lon-lonDelta, undo.push);
46                                                         moved[node.id]=true;
47                                                 } else if (entity is Way) {
48                                                         undo.push(new MoveWayAction(Way(entity), latDelta, lonDelta, moved));
49                                                 }
50                                         }
51                                         MainUndoStack.getGlobalStack().addAction(undo);
52                 }
53                                 return controller.findStateForSelection(selection);
54
55                         } else if ( event.type == MouseEvent.MOUSE_MOVE) {
56                                 // dragging
57                                 if (dragstate==NOT_DRAGGING) {
58                                         return this;
59                                 } else if (dragstate==NOT_MOVED && 
60                                                ((Math.abs(downX - event.localX) < 3 && Math.abs(downY - event.localY) < 3) ||
61                                                 (new Date().getTime()-enterTime)<300)) {
62                                         return this;
63                                 }
64                                 dragstate=DRAGGING;
65                 return dragTo(event);
66
67                         } else {
68                                 // event not handled
69                 return this;
70                         }
71         }
72
73                 /** Abort dragging if ESC pressed. */
74                 override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
75                         if (event.keyCode==Keyboard.ESCAPE) {
76                                 for each (var entity:Entity in selection) {
77                                         entity.dispatchEvent(new EntityDraggedEvent(Connection.ENTITY_DRAGGED, entity, 0, 0));
78                                 }
79                                 return controller.findStateForSelection(selection);
80                         }
81                         return this;
82                 }
83
84         private function dragTo(event:MouseEvent):ControllerState {
85                         for each (var entity:Entity in selection) {
86                                 entity.dispatchEvent(new EntityDraggedEvent(Connection.ENTITY_DRAGGED, entity, event.localX-downX, event.localY-downY));
87                         }
88             return this;
89         }
90         
91                 public function forceDragStart():void {
92                         dragstate=NOT_MOVED;
93                 }
94
95         /** Highlight the dragged selection. */
96         override public function enterState():void {
97                         for each (var entity:Entity in selection) {
98                                 layer.setHighlight(entity, { selected: true });
99                         }
100         }
101         
102         /** Un-highlight the dragged selection. */
103         override public function exitState(newState:ControllerState):void {
104                         for each (var entity:Entity in selection) {
105                                 layer.setHighlight(entity, { selected: false });
106                         }
107         }
108         /** "DragSelection" */
109         override public function toString():String {
110             return "DragSelection";
111         }
112
113
114     }
115 }