--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 11 Build 196, SVG Export Plug-In . SVG Version: 6.0.0 Build 78) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
+ <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ width="14.999" height="15" viewBox="0 0 14.999 15" overflow="visible" enable-background="new 0 0 14.999 15"
+ xml:space="preserve">
+ <g id="Layer_1">
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="0.774" y1="14.271" x2="14.012" y2="1.034"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="3.174" y1="14.271" x2="14.386" y2="3.061"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="0.774" y1="11.872" x2="12.069" y2="0.577"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="0.774" y1="9.472" x2="9.681" y2="0.565"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="0.774" y1="7.071" x2="7.272" y2="0.573"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="0.774" y1="4.671" x2="4.845" y2="0.601"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="0.774" y1="2.271" x2="2.476" y2="0.569"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="5.574" y1="14.271" x2="14.418" y2="5.428"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="7.975" y1="14.271" x2="14.388" y2="7.858"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="10.374" y1="14.271" x2="14.42" y2="10.225"/>
+ <line fill="none" stroke="#7F7F7F" stroke-width="0.5" x1="12.774" y1="14.271" x2="14.373" y2="12.673"/>
+ <rect x="4.499" y="4.971" fill="#FFFFFF" stroke="#000000" width="7.2" height="6.401"/>
+ <rect x="0.6" y="0.6" fill="none" stroke="#000000" stroke-width="1.2" width="13.8" height="13.799"/>
+ </g>
+</svg>
alpha="{getAlpha('split')}"
toolTip="Split way (X)"
width="28" height="28" y="4" x="66" />
- <s:Button icon="@Embed('../../../embedded/merge.svg')"
+ <s:Button
id="mergeButton"
click='doMerge();'
- enabled="{canDo('merge')}"
- alpha="{getAlpha('merge')}"
toolTip="Merge ways"
width="28" height="28" y="4" x="96" />
public var deleteWay:String = "Delete Way (Shift+Delete)";
public var deleteItem:String = "Delete Item"; // When nothing is selected
+ [Bindable] [Embed(source="../../../embedded/merge.svg" )] private var mergeIcon:Class;
+ [Bindable] [Embed(source="../../../embedded/multipolygon.svg")] private var multipolygonIcon:Class;
+
public function init(controller:EditController):void {
this.controller=controller;
/* check if the toolbox was explictly turned off in a previous session */
dispatchEvent(new Event("updateSkin"));
dispatchEvent(new Event("updateAlpha"));
updateDirectionArrow();
+ updateMergeIcon();
}
private function handleDown(e:Event):void {
case 'circularise': return controller.state.hasSelectedAreas();
case 'split': return (controller.state is SelectedWayNode);
case 'parallelise': return (controller.state is SelectedWay);
- case 'merge': return controller.state.hasAdjoiningWays();
}
return false;
}
}
}
+ private function updateMergeIcon():void {
+ var multi:Object=controller.state.multipolygonMembers();
+ if (multi.outer) {
+ mergeButton.setStyle("icon",multipolygonIcon);
+ mergeButton.alpha=1;
+ mergeButton.enabled=true;
+ } else if (controller.state.hasAdjoiningWays()) {
+ mergeButton.setStyle("icon",mergeIcon);
+ mergeButton.alpha=1;
+ mergeButton.enabled=true;
+ } else {
+ mergeButton.setStyle("icon",mergeIcon);
+ mergeButton.alpha=0.5;
+ mergeButton.enabled=false;
+ }
+ }
+
private function reverseClicked():void {
if(canDo('reverseDirection')) {
doReverseDirection();
}
public function doMerge():void {
- controller.setState(SelectedMultiple(controller.state).mergeWays());
+ var multi:Object=controller.state.multipolygonMembers();
+ if (multi.outer) {
+ controller.setState(SelectedMultiple(controller.state).createMultipolygon());
+ } else {
+ controller.setState(SelectedMultiple(controller.state).mergeWays());
+ }
}
public function doReverseDirection():void {
return false;
}
+ /** Identify the inners and outer from the current selection for making a multipolygon. */
+
+ public function multipolygonMembers():Object {
+ if (_selection.length<2) { return {}; }
+
+ var entity:Entity;
+ var relation:Relation;
+ var outer:Way;
+ var inners:Array=[];
+
+ // If there's an existing outer in the selection, use that
+ for each (entity in selection) {
+ if (!entity is Way) return {};
+ var r:Array=entity.findParentRelationsOfType('multipolygon','outer');
+ if (r.length) { outer=Way(entity); relation=r[0]; }
+ }
+
+ // Otherwise, find the way with the biggest area
+ var largest:Number=0;
+ if (!outer) {
+ for each (entity in selection) {
+ if (!entity is Way) return {};
+ if (!Way(entity).isArea()) return {};
+ var props:Object=layer.wayUIProperties(entity as Way);
+ if (props.patharea>largest) { outer=Way(entity); largest=props.patharea; }
+ }
+ }
+ if (!outer) return {};
+
+ // Identify the inners
+ for each (entity in selection) {
+ if (entity==outer) continue;
+ if (!entity is Way) return {};
+ if (!Way(entity).isArea()) return {};
+ var node:Node=Way(entity).getFirstNode();
+ if (outer.pointWithin(node.lon,node.lat)) inners.push(entity);
+ }
+ if (inners.length==0) return {};
+
+ return { outer: outer,
+ inners: inners,
+ relation: relation }
+ }
+
+
// Selection setters
public function set selection(items:Array):void {
}
override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
- if (event.keyCode==74) return mergeWays(); // 'J'
- if (event.keyCode==75) return createMultipolygon();
+ if (event.keyCode==74) return mergeWays(); // 'J' (join)
+ if (event.keyCode==72) return createMultipolygon(); // 'H' (hole)
var cs:ControllerState = sharedKeyboardEvents(event);
return cs ? cs : this;
}
/** Create multipolygon from selection, or add to existing multipolygon. */
public function createMultipolygon():ControllerState {
- var entity:Entity;
- var relation:Relation;
- var outer:Way;
var inner:Way;
- var inners:Array=[];
-
- // If there's an existing outer in the selection, use that
- for each (entity in selection) {
- if (!entity is Way) continue;
- var r:Array=entity.findParentRelationsOfType('multipolygon','outer');
- if (r.length) { outer=Way(entity); relation=r[0]; }
- }
-
- // Otherwise, find the way with the biggest area
- var largest:Number=0;
- if (!outer) {
- for each (entity in selection) {
- if (!entity is Way) continue;
- if (!Way(entity).isArea()) continue;
- var props:Object=layer.wayUIProperties(entity as Way);
- if (props.patharea>largest) { outer=Way(entity); }
- }
- }
-
- // If we still don't have an outer, then squawk
- if (!outer) {
- controller.dispatchEvent(new AttentionEvent(AttentionEvent.ALERT, null, "No areas selected"));
- return this;
- }
-
- // Identify the inners
- for each (entity in selection) {
- if (entity==outer) continue;
- if (!entity is Way) continue;
- if (!Way(entity).isArea()) continue;
- var node:Node=Way(entity).getFirstNode();
- if (outer.pointWithin(node.lon,node.lat)) inners.push(entity);
- }
- if (inners.length==0) {
- controller.dispatchEvent(new AttentionEvent(AttentionEvent.ALERT, null, "Couldn't identify inner areas"));
+ var multi:Object=multipolygonMembers();
+ if (!multi.outer) {
+ controller.dispatchEvent(new AttentionEvent(AttentionEvent.ALERT, null, "Couldn't make the multipolygon"));
return this;
}
// If relation exists, add any inners that aren't currently present
- if (relation) {
+ if (multi.relation) {
var action:CompositeUndoableAction = new CompositeUndoableAction("Add to multipolygon");
- for each (inner in inners) {
- if (!relation.hasMemberInRole(inner,'inner'))
- relation.appendMember(new RelationMember(inner,'inner'),action.push);
+ for each (inner in multi.inners) {
+ if (!multi.relation.hasMemberInRole(inner,'inner'))
+ multi.relation.appendMember(new RelationMember(inner,'inner'),action.push);
}
MainUndoStack.getGlobalStack().addAction(action);
// Otherwise, create whole new relation
} else {
- var memberlist:Array=[new RelationMember(outer,'outer')];
- for each (inner in inners)
+ var memberlist:Array=[new RelationMember(multi.outer,'outer')];
+ for each (inner in multi.inners)
memberlist.push(new RelationMember(inner,'inner'));
- relation = entity.connection.createRelation( { type: 'multipolygon' }, memberlist, MainUndoStack.getGlobalStack().addAction);
+ layer.connection.createRelation( { type: 'multipolygon' }, memberlist, MainUndoStack.getGlobalStack().addAction);
}
- return new SelectedWay(outer);
+ return new SelectedWay(multi.outer);
}
-
+
override public function enterState():void {
selection=initSelection.concat();
for each (var entity:Entity in selection) {