== Core geometry ==
* Undo/redo: split
-* Remove node from this way only (will require SelectedWayNode to become aware of currently selected index)
* Bit more work required on relations when splitting ways
* CSS editing
* Toolbox fixes (see comments in file)
* Quick-search on add-relations-to-way dialog (RelationSelectPanel)
-* Bug: when drawing a way, delete should delete the previous node ("unzipping" way)
-* Bug: when way highlighted, then junction node clicked, sometimes other way is selected (lowest osm_id?)
* Bug: when drawing way, escape ends drawing. Should revert to previous way.
* Mouse icon should indicate when a join is being made (blue nodes might not be visible)
* Bug: when joining way to existing, a blue node is shown until mouse moves
} else if ( focus is Node ) {
// select POI node
return new DragPOINode(entity as Node,event,false);
-// } else if ( entity is Node && selectedWay && entity.hasParent(selectedWay) ) {
-// // select node within this way
-// return new DragWayNode(selectedWay, Node(entity), event, false);
+ } else if ( entity is Node && selectedWay && entity.hasParent(selectedWay) ) {
+ // select node within this way
+ return new DragWayNode(selectedWay, getNodeIndex(selectedWay,entity as Node), event, false);
} else if ( entity is Node && focus is Way ) {
// select way node
- return new DragWayNode(focus as Way,entity as Node,event,false);
+ return new DragWayNode(focus as Way, getNodeIndex(focus as Way,entity as Node), event, false);
}
} else if ( event.type == MouseEvent.MOUSE_UP && focus == null && map.dragstate!=map.DRAGGING ) {
return new NoSelection();
return null;
}
+ protected function getNodeIndex(way:Way,node:Node):uint {
+ for (var i:uint=0; i<way.length; i++) {
+ if (way.getNode(i)==node) { return i; }
+ }
+ return null;
+ }
+
}
}
public class DragWayNode extends ControllerState {
private var draggingNode:Node;
+ private var draggingIndex:int;
private var isDraggingStarted:Boolean = false;
private var isNew:Boolean = false;
private const NOT_MOVED:uint=1;
private const DRAGGING:uint=2;
- public function DragWayNode(way:Way, node:Node, event:MouseEvent, newNode:Boolean) {
+ public function DragWayNode(way:Way, index:int, event:MouseEvent, newNode:Boolean) {
selectedWay = way;
- draggingNode = node;
+ draggingIndex = index;
+ draggingNode = way.getNode(index);
downX = event.localX;
downY = event.localY;
isNew = newNode;
if (event.type==MouseEvent.MOUSE_UP) {
if (dragstate==DRAGGING) {
// mouse-up while dragging, so end drag
- return new SelectedWayNode(selectedWay,draggingNode);
+ return new SelectedWayNode(selectedWay,draggingIndex);
// return endDrag();
} else if (event.shiftKey && !isNew) {
// start new way
MainUndoStack.getGlobalStack().addAction);
return new DrawWay(way, true, false);
} else if (event.shiftKey && isNew) {
- return new SelectedWayNode(selectedWay,draggingNode);
+ return new SelectedWayNode(selectedWay,draggingIndex);
} else {
// select node
dragstate=NOT_DRAGGING;
- return SelectedWayNode.selectOrEdit(selectedWay, draggingNode);
+ return SelectedWayNode.selectOrEdit(selectedWay, draggingIndex);
}
} else if ( event.type == MouseEvent.MOUSE_MOVE) {
// delete controller.map.ways[selectedWay.id];
return new NoSelection();
} else if ( leaveNodeSelected ) {
- return new SelectedWayNode(selectedWay, selectedWay.getNode(editEnd ? selectedWay.length - 1 : 0));
+ return new SelectedWayNode(selectedWay, editEnd ? selectedWay.length - 1 : 0);
} else {
return new SelectedWay(selectedWay);
}
// start new way
var way:Way = controller.connection.createWay({}, [entity], MainUndoStack.getGlobalStack().addAction);
return new DrawWay(way, true, false);
- } else if ( event.type == MouseEvent.MOUSE_UP && entity is Way && event.ctrlKey ) {
+ } else if ( event.type == MouseEvent.MOUSE_DOWN && entity is Way && event.ctrlKey ) {
// merge way
- mergeWith(entity as Way);
- return this;
+ return mergeWith(entity as Way);
} else if ( event.type == MouseEvent.MOUSE_DOWN && entity is Way && focus==selectedWay && event.shiftKey) {
// insert node within way (shift-click)
var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event, true);
return this;
}
- protected function addNode(event:MouseEvent):Node {
+ protected function addNode(event:MouseEvent):int {
trace("add node");
var lat:Number = controller.map.coord2lat(event.localY);
var lon:Number = controller.map.coord2lon(event.localX);
var undo:CompositeUndoableAction = new CompositeUndoableAction("Insert node");
var node:Node = controller.connection.createNode({}, lat, lon, undo.push);
- selectedWay.insertNodeAtClosestPosition(node, true, undo.push);
+ var index:int = selectedWay.insertNodeAtClosestPosition(node, true, undo.push);
MainUndoStack.getGlobalStack().addAction(undo);
- return node;
+ return index;
}
- protected function mergeWith(otherWay:Way):Boolean {
+ protected function mergeWith(otherWay:Way):ControllerState {
var way1:Way;
var way2:Way;
if ( selectedWay.id < otherWay.id && selectedWay.id >= 0 ) {
var undo:Function = MainUndoStack.getGlobalStack().addAction;
// find common point
- if (way1 == way2) { return false; }
+ if (way1 == way2) { return this; }
if (way1.getNode(0) ==way2.getNode(0) ) { way1.mergeWith(way2,0,0,undo); }
else if (way1.getNode(0) ==way2.getLastNode()) { way1.mergeWith(way2,0,way2.length-1,undo); }
else if (way1.getLastNode()==way2.getNode(0) ) { way1.mergeWith(way2,way1.length-1,0,undo); }
else if (way1.getLastNode()==way2.getLastNode()) { way1.mergeWith(way2,way1.length-1,way2.length-1,undo); }
- return true;
+ return new SelectedWay(way1);
}
public function deleteWay():ControllerState {
import net.systemeD.halcyon.Globals;
public class SelectedWayNode extends SelectedWay {
- protected var initNode:Node;
+ protected var selectedIndex:int;
+ protected var initIndex:int;
- public function SelectedWayNode(way:Way,node:Node) {
+ public function SelectedWayNode(way:Way,index:int) {
super (way);
- initNode = node;
+ initIndex = index;
}
- protected function selectNode(way:Way,node:Node):void {
+ protected function selectNode(way:Way,index:int):void {
+ var node:Node=way.getNode(index);
if ( way == selectedWay && node == selectedNode )
return;
clearSelection();
controller.setSelectedEntity(node);
controller.map.setHighlight(way, { showNodes: true, nodeSelected: node.id });
- selectedWay = way; initWay = way;
- selectedNode = node; initNode = node;
+ selectedWay = way; initWay = way;
+ selectedIndex = index; initIndex = index;
+ selectedNode = node;
}
override protected function clearSelection():void {
return new DrawWay(way, true, false);
} else if ( event.type == MouseEvent.MOUSE_UP && entity is Node && focus == selectedWay ) {
// select node within way
- return selectOrEdit(selectedWay, Node(entity));
+ return selectOrEdit(selectedWay, getNodeIndex(selectedWay,Node(entity)));
} else if ( event.type == MouseEvent.MOUSE_DOWN && entity is Way && focus==selectedWay && event.shiftKey) {
// insert node within way (shift-click)
var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event, true);
override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
switch (event.keyCode) {
- case 88: return splitWay();
+ case 189: return removeNode(); // '-'
+ case 88: return splitWay(); // 'X'
case Keyboard.BACKSPACE: return deleteNode();
case Keyboard.DELETE: return deleteNode();
}
}
override public function enterState():void {
- selectNode(initWay,initNode);
+ selectNode(initWay,initIndex);
Globals.vars.root.addDebug("**** -> "+this);
}
override public function exitState():void {
return "SelectedWayNode";
}
- public static function selectOrEdit(selectedWay:Way, entity:Node):ControllerState {
+ public static function selectOrEdit(selectedWay:Way, index:int):ControllerState {
var isFirst:Boolean = false;
var isLast:Boolean = false;
- isFirst = selectedWay.getNode(0) == entity;
- isLast = selectedWay.getNode(selectedWay.length - 1) == entity;
+ var node:Node = selectedWay.getNode(index);
+ isFirst = selectedWay.getNode(0) == node;
+ isLast = selectedWay.getNode(selectedWay.length - 1) == node;
if ( isFirst == isLast ) // both == looped, none == central node
- return new SelectedWayNode(selectedWay, entity);
+ return new SelectedWayNode(selectedWay, index);
else
return new DrawWay(selectedWay, isLast, true);
}
return new SelectedWay(selectedWay);
}
+ public function removeNode():ControllerState {
+ if (selectedNode.numParentWays==1) { return deleteNode(); }
+ selectedWay.removeNodeByIndex(selectedIndex, MainUndoStack.getGlobalStack().addAction);
+ return new SelectedWay(selectedWay);
+ }
+
public function deleteNode():ControllerState {
selectedNode.remove(MainUndoStack.getGlobalStack().addAction);
return new SelectedWay(selectedWay);