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:Number=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);
58 protected function removeGenericEventListeners():void {
59 entity.removeEventListener(Connection.TAG_CHANGED, tagChanged);
60 entity.removeEventListener(Connection.ADDED_TO_RELATION, relationAdded);
61 entity.removeEventListener(Connection.REMOVED_FROM_RELATION, relationRemoved);
62 entity.removeEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
63 entity.removeEventListener(Connection.RESUME_REDRAW, resumeRedraw);
64 listenSprite.removeEventListener(MouseEvent.CLICK, mouseEvent);
65 listenSprite.removeEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
66 listenSprite.removeEventListener(MouseEvent.ROLL_OVER, mouseEvent);
67 listenSprite.removeEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
68 listenSprite.removeEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
69 listenSprite.removeEventListener(MouseEvent.MOUSE_UP, mouseEvent);
70 listenSprite.removeEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
73 // -----------------------------------------------------------------
76 protected function attachRelationListeners():void {
77 var relations:Array = entity.parentRelations;
78 for each(var relation:Relation in relations ) {
79 relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
83 protected function relationAdded(event:RelationMemberEvent):void {
84 event.relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
85 invalidateStyleList();
89 protected function relationRemoved(event:RelationMemberEvent):void {
90 event.relation.removeEventListener(Connection.TAG_CHANGED, relationTagChanged);
91 invalidateStyleList();
95 protected function tagChanged(event:TagEvent):void {
96 invalidateStyleList();
100 protected function relationTagChanged(event:TagEvent):void {
101 invalidateStyleList();
105 protected function mouseEvent(event:MouseEvent):void {
106 paint.map.entityMouseEvent(event, entity);
110 // -----------------------------------------------------------------
112 // Add object (stroke/fill/roadname) to layer sprite
114 protected function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
115 var l:Sprite, o:Sprite;
117 o=paint.sublayer(layer,sublayer);
119 l=paint.getPaintSpriteAt(layer);
120 o=l.getChildAt(t) as Sprite;
123 if (sprites.indexOf(s)==-1) { sprites.push(s); }
125 Sprite(s).mouseChildren = false;
126 Sprite(s).mouseEnabled = false;
130 protected function setListenSprite():void {
131 var l:Sprite=paint.getHitSpriteAt(layer);
133 if (entity is Way) { s=l.getChildAt(0) as Sprite; }
134 else { s=l.getChildAt(1) as Sprite; }
137 if (!listenSprite.parent) { s.addChild(listenSprite); if (sprites.indexOf(listenSprite)==-1) { sprites.push(listenSprite); } }
138 if (!hitzone.parent) { s.addChild(hitzone ); if (sprites.indexOf(hitzone )==-1) { sprites.push(hitzone ); } }
139 listenSprite.hitArea = hitzone;
140 listenSprite.buttonMode = true;
141 listenSprite.mouseChildren = true;
142 listenSprite.mouseEnabled = true;
143 } else if (listenSprite.parent) {
144 listenSprite.parent.removeChild(listenSprite);
148 public function removeSprites():void {
149 while (sprites.length>0) {
150 var d:DisplayObject=sprites.pop();
151 if (d.parent) { d.parent.removeChild(d); }
153 listenSprite.hitArea=null;
157 protected function offsetSprites(x:Number, y:Number):void {
158 for each (var d:DisplayObject in sprites) {
163 public function setHighlight(settings:Object):void {
164 var changed:Boolean=false;
165 for (var stateType:String in settings) {
166 if (setStateClass(stateType, settings[stateType])) { changed=true; }
168 if (changed) redraw();
172 * Sets a state class (eg :hover, :dupe) for this entityUI. If the state class has changed it will
173 * invalidate the style list to force the style to be recalculated during redraw.
175 public function setStateClass(stateType:String, isOn:*):Boolean {
176 if ( isOn == true ) { isOn='yes'; }
177 if ( isOn && stateClasses[stateType] != isOn ) {
178 stateClasses[stateType] = isOn;
179 invalidateStyleList();
181 } else if ( !isOn && stateClasses[stateType] != null ) {
182 delete stateClasses[stateType];
183 invalidateStyleList();
190 * applies the state classes (eg :hover, :area) for this entityUI to the given list of 'real' tags.
191 * This then gives you a modified list of tags used for styling the entityUI.
193 public function applyStateClasses(tags:Object):Object {
194 for (var stateKey:String in stateClasses) {
195 tags[":"+stateKey] = 'yes';
200 public function toString():String {
201 return "[EntityUI "+entity+"]";
206 public function redraw():Boolean {
207 if (suspended) { redrawDue=true; return false; }
211 public function doRedraw():Boolean {
216 public function suspendRedraw(event:EntityEvent):void {
221 public function resumeRedraw(event:EntityEvent):void {
229 public function invalidateStyleList():void {