1 package net.systemeD.potlatch2.controller {
3 import flash.geom.Point;
4 import flash.ui.Keyboard;
5 import net.systemeD.potlatch2.EditController;
6 import net.systemeD.halcyon.MapPaint;
7 import net.systemeD.halcyon.connection.*;
8 import net.systemeD.halcyon.connection.actions.*;
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;
15 private var downX:Number;
16 private var downY:Number;
17 private var dragstate:uint=NOT_MOVED;
18 private var initialMouseEvent:MouseEvent;
19 private var wayList:Array;
21 private const NOT_DRAGGING:uint=0;
23 /** "Dragging" but hasn't actually moved yet. */
24 private const NOT_MOVED:uint=1;
27 private const DRAGGING:uint=2;
29 /** Start the drag by recording the dragged way, where it started, and when. */
30 public function DragSelection(sel:Array, event:MouseEvent, ways:Array = null) {
31 selection = sel.concat();
35 enterTime = (new Date()).getTime();
36 initialMouseEvent = event;
39 /** Handle dragging and end drag events. Filters out very short or quick drags. */
40 override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
41 if (event.type==MouseEvent.MOUSE_UP) {
42 if (dragstate==DRAGGING) {
43 var undo:CompositeUndoableAction = new CompositeUndoableAction("Move items");
44 var lonDelta:Number = controller.map.coord2lon(downX)-controller.map.coord2lon(event.localX);
45 var latDelta:Number = controller.map.coord2lat(downY)-controller.map.coord2lat(event.localY);
46 var moved:Object = {};
47 for each (var entity:Entity in selection) {
49 var node:Node=Node(entity);
50 node.setLatLon(node.lat-latDelta, node.lon-lonDelta, undo.push);
52 } else if (entity is Way) {
53 undo.push(new MoveWayAction(Way(entity), latDelta, lonDelta, moved));
56 MainUndoStack.getGlobalStack().addAction(undo);
58 return controller.findStateForSelection(selection);
60 } else if ( event.type == MouseEvent.MOUSE_MOVE) {
62 if (dragstate==NOT_DRAGGING) {
64 } else if (dragstate==NOT_MOVED &&
65 ((Math.abs(downX - event.localX) < 3 && Math.abs(downY - event.localY) < 3) ||
66 (new Date().getTime()-enterTime)<300)) {
78 /** Abort dragging if ESC pressed. */
79 override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
80 if (event.keyCode==Keyboard.SPACE) { return cycleAllWays(initialMouseEvent); }
81 if (event.keyCode==Keyboard.ESCAPE) {
82 for each (var entity:Entity in selection) {
83 entity.dispatchEvent(new EntityDraggedEvent(Connection.ENTITY_DRAGGED, entity, 0, 0));
85 return controller.findStateForSelection(selection);
90 private function dragTo(event:MouseEvent):ControllerState {
91 for each (var entity:Entity in selection) {
92 entity.dispatchEvent(new EntityDraggedEvent(Connection.ENTITY_DRAGGED, entity, event.localX-downX, event.localY-downY));
97 public function forceDragStart():void {
101 private function cycleAllWays(event:MouseEvent):ControllerState {
102 trace("cycleAllWays");
103 if (!(downX && downY) || (wayList && wayList.length<2) || selection.length != 1) { return this; }
104 trace("cycleAllWays2");
107 for each (var l:MapPaint in controller.map.getLayers()) {
108 trace("Layer "+l.connection.name);
109 trace(l.findWaysAtPoint(event.stageX, event.stageY).length);
110 wayList = wayList.concat(l.findWaysAtPoint(event.stageX, event.stageY,selection[0]));
113 for each (var way:Way in wayList) {
114 trace(way + "::" + way.connection.name);
116 wayList=wayList.slice(1).concat(wayList[0]);
117 // Find the new way's index of the currently "selected" node, to facilitate keyboard navigation
118 return new DragSelection([wayList[0]], event, wayList);
121 /** Highlight the dragged selection. */
122 override public function enterState():void {
123 for each (var entity:Entity in selection) {
124 layer.setHighlight(entity, { selected: true });
128 /** Un-highlight the dragged selection. */
129 override public function exitState(newState:ControllerState):void {
130 for each (var entity:Entity in selection) {
131 layer.setHighlight(entity, { selected: false });
134 /** "DragSelection" */
135 override public function toString():String {
136 return "DragSelection";