From 9c420a26968b1671087409d70c722fc7199930e8 Mon Sep 17 00:00:00 2001 From: Richard Fairhurst Date: Wed, 15 Jun 2011 23:28:18 +0100 Subject: [PATCH] Unify selection ControllerStates so they can work on either background or editable objects --- net/systemeD/halcyon/Map.as | 8 ++ net/systemeD/halcyon/MapPaint.as | 5 ++ .../actions/RemoveNodeByIndexAction.as | 2 +- net/systemeD/potlatch2/EditController.as | 8 +- .../potlatch2/controller/ControllerState.as | 27 +++--- .../potlatch2/controller/SelectArea.as | 13 ++- .../controller/SelectedBackgroundNode.as | 68 --------------- .../controller/SelectedBackgroundWay.as | 86 ------------------- .../potlatch2/controller/SelectedMultiple.as | 8 +- .../potlatch2/controller/SelectedPOINode.as | 16 ++-- .../potlatch2/controller/SelectedWay.as | 35 +++++--- .../potlatch2/controller/SelectedWayNode.as | 2 +- 12 files changed, 85 insertions(+), 193 deletions(-) delete mode 100644 net/systemeD/potlatch2/controller/SelectedBackgroundNode.as delete mode 100644 net/systemeD/potlatch2/controller/SelectedBackgroundWay.as diff --git a/net/systemeD/halcyon/Map.as b/net/systemeD/halcyon/Map.as index 1377d446..8a45b074 100644 --- a/net/systemeD/halcyon/Map.as +++ b/net/systemeD/halcyon/Map.as @@ -291,6 +291,14 @@ package net.systemeD.halcyon { return editableLayer; } + /** Find which paint object an entity will be displayed on. */ + public function getLayerForEntity(entity:Entity):MapPaint { + for (var i:uint=0; i1) { return new SelectedMultiple(sel); } - else if (sel[0] is Way) { return new SelectedWay(sel[0]); } + var layer:MapPaint=_map.getLayerForEntity(sel[0]); + + if (sel.length>1) { return new SelectedMultiple(sel, layer); } + else if (sel[0] is Way) { return new SelectedWay(sel[0], layer); } else if (sel[0] is Node && Node(sel[0]).hasParentWays) { var way:Way=sel[0].parentWays[0] as Way; return new SelectedWayNode(way, way.indexOfNode(sel[0] as Node)); } else { - return new SelectedPOINode(sel[0] as Node); + return new SelectedPOINode(sel[0] as Node, layer); } } diff --git a/net/systemeD/potlatch2/controller/ControllerState.as b/net/systemeD/potlatch2/controller/ControllerState.as index 3c02e1b4..416216d6 100644 --- a/net/systemeD/potlatch2/controller/ControllerState.as +++ b/net/systemeD/potlatch2/controller/ControllerState.as @@ -108,20 +108,23 @@ package net.systemeD.potlatch2.controller { if ( paint && paint.isBackground ) { if (event.type == MouseEvent.MOUSE_DOWN && ((event.shiftKey && event.ctrlKey) || event.altKey) ) { // alt-click to pull data out of vector background layer - paint.setHighlight(entity, { hover:false, selected: false }); - if (entity is Way) paint.setHighlightOnNodes(Way(entity), { selectedway: false }); - var newEntity:Entity=paint.pullThrough(entity,controller.map.editableLayer); - if (entity is Way ) { return new SelectedWay(newEntity as Way); } - else if (entity is Node) { return new SelectedPOINode(newEntity as Node); } + var newSelection:Array=[]; + if (selection.indexOf(entity)==-1) { selection=[entity]; } + for each (var entity:Entity in selection) { + paint.setHighlight(entity, { hover:false, selected: false }); + if (entity is Way) paint.setHighlightOnNodes(Way(entity), { selectedway: false }); + newSelection.push(paint.pullThrough(entity,controller.map.editableLayer)); + } + return controller.findStateForSelection(newSelection); } else if (!paint.interactive) { return null; } else if (event.type == MouseEvent.MOUSE_DOWN && paint.interactive) { - if (entity is Way ) { return new SelectedBackgroundWay(entity as Way, paint); } - else if (entity is Node ) { return new SelectedBackgroundNode(entity as Node, paint); } + if (entity is Way ) { return new SelectedWay(entity as Way, paint); } + else if (entity is Node ) { if (!entity.hasParentWays) return new SelectedPOINode(entity as Node, paint); } else if (entity is Marker) { return new SelectedMarker(entity as Marker, paint); } - } else if ( event.type == MouseEvent.MOUSE_UP) { + } else if ( event.type == MouseEvent.MOUSE_UP && !event.ctrlKey) { return (this is NoSelection) ? null : new NoSelection(); - } else if ( event.type == MouseEvent.CLICK && focus == null && map.dragstate!=map.DRAGGING) { + } else if ( event.type == MouseEvent.CLICK && focus == null && map.dragstate!=map.DRAGGING && !event.ctrlKey) { return (this is NoSelection) ? null : new NoSelection(); } @@ -139,11 +142,11 @@ package net.systemeD.potlatch2.controller { return new DragSelection(selection, event); } else if (entity) { return new DragSelection([entity], event); - } else if (event.ctrlKey) { - return new SelectArea(event.localX,event.localY); + } else if (event.ctrlKey && !layer.isBackground) { + return new SelectArea(event.localX,event.localY,selection); } - } else if ( (event.type==MouseEvent.CLICK || event.type==MouseEvent.MOUSE_UP) && focus == null && map.dragstate!=map.DRAGGING) { + } else if ( (event.type==MouseEvent.CLICK || event.type==MouseEvent.MOUSE_UP) && focus == null && map.dragstate!=map.DRAGGING && !event.ctrlKey) { return (this is NoSelection) ? null : new NoSelection(); } return null; diff --git a/net/systemeD/potlatch2/controller/SelectArea.as b/net/systemeD/potlatch2/controller/SelectArea.as index 1a0ad60b..b00b944b 100644 --- a/net/systemeD/potlatch2/controller/SelectArea.as +++ b/net/systemeD/potlatch2/controller/SelectArea.as @@ -12,8 +12,11 @@ package net.systemeD.potlatch2.controller { private var endY:Number; private var box:Shape; private const TOLERANCE:uint=4; + private var originalSelection:Array; - public function SelectArea(x:Number,y:Number) { + public function SelectArea(x:Number,y:Number,sel:Array) { + selection = sel.concat(); + originalSelection = sel.concat(); startX=endX=x; startY=endY=y; } @@ -29,7 +32,7 @@ package net.systemeD.potlatch2.controller { var a:Number; if (startX>endX) { a=startX; startX=endX; endX=a; } if (startY>endY) { a=startY; startY=endY; endY=a; } - if (endX-startX1) { return this; } return controller.findStateForSelection(selection); + + } else if ( event.type == MouseEvent.MOUSE_UP && selection.indexOf(focus)>-1 ) { + return this; } var cs:ControllerState = sharedMouseEvents(event, entity); return cs ? cs : this; diff --git a/net/systemeD/potlatch2/controller/SelectedPOINode.as b/net/systemeD/potlatch2/controller/SelectedPOINode.as index 2e6af17c..b3279501 100644 --- a/net/systemeD/potlatch2/controller/SelectedPOINode.as +++ b/net/systemeD/potlatch2/controller/SelectedPOINode.as @@ -1,13 +1,16 @@ package net.systemeD.potlatch2.controller { import flash.events.*; + import flash.display.*; import flash.ui.Keyboard; import net.systemeD.potlatch2.EditController; import net.systemeD.halcyon.connection.*; + import net.systemeD.halcyon.MapPaint; public class SelectedPOINode extends ControllerState { protected var initNode:Node; - public function SelectedPOINode(node:Node) { + public function SelectedPOINode(node:Node, layer:MapPaint=null) { + if (layer) this.layer=layer; initNode = node; } @@ -32,11 +35,14 @@ package net.systemeD.potlatch2.controller { override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState { if (event.type==MouseEvent.MOUSE_MOVE) { return this; } - if (event.type==MouseEvent.MOUSE_DOWN && event.ctrlKey && entity && entity!=firstSelected) { - return new SelectedMultiple([firstSelected,entity]); - } - if (event.type==MouseEvent.MOUSE_DOWN && event.shiftKey && !entity) { + var paint:MapPaint = getMapPaint(DisplayObject(event.target)); + + if (event.type==MouseEvent.MOUSE_DOWN && event.ctrlKey && entity && entity!=firstSelected && paint==layer) { + return new SelectedMultiple([firstSelected,entity],layer); + } else if (event.type==MouseEvent.MOUSE_DOWN && event.shiftKey && !entity && !layer.isBackground) { return new DrawQuadrilateral(firstSelected as Node); + } else if ( event.type == MouseEvent.MOUSE_UP && entity==firstSelected ) { + return this; } var cs:ControllerState = sharedMouseEvents(event, entity); return cs ? cs : this; diff --git a/net/systemeD/potlatch2/controller/SelectedWay.as b/net/systemeD/potlatch2/controller/SelectedWay.as index fd978beb..192e2417 100644 --- a/net/systemeD/potlatch2/controller/SelectedWay.as +++ b/net/systemeD/potlatch2/controller/SelectedWay.as @@ -1,8 +1,10 @@ package net.systemeD.potlatch2.controller { + import flash.display.*; import flash.events.*; import flash.geom.Point; import flash.ui.Keyboard; + import net.systemeD.halcyon.MapPaint; import net.systemeD.halcyon.connection.*; import net.systemeD.potlatch2.tools.Quadrilateralise; import net.systemeD.potlatch2.tools.Simplify; @@ -19,7 +21,8 @@ package net.systemeD.potlatch2.controller { * @param way The way that is now selected. * @param point The location that was clicked. * @param ways An ordered list of ways sharing a node, to make "way cycling" work. */ - public function SelectedWay(way:Way, point:Point=null, ways:Array=null, index:int=0) { + public function SelectedWay(way:Way, layer:MapPaint=null, point:Point=null, ways:Array=null, index:int=0) { + if (layer) this.layer=layer; initWay = way; clicked = point; wayList = ways; @@ -43,20 +46,23 @@ package net.systemeD.potlatch2.controller { /** Behaviour includes: start drawing a new way, insert a node within this way, select an additional way */ override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState { if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.ROLL_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; } + var paint:MapPaint = getMapPaint(DisplayObject(event.target)); var focus:Entity = getTopLevelFocusEntity(entity); - if ( event.type == MouseEvent.MOUSE_UP && entity is Node && event.shiftKey ) { + if ( event.type == MouseEvent.MOUSE_UP && entity is Node && event.shiftKey && !layer.isBackground ) { // start new way var way:Way = entity.connection.createWay({}, [entity], MainUndoStack.getGlobalStack().addAction); return new DrawWay(way, true, false); - } else if ( event.type == MouseEvent.MOUSE_DOWN && entity is Way && focus==firstSelected && event.shiftKey) { + } else if ( event.type == MouseEvent.MOUSE_DOWN && entity is Way && focus==firstSelected && event.shiftKey && !layer.isBackground ) { // insert node within way (shift-click) var d:DragWayNode=new DragWayNode(firstSelected as Way, -1, event, true); d.forceDragStart(); return d; - } else if ( event.type == MouseEvent.MOUSE_DOWN && event.ctrlKey && entity && entity!=firstSelected) { + } else if ( event.type == MouseEvent.MOUSE_DOWN && event.ctrlKey && entity && entity!=firstSelected && paint==layer) { // multiple selection - return new SelectedMultiple([firstSelected,entity]); + return new SelectedMultiple([firstSelected,entity],layer); + } else if ( event.type == MouseEvent.MOUSE_UP && focus==firstSelected ) { + return this; } var cs:ControllerState = sharedMouseEvents(event, entity); return cs ? cs : this; @@ -65,17 +71,20 @@ package net.systemeD.potlatch2.controller { /** Behaviour includes: parallel way, repeat tags, reverse direction, simplify, cycle way selection, delete */ override public function processKeyboardEvent(event:KeyboardEvent):ControllerState { switch (event.keyCode) { - case 80: /* P */ return new SelectedParallelWay(firstSelected as Way); - case 81: /* Q */ Quadrilateralise.quadrilateralise(firstSelected as Way, MainUndoStack.getGlobalStack().addAction); return this; case 82: /* R */ repeatTags(firstSelected); return this; - case 86: /* V */ Way(firstSelected).reverseNodes(MainUndoStack.getGlobalStack().addAction); return this; - case 89: /* Y */ Simplify.simplify(firstSelected as Way, controller.map, true); return this; case 191: /* / */ return cycleWays(); case Keyboard.BACKSPACE: case Keyboard.DELETE: if (event.shiftKey) { return deleteWay(); } break; - case 188: /* , */ return new SelectedWayNode(initWay, initIndex); // allows navigating from one way to another by keyboard - case 190: /* . */ return new SelectedWayNode(initWay, initIndex); // using <, > and / - + } + if (!layer.isBackground) { + switch (event.keyCode) { + case 80: /* P */ return new SelectedParallelWay(firstSelected as Way); + case 81: /* Q */ Quadrilateralise.quadrilateralise(firstSelected as Way, MainUndoStack.getGlobalStack().addAction); return this; + case 86: /* V */ Way(firstSelected).reverseNodes(MainUndoStack.getGlobalStack().addAction); return this; + case 89: /* Y */ Simplify.simplify(firstSelected as Way, controller.map, true); return this; + case 188: /* , */ return new SelectedWayNode(initWay, initIndex); // allows navigating from one way to another by keyboard + case 190: /* . */ return new SelectedWayNode(initWay, initIndex); // using <, > and / + } } var cs:ControllerState = sharedKeyboardEvents(event); return cs ? cs : this; @@ -90,7 +99,7 @@ package net.systemeD.potlatch2.controller { wayList=wayList.slice(1).concat(wayList[0]); // Find the new way's index of the currently "selected" node, to facilitate keyboard navigation var newindex:int = Way(wayList[0]).indexOfNode(initWay.getNode(initIndex)); - return new SelectedWay(wayList[0], clicked, wayList, newindex); + return new SelectedWay(wayList[0], layer, clicked, wayList, newindex); } /** Perform deletion of currently selected way. */ diff --git a/net/systemeD/potlatch2/controller/SelectedWayNode.as b/net/systemeD/potlatch2/controller/SelectedWayNode.as index 03ba21cb..86766c2f 100644 --- a/net/systemeD/potlatch2/controller/SelectedWayNode.as +++ b/net/systemeD/potlatch2/controller/SelectedWayNode.as @@ -97,7 +97,7 @@ package net.systemeD.potlatch2.controller { wayList.splice(wayList.indexOf(parentWay),1); // find index of this node in the newly selected way, to maintain state for keyboard navigation var newindex:int = Way(wayList[0]).indexOfNode(parentWay.getNode(initIndex)); - return new SelectedWay(wayList[0], + return new SelectedWay(wayList[0], layer, new Point(controller.map.lon2coord(Node(firstSelected).lon), controller.map.latp2coord(Node(firstSelected).latp)), wayList.concat(parentWay), -- 2.30.0