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