package net.systemeD.potlatch2 {
import net.systemeD.halcyon.Map;
+ import net.systemeD.halcyon.MapPaint;
import net.systemeD.halcyon.MapController;
import net.systemeD.halcyon.MapEvent;
import net.systemeD.halcyon.connection.*;
- import net.systemeD.halcyon.VectorLayer;
+ import net.systemeD.halcyon.Globals;
import net.systemeD.potlatch2.controller.*;
import net.systemeD.potlatch2.FunctionKeyManager;
import mx.managers.CursorManager;
import flash.external.ExternalInterface;
import flash.events.*;
import flash.geom.*;
+ import flash.display.*;
import flash.ui.Keyboard;
+ import flash.ui.Mouse;
+ import flash.ui.MouseCursorData;
+ import flash.system.Capabilities;
import flash.text.TextField;
import mx.controls.TextArea;
/** Controller for the main map editing window itself. The logic that responds to mouse and keyboard events is all
* buried in various ControllerState classes. */
- public class EditController implements MapController {
+ public class EditController extends EventDispatcher implements MapController {
private var _map:Map;
public var tagViewer:TagViewer;
private var toolbox:Toolbox;
-
+
+ /** The current ControllerState */
public var state:ControllerState;
- private var _connection:Connection;
+ /** Hash of when a key was pressed. A user can keyDown within a TextInput, press Enter (leaving
+ the TextInput), and then keyup - resulting in the keypress being interpreted again.
+ We prevent this by tracking keyDowns within the TextInput and ignoring corresponding keyUps. */
private var keys:Object={};
+
+ public var spaceHeld:Boolean=false;
public var clipboards:Object={};
public var cursorsEnabled:Boolean=true;
private var maximised:Boolean=false;
this._map = map;
setState(new NoSelection());
this.tagViewer = tagViewer;
+ this.tagViewer.controller = this;
this.toolbox = toolbox;
this.toolbox.init(this);
- this.maximiseFunction = Connection.getParam("maximise_function", null);
- this.minimiseFunction = Connection.getParam("minimise_function", null);
- this.moveFunction = Connection.getParam("move_function", null);
+ this.toolbox.updateSelectionUI();
+ this.maximiseFunction = Globals.vars.flashvars["maximise_function"];
+ this.minimiseFunction = Globals.vars.flashvars["minimise_function"];
+ this.moveFunction = Globals.vars.flashvars["move_function"];
map.parent.addEventListener(MouseEvent.MOUSE_MOVE, mapMouseEvent);
map.parent.addEventListener(MouseEvent.MOUSE_UP, mapMouseEvent);
if (this.moveFunction) {
map.addEventListener(MapEvent.MOVE, moveHandler);
}
+
+ if (supportsMouseCursors()) {
+ createBitmapCursor("pen" ,new pen());
+ createBitmapCursor("pen_x" ,new pen_x());
+ createBitmapCursor("pen_o" ,new pen_o());
+ createBitmapCursor("pen_so" ,new pen_so());
+ createBitmapCursor("pen_plus",new pen_plus());
+ }
}
public function setActive():void {
map.setController(this);
- _connection = map.connection;
}
/** Accesses map object. */
return _map;
}
- /** Accesss connection object. */
- public function get connection():Connection {
- return _connection;
- }
-
/**
* Updates the various user interfaces that change when the selection changes.
* Currently this is the TagViewer and the Toolbox
*
* @param layer Optionally pass the layer of the currently selected entity, eg for BugLayers
*/
- public function updateSelectionUI(layer:VectorLayer = null):void {
+ public function updateSelectionUI(layer:MapPaint = null):void {
tagViewer.setEntity(state.selection, layer);
toolbox.updateSelectionUI();
}
}
private function keyDownHandler(event:KeyboardEvent):void {
- if ((event.target is TextField) || (event.target is TextArea)) return;
- keys[event.keyCode]=true;
+ if ((event.target is TextField) || (event.target is TextArea)) {
+ keys[event.keyCode]=new Date().getTime();
+ return;
+ }
+ delete keys[event.keyCode];
+ if (event.keyCode==Keyboard.SPACE) spaceHeld=true;
}
private function keyUpHandler(event:KeyboardEvent):void {
- if (!keys[event.keyCode]) return;
- delete keys[event.keyCode];
- if ((event.target is TextField) || (event.target is TextArea)) return; // not meant for us
+ if ((event.target is TextField) || (event.target is TextArea)) return;
+ if (event.keyCode==Keyboard.SPACE) spaceHeld=false;
+ if (keys[event.keyCode] && new Date().getTime()-keys[event.keyCode]<300) return;
+ delete keys[event.keyCode];
if (FunctionKeyManager.instance().handleKeypress(event.keyCode)) { return; }
setState(newState);
}
- /** Is the given key currently pressed? */
- public function keyDown(key:Number):Boolean {
- return Boolean(keys[key]);
- }
-
private function mapMouseEvent(event:MouseEvent):void {
if (isInteractionEvent(event)) map.stage.focus = map.parent;
if (event.type==MouseEvent.MOUSE_UP && map.dragstate==map.DRAGGING) { return; }
return true;
}
- /** Exit the current state and switch to a new one. */
+ /** Exit the current state and switch to a new one.
+ *
+ * @param newState The ControllerState to switch to. */
public function setState(newState:ControllerState):void {
if ( newState == state )
return;
/** Given what is currently selected (or not), find the matching ControllerState. */
public function findStateForSelection(sel:Array):ControllerState {
if (sel.length==0) { return new NoSelection(); }
- else if (sel.length>1) { 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);
}
}
/** Set a mouse pointer. */
- public function setCursor(cursor:Class):void {
- CursorManager.removeAllCursors();
- if (cursor && cursorsEnabled) { CursorManager.setCursor(cursor,2,-4,0); }
+ public function setCursor(name:String=""):void {
+ if (name && cursorsEnabled && supportsMouseCursors()) { Mouse.cursor=name; }
+ else { Mouse.cursor=flash.ui.MouseCursor.AUTO; }
+ }
+
+ private function createBitmapCursor(name:String, source:Bitmap, hotX:int=4, hotY:int=0):void {
+ var bitmapVector:Vector.<BitmapData> = new Vector.<BitmapData>(1, true);
+ bitmapVector[0] = source.bitmapData;
+ var cursorData:MouseCursorData = new MouseCursorData();
+ cursorData.hotSpot = new Point(hotX,hotY);
+ cursorData.data = bitmapVector;
+ Mouse.registerCursor(name, cursorData);
+ }
+
+ private function supportsMouseCursors():Boolean {
+ var fpArray:Array=Capabilities.version.split(",");
+ var fpVersion:Number=Number(fpArray[0].split(" ")[1])+Number(fpArray[1])/10;
+ return (fpVersion>10.1);
}
private function toggleSize():void {