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