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