protected var layer:Number=0; // map layer
protected var suspended:Boolean=false; // suspend redrawing?
protected var redrawDue:Boolean=false; // redraw called while suspended?
+ protected var clearLimit:uint=0; // sprite to clear back to
public var paint:MapPaint; // reference to parent MapPaint
public var ruleset:RuleSet; // reference to ruleset in operation
public var interactive:Boolean=true; // does object respond to clicks?
}
public function removeSprites():void {
- while (sprites.length>0) {
+ while (sprites.length>clearLimit) {
var d:DisplayObject=sprites.pop();
if (d.parent) { d.parent.removeChild(d); }
}
- listenSprite.hitArea=null;
- hitzone=null;
+ if (clearLimit==0) {
+ listenSprite.hitArea=null;
+ hitzone=null;
+ }
}
+
+ public function protectSprites():void { clearLimit=sprites.length; }
+ public function unprotectSprites():void { clearLimit=0; }
protected function offsetSprites(x:Number, y:Number):void {
for each (var d:DisplayObject in sprites) {
public function redraw():Boolean {
if (suspended) { redrawDue=true; return false; }
- return doRedraw();
+ var r:Boolean=doRedraw();
+ cacheSpritesAsBitmap(true);
+ return r;
}
public function doRedraw():Boolean {
public function invalidateStyleList():void {
styleList=null;
}
+
+ private function cacheSpritesAsBitmap(cache:Boolean):void {
+ for each (var s:DisplayObject in sprites) {
+ if (s!=listenSprite) s.cacheAsBitmap=cache;
+ }
+ }
}
package net.systemeD.halcyon {
import flash.text.TextField;
+ import flash.geom.Rectangle;
import flash.display.DisplayObjectContainer;
import flash.display.Loader;
import flash.display.Sprite;
gotEnvironment(null);
addEventListener(Event.ENTER_FRAME, everyFrame);
+ scrollRect=new Rectangle(0,0,800,600);
}
public function gotEnvironment(r:Object):void {
// Recalculate co-ordinates from new Flash origin
public function updateCoords(tx:Number,ty:Number):void {
- x=tx; y=ty;
+ setScrollRectXY(tx,ty);
- edge_t=coord2lat(-y );
- edge_b=coord2lat(-y+mapheight);
- edge_l=coord2lon(-x );
- edge_r=coord2lon(-x+mapwidth );
+ edge_t=coord2lat(-ty );
+ edge_b=coord2lat(-ty+mapheight);
+ edge_l=coord2lon(-tx );
+ edge_r=coord2lon(-tx+mapwidth );
setCentre();
tileset.update();
updateCoords(cx,cy);
}
+ private function setScrollRectXY(tx:Number,ty:Number):void {
+ var w:Number=scrollRect.width;
+ var h:Number=scrollRect.height;
+ scrollRect=new Rectangle(-tx,-ty,w,h);
+ }
+ private function setScrollRectSize(width:Number,height:Number):void {
+ var sx:Number=scrollRect.x ? scrollRect.x : 0;
+ var sy:Number=scrollRect.y ? scrollRect.y : 0;
+ scrollRect=new Rectangle(sx,sy,width,height);
+ }
+
+ private function getX():Number { return -scrollRect.x; }
+ private function getY():Number { return -scrollRect.y; }
+
private function setCentre():void {
- centre_lat=coord2lat(-y+mapheight/2);
- centre_lon=coord2lon(-x+mapwidth/2);
+ centre_lat=coord2lat(-getY()+mapheight/2);
+ centre_lon=coord2lon(-getX()+mapwidth/2);
this.dispatchEvent(new MapEvent(MapEvent.MOVE, {lat:centre_lat, lon:centre_lon, scale:scale, minlon:edge_l, maxlon:edge_r, minlat:edge_b, maxlat:edge_t}));
}
}
private function moveMap(dx:Number,dy:Number):void {
- updateCoords(x+dx,y+dy);
+ updateCoords(getX()+dx,getY()+dy);
updateEntityUIs(false, false);
download();
}
public function lat2coord(a:Number):Number { return -(lat2latp(a)-basey)*scalefactor; }
public function coord2lat(a:Number):Number { return latp2lat(a/-scalefactor+basey); }
-// public function centrelat(o) { return coord2lat((yradius-_root.map._y-o)/Math.pow(2,_root.scale-13)); }
-// public function centrelon(o) { return coord2lon((xradius-_root.map._x-o)/Math.pow(2,_root.scale-13)); }
-
// ------------------------------------------------------------------------------------------
// Resize map size based on current stage and height
public function updateSize(w:uint, h:uint):void {
- mapwidth = w; centre_lon=coord2lon(-x+w/2);
- mapheight= h; centre_lat=coord2lat(-y+h/2);
+ mapwidth = w; centre_lon=coord2lon(-getX()+w/2);
+ mapheight= h; centre_lat=coord2lat(-getY()+h/2);
+ setScrollRectSize(w,h);
this.dispatchEvent(new MapEvent(MapEvent.RESIZE, {width:w, height:h}));
if (paint.wayuis[way.id]) paint.wayuis[way.id].setHighlightOnNodes(settings);
}
+ public function protectWay(way:Way):void {
+ if (paint.wayuis[way.id]) paint.wayuis[way.id].protectSprites();
+ }
+
+ public function unprotectWay(way:Way):void {
+ if (paint.wayuis[way.id]) paint.wayuis[way.id].unprotectSprites();
+ }
+
+ public function limitWayDrawing(way:Way,except:Number=NaN,only:Number=NaN):void {
+ if (!paint.wayuis[way.id]) return;
+ paint.wayuis[way.id].drawExcept=except;
+ paint.wayuis[way.id].drawOnly =only;
+ paint.wayuis[way.id].redraw();
+ }
+
/* Protect Entities and EntityUIs against purging. This prevents the currently selected items
from being purged even though they're off-screen. */
public function mouseDownHandler(event:MouseEvent):void {
if (!_draggable) { return; }
dragstate=NOT_MOVED;
- lastxmouse=mouseX; downX=stage.mouseX;
- lastymouse=mouseY; downY=stage.mouseY;
+ lastxmouse=stage.mouseX; downX=stage.mouseX;
+ lastymouse=stage.mouseY; downY=stage.mouseY;
downTime=new Date().getTime();
}
public function mouseUpHandler(event:MouseEvent=null):void {
- if (dragstate==DRAGGING) { moveMap(0,0); }
+ if (dragstate==DRAGGING) { moveMap(x,y); }
dragstate=NOT_DRAGGING;
}
dragstate=DRAGGING;
}
- x+=mouseX-lastxmouse;
- y+=mouseY-lastymouse;
- lastxmouse=mouseX; lastymouse=mouseY;
+ setScrollRectXY(getX()+stage.mouseX-lastxmouse,getY()+stage.mouseY-lastymouse);
+ lastxmouse=stage.mouseX; lastymouse=stage.mouseY;
setCentre();
}
public var centroid_x:Number; // centroid
public var centroid_y:Number; // |
public var heading:Array=new Array(); // angle at each node
+ public var drawExcept:Number; // vertex to draw exclusively, or not at all (used by DragWayNode)
+ public var drawOnly:Number; // |
+ private var indexStart:uint; // |
+ private var indexEnd:uint; // |
public var nameformat:TextFormat;
private var recalculateDue:Boolean=false;
if (tags['layer']) { layer=Math.min(Math.max(tags['layer'],paint.minlayer),paint.maxlayer); }
}
+ // Do we have to draw all nodes in the way?
+ if (isNaN(drawOnly)) {
+ indexStart=0; indexEnd=Way(entity).length;
+ } else {
+ indexStart=Math.max(0,drawOnly-1);
+ indexEnd =Math.min(drawOnly+2,Way(entity).length);
+ }
+
// Iterate through each sublayer, drawing any styles on that layer
var drawn:Boolean;
var multis:Array=entity.findParentRelationsOfType('multipolygon','outer');
// Draw icons
var r:Number;
var nodeSelected:int=stateClasses["nodeSelected"];
- for (var i:uint = 0; i < Way(entity).length; i++) {
+ for (var i:uint = indexStart; i < indexEnd; i++) {
var node:Node = Way(entity).getNode(i);
var nodeStateClasses:Object={};
// if (i==0) { nodetags['_heading']= heading[i]; }
// Draw solid polyline
public function solidLines(g:Graphics,inners:Array):void {
- solidLine(g,entity as Way);
- for each (var w:Way in inners) { solidLine(g,w); }
+ solidLine(g);
+ for each (var w:Way in inners) { solidLineOtherWay(g,w); }
}
- private function solidLine(g:Graphics,w:Way):void {
- if (w.length==0) { return; }
- var node:Node = w.getNode(0);
+ private function solidLine(g:Graphics):void {
+ if (indexEnd==0) { return; }
+ var way:Way=entity as Way;
+
+ var node:Node = way.getNode(indexStart);
+ g.moveTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
+ for (var i:uint = indexStart+1; i < indexEnd; i++) {
+ node = way.getNode(i);
+ if (!isNaN(drawExcept) && (i-1==drawExcept || i==drawExcept)) {
+ g.moveTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
+ } else {
+ g.lineTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
+ }
+ }
+ }
+
+ private function solidLineOtherWay(g:Graphics,way:Way):void {
+ if (way.length==0) { return; }
+
+ var node:Node = way.getNode(indexStart);
g.moveTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
- for (var i:uint = 1; i < w.length; i++) {
- node = w.getNode(i);
+ for (var i:uint = 1; i < way.length; i++) {
+ node = way.getNode(i);
g.lineTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
}
}
var a:Number, xc:Number, yc:Number;
var curx:Number, cury:Number;
var dx:Number, dy:Number, segleft:Number=0;
- var i:int=0;
+ var i:int=indexStart;
- var node:Node = way.getNode(0);
- var nextNode:Node = way.getNode(0);
+ var node:Node = way.getNode(i);
+ var nextNode:Node = way.getNode(i);
g.moveTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
- while (i < way.length-1 || segleft>0) {
+ while (i < indexEnd-1 || segleft>0) {
if (dashleft<=0) { // should be ==0
if (dc.length==0) { dc=dashes.slice(0); }
dashleft=dc.shift();
if (draw) { segments.push([curx,cury,dx,dy]); }
draw=!draw;
}
+ if (i==drawExcept || i==drawExcept+1) { draw=false; }
if (segleft<=0) { // should be ==0
node = way.getNode(i);
nextNode = way.getNode(i+1);
originalLon = draggingNode.lon;
controller.map.setHighlightOnNodes(parentWay, { selectedway: true } );
+ controller.map.limitWayDrawing(parentWay, draggingIndex);
controller.map.setHighlight(draggingNode, { selected: true } );
+ controller.map.protectWay(parentWay);
+ controller.map.limitWayDrawing(parentWay, NaN, draggingIndex);
Globals.vars.root.addDebug("**** -> "+this);
}
override public function exitState(newState:ControllerState):void {
+ controller.map.unprotectWay(parentWay);
+ controller.map.limitWayDrawing(parentWay);
controller.map.setHighlightOnNodes(parentWay, { selectedway: false } );
controller.map.setHighlight(draggingNode, { selected: false } );
Globals.vars.root.addDebug("**** <- "+this);