Potlatch 2 in progress. Haven't figured out the mouse events still...
[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 Object {
17                 
18         private var node:Node;
19                 public var map:Map;                                                     // reference to parent map
20                 public var icon:Sprite;                                         // instance in display list
21                 public var name:Sprite;                                         //  |
22                 private var iconname:String='';                         // name of icon
23                 private var heading:Number=0;                           // heading within way
24                 private var rotation:Number=0;                          // rotation applied to this POI
25                 public var loaded:Boolean=false;
26
27                 public static const DEFAULT_TEXTFIELD_PARAMS:Object = {
28 //                      embedFonts: true,
29                         antiAliasType: AntiAliasType.ADVANCED,
30                         gridFitType: GridFitType.NONE
31                 };
32 //              [Embed(source="fonts/DejaVuSans.ttf", fontFamily="DejaVu", fontWeight="normal", mimeType="application/x-font-truetype")]
33 //              public static var DejaVu:Class;
34
35                 public function NodeUI(node:Node, map:Map, rotation:Number=0) {
36                         this.map = map;
37                         this.node = node;
38                         this.rotation = rotation;
39                         node.addEventListener(Connection.NODE_MOVED, nodeMoved);
40                 }
41                 
42                 public function nodeMoved(event:Event):void {
43                     updatePosition();
44                 }
45                 
46                 public function redraw(sl:StyleList=null,forceDraw:Boolean=false):Boolean {
47                         var tags:Object = node.getTagsCopy();
48                         tags['_heading']=heading;
49                         // ** apply :hover etc.
50                         if (!sl) { sl=map.ruleset.getStyles(this.node,tags); }
51
52                         var inWay:Boolean=node.hasParentWays;
53                         var hasStyles:Boolean=sl.hasStyles();
54                         
55                         removePrevious();
56                         if (!hasStyles && !inWay) {
57                                 // No styles, not in way; usually return, but render as green circle if showall set
58                                 if (!map.showall) { return false; }
59                                 return renderAsCircle();
60                         } else if (!hasStyles && inWay) {
61                                 // No styles, in way; so render as highlight
62                                 // *** needs to be blue/red depending on mouse-over
63                                 if (forceDraw) {
64                                         return renderAsSquare();
65                                 } else {
66                                         return false;
67                                 }
68                         } else {
69                                 // Styled, so render properly
70                                 return renderFromStyle(sl,tags);
71                         }
72                 }
73
74                 private function renderAsSquare():Boolean {
75                         createIcon();
76                         icon.graphics.beginFill(0xFF0000);
77                         icon.graphics.drawRect(0,0,6,6);        // ** NODESIZE
78                         loaded=true;
79                         updatePosition();
80                         iconname='_square';
81                         return true;
82                 }
83                 
84                 private function renderAsCircle():Boolean {
85                         createIcon();
86                         icon.graphics.lineStyle(1,0,1);
87                         icon.graphics.beginFill(0x00FF00);
88                         icon.graphics.drawCircle(4,4,4);        // ** NODESIZE
89                         loaded=true;
90                         updatePosition();
91                         iconname='_circle';
92                         return true;
93                 }
94                 
95                 private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
96                         var r:Boolean=false;    // ** rendered
97                         for (var sublayer:uint=0; sublayer<10; sublayer++) {
98
99                                 if (sl.pointStyles[sublayer]) {
100                                         var s:PointStyle=sl.pointStyles[sublayer];
101                                         r=true;
102                                         if (s.rotation) { rotation=s.rotation; }
103                                         if (s.icon_image!=iconname) {
104                                                 // 'load' icon (actually just from library)
105                                                 if (map.ruleset.images[s.icon_image]) {
106                                                         var loader:Loader = new Loader();
107                                                         loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedIcon);
108                                                         loader.loadBytes(map.ruleset.images[s.icon_image]);
109                                                         iconname=s.icon_image;
110                                                 }
111                                         } else {
112                                                 // already loaded, so just reposition
113                                                 updatePosition();
114                                         }
115                                 }
116
117                                 // name sprite
118                                 var a:String, t:TextStyle;
119                                 if (sl.textStyles[sublayer]) {
120                                         t=sl.textStyles[sublayer];
121                                         a=tags[t.text];
122                                 }
123
124                                 if (a) { 
125                                         var l:DisplayObject=map.getChildAt(map.NAMESPRITE);
126                                         if (!name) { name=new Sprite(); Sprite(l).addChild(name); }
127                                         t.writeNameLabel(name,a,map.lon2coord(node.lon),map.latp2coord(node.latp));
128                                 }
129                         }
130                         return r;
131                 }
132
133                 private function removePrevious():void {
134                         var l:DisplayObject;
135                         
136                         if (icon) {
137                                 l=map.getChildAt(map.POISPRITE);
138                                 Sprite(l).removeChild(icon);
139                                 icon=null;
140                                 iconname='';
141                         }
142                         if (name) {
143                                 l=map.getChildAt(map.NAMESPRITE);
144                                 Sprite(l).removeChild(name);
145                                 name=null;
146                         }
147                 }
148
149                 private function loadedIcon(event:Event):void {
150                         createIcon();
151                         icon.addChild(Bitmap(event.target.content));
152                         loaded=true;
153                         updatePosition();
154                 }
155
156                 private function createIcon():void {
157                         icon = new Sprite();
158                         var l:DisplayObject=map.getChildAt(map.POISPRITE);
159                         Sprite(l).addChild(icon);
160             icon.addEventListener(MouseEvent.CLICK, mouseEvent);
161             icon.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
162             icon.addEventListener(MouseEvent.MOUSE_OVER, mouseEvent);
163             icon.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
164             icon.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
165             icon.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
166             icon.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
167             icon.buttonMode = true;
168             icon.mouseEnabled = true;
169                 }
170
171         private function mouseEvent(event:MouseEvent):void {
172                         map.entityMouseEvent(event, node);
173         }
174
175                 private function updatePosition():void {
176                         if (!loaded || !icon) { return; }
177                         icon.x=0; icon.y=0; icon.rotation=0;
178
179                         var m:Matrix=new Matrix();
180 //                      m.identity();
181                         m.translate(-icon.width/2,-icon.height/2);
182                         m.rotate(rotation);
183                         m.translate(map.lon2coord(node.lon),map.latp2coord(node.latp));
184                         icon.transform.matrix=m;
185                 }
186
187         }
188 }