1 <?xml version="1.0" encoding="utf-8"?>
3 xmlns:mx="http://www.adobe.com/2006/mxml"
4 xmlns:potlatch2="net.systemeD.potlatch2.*"
5 height="76" width="129"
6 headerHeight="6" headerColors="[black, gray]"
7 borderThicknessRight="0" borderThicknessLeft="0" borderThicknessBottom="0"
8 paddingLeft="4" paddingTop="4" layout="absolute" >
10 <mx:Image data="@Embed('../../../embedded/close_small.png')"
11 includeInLayout="false" id="toolboxClose" click="toggle();"
16 <mx:Button icon="@Embed('../../../embedded/delete.svg')"
18 enabled="{canDo('delete')}"
19 alpha="{getAlpha('delete')}"
20 toolTip="{deleteToolTipText()}"
21 width="28" height="28" textAlign="left" y="4" x="6" paddingLeft="6" paddingRight="0" />
22 <mx:Button icon="@Embed('../../../embedded/direction.svg')"
23 click='doReverseDirection();'
24 enabled="{canDo('reverseDirection')}"
25 alpha="{getAlpha('reverseDirection')}"
26 toolTip="Reverse direction (V)"
27 width="28" height="28" textAlign="left" y="4" x="36" paddingLeft="8" paddingRight="0" />
28 <mx:Button icon="@Embed('../../../embedded/cut.svg')"
30 enabled="{canDo('split')}"
31 alpha="{getAlpha('split')}"
32 toolTip="Split way (X)"
33 width="28" height="28" textAlign="left" y="4" x="66" paddingLeft="8" paddingRight="0" />
34 <mx:Button icon="@Embed('../../../embedded/merge.svg')"
36 enabled="{canDo('merge')}"
37 alpha="{getAlpha('merge')}"
39 width="28" height="28" textAlign="left" y="4" x="96" paddingLeft="3" paddingRight="0" />
43 <mx:Button icon="@Embed('../../../embedded/straighten.svg')"
44 click='doStraighten();'
45 enabled="{canDo('straighten')}"
46 alpha="{getAlpha('straighten')}"
47 toolTip="Straighten way"
48 width="28" height="28" textAlign="left" y="34" x="6" paddingLeft="5" paddingRight="0" />
49 <mx:Button icon="@Embed('../../../embedded/circle.svg')"
50 click='doCircularise();'
51 enabled="{canDo('circularise')}"
52 alpha="{getAlpha('circularise')}"
53 toolTip="Make circular"
54 width="28" height="28" textAlign="left" y="34" x="36" paddingLeft="4" paddingRight="0" />
55 <mx:Button icon="@Embed('../../../embedded/quadrilateralise.svg')"
56 click='doQuadrilateralise();'
57 enabled="{canDo('quadrilateralise')}"
58 alpha="{getAlpha('quadrilateralise')}"
59 toolTip="Make right-angled"
60 width="28" height="28" textAlign="left" y="34" x="66" paddingLeft="6" paddingRight="0" />
61 <mx:Button icon="@Embed('../../../embedded/parallel.svg')"
62 click='doParallelise();'
63 enabled="{canDo('parallelise')}"
64 alpha="{getAlpha('parallelise')}"
65 toolTip="Create parallel way (P)"
66 width="28" height="28" textAlign="left" y="34" x="96" paddingLeft="8" paddingRight="0" />
70 import flash.events.Event;
71 import flash.events.MouseEvent;
72 import net.systemeD.halcyon.connection.*;
73 import net.systemeD.halcyon.connection.actions.*;
74 import net.systemeD.potlatch2.controller.*;
75 import net.systemeD.potlatch2.tools.*;
77 private var controller:EditController;
79 public function init(controller:EditController):void {
80 this.controller=controller;
81 /* check if the toolbox was explictly turned off in a previous session */
82 if( SharedObject.getLocal("user_state").data['toolbox_visible'] == false) {
87 override protected function createChildren():void {
88 super.createChildren();
89 super.titleBar.addEventListener(MouseEvent.MOUSE_DOWN,handleDown);
90 super.titleBar.addEventListener(MouseEvent.MOUSE_UP,handleUp);
93 public function updateSelectionUI():void {
94 dispatchEvent(new Event("updateSkin"));
95 dispatchEvent(new Event("updateAlpha"));
98 private function handleDown(e:Event):void {
102 private function handleUp(e:Event):void {
106 public function toggle():void {
107 this.visible=!this.visible;
108 var obj:SharedObject = SharedObject.getLocal("user_state");
109 obj.setProperty("toolbox_visible",this.visible);
113 // --------------------------------------------------------------------------------
114 // Enable/disable toolbox buttons
115 // (ideally we'd use CSS to set alpha in disabled state, but Flex's CSS
116 // capabilities aren't up to it)
118 [Bindable(event="updateSkin")]
119 public function canDo(op:String):Boolean {
120 if (controller.state.selectCount==0) return false;
123 case 'delete': return true;
124 case 'reverseDirection': return controller.state.hasSelectedWays();
125 case 'quadrilateralise': return controller.state.hasSelectedAreas();
126 case 'straighten': return controller.state.hasSelectedUnclosedWays();
127 case 'circularise': return controller.state.hasSelectedAreas();
128 case 'split': return (controller.state is SelectedWayNode);
129 case 'parallelise': return (controller.state is SelectedWay);
130 case 'merge': return controller.state.hasAdjoiningWays();
135 [Bindable(event="updateAlpha")]
136 public function getAlpha(op:String):Number {
137 if (canDo(op)) { return 1; }
141 [Bindable(event="updateSkin")]
142 private function deleteToolTipText():String {
143 var entity:Entity=controller.state.firstSelected;
144 if (entity is Node) { return "Delete Node (Delete)"; }
145 if (entity is Way && Way(entity).isArea()) { return "Delete Area (Shift+Delete)"; }
146 if (entity is Way) { return "Delete Way (Shift+Delete)"; }
147 return "Delete Item"; // When nothing is selected
150 // --------------------------------------------------------------------------------
151 // Individual toolbox actions
153 public function doDelete():void {
154 var undo:CompositeUndoableAction = new CompositeUndoableAction("Delete objects");
155 for each (var entity:Entity in controller.state.selection) {
156 if (entity is Node) { controller.connection.unregisterPOI(Node(entity)); }
157 entity.remove(undo.push);
159 MainUndoStack.getGlobalStack().addAction(undo);
161 if (controller.state is SelectedWayNode) {
162 controller.setState(new SelectedWay(SelectedWayNode(controller.state).selectedWay));
164 controller.setState(new NoSelection());
168 public function doMerge():void {
170 var waylist:Array=controller.state.selectedWays;
172 // ** FIXME - we should have one CompositeUndoableAction for the whole caboodle,
173 // but that screws up the execution order and can make the merge not work
174 var undo:CompositeUndoableAction = new CompositeUndoableAction("Merge ways");
175 changed=tryMerge(waylist, undo);
176 MainUndoStack.getGlobalStack().addAction(undo);
177 } while (changed==true);
178 controller.setState(controller.findStateForSelection(waylist));
181 private function tryMerge(waylist:Array, undo:CompositeUndoableAction):Boolean {
182 var way1:Way, way2:Way, del:uint;
183 for (var i:uint=0; i<waylist.length; i++) {
184 for (var j:uint=0; j<waylist.length; j++) {
185 if (waylist[i]!=waylist[j]) {
187 // Preserve positive IDs if we can
188 if (waylist[i].id < waylist[j].id && waylist[i].id >= 0) {
189 way1=waylist[i]; way2=waylist[j]; del=j;
191 way1=waylist[j]; way2=waylist[i]; del=i;
194 // Merge as appropriate
195 if (way1.getNode(0)==way2.getNode(0)) {
196 waylist.splice(del,1);
197 undo.push(new MergeWaysAction(way1,way2,0,0));
199 } else if (way1.getNode(0)==way2.getLastNode()) {
200 waylist.splice(del,1);
201 undo.push(new MergeWaysAction(way1,way2,0,way2.length-1));
203 } else if (way1.getLastNode()==way2.getNode(0)) {
204 waylist.splice(del,1);
205 undo.push(new MergeWaysAction(way1,way2,way1.length-1,0));
207 } else if (way1.getLastNode()==way2.getLastNode()) {
208 waylist.splice(del,1);
209 undo.push(new MergeWaysAction(way1,way2,way1.length-1,way2.length-1));
218 public function doReverseDirection():void {
219 var undo:CompositeUndoableAction = new CompositeUndoableAction("Reverse direction of objects");
220 for each (var way:Way in controller.state.selectedWays) {
221 way.reverseNodes(undo.push);
223 MainUndoStack.getGlobalStack().addAction(undo);
226 public function doQuadrilateralise():void {
227 var undo:CompositeUndoableAction = new CompositeUndoableAction("Make objects right-angled");
228 for each (var way:Way in controller.state.selectedWays) {
229 Quadrilateralise.quadrilateralise(way, undo.push);
231 MainUndoStack.getGlobalStack().addAction(undo);
234 public function doStraighten():void {
235 var undo:CompositeUndoableAction = new CompositeUndoableAction("Straighten objects");
236 for each (var way:Way in controller.state.selectedWays) {
237 Straighten.straighten(way, controller.map, undo.push);
239 MainUndoStack.getGlobalStack().addAction(undo);
242 public function doCircularise():void {
243 var undo:CompositeUndoableAction = new CompositeUndoableAction("Make objects circular ");
244 for each (var way:Way in controller.state.selectedWays) {
245 Circularise.circularise(way, controller.map, undo.push);
247 MainUndoStack.getGlobalStack().addAction(undo);
250 public function doSplit():void {
251 if (controller.state is SelectedWayNode) {
252 controller.setState(SelectedWayNode(controller.state).splitWay());
256 public function doParallelise():void {
257 if (controller.state is SelectedWay) {
258 controller.setState(new SelectedParallelWay(Way(controller.state.firstSelected)));