categories of additional tags for roads
[potlatch2.git] / net / systemeD / potlatch2 / TagViewer.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:VBox
3         xmlns:mx="http://www.adobe.com/2006/mxml"
4         xmlns:flexlib="flexlib.containers.*"
5     backgroundColor="white"
6     creationComplete="loadFeatures()">
7
8   <mx:ViewStack id="stack" width="100%" height="100%">
9   <mx:VBox width="100%" height="100%" label="Simple">
10     <mx:HBox borderStyle="inset" verticalAlign="middle" width="100%" paddingLeft="3" id="iconContainer">
11         <mx:Image id="iconImage"/>
12         <mx:VBox width="100%" verticalGap="1">
13           <mx:PopUpButton id="popupChange" creationComplete="initFeatureBox()" openAlways="true" width="100%"/>
14           <mx:Text condenseWhite="true" width="100%" id="iconText"/>
15         </mx:VBox>
16         <mx:LinkButton label="?" click="openDescription()" id="helpLabel"/>
17     </mx:HBox>
18     <flexlib:SuperTabNavigator id="editorStack" width="100%" height="100%" paddingLeft="2" paddingRight="2"
19         allowTabSqueezing="false" minTabWidth="10" closePolicy="close_never"
20         scrollSpeed="20"/>
21   </mx:VBox>
22
23   <mx:VBox width="100%" height="100%" label="Advanced" initialize="checkAdvanced()" verticalGap="1">
24     <mx:Label id="advancedID">
25       <mx:htmlText><![CDATA[<i>No Selection</i>]]></mx:htmlText>
26     </mx:Label>
27
28     <mx:DataGrid editable="true" width="100%" height="100%" id="advancedTagGrid">
29             <mx:columns>
30                 <mx:DataGridColumn editable="true" dataField="key" headerText="Key"/>
31                 <mx:DataGridColumn editable="true" dataField="value" headerText="Value"/>
32             </mx:columns>
33     </mx:DataGrid>
34
35     <mx:HBox horizontalAlign="right" width="100%">
36       <mx:LinkButton label="Delete" click="removeTag()"/>
37       <mx:LinkButton label="Add" click="addNewTag()"/>
38     </mx:HBox>
39   </mx:VBox>
40
41   </mx:ViewStack>
42
43   <mx:LinkBar dataProvider="{stack}"/>
44
45   <mx:Script><![CDATA[
46       import net.systemeD.halcyon.connection.*;
47       import net.systemeD.potlatch2.mapfeatures.*;
48
49       import mx.collections.*;
50       import mx.containers.*;
51       import mx.events.*;
52       import mx.core.*;
53       import mx.managers.PopUpManager;
54       import flash.geom.Point;
55       
56       private var mapFeatures:MapFeatures;
57       private var selectedEntity:Entity;
58       private var collection:ArrayCollection;
59       private var tw:CategorySelector = null;
60       private var feature:Feature = null;
61
62       public function setEntity(entity:Entity):void {
63           if ( selectedEntity != entity ) {
64               if ( selectedEntity != null )
65                   selectedEntity.removeEventListener(Connection.TAG_CHANGE, tagChanged);
66               selectedEntity = entity;
67               if ( selectedEntity != null )
68                   selectedEntity.addEventListener(Connection.TAG_CHANGE, tagChanged);
69           }
70
71           if ( advancedID != null )
72               setupAdvanced(entity);
73
74           refreshFeatureIcon();
75       }
76
77       private function refreshFeatureIcon():void {
78           var oldFeature:Feature = feature;
79           feature = selectedEntity == null ? null : mapFeatures.findMatchingFeature(selectedEntity);
80           if ( feature != oldFeature )
81               initialiseEditors();
82
83           if ( feature != null )
84               setFeatureIcon(selectedEntity, feature);
85           else
86               blankFeatureIcon(selectedEntity);
87       }
88
89       private function setFeatureIcon(entity:Entity, feature:Feature):void {
90           //blankFeatureIcon(entity);
91           
92           iconImage.source = feature.image;
93
94           var txt:String = feature.htmlDetails(entity);
95           iconText.htmlText = txt;
96           popupChange.label = feature.name;
97           tw.setSelectedFeature(feature);
98       }
99
100       private function blankFeatureIcon(entity:Entity):void {
101           iconImage.source = null;
102           iconText.htmlText = entity == null ?
103                "<i>Nothing selected</i>" :
104                "<b>Not recognised</b><br/>Try looking at the tags under the advanced properties";
105           popupChange.label = "unknown";
106           tw.setSelectedFeature(null);
107       }
108
109       private function initialiseEditors():void {
110           editorStack.removeAllChildren();
111           if ( selectedEntity == null || feature == null )
112               return;
113           
114           var editorBox:VBox = createEditorBox();
115           editorBox.label = "Basic";
116           editorStack.addChild(editorBox);
117           
118           var tabs:Object = {};
119           
120           for each (var factory:EditorFactory in feature.editors) {
121               if ( factory.presence.isEditorPresent(factory, selectedEntity, null) ) {
122                   var editor:DisplayObject = factory.createEditorInstance(selectedEntity);
123                   if ( editor != null )
124                       editorBox.addChild(editor);
125               }
126               var category:String = factory.category;
127               var tab:VBox = tabs[category];
128               if ( tab == null ) {
129                   tab = createEditorBox();
130                   tab.label = category;
131                   editorStack.addChild(tab);
132                   tabs[category] = tab;
133               }
134               var catEditor:DisplayObject = factory.createEditorInstance(selectedEntity);
135               if ( catEditor != null )
136                   tab.addChild(catEditor);
137           }
138       }
139       
140       private function createEditorBox():VBox {
141           var box:VBox = new VBox();
142           box.percentWidth = 100;
143           box.percentHeight = 100;
144           return box;
145       }
146
147       private function checkAdvanced():void {
148           if ( selectedEntity != null )
149              setupAdvanced(selectedEntity);
150       }
151
152       private function setupAdvanced(entity:Entity):void {
153           if ( collection == null ) {
154               collection = new ArrayCollection();
155               advancedTagGrid.dataProvider = collection;
156           }
157
158           collection.removeAll();
159           
160           if ( entity == null ) {
161               advancedID.htmlText = "";
162           } else {
163               var entityText:String = "xx";
164               if ( entity is Node ) entityText = "Node";
165               else if ( entity is Way ) entityText = "Way";
166               else if ( entity is Relation ) entityText = "Relation";
167               advancedID.htmlText = entityText+": <b>"+entity.id+"</b>";
168
169               var tags:Array = entity.getTagArray();
170               tags.sortOn("key");
171               for each(var tag:Tag in tags)
172                   collection.addItem(tag);
173           }
174       }
175
176       private function tagChanged(event:TagEvent):void {
177           refreshFeatureIcon();
178           
179           if ( collection != null ) {
180               // check to see if the key is already in our list
181               var exists:Boolean = false;
182               var tag:Tag = null;
183               var i:uint;
184               for ( i = 0; i < collection.length && !exists; i++ ) {
185                   tag = Tag(collection.getItemAt(i));
186                   exists = tag.key == event.key;
187               }
188               if ( !exists ) {
189                   tag = new Tag(selectedEntity, event.key, event.newValue);
190                   collection.addItem(tag);
191                   collection.refresh();
192               } else {
193                   if ( event.newValue == null ) {
194                       collection.removeItemAt(i-1);
195                       collection.refresh();
196                   } else {
197                       collection.itemUpdated(tag, "value");
198                   }
199               }
200           }
201       }
202
203       public function loadFeatures():void {
204           mapFeatures = MapFeatures.getInstance();
205       }
206
207       public function openDescription():void {
208           trace("open description here");
209       }
210
211       public function addNewTag():void {
212           var newKey:String = "(new tag)";
213           var newTag:Tag = new Tag(selectedEntity, newKey, "(new value)");
214           collection.addItem(newTag);
215           advancedTagGrid.editedItemPosition = {rowIndex: collection.getItemIndex(newTag), columnIndex: 0};
216       }
217
218       public function removeTag():void {
219           var k:String = advancedTagGrid.selectedItem.key;
220           selectedEntity.setTag(k, null);
221       }
222       
223       public function initFeatureBox():void {
224           tw = new CategorySelector();
225           tw.addEventListener("selectedType", changeFeatureType);
226           popupChange.popUp = tw;
227       }
228       
229       public function changeFeatureType(event:Event):void {
230           if ( selectedEntity == null )
231               return;
232
233           var newFeature:Feature = tw.selectedType;
234           
235           // remove tags from the current feature
236           if ( feature != null ) {
237               for each( var oldtag:Object in feature.tags ) {
238                   selectedEntity.setTag(oldtag["k"], null);
239               }
240           }
241           
242           // set tags for new feature
243           if ( newFeature != null ) {
244               for each( var newtag:Object in newFeature.tags ) {
245                   selectedEntity.setTag(newtag["k"], newtag["v"]);
246               }
247           }
248           
249           popupChange.close();
250       }
251   ]]></mx:Script>
252 </mx:VBox>
253