1 package net.systemeD.halcyon {
3 import flash.display.*;
4 import flash.events.MouseEvent;
5 import flash.text.AntiAliasType;
6 import flash.text.GridFitType;
7 import net.systemeD.halcyon.Globals;
8 import net.systemeD.halcyon.styleparser.StyleList;
9 import net.systemeD.halcyon.styleparser.RuleSet;
10 import net.systemeD.halcyon.connection.*;
12 public class EntityUI {
14 protected var entity:Entity;
15 protected var styleList:StyleList; // current StyleList for this entity
16 protected var sprites:Array=new Array(); // instances in display list
17 protected var listenSprite:Sprite=new Sprite(); // clickable sprite to receive events
18 protected var hitzone:Sprite; // hitzone for above
19 protected var stateClasses:Object=new Object(); // special context-sensitive classes, e.g. :hover
20 protected var layer:int=0; // map layer
21 protected var suspended:Boolean=false; // suspend redrawing?
22 protected var redrawDue:Boolean=false; // redraw called while suspended?
23 public var paint:MapPaint; // reference to parent MapPaint
24 public var ruleset:RuleSet; // reference to ruleset in operation
25 public var interactive:Boolean=true; // does object respond to clicks?
26 public var purgable:Boolean=true; // can it be deleted when offscreen?
28 protected const FILLSPRITE:uint=0;
29 protected const CASINGSPRITE:uint=1;
30 protected const STROKESPRITE:uint=2;
31 protected const NAMESPRITE:uint=3;
32 protected const WAYCLICKSPRITE:uint=0;
33 protected const NODECLICKSPRITE:uint=1;
35 public static const DEFAULT_TEXTFIELD_PARAMS:Object = {
37 antiAliasType: AntiAliasType.ADVANCED,
38 gridFitType: GridFitType.NONE
41 public function EntityUI(entity:Entity, paint:MapPaint) {
44 entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
45 entity.addEventListener(Connection.ADDED_TO_RELATION, relationAdded);
46 entity.addEventListener(Connection.REMOVED_FROM_RELATION, relationRemoved);
47 entity.addEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
48 entity.addEventListener(Connection.RESUME_REDRAW, resumeRedraw);
49 listenSprite.addEventListener(MouseEvent.CLICK, mouseEvent);
50 listenSprite.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
51 listenSprite.addEventListener(MouseEvent.ROLL_OVER, mouseEvent);
52 listenSprite.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
53 listenSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
54 listenSprite.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
55 listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
59 // -----------------------------------------------------------------
62 protected function attachRelationListeners():void {
63 var relations:Array = entity.parentRelations;
64 for each(var relation:Relation in relations ) {
65 relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
69 protected function relationAdded(event:RelationMemberEvent):void {
70 event.relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
71 invalidateStyleList();
75 protected function relationRemoved(event:RelationMemberEvent):void {
76 event.relation.removeEventListener(Connection.TAG_CHANGED, relationTagChanged);
77 invalidateStyleList();
81 protected function tagChanged(event:TagEvent):void {
82 invalidateStyleList();
86 protected function relationTagChanged(event:TagEvent):void {
87 invalidateStyleList();
91 protected function mouseEvent(event:MouseEvent):void {
92 paint.map.entityMouseEvent(event, entity);
96 // -----------------------------------------------------------------
98 // Add object (stroke/fill/roadname) to layer sprite
100 protected function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
101 var l:Sprite, o:Sprite;
103 o=paint.sublayer(layer,sublayer);
105 l=paint.getPaintSpriteAt(layer);
106 o=l.getChildAt(t) as Sprite;
109 if (sprites.indexOf(s)==-1) { sprites.push(s); }
111 Sprite(s).mouseChildren = false;
112 Sprite(s).mouseEnabled = false;
116 protected function setListenSprite():void {
117 var l:Sprite=paint.getHitSpriteAt(layer);
119 if (entity is Way) { s=l.getChildAt(0) as Sprite; }
120 else { s=l.getChildAt(1) as Sprite; }
123 if (!listenSprite.parent) { s.addChild(listenSprite); if (sprites.indexOf(listenSprite)==-1) { sprites.push(listenSprite); } }
124 if (!hitzone.parent) { s.addChild(hitzone ); if (sprites.indexOf(hitzone )==-1) { sprites.push(hitzone ); } }
125 listenSprite.hitArea = hitzone;
126 listenSprite.buttonMode = true;
127 listenSprite.mouseChildren = true;
128 listenSprite.mouseEnabled = true;
129 } else if (listenSprite.parent) {
130 listenSprite.parent.removeChild(listenSprite);
134 public function removeSprites():void {
135 while (sprites.length>0) {
136 var d:DisplayObject=sprites.pop();
137 if (d.parent) { d.parent.removeChild(d); }
139 listenSprite.hitArea=null;
143 protected function offsetSprites(x:Number, y:Number):void {
144 for each (var d:DisplayObject in sprites) {
149 public function setHighlight(settings:Object):void {
150 var changed:Boolean=false;
151 for (var stateType:String in settings) {
152 if (setStateClass(stateType, settings[stateType])) { changed=true; }
154 if (changed) redraw();
157 public function setStateClass(stateType:String, isOn:*):Boolean {
158 if ( isOn && stateClasses[stateType] != isOn ) {
159 stateClasses[stateType] = isOn;
160 invalidateStyleList();
162 } else if ( !isOn && stateClasses[stateType] != null ) {
163 delete stateClasses[stateType];
164 invalidateStyleList();
170 public function applyStateClasses(tags:Object):Object {
171 for (var stateKey:String in stateClasses) {
172 tags[":"+stateKey] = 'yes';
177 public function toString():String {
178 return "[EntityUI "+entity+"]";
183 public function redraw():Boolean {
184 if (suspended) { redrawDue=true; return false; }
188 public function doRedraw():Boolean {
193 public function suspendRedraw(event:EntityEvent):void {
198 public function resumeRedraw(event:EntityEvent):void {
206 public function invalidateStyleList():void {