complete arbitrary sublayer support; fix roundabout tagging issue; couple of small...
[potlatch2.git] / net / systemeD / halcyon / NodeUI.as
1 package net.systemeD.halcyon {
2
3         import flash.display.*;
4         import flash.events.*;
5         import flash.text.AntiAliasType;
6         import flash.text.GridFitType;
7         import flash.text.TextField;
8         import flash.text.TextFormat;
9         import flash.geom.Matrix;
10         import flash.geom.Point;
11         import net.systemeD.halcyon.styleparser.*;
12     import net.systemeD.halcyon.connection.*;
13         import net.systemeD.halcyon.Globals;
14         
15         public class NodeUI extends EntityUI {
16                 
17                 public var loaded:Boolean=false;
18                 private var iconname:String='';                         // name of icon
19                 private var heading:Number=0;                           // heading within way
20                 private var rotation:Number=0;                          // rotation applied to this POI
21
22                 public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, interactive:Boolean=true, sl:StyleList=null) {
23                         super(node,paint,interactive);
24                         this.heading = heading;
25             entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
26                         entity.addEventListener(Connection.NODE_MOVED, nodeMoved);
27                         entity.addEventListener(Connection.NODE_DELETED, nodeDeleted);
28             attachRelationListeners();
29                         redraw(sl);
30                 }
31                 
32                 public function nodeMoved(event:Event):void {
33                     updatePosition();
34                 }
35
36                 public function nodeDeleted(event:Event):void {
37                         removeSprites();
38                 }
39                 
40                 override public function doRedraw(sl:StyleList):Boolean {
41                         if (!paint.ready) { return false; }
42                         if (entity.deleted) { return false; }
43
44                         var tags:Object = entity.getTagsCopy();
45                         tags=applyStateClasses(tags);
46                         if (!entity.hasParentWays) { tags[':poi']='yes'; }
47                         if (!sl) { sl=paint.ruleset.getStyles(entity,tags,paint.map.scale); }
48
49                         var inWay:Boolean=entity.hasParentWays;
50                         var hasStyles:Boolean=sl.hasStyles();
51                         
52                         removeSprites(); iconname='';
53                         return renderFromStyle(sl,tags);
54                 }
55
56                 private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
57                         var r:Boolean=false;    // ** rendered
58                         var w:Number;
59                         var icon:Sprite;
60                         layer=paint.maxlayer;
61                         for each (var sublayer:Number in sl.sublayers) {
62
63                                 if (sl.pointStyles[sublayer]) {
64                                         var s:PointStyle=sl.pointStyles[sublayer];
65                                         r=true;
66                                         if (s.rotation) { rotation=s.rotation; }
67
68                                         if (s.icon_image!=iconname) {
69                                                 if (s.icon_image=='square') {
70                                                         // draw square
71                                                         icon=new Sprite();
72                                                         addToLayer(icon,STROKESPRITE,sublayer);
73                                                         w=styleIcon(icon,sl,sublayer);
74                                                         icon.graphics.drawRect(0,0,w,w);
75                                                         addHitSprite(w);
76                                                         updatePosition();
77                                                         iconname='_square';
78
79                                                 } else if (s.icon_image=='circle') {
80                                                         // draw circle
81                                                         icon=new Sprite();
82                                                         addToLayer(icon,STROKESPRITE,sublayer);
83                                                         w=styleIcon(icon,sl,sublayer);
84                                                         icon.graphics.drawCircle(w,w,w);
85                                                         addHitSprite(w);
86                                                         updatePosition();
87                                                         iconname='_circle';
88
89                                                 } else if (paint.ruleset.images[s.icon_image]) {
90                                                         // 'load' icon (actually just from library)
91                                                         var loader:Loader = new Loader();
92                                                         loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { 
93                                                                 loadedIcon(e,sublayer); } );
94                                                         loader.loadBytes(paint.ruleset.images[s.icon_image]);
95                                                         iconname=s.icon_image;
96                                                 }
97                                         } else {
98                                                 // already loaded, so just reposition
99                                                 updatePosition();
100                                         }
101                                 }
102
103                                 // name sprite
104                                 var a:String='', t:TextStyle;
105                                 if (sl.textStyles[sublayer]) {
106                                         t=sl.textStyles[sublayer];
107                                         a=tags[t.text];
108                                 }
109
110                                 if (a) { 
111                                         var name:Sprite=new Sprite();
112                                         addToLayer(name,NAMESPRITE);
113                                         t.writeNameLabel(name,a,0,0);
114                                 }
115                         }
116                         return r;
117                 }
118
119
120                 private function styleIcon(icon:Sprite, sl:StyleList, sublayer:uint):Number {
121                         loaded=true;
122
123                         // get colours
124                         if (sl.shapeStyles[sublayer]) {
125                                 var s:ShapeStyle=sl.shapeStyles[sublayer];
126                                 if (s.color) { icon.graphics.beginFill(s.color); }
127                                 if (s.casing_width || !isNaN(s.casing_color)) {
128                                         icon.graphics.lineStyle(s.casing_width ? s.casing_width : 1,
129                                                                                         s.casing_color ? s.casing_color : 0,
130                                                                                         s.casing_opacity ? s.casing_opacity : 1);
131                                 }
132                         }
133
134                         // return width
135                         return sl.pointStyles[sublayer].icon_width ? sl.pointStyles[sublayer].icon_width : 4;
136                 }
137
138                 private function addHitSprite(w:uint):void {
139             var hitzone:Sprite = new Sprite();
140             hitzone.graphics.lineStyle(4, 0x000000, 1, false, "normal", CapsStyle.ROUND, JointStyle.ROUND);
141                         hitzone.graphics.beginFill(0);
142                         hitzone.graphics.drawRect(0,0,w,w);
143             addToLayer(hitzone, CLICKSPRITE);
144             hitzone.visible = false;
145                         setListenSprite(hitzone);
146                 }
147
148                 private function loadedIcon(event:Event,sublayer:uint):void {
149                         var icon:Sprite=new Sprite();
150                         addToLayer(icon,STROKESPRITE,sublayer);
151                         icon.addChild(Bitmap(event.target.content));
152                         addHitSprite(icon.width);
153                         loaded=true;
154                         updatePosition();
155                 }
156
157                 private function updatePosition():void {
158                         if (!loaded) { return; }
159
160                         for (var i:uint=0; i<sprites.length; i++) {
161                                 var d:DisplayObject=sprites[i];
162                                 d.x=0; d.y=0; d.rotation=0;
163
164                                 var m:Matrix=new Matrix();
165                                 m.translate(-d.width/2,-d.height/2);
166                                 m.rotate(rotation);
167                                 m.translate(paint.map.lon2coord(Node(entity).lon),paint.map.latp2coord(Node(entity).latp));
168                                 d.transform.matrix=m;
169                         }
170                 }
171         }
172 }