1 <?xml version="1.0" encoding="utf-8"?>
3 xmlns:fx="http://ns.adobe.com/mxml/2009"
4 xmlns:mx="library://ns.adobe.com/flex/mx"
5 xmlns:s="library://ns.adobe.com/flex/spark"
6 xmlns:potlatch2="net.systemeD.potlatch2.*"
7 height="76" width="129" layout="absolute"
8 styleName="theToolBox">
10 <mx:Image data="@Embed('../../../embedded/close_small.png')"
11 includeInLayout="false" id="toolboxClose" click="toggle();"
16 <s:Button icon="@Embed('../../../embedded/delete.svg')"
18 enabled="{canDo('delete')}"
19 alpha="{getAlpha('delete')}"
20 toolTip="{deleteToolTipText()}"
21 width="28" height="28" y="4" x="6" />
23 <mx:HBox id="reverseButton" width="28" height="28" y="4" x="36" borderStyle="none"
24 horizontalAlign="center" verticalAlign="middle" toolTip="Reverse direction (V)">
25 <mx:ViewStack id="rotateButtonStack" creationPolicy="all">
26 <mx:HBox id="arrowBoxWrapper">
27 <s:NavigatorContent width="28" height="28">
28 <s:Button id="arrow" icon="{Arrow}" width="28" height="28" alpha="{getAlpha('reverseDirection')}" click="reverseClicked();"/>
31 <mx:HBox id="clockwiseBox" horizontalAlign="center" verticalAlign="middle">
32 <s:Button id="clockwise" icon="@Embed('../../../embedded/clockwise.svg')"
33 alpha="{getAlpha('reverseDirection')}"
34 width="28" height="28" click="reverseClicked();" />
36 <mx:HBox id="antiClockwiseBox" horizontalAlign="center" verticalAlign="middle">
37 <s:Button id="anticlockwise" icon="@Embed('../../../embedded/anti-clockwise.svg')"
38 enabled="{canDo('reverseDirection')}"
39 alpha="{getAlpha('reverseDirection')}"
40 width="28" height="28" click="reverseClicked();" />
44 <s:Button icon="@Embed('../../../embedded/cut.svg')"
47 enabled="{canDo('split')}"
48 alpha="{getAlpha('split')}"
49 toolTip="Split way (X)"
50 width="28" height="28" y="4" x="66" />
51 <s:Button icon="@Embed('../../../embedded/merge.svg')"
54 enabled="{canDo('merge')}"
55 alpha="{getAlpha('merge')}"
57 width="28" height="28" y="4" x="96" />
61 <s:Button icon="@Embed('../../../embedded/straighten.svg')"
63 click='doStraighten();'
64 enabled="{canDo('straighten')}"
65 alpha="{getAlpha('straighten')}"
66 toolTip="Straighten way"
67 width="28" height="28" y="34" x="6" />
68 <s:Button icon="@Embed('../../../embedded/circle.svg')"
69 id="circulariseButton"
70 click='doCircularise();'
71 enabled="{canDo('circularise')}"
72 alpha="{getAlpha('circularise')}"
73 toolTip="Make circular"
74 width="28" height="28" y="34" x="36" />
75 <s:Button icon="@Embed('../../../embedded/quadrilateralise.svg')"
76 id="quadrilateraliseButton"
77 click='doQuadrilateralise();'
78 enabled="{canDo('quadrilateralise')}"
79 alpha="{getAlpha('quadrilateralise')}"
80 toolTip="Make right-angled (Q)"
81 width="28" height="28" y="34" x="66" />
82 <s:Button icon="@Embed('../../../embedded/parallel.svg')"
83 id="parralleliseButton"
84 click='doParallelise();'
85 enabled="{canDo('parallelise')}"
86 alpha="{getAlpha('parallelise')}"
87 toolTip="Create parallel way (P)"
88 width="28" height="28" y="34" x="96" />
92 import flash.events.Event;
93 import flash.events.MouseEvent;
94 import net.systemeD.halcyon.connection.*;
95 import net.systemeD.halcyon.connection.actions.*;
96 import net.systemeD.potlatch2.controller.*;
97 import net.systemeD.potlatch2.tools.*;
98 import embedded.*; // for FXG icons
100 private var controller:EditController;
103 public var angle:int=0;
105 public var deleteNode:String = "Delete Node (Delete)";
106 public var deleteArea:String = "Delete Area (Shift+Delete)";
107 public var deleteWay:String = "Delete Way (Shift+Delete)";
108 public var deleteItem:String = "Delete Item"; // When nothing is selected
110 public function init(controller:EditController):void {
111 this.controller=controller;
112 /* check if the toolbox was explictly turned off in a previous session */
113 if( SharedObject.getLocal("user_state").data['toolbox_visible'] == false) {
114 this.visible = false;
118 override protected function createChildren():void {
119 super.createChildren();
120 super.titleBar.addEventListener(MouseEvent.MOUSE_DOWN,handleDown);
123 public function updateSelectionUI():void {
124 dispatchEvent(new Event("updateSkin"));
125 dispatchEvent(new Event("updateAlpha"));
126 updateDirectionArrow();
129 private function handleDown(e:Event):void {
131 stage.addEventListener(MouseEvent.MOUSE_UP,handleUp);
134 private function handleUp(e:Event):void {
136 stage.removeEventListener(MouseEvent.MOUSE_UP,handleUp);
139 public function toggle():void {
140 this.visible=!this.visible;
141 var obj:SharedObject = SharedObject.getLocal("user_state");
142 obj.setProperty("toolbox_visible",this.visible);
146 // --------------------------------------------------------------------------------
147 // Enable/disable toolbox buttons
148 // (ideally we'd use CSS to set alpha in disabled state, but Flex's CSS
149 // capabilities aren't up to it)
151 [Bindable(event="updateSkin")]
152 public function canDo(op:String):Boolean {
153 if (controller.state.selectCount==0) return false;
156 case 'delete': return true;
157 case 'reverseDirection': return controller.state.hasSelectedWays();
158 case 'quadrilateralise': return (controller.state.hasSelectedAreas() || controller.state.hasSelectedWayNodesInAreas());
159 case 'straighten': return controller.state.hasSelectedUnclosedWays();
160 case 'circularise': return controller.state.hasSelectedAreas();
161 case 'split': return (controller.state is SelectedWayNode);
162 case 'parallelise': return (controller.state is SelectedWay);
163 case 'merge': return controller.state.hasAdjoiningWays();
168 [Bindable(event="updateAlpha")]
169 public function getAlpha(op:String):Number {
170 if (canDo(op)) { return 1; }
174 [Bindable(event="updateSkin")]
175 private function deleteToolTipText():String {
176 var entity:Entity=controller.state.firstSelected;
177 if (entity is Node) { return deleteNode; }
178 if (entity is Way && Way(entity).isArea()) { return deleteArea; }
179 if (entity is Way) { return deleteWay; }
180 return deleteItem; // When nothing is selected
183 private function updateDirectionArrow():void {
184 if (controller.state is SelectedWay) {
185 var w:Way = Way(controller.state.firstSelected);
186 if (w) { // not entirely sure why this protection is necessary, but it appears so
188 // so Way.clockwise appears to give wrong results. Patches welcome, I guess, but for now...
189 w.clockwise? rotateButtonStack.selectedChild = antiClockwiseBox : rotateButtonStack.selectedChild = clockwiseBox;
191 rotateButtonStack.selectedChild = arrowBoxWrapper;
192 arrow.iconDisplay.rotation=w.angle;
193 arrow.iconDisplay.smooth=true;
199 private function reverseClicked():void {
200 if(canDo('reverseDirection')) {
201 doReverseDirection();
205 // --------------------------------------------------------------------------------
206 // Individual toolbox actions
208 public function doDelete():void {
209 var undo:CompositeUndoableAction = new CompositeUndoableAction("Delete objects");
210 for each (var entity:Entity in controller.state.selection) {
211 if (entity is Node) { entity.connection.unregisterPOI(Node(entity)); }
212 entity.remove(undo.push);
214 MainUndoStack.getGlobalStack().addAction(undo);
216 if (controller.state is SelectedWayNode) {
217 controller.setState(new SelectedWay(SelectedWayNode(controller.state).selectedWay));
219 controller.setState(new NoSelection());
223 public function doMerge():void {
224 controller.setState(SelectedMultiple(controller.state).mergeWays());
227 public function doReverseDirection():void {
228 var undo:CompositeUndoableAction = new CompositeUndoableAction("Reverse direction of objects");
229 for each (var way:Way in controller.state.selectedWays) {
230 way.reverseNodes(undo.push);
232 MainUndoStack.getGlobalStack().addAction(undo);
235 public function doQuadrilateralise():void {
236 var undo:CompositeUndoableAction = new CompositeUndoableAction("Make objects right-angled");
237 for each (var way:Way in controller.state.selectedWays) {
238 Quadrilateralise.quadrilateralise(way, undo.push);
240 for each (var node:Node in controller.state.selectedNodes) {
241 for each (var parentWay:Way in node.parentWays) {
242 Quadrilateralise.quadrilateralise(parentWay, undo.push);
245 MainUndoStack.getGlobalStack().addAction(undo);
248 public function doStraighten():void {
249 var undo:CompositeUndoableAction = new CompositeUndoableAction("Straighten objects");
250 for each (var way:Way in controller.state.selectedWays) {
251 Straighten.straighten(way, controller.map, undo.push);
253 MainUndoStack.getGlobalStack().addAction(undo);
256 public function doCircularise():void {
257 var undo:CompositeUndoableAction = new CompositeUndoableAction("Make objects circular ");
258 for each (var way:Way in controller.state.selectedWays) {
259 Circularise.circularise(way, controller.map, undo.push);
261 MainUndoStack.getGlobalStack().addAction(undo);
264 public function doSplit():void {
265 if (controller.state is SelectedWayNode) {
266 controller.setState(SelectedWayNode(controller.state).splitWay());
270 public function doParallelise():void {
271 if (controller.state is SelectedWay) {
272 controller.setState(new SelectedParallelWay(Way(controller.state.firstSelected)));