add undo for creating stuff
[potlatch2.git] / net / systemeD / potlatch2 / controller / SelectedWayNode.as
1 package net.systemeD.potlatch2.controller {
2         import flash.events.*;
3         import flash.ui.Keyboard;
4     import net.systemeD.potlatch2.EditController;
5     import net.systemeD.halcyon.connection.*;
6         import net.systemeD.halcyon.Globals;
7
8     public class SelectedWayNode extends SelectedWay {
9         protected var selectedNode:Node;
10         protected var initNode:Node;
11         
12         public function SelectedWayNode(way:Way,node:Node) {
13                         super (way);
14             initNode = node;
15         }
16  
17         protected function selectNode(way:Way,node:Node):void {
18             if ( way == selectedWay && node == selectedNode )
19                 return;
20
21             clearSelection();
22             controller.setSelectedEntity(node);
23             controller.map.setHighlight(way, { showNodes: true, nodeSelected: node.id });
24             selectedWay = way;   initWay  = way;
25             selectedNode = node; initNode = node;
26         }
27                 
28         override protected function clearSelection():void {
29             if ( selectedNode != null ) {
30                 controller.map.setHighlight(selectedWay, { selected: false, showNodes: false, nodeSelected: null });
31                 controller.setSelectedEntity(null);
32                 selectedNode = null;
33                                 selectedWay = null;
34             }
35         }
36         
37         override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
38                         if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.ROLL_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
39             var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
40
41             if ( event.type == MouseEvent.MOUSE_UP ) {
42                                 if ( entity is Node && event.shiftKey ) {
43                                         // start new way
44                     var way:Way = controller.connection.createWay({}, [entity],
45                         MainUndoStack.getGlobalStack().addAction);
46                     return new DrawWay(way, true, false);
47                                 } else if ( entity is Node && focus == selectedWay ) {
48                                         // select node within way
49                                         return selectOrEdit(selectedWay, Node(entity));
50                 } else if ( entity is Way ) {
51                                         // select way
52                                         return new SelectedWay(Way(entity));
53                 } else if ( focus == null && map.dragstate!=map.DRAGGING ) {
54                     return new NoSelection();
55                                 }
56             } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
57                                 if ( entity is Way && focus==selectedWay && event.shiftKey) {
58                                         // insert node within way (shift-click)
59                         var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event, true);
60                                         d.forceDragStart();
61                                         return d;
62                                 } else if ( entity is Node && entity.hasParent(selectedWay) ) {
63                     return new DragWayNode(selectedWay, Node(entity), event, false);
64                                 } else if ( focus is Node ) {
65                                         return new DragPOINode(entity as Node,event,false);
66                                 }
67             }
68
69             return this;
70         }
71
72                 override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
73                         switch (event.keyCode) {
74                                 case 88:                                        return splitWay();
75                                 case Keyboard.BACKSPACE:        return deleteNode();
76                                 case Keyboard.DELETE:           return deleteNode();
77                         }
78                         return this;
79                 }
80                 
81                 override public function enterState():void {
82             selectNode(initWay,initNode);
83                         Globals.vars.root.addDebug("**** -> "+this);
84         }
85                 override public function exitState():void {
86             clearSelection();
87                         Globals.vars.root.addDebug("**** <- "+this);
88         }
89
90         override public function toString():String {
91             return "SelectedWayNode";
92         }
93
94         public static function selectOrEdit(selectedWay:Way, entity:Node):ControllerState {
95                 var isFirst:Boolean = false;
96                         var isLast:Boolean = false;
97                         isFirst = selectedWay.getNode(0) == entity;
98                         isLast = selectedWay.getNode(selectedWay.length - 1) == entity;
99                         if ( isFirst == isLast )    // both == looped, none == central node 
100                             return new SelectedWayNode(selectedWay, entity);
101                         else
102                             return new DrawWay(selectedWay, isLast, true);
103         }
104
105                 public function splitWay():ControllerState {
106                         // abort if start or end
107                         if (selectedWay.getNode(0                   ) == selectedNode) { return this; }
108                         if (selectedWay.getNode(selectedWay.length-1) == selectedNode) { return this; }
109
110                         // create new way
111                         var newWay:Way = controller.connection.createWay(
112                                 selectedWay.getTagsCopy(), 
113                                 selectedWay.sliceNodes(selectedWay.indexOfNode(selectedNode),selectedWay.length),
114                                 MainUndoStack.getGlobalStack().addAction);
115                         newWay.suspend();
116                         selectedWay.suspend();
117                         selectedWay.deleteNodesFrom(selectedWay.indexOfNode(selectedNode)+1);
118                         
119                         // copy relations
120                         for each (var r:Relation in selectedWay.parentRelations) {
121                                 // ** needs to copy roles as well
122                                 r.appendMember(new RelationMember(newWay, ''));
123                         }
124                         newWay.resume();
125                         selectedWay.resume();
126
127                         return new SelectedWay(selectedWay);
128                 }
129                 
130                 public function deleteNode():ControllerState {
131                         selectedNode.remove(MainUndoStack.getGlobalStack().addAction);
132                         return new SelectedWay(selectedWay);
133                 }
134
135     }
136 }