listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
}
+ protected function removeGenericEventListeners():void {
+ entity.removeEventListener(Connection.TAG_CHANGED, tagChanged);
+ entity.removeEventListener(Connection.ADDED_TO_RELATION, relationAdded);
+ entity.removeEventListener(Connection.REMOVED_FROM_RELATION, relationRemoved);
+ entity.removeEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
+ entity.removeEventListener(Connection.RESUME_REDRAW, resumeRedraw);
+ listenSprite.removeEventListener(MouseEvent.CLICK, mouseEvent);
+ listenSprite.removeEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
+ listenSprite.removeEventListener(MouseEvent.ROLL_OVER, mouseEvent);
+ listenSprite.removeEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
+ listenSprite.removeEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
+ listenSprite.removeEventListener(MouseEvent.MOUSE_UP, mouseEvent);
+ listenSprite.removeEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
+ }
// -----------------------------------------------------------------
// Event listeners
if (paint.wayuis[way.id]) paint.wayuis[way.id].setHighlightOnNodes(settings);
}
- public function setPurgable(entity:Entity, purgable:Boolean):void {
- if ( entity is Way ) {
- var way:Way=entity as Way;
- if (paint.wayuis[way.id]) { paint.wayuis[way.id].purgable=purgable; }
- for (var i:uint=0; i<way.length; i++) {
- if (paint.nodeuis[way.getNode(i).id]) {
- paint.nodeuis[way.getNode(i).id].purgable=purgable;
+ public function setPurgable(entities:Array, purgable:Boolean):void {
+ for each (var entity:Entity in entities) {
+ if ( entity is Way ) {
+ var way:Way=entity as Way;
+ if (paint.wayuis[way.id]) { paint.wayuis[way.id].purgable=purgable; }
+ for (var i:uint=0; i<way.length; i++) {
+ if (paint.nodeuis[way.getNode(i).id]) {
+ paint.nodeuis[way.getNode(i).id].purgable=purgable;
+ }
}
+ } else if ( entity is Node && paint.nodeuis[entity.id]) {
+ paint.nodeuis[entity.id].purgable=purgable;
}
- } else if ( entity is Node && paint.nodeuis[entity.id]) {
- paint.nodeuis[entity.id].purgable=purgable;
}
}
}
public function addDebug(text:String):void {
+ trace(text);
if (!Globals.vars.hasOwnProperty('debug')) return;
if (!Globals.vars.debug.visible) return;
Globals.vars.debug.appendText(text+"\n");
import flash.display.DisplayObject;
import net.systemeD.halcyon.NodeUI;
import net.systemeD.halcyon.WayUI;
- import net.systemeD.halcyon.connection.*;
+ import net.systemeD.halcyon.connection.*;
import net.systemeD.halcyon.styleparser.RuleSet;
import net.systemeD.halcyon.Globals;
- public class MapPaint extends Sprite {
+ public class MapPaint extends Sprite {
public var map:Map;
public var minlayer:int;
public var maxlayer:int;
public var ruleset:RuleSet; // rules
public var wayuis:Object=new Object(); // sprites for ways and (POI/tagged) nodes
- public var nodeuis:Object=new Object(); // |
+ public var nodeuis:Object=new Object(); // |
public var isBackground:Boolean = true; // is it a background layer or the core paint object?
public var sublayerIndex:Object={}; // hash of index->position
private const VERYBIG:Number=Math.pow(2,16);
+ private static const NO_LAYER:int=-99999; // same as NodeUI
// Set up layering
// Add paint sprites
for (l=minlayer; l<=maxlayer; l++) { // each layer (10 is +5, 0 is -5)
- s = getPaintSprite(); // |
+ s = getPaintSprite(); // |
s.addChild(getPaintSprite()); // | 0 fill
s.addChild(getPaintSprite()); // | 1 casing
- var t:Sprite = getPaintSprite(); // | 2 stroke
- t.addChild(getPaintSprite()); // | | sublayer
- s.addChild(t); // | |
+ var t:Sprite = getPaintSprite(); // | 2 stroke
+ t.addChild(getPaintSprite()); // | | sublayer
+ s.addChild(t); // | |
s.addChild(getPaintSprite()); // | 3 names
- addChild(s); // |
+ addChild(s); // |
}
// Add hit sprites
for (l=minlayer; l<=maxlayer; l++) { // each layer (21 is +5, 11 is -5)
- s = getHitSprite(); // |
+ s = getHitSprite(); // |
s.addChild(getHitSprite()); // | 0 way hit tests
- s.addChild(getHitSprite()); // | 1 node hit tests
+ s.addChild(getHitSprite()); // | 1 node hit tests
addChild(s);
}
}
// update index
// (we do it in this rather indirect way because if you alter sublayerIndex directly
- // within the loop, it confuses the iterator)
+ // within the loop, it confuses the iterator)
var toUpdate:Array=[];
for (index in sublayerIndex) {
ix=Number(index);
deleteWayUI(event.entity as Way);
}
- public function createNodeUI(node:Node):NodeUI {
- if (!nodeuis[node.id]) {
- nodeuis[node.id]=new NodeUI(node,this,0);
- } else {
- nodeuis[node.id].redraw();
- }
- return nodeuis[node.id];
- }
-
public function deleteWayUI(way:Way):void {
way.removeEventListener(Connection.WAY_DELETED, wayDeleted);
if (wayuis[way.id]) {
}
}
+ public function createNodeUI(node:Node,rotation:Number=0,layer:int=NO_LAYER,stateClasses:Object=null):NodeUI {
+ if (!nodeuis[node.id]) {
+ nodeuis[node.id]=new NodeUI(node,this,rotation,layer,stateClasses);
+ node.addEventListener(Connection.NODE_DELETED, nodeDeleted);
+ } else {
+ for (var state:String in stateClasses) {
+ nodeuis[node.id].setStateClass(state,stateClasses[state]);
+ }
+ nodeuis[node.id].redraw();
+ }
+ return nodeuis[node.id];
+ }
+
+ public function nodeDeleted(event:EntityEvent):void {
+ deleteNodeUI(event.entity as Node);
+ }
+
public function deleteNodeUI(node:Node):void {
if (!nodeuis[node.id]) { return; }
- if (!nodeuis[node.id].purgable) { return; }
+ node.removeEventListener(Connection.NODE_DELETED, nodeDeleted);
nodeuis[node.id].removeSprites();
+ nodeuis[node.id].removeEventListeners();
delete nodeuis[node.id];
}
delete nodeuis[oldID];
}
- private function getPaintSprite():Sprite {
- var s:Sprite = new Sprite();
- s.mouseEnabled = false;
- s.mouseChildren = false;
- return s;
- }
+ private function getPaintSprite():Sprite {
+ var s:Sprite = new Sprite();
+ s.mouseEnabled = false;
+ s.mouseChildren = false;
+ return s;
+ }
- private function getHitSprite():Sprite {
- var s:Sprite = new Sprite();
- return s;
- }
+ private function getHitSprite():Sprite {
+ var s:Sprite = new Sprite();
+ return s;
+ }
public function redraw():void {
for each (var w:WayUI in wayuis) { w.recalculate(); w.invalidateStyleList(); w.redraw(); }
- /* sometimes (e.g. in Map.setStyle) Mappaint.redrawPOIs() is called immediately afterwards anyway. FIXME? */
+ /* sometimes (e.g. in Map.setStyle) Mappaint.redrawPOIs() is called immediately afterwards anyway. FIXME? */
for each (var p:NodeUI in nodeuis) { p.invalidateStyleList(); p.redraw(); }
}
if (stateClasses[state]) { this.stateClasses[state]=stateClasses[state]; }
}
}
- entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
entity.addEventListener(Connection.NODE_MOVED, nodeMoved);
- entity.addEventListener(Connection.NODE_DELETED, nodeDeleted);
attachRelationListeners();
redraw();
}
- public function nodeMoved(event:Event):void {
- updatePosition();
+ public function removeEventListeners():void {
+ removeGenericEventListeners();
+ entity.removeEventListener(Connection.NODE_MOVED, nodeMoved);
}
- public function nodeDeleted(event:Event):void {
- removeSprites();
+ public function nodeMoved(event:Event):void {
+ updatePosition();
}
override public function doRedraw():Boolean {
}
public function removeEventListeners():void {
+ removeGenericEventListeners();
entity.removeEventListener(Connection.WAY_NODE_ADDED, wayNodeAdded);
entity.removeEventListener(Connection.WAY_NODE_REMOVED, wayNodeRemoved);
entity.removeEventListener(Connection.WAY_REORDERED, wayReordered);
// else { nodetags['_heading']=(heading[i]+heading[i-1])/2; }
// ** FIXME - heading isn't currently applied
nodeStateClasses['junction']=(node.numParentWays>1);
-
- if (paint.nodeuis[node.id]) {
- var nodeui:NodeUI=paint.nodeuis[node.id];
- for (var state:String in nodeStateClasses) {
- nodeui.setStateClass(state,nodeStateClasses[state]);
- }
- nodeui.redraw();
- } else {
- paint.nodeuis[node.id]=new NodeUI(node,paint,r,layer,nodeStateClasses);
- }
+ paint.createNodeUI(node,r,layer,nodeStateClasses);
}
if (!drawn) { return false; }
} else {
markDirty();
}
- node.dispatchEvent(new EntityEvent(Connection.NODE_DELETED, node));
+ node.dispatchEvent(new EntityEvent(Connection.NODE_DELETED, node)); // delete NodeUI
return SUCCESS;
}
} else {
markClean();
}
- entity.dispatchEvent(new EntityEvent(Connection.NEW_NODE, entity));
+ Connection.getConnection().dispatchEvent(new EntityEvent(Connection.NEW_NODE, entity));
if ( effects != null )
effects.undoAction();
return SUCCESS;
oldNodeList = nodeList.slice();
while (nodeList.length > 0) {
node=nodeList.pop();
- way.dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, node, way, 0));
node.removeParent(way);
+ way.dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, node, way, 0));
if (!node.hasParents && !node.hasInterestingTags()) { //need to trigger redraw of new POIs?
node.remove(effects.push);
}
} else {
markDirty();
}
- way.dispatchEvent(new EntityEvent(Connection.WAY_DELETED, way));
+ way.dispatchEvent(new EntityEvent(Connection.WAY_DELETED, way)); // delete WayUI
way.resume();
return SUCCESS;
} else {
markClean();
}
- way.dispatchEvent(new EntityEvent(Connection.NEW_WAY, way));
+ Connection.getConnection().dispatchEvent(new EntityEvent(Connection.NEW_WAY, way));
effects.undoAction();
for each(var node:Node in oldNodeList) {
nodeList.push(node);
+ node.addParent(way);
way.dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_ADDED, node, way, 0));
}
- way.resume();
+ way.resume();
return SUCCESS;
}
}
public function updateSelectionUI():void {
var entity:Entity=state.firstSelected;
tagViewer.setEntity(entity);
- toolbox.setEntity(entity);
+ toolbox.updateSelectionUI();
}
private function keyDownHandler(event:KeyboardEvent):void {
import net.systemeD.potlatch2.controller.*;
import net.systemeD.potlatch2.tools.*;
- private var entity:Entity;
private var controller:EditController;
public function init(controller:EditController):void {
super.titleBar.addEventListener(MouseEvent.MOUSE_UP,handleUp);
}
- public function setEntity(entity:Entity):void {
- this.entity=entity;
+ public function updateSelectionUI():void {
dispatchEvent(new Event("updateSkin"));
dispatchEvent(new Event("updateAlpha"));
}
[Bindable(event="updateSkin")]
public function canDo(op:String):Boolean {
+ if (controller.state.selectCount==0) return false;
+
+ var entity:Entity=controller.state.firstSelected;
switch (op) {
- case 'delete': return (entity is Way || entity is Node);
+ case 'delete': return true;
case 'reverseDirection': return (entity is Way);
case 'quadrilateralise': return (entity is Way && Way(entity).isArea());
case 'straighten': return (entity is Way && !Way(entity).isArea());
case 'circularise': return (entity is Way && Way(entity).isArea());
- case 'split': return (entity is Node && controller.state is SelectedWayNode);
+ case 'split': return (controller.state is SelectedWayNode);
case 'parallelise': return (entity is Way);
}
return false;
[Bindable(event="updateSkin")]
private function deleteToolTipText():String {
+ var entity:Entity=controller.state.firstSelected;
if (entity is Node) { return "Delete Node (Delete)"; }
if (entity is Way && Way(entity).isArea()) { return "Delete Area (Shift+Delete)"; }
if (entity is Way) { return "Delete Way (Shift+Delete)"; }
// Individual toolbox actions
public function doDelete():void {
- if (entity is Node) { controller.connection.unregisterPOI(Node(entity)); }
- entity.remove(MainUndoStack.getGlobalStack().addAction);
+ var undo:CompositeUndoableAction = new CompositeUndoableAction("Delete objects");
+ for each (var entity:Entity in controller.state.selection) {
+ if (entity is Node) { controller.connection.unregisterPOI(Node(entity)); }
+ entity.remove(undo.push);
+ }
+ MainUndoStack.getGlobalStack().addAction(undo);
if (controller.state is SelectedWayNode) {
controller.setState(new SelectedWay(SelectedWayNode(controller.state).selectedWay));
}
public function doReverseDirection():void {
- if (entity is Way) {
- Way(entity).reverseNodes(MainUndoStack.getGlobalStack().addAction);
+ if (controller.state is SelectedWay) {
+ Way(controller.state.firstSelected).reverseNodes(MainUndoStack.getGlobalStack().addAction);
}
}
public function doQuadrilateralise():void {
- if (entity is Way) {
- Quadrilateralise.quadrilateralise(Way(entity));
+ if (controller.state is SelectedWay) {
+ Quadrilateralise.quadrilateralise(Way(controller.state.firstSelected));
}
}
public function doStraighten():void {
- if (entity is Way) {
- Straighten.straighten(Way(entity),controller.map);
+ if (controller.state is SelectedWay) {
+ Straighten.straighten(Way(controller.state.firstSelected),controller.map);
}
}
public function doCircularise():void {
- if (entity is Way) {
- Circularise.circularise(Way(entity),controller.map);
+ if (controller.state is SelectedWay) {
+ Circularise.circularise(Way(controller.state.firstSelected),controller.map);
}
}
public function doSplit():void {
- if (entity is Node && controller.state is SelectedWayNode) {
+ if (controller.state is SelectedWayNode) {
controller.setState(SelectedWayNode(controller.state).splitWay());
}
}
public function doParallelise():void {
- if (entity is Way) {
- controller.setState(new SelectedParallelWay(Way(entity)));
+ if (controller.state is SelectedWay) {
+ controller.setState(new SelectedParallelWay(Way(controller.state.firstSelected)));
}
}
if ( entity == null || isBackground ) {
node = createAndAddNode(event, MainUndoStack.getGlobalStack().addAction);
controller.map.setHighlight(node, { selectedway: true });
- controller.map.setPurgable(node, false);
+ controller.map.setPurgable([node], false);
resetElastic(node);
lastClick=node;
} else if ( entity is Node ) {
Way(entity).insertNodeAtClosestPosition(node, true, jnct.push);
MainUndoStack.getGlobalStack().addAction(jnct);
controller.map.setHighlight(node, { selectedway: true });
- controller.map.setPurgable(node, false);
+ controller.map.setPurgable([node], false);
}
resetElastic(node);
lastClick=node;
newDraw=0;
}
if (node.numParentWays==1 && Way(firstSelected).hasOnceOnly(node)) {
- controller.map.setPurgable(node, true);
+ controller.map.setPurgable([node], true);
controller.connection.unregisterPOI(node);
node.remove(undo.push);
}
override public function enterState():void {
selectNode(initNode);
- controller.map.setPurgable(firstSelected,false);
+ controller.map.setPurgable(selection,false);
Globals.vars.root.addDebug("**** -> "+this);
}
override public function exitState(newState:ControllerState):void {
controller.clipboards['node']=firstSelected.getTagsCopy();
- controller.map.setPurgable(firstSelected,true);
+ controller.map.setPurgable(selection,true);
clearSelection(newState);
Globals.vars.root.addDebug("**** <- "+this);
}
} else if ( event.type == MouseEvent.MOUSE_DOWN && entity is Way && event.shiftKey ) {
// merge way
return mergeWith(entity as Way);
+ } else if ( event.type == MouseEvent.MOUSE_DOWN && event.ctrlKey && entity!=firstSelected) {
+ // multiple selection
+ return new SelectedMultiple([firstSelected,entity]);
}
var cs:ControllerState = sharedMouseEvents(event, entity);
return cs ? cs : this;
}
public function deleteWay():ControllerState {
- controller.map.setHighlightOnNodes(firstSelected as Way, {selectedway: false});
+ controller.map.setHighlightOnNodes(firstSelected as Way, {selectedway: false});
selectedWay.remove(MainUndoStack.getGlobalStack().addAction);
return new NoSelection();
}
override public function enterState():void {
selectWay(initWay);
- controller.map.setPurgable(firstSelected,false);
+ controller.map.setPurgable(selection,false);
Globals.vars.root.addDebug("**** -> "+this+" "+firstSelected.id);
}
override public function exitState(newState:ControllerState):void {
controller.clipboards['way']=firstSelected.getTagsCopy();
- controller.map.setPurgable(firstSelected,true);
+ controller.map.setPurgable(selection,true);
clearSelection(newState);
Globals.vars.root.addDebug("**** <- "+this);
}
override public function enterState():void {
selectNode(parentWay,initIndex);
- controller.map.setPurgable(firstSelected,false);
+ controller.map.setPurgable(selection,false);
Globals.vars.root.addDebug("**** -> "+this);
}
override public function exitState(newState:ControllerState):void {
controller.clipboards['node']=firstSelected.getTagsCopy();
- controller.map.setPurgable(firstSelected,true);
+ controller.map.setPurgable(selection,true);
clearSelection(newState);
Globals.vars.root.addDebug("**** <- "+this);
}
if (parentWay.getLastNode() == firstSelected) { return this; }
controller.map.setHighlightOnNodes(parentWay, { selectedway: false } );
- controller.map.setPurgable(parentWay,true);
+ controller.map.setPurgable([parentWay],true);
MainUndoStack.getGlobalStack().addAction(new SplitWayAction(parentWay, firstSelected as Node));
return new SelectedWay(parentWay);
}
public function deleteNode():ControllerState {
- controller.map.setPurgable(firstSelected,true);
+ controller.map.setPurgable(selection,true);
firstSelected.remove(MainUndoStack.getGlobalStack().addAction);
return new SelectedWay(parentWay);
}