filter category selector by element type
[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     initialize="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="75%" 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     
40     <mx:DataGrid editable="true" width="100%" height="25%" id="relationsGrid"
41         doubleClickEnabled="true"
42         itemDoubleClick="editRelation(ListEvent(event).rowIndex)">
43         <mx:columns>
44             <mx:DataGridColumn editable="false" dataField="description" headerText="Relation"/>
45             <mx:DataGridColumn editable="false" dataField="id" headerText="ID"/>
46             <mx:DataGridColumn editable="true" dataField="role" headerText="Role"/>
47         </mx:columns>
48     </mx:DataGrid>
49
50     <mx:HBox horizontalAlign="right" width="100%">
51       <mx:LinkButton label="Remove from" click="removeFromRelation()"/>
52       <mx:LinkButton label="Add to" click="addToRelation()"/>
53     </mx:HBox>
54
55   </mx:VBox>
56
57   </mx:ViewStack>
58
59   <mx:LinkBar dataProvider="{stack}"/>
60
61   <mx:Script><![CDATA[
62       import net.systemeD.halcyon.connection.*;
63       import net.systemeD.potlatch2.mapfeatures.*;
64
65       import mx.collections.*;
66       import mx.containers.*;
67       import mx.events.*;
68       import mx.core.*;
69       import mx.managers.PopUpManager;
70       import flash.geom.Point;
71       
72       private var mapFeatures:MapFeatures;
73       private var selectedEntity:Entity;
74       private var tagDataProvider:ArrayCollection;
75       private var tw:CategorySelector = null;
76       private var feature:Feature = null;
77
78       public function setEntity(entity:Entity):void {
79           if ( selectedEntity != entity ) {
80               if ( selectedEntity != null )
81                   selectedEntity.removeEventListener(Connection.TAG_CHANGE, tagChanged);
82               selectedEntity = entity;
83               if ( selectedEntity != null )
84                   selectedEntity.addEventListener(Connection.TAG_CHANGE, tagChanged);
85           }
86
87           if ( advancedID != null )
88               setupAdvanced(entity);
89
90           refreshFeatureIcon();
91       }
92
93       private function refreshFeatureIcon():void {
94           var oldFeature:Feature = feature;
95           feature = selectedEntity == null ? null : mapFeatures.findMatchingFeature(selectedEntity);
96           if ( feature != oldFeature )
97               initialiseEditors();
98
99           if ( feature != null )
100               setFeatureIcon(selectedEntity, feature);
101           else
102               blankFeatureIcon(selectedEntity);
103       }
104
105       private function setFeatureIcon(entity:Entity, feature:Feature):void {
106           //blankFeatureIcon(entity);
107           
108           iconImage.source = feature.image;
109
110           var txt:String = feature.htmlDetails(entity);
111           iconText.htmlText = txt;
112           popupChange.label = feature.name;
113           setLimitTypes(entity);
114           tw.setSelectedFeature(feature);
115       }
116       
117       private function setLimitTypes(entity:Entity):void {
118           var type:String = null;
119           if ( entity is Node )
120               type = "point";
121           else if ( entity is Way )
122               type = Way(entity).isArea() ? "area" : "line";
123           else if ( entity is Relation )
124               type = "relation";
125           tw.setLimitTypes(type);
126       }
127
128       private function blankFeatureIcon(entity:Entity):void {
129           iconImage.source = null;
130           iconText.htmlText = entity == null ?
131                "<i>Nothing selected</i>" :
132                "<b>Not recognised</b><br/>Try looking at the tags under the advanced properties";
133           popupChange.label = "unknown";
134           setLimitTypes(entity);
135           tw.setSelectedFeature(null);
136       }
137
138       private function initialiseEditors():void {
139           editorStack.removeAllChildren();
140           if ( selectedEntity == null || feature == null )
141               return;
142           
143           var editorBox:VBox = createEditorBox();
144           editorBox.label = "Basic";
145           editorStack.addChild(editorBox);
146           
147           var tabs:Object = {};
148           
149           for each (var factory:EditorFactory in feature.editors) {
150               if ( factory.presence.isEditorPresent(factory, selectedEntity, null) ) {
151                   var editor:DisplayObject = factory.createEditorInstance(selectedEntity);
152                   if ( editor != null )
153                       editorBox.addChild(editor);
154               }
155               var category:String = factory.category;
156               var tab:VBox = tabs[category];
157               if ( tab == null ) {
158                   tab = createEditorBox();
159                   tab.label = category;
160                   editorStack.addChild(tab);
161                   tabs[category] = tab;
162               }
163               var catEditor:DisplayObject = factory.createEditorInstance(selectedEntity);
164               if ( catEditor != null )
165                   tab.addChild(catEditor);
166           }
167       }
168       
169       private function createEditorBox():VBox {
170           var box:VBox = new VBox();
171           box.percentWidth = 100;
172           box.percentHeight = 100;
173           return box;
174       }
175
176       private function checkAdvanced():void {
177           if ( selectedEntity != null )
178              setupAdvanced(selectedEntity);
179       }
180
181       private function setupAdvanced(entity:Entity):void {
182           if ( tagDataProvider == null ) {
183               tagDataProvider = new ArrayCollection();
184               advancedTagGrid.dataProvider = tagDataProvider;
185           }
186
187           tagDataProvider.removeAll();
188           
189           if ( entity == null ) {
190               advancedID.htmlText = "";
191           } else {
192               var entityText:String = "xx";
193               if ( entity is Node ) entityText = "Node";
194               else if ( entity is Way ) entityText = "Way";
195               else if ( entity is Relation ) entityText = "Relation";
196               advancedID.htmlText = entityText+": <b>"+entity.id+"</b>";
197
198               var tags:Array = entity.getTagArray();
199               tags.sortOn("key");
200               for each(var tag:Tag in tags)
201                   tagDataProvider.addItem(tag);
202           }
203           
204           if ( entity == null ) {
205               relationsGrid.dataProvider = null;
206           } else {
207               var relations:Array = [];
208               for each( var rel:Relation in entity.parentRelations ) {
209                   var props:Object = {};
210                   props["relation"] = rel;
211                   props["id"] = rel.id;
212                   var memberIndex:uint = rel.findEntityMemberIndex(entity);
213                   props["role"] = rel.getMember(memberIndex).role;
214                   
215                   var desc:String = "";
216                   var relTags:Object = rel.getTagsHash();
217                   if ( relTags["type"] ) {
218                       desc = relTags["type"];
219                       if ( relTags[desc] )
220                           desc += " " + relTags[desc];
221                   }
222                   if ( relTags["ref"] )
223                       desc += " " + relTags["ref"];
224                   if ( relTags["name"] )
225                       desc += " " + relTags["name"];
226                   props["description"] = desc;
227                   
228                   relations.push(props);
229               }
230               relationsGrid.dataProvider = relations;
231           }
232       }
233
234       private function editRelation(index:uint):void {
235           trace("edit relation "+index+" "+selectedEntity.parentRelations[index]);
236           var panel:RelationEditorPanel = RelationEditorPanel(
237               PopUpManager.createPopUp(Application(Application.application), RelationEditorPanel, true));
238           panel.setRelation(selectedEntity.parentRelations[index]);
239           PopUpManager.centerPopUp(panel);
240       }
241       
242       private function tagChanged(event:TagEvent):void {
243           refreshFeatureIcon();
244           
245           if ( tagDataProvider != null ) {
246               // check to see if the key is already in our list
247               var exists:Boolean = false;
248               var tag:Tag = null;
249               var i:uint;
250               for ( i = 0; i < tagDataProvider.length && !exists; i++ ) {
251                   tag = Tag(tagDataProvider.getItemAt(i));
252                   exists = tag.key == event.key;
253               }
254               if ( !exists ) {
255                   tag = new Tag(selectedEntity, event.key, event.newValue);
256                   tagDataProvider.addItem(tag);
257                   tagDataProvider.refresh();
258               } else {
259                   if ( event.newValue == null ) {
260                       tagDataProvider.removeItemAt(i-1);
261                       tagDataProvider.refresh();
262                   } else {
263                       tagDataProvider.itemUpdated(tag, "value");
264                   }
265               }
266           }
267       }
268
269       public function loadFeatures():void {
270           mapFeatures = MapFeatures.getInstance();
271       }
272
273       public function openDescription():void {
274           trace("open description here");
275       }
276
277       public function addNewTag():void {
278           var newKey:String = "(new tag)";
279           var newTag:Tag = new Tag(selectedEntity, newKey, "(new value)");
280           tagDataProvider.addItem(newTag);
281           advancedTagGrid.editedItemPosition = {rowIndex: tagDataProvider.getItemIndex(newTag), columnIndex: 0};
282       }
283
284       public function removeTag():void {
285           var k:String = advancedTagGrid.selectedItem.key;
286           selectedEntity.setTag(k, null);
287       }
288       
289       public function addToRelation():void {
290       }
291       
292       public function removeFromRelation():void {
293       }
294       
295       public function initFeatureBox():void {
296           tw = new CategorySelector();
297           tw.addEventListener("selectedType", changeFeatureType);
298           popupChange.popUp = tw;
299       }
300       
301       public function changeFeatureType(event:Event):void {
302           if ( selectedEntity == null )
303               return;
304
305           var newFeature:Feature = tw.selectedType;
306           
307           // remove tags from the current feature
308           if ( feature != null ) {
309               for each( var oldtag:Object in feature.tags ) {
310                   selectedEntity.setTag(oldtag["k"], null);
311               }
312           }
313           
314           // set tags for new feature
315           if ( newFeature != null ) {
316               for each( var newtag:Object in newFeature.tags ) {
317                   selectedEntity.setTag(newtag["k"], newtag["v"]);
318               }
319           }
320           
321           popupChange.close();
322       }
323   ]]></mx:Script>
324 </mx:VBox>
325