more turn restriction stuff, and checkboxes, and a bunch of little fixes
[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 iconnames:Object={};                        // name of icon on each sublayer
19                 private var heading:Number=0;                           // heading within way
20                 private var rotation:Number=0;                          // rotation applied to this POI
21                 private static const NO_LAYER:int=-99999;
22
23                 public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, layer:int=NO_LAYER, sl:StyleList=null) {
24                         super(node,paint);
25                         if (layer==NO_LAYER) { this.layer=paint.maxlayer; } else { this.layer=layer; }
26                         this.heading = heading;
27             entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
28                         entity.addEventListener(Connection.NODE_MOVED, nodeMoved);
29                         entity.addEventListener(Connection.NODE_DELETED, nodeDeleted);
30             attachRelationListeners();
31                         redraw(sl);
32                 }
33                 
34                 public function nodeMoved(event:Event):void {
35                     updatePosition();
36                 }
37
38                 public function nodeDeleted(event:Event):void {
39                         removeSprites();
40                 }
41                 
42                 override public function doRedraw(sl:StyleList):Boolean {
43                         if (!paint.ready) { return false; }
44                         if (entity.deleted) { return false; }
45
46                         var tags:Object = entity.getTagsCopy();
47                         tags=applyStateClasses(tags);
48                         if (!entity.hasParentWays) { tags[':poi']='yes'; }
49                         if (!sl) { sl=paint.ruleset.getStyles(entity,tags,paint.map.scale); }
50
51                         var inWay:Boolean=entity.hasParentWays;
52                         var hasStyles:Boolean=sl.hasStyles();
53                         
54                         removeSprites(); iconnames={};
55                         return renderFromStyle(sl,tags);
56                 }
57
58                 private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
59                         var r:Boolean=false;                    // ** rendered
60                         var maxwidth:Number=4;                  // biggest width
61                         var w:Number;
62                         var icon:Sprite;
63                         interactive=false;
64                         for each (var sublayer:Number in sl.sublayers) {
65
66                                 if (sl.pointStyles[sublayer]) {
67                                         var s:PointStyle=sl.pointStyles[sublayer];
68                                         interactive||=s.interactive;
69                                         r=true;
70                                         if (s.rotation) { rotation=s.rotation; }
71                                         if (s.icon_image!=iconnames[sublayer]) {
72                                                 if (s.icon_image=='square') {
73                                                         // draw square
74                                                         icon=new Sprite();
75                                                         addToLayer(icon,STROKESPRITE,sublayer);
76                                                         w=styleIcon(icon,sl,sublayer);
77                                                         icon.graphics.drawRect(0,0,w,w);
78                                                         if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
79                                                         iconnames[sublayer]='_square';
80
81                                                 } else if (s.icon_image=='circle') {
82                                                         // draw circle
83                                                         icon=new Sprite();
84                                                         addToLayer(icon,STROKESPRITE,sublayer);
85                                                         w=styleIcon(icon,sl,sublayer);
86                                                         icon.graphics.drawCircle(w,w,w);
87                                                         if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
88                                                         iconnames[sublayer]='_circle';
89
90                                                 } else if (paint.ruleset.images[s.icon_image]) {
91                                                         // 'load' icon (actually just from library)
92                                                         var loader:ExtendedLoader = new ExtendedLoader();
93                                                         loader.info['sublayer']=sublayer;
94                                                         loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedIcon);
95                                                         loader.loadBytes(paint.ruleset.images[s.icon_image]);
96                                                         iconnames[sublayer]=s.icon_image;
97                                                 }
98                                         }
99                                 }
100
101                                 // name sprite
102                                 var a:String='', t:TextStyle;
103                                 if (sl.textStyles[sublayer]) {
104                                         t=sl.textStyles[sublayer];
105                                         interactive||=t.interactive;
106                                         a=tags[t.text];
107                                 }
108
109                                 if (a) { 
110                                         var name:Sprite=new Sprite();
111                                         addToLayer(name,NAMESPRITE);
112                                         t.writeNameLabel(name,a,0,0);
113                                 }
114                         }
115                         if (!r) { return false; }
116                         if (interactive) { addHitSprite(maxwidth); }
117                         updatePosition();
118                         return true;
119                 }
120
121
122                 private function styleIcon(icon:Sprite, sl:StyleList, sublayer:Number):Number {
123                         loaded=true;
124
125                         // get colours
126                         if (sl.shapeStyles[sublayer]) {
127                                 var s:ShapeStyle=sl.shapeStyles[sublayer];
128                                 if (s.color) { icon.graphics.beginFill(s.color); 
129                                         }
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;
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, NODECLICKSPRITE);
147             hitzone.visible = false;
148                         setListenSprite(NODECLICKSPRITE, hitzone);
149                 }
150
151                 private function loadedIcon(event:Event):void {
152                         var icon:Sprite=new Sprite();
153                         var sublayer:Number=event.target.loader.info['sublayer'];
154                         addToLayer(icon,STROKESPRITE,sublayer);
155                         icon.addChild(Bitmap(event.target.content));
156                         addHitSprite(icon.width);
157                         loaded=true;
158                         updatePosition();
159                 }
160
161                 private function updatePosition():void {
162                         if (!loaded) { return; }
163
164                         for (var i:uint=0; i<sprites.length; i++) {
165                                 var d:DisplayObject=sprites[i];
166                                 d.x=0; d.y=0; d.rotation=0;
167
168                                 var m:Matrix=new Matrix();
169                                 m.translate(-d.width/2,-d.height/2);
170                                 m.rotate(rotation);
171                                 m.translate(paint.map.lon2coord(Node(entity).lon),paint.map.latp2coord(Node(entity).latp));
172                                 d.transform.matrix=m;
173                         }
174                 }
175         }
176 }