separate out TagGrid and do all the lovely autocomplete stuff
authorRichard Fairhurst <richard@systemed.net>
Tue, 2 Nov 2010 09:45:59 +0000 (09:45 +0000)
committerRichard Fairhurst <richard@systemed.net>
Tue, 2 Nov 2010 09:45:59 +0000 (09:45 +0000)
embedded/delete_small.svg [new file with mode: 0644]
net/systemeD/potlatch2/TagGrid.mxml [new file with mode: 0644]
net/systemeD/potlatch2/TagViewer.mxml
net/systemeD/potlatch2/mapfeatures/MapFeatures.as

diff --git a/embedded/delete_small.svg b/embedded/delete_small.svg
new file mode 100644 (file)
index 0000000..168262c
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 11 Build 196, SVG Export Plug-In . SVG Version: 6.0.0 Build 78)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+       <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+       <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+       <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+       <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+       <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+       <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+       <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+       <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+       <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+       <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg  xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
+        xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" width="12" height="12"
+        viewBox="0 0 12 12" overflow="visible" enable-background="new 0 0 12 12" xml:space="preserve">
+       <metadata>
+               <sfw  xmlns="&ns_sfw;">
+                       <slices></slices>
+                       <sliceSourceBounds  y="290.775" x="416.5" width="12" height="12" bottomLeftOrigin="true"></sliceSourceBounds>
+               </sfw>
+                       </metadata>
+               <g id="Layer_1">
+                       <circle fill="#808080" cx="6" cy="6" r="6"/> 
+                       <line fill="none" stroke="#FFFFFF" stroke-width="2" x1="3.046" y1="8.953" x2="8.953" y2="3.046"/>
+                       <line fill="none" stroke="#FFFFFF" stroke-width="2" x1="3.046" y1="3.046" x2="8.953" y2="8.953"/>
+               </g>
+       </svg>
diff --git a/net/systemeD/potlatch2/TagGrid.mxml b/net/systemeD/potlatch2/TagGrid.mxml
new file mode 100644 (file)
index 0000000..7a2f462
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+       Advanced tag grid
+       ** TODO: the 'X' button should be positioned more prettily
+-->
+
+<mx:DataGrid editable="true" doubleClickEnabled="true" doubleClick="addNewTag()"
+       xmlns:controls="net.systemeD.controls.*"
+       xmlns:mx="http://www.adobe.com/2006/mxml">
+       <mx:columns>
+
+               <!-- Key -->
+
+               <mx:DataGridColumn editable="true" dataField="key" headerText="Key">
+                       <mx:itemEditor>
+                               <mx:Component>
+                                       <controls:AutoComplete 
+                                               dataProvider="{MapFeatures.getInstance().getAutoCompleteKeys(outerDocument.getEntityType())}" 
+                                               labelField="name" 
+                                               rowCount="10"
+                                               typedText="{outerDocument.selectedItem.key}">
+                                       <mx:Script><![CDATA[ import net.systemeD.potlatch2.mapfeatures.*; ]]></mx:Script>
+                                       </controls:AutoComplete>
+                               </mx:Component>
+                       </mx:itemEditor>
+               </mx:DataGridColumn>
+
+               <!-- Value -->
+
+               <mx:DataGridColumn editable="true" dataField="value" headerText="Value">
+                       <mx:itemEditor>
+                               <mx:Component>
+                                       <controls:AutoComplete 
+                                               dataProvider="{MapFeatures.getInstance().getAutoCompleteValues(outerDocument.getEntityType(),outerDocument.selectedItem.key)}" 
+                                               labelField="name" 
+                                               rowCount="10"
+                                               typedText="{outerDocument.selectedItem.value}">
+                                       <mx:Script><![CDATA[ import net.systemeD.potlatch2.mapfeatures.*; ]]></mx:Script>
+                                       </controls:AutoComplete>
+                               </mx:Component>
+                       </mx:itemEditor>
+               </mx:DataGridColumn>
+
+               <!-- Delete button -->
+
+               <mx:DataGridColumn width="12" editable="false">
+                       <mx:itemRenderer>
+                               <mx:Component>
+                                       <mx:Image source="@Embed('../../../embedded/delete_small.svg')" 
+                                               click='event.stopPropagation();outerDocument.removeTag();'
+                                               buttonMode="true" useHandCursor="true">
+                                       </mx:Image>
+                               </mx:Component>
+                       </mx:itemRenderer>
+               </mx:DataGridColumn>
+       </mx:columns>
+
+       <mx:Script><![CDATA[
+
+               import net.systemeD.halcyon.connection.*;
+               import mx.collections.*;
+
+               private var selectedEntity:Entity;
+               private var tagDataProvider:ArrayCollection;
+
+               public function init(entity:Entity):void {
+                       if ( tagDataProvider == null ) {
+                               tagDataProvider = new ArrayCollection();
+                               dataProvider = tagDataProvider;
+                       }
+
+                       selectedEntity=entity;
+                       updateTagDataProvider();
+               }
+
+               private function updateTagDataProvider():void {
+                       tagDataProvider.removeAll();
+                       if (selectedEntity==null) { return; }
+                       var tags:Array = selectedEntity.getTagArray();
+                       tags.sortOn("key");
+                       for each(var tag:Tag in tags) { tagDataProvider.addItem(tag); }
+               }
+
+               public function addNewTag():void {
+                       var newKey:String = "(new tag)";
+                       var newTag:Tag = new Tag(selectedEntity, newKey, "(new value)");
+                       tagDataProvider.addItem(newTag);
+                       editedItemPosition = {rowIndex: tagDataProvider.getItemIndex(newTag), columnIndex: 0};
+               }
+
+               public function removeTag():void {
+                       var k:String = selectedItem.key;
+                       selectedEntity.setTag(k, null, MainUndoStack.getGlobalStack().addAction);
+                       updateTagDataProvider();
+               }
+               
+               public function getEntityType():String {
+                       return selectedEntity.getType();
+               }
+
+       ]]></mx:Script>
+</mx:DataGrid>
index e9df58d..1a57bfe 100644 (file)
@@ -3,6 +3,7 @@
        xmlns:mx="http://www.adobe.com/2006/mxml"
        xmlns:flexlib="flexlib.containers.*"
        xmlns:controls="net.systemeD.controls.*"
+       xmlns:potlatch2="net.systemeD.potlatch2.*"
        horizontalScrollPolicy="off"
     backgroundColor="white"
     initialize="loadFeatures()">
           <mx:htmlText><![CDATA[<i>No Selection</i>]]></mx:htmlText>
         </mx:Label>
 
-               <!-- ** FIXME:
-               
-                        This needs finishing and refactoring to:
-                        a) be a nice custom control which can be dropped in anywhere
-                        b) do autocomplete on values as well as keys
-                        c) do autocomplete on keys _properly_
-                        d) have proper lovely callback methods and events and stuff, rather than horrible parent.parent.parent.parent.badger.badger.badger hacks
-                        e) replace the big (X) with a little one
-                        f) be styled attractively
-                        g) generally suck less
-                       
-               -->
-
-        <mx:DataGrid editable="true" width="100%" height="75%" id="advancedTagGrid" 
-            doubleClickEnabled="true"
-            doubleClick="if (event.target.parent==advancedTagGrid) { addNewTag(); }">
-                <mx:columns>
-                    <mx:DataGridColumn editable="true" dataField="key" headerText="Key">
-                                               <mx:itemEditor>
-                                                       <mx:Component>
-                                                               <controls:AutoComplete 
-                                                                 dataProvider="{autoCompleteKeys()}" 
-                                                                 labelField="name" 
-                                                                 rowCount="10"
-                                                                 typedText="{getSelectedKey()}">
-                                                                       <mx:Script><![CDATA[
-                                                                               import net.systemeD.potlatch2.mapfeatures.MapFeatures;
-                                                                               import mx.collections.ArrayCollection;
-                                                                               import mx.controls.DataGrid;
-
-                                                                               public function autoCompleteKeys():Array {
-                                                                                       var a:Array=[];
-                                                                                       for each (var k:String in MapFeatures.getInstance().getAutoCompleteKeys()) {
-                                                                                               a.push( { name: k } );
-                                                                                       }
-                                                                                       return a;
-                                                                               }
-
-                                                                               internal function getSelectedKey():String {
-                                                                                       return DataGrid(this.parent.parent).selectedItem.key;
-                                                                               }
-                                                                       ]]></mx:Script>
-                                                               </controls:AutoComplete>
-                                                       </mx:Component>
-                                               </mx:itemEditor>
-                                       </mx:DataGridColumn>
-                    <mx:DataGridColumn editable="true" dataField="value" headerText="Value" />
-                                       <mx:DataGridColumn width="20" editable="false">
-                                               <mx:itemRenderer>
-                                                       <mx:Component>
-                                                               <mx:Image source="@Embed('../../../embedded/delete.svg')" 
-                                                                       click='event.stopPropagation();TagViewer(this.parent.parent.parent.parent.parent.parent.parent).removeTag();'
-                                                               buttonMode="true" useHandCursor="true" />
-                                                       </mx:Component>
-                                               </mx:itemRenderer>
-                                       </mx:DataGridColumn>
-                </mx:columns>
-        </mx:DataGrid>
+               <potlatch2:TagGrid id="advancedTagGrid" width="100%" height="75%" />
 
         <mx:HBox horizontalAlign="right" width="100%">
-          <mx:LinkButton label="Delete" click="removeTag()" enabled="{advancedTagGrid.selectedItem != null? true : false}"/>
-          <mx:LinkButton label="Add" click="addNewTag()"/>
+          <mx:LinkButton label="Delete" click="advancedTagGrid.removeTag()" enabled="{advancedTagGrid.selectedItem != null? true : false}"/>
+          <mx:LinkButton label="Add" click="advancedTagGrid.addNewTag()"/>
         </mx:HBox>
         
         <mx:DataGrid editable="true" width="100%" height="25%" id="relationsGrid"
       private var listeningToRelations:Array = [];
       
       private function setupAdvanced(entity:Entity):void {
-          if ( tagDataProvider == null ) {
-              tagDataProvider = new ArrayCollection();
-              advancedTagGrid.dataProvider = tagDataProvider;
-          }
+               advancedTagGrid.init(entity);
+
+               if ( entity == null ) {
+                       advancedID.htmlText = "";
+               } else {
+                       var entityText:String = "xx";
+                       if      ( entity is Node     ) entityText = "Node";
+                       else if ( entity is Way      ) entityText = "Way";
+                       else if ( entity is Relation ) entityText = "Relation";
+                       advancedID.htmlText = entityText+": <b>"+entity.id+"</b>";
+               }
 
-          tagDataProvider.removeAll();
-          
-          if ( entity == null ) {
-              advancedID.htmlText = "";
-          } else {
-              var entityText:String = "xx";
-              if ( entity is Node ) entityText = "Node";
-              else if ( entity is Way ) entityText = "Way";
-              else if ( entity is Relation ) entityText = "Relation";
-              advancedID.htmlText = entityText+": <b>"+entity.id+"</b>";
-
-              var tags:Array = entity.getTagArray();
-              tags.sortOn("key");
-              for each(var tag:Tag in tags)
-                  tagDataProvider.addItem(tag);
-          }
-                    
-          removeRelationListeners();
-          if ( selectedEntity != null ) {
-              selectedEntity.removeEventListener(Connection.ADDED_TO_RELATION, addedToRelation);
-              selectedEntity.removeEventListener(Connection.REMOVED_FROM_RELATION, removedFromRelation);
-          }
-          
-          if ( entity == null ) {
-              relationsGrid.dataProvider = null;
-          } else {
-              resetRelationsGrid(entity);
-              entity.addEventListener(Connection.ADDED_TO_RELATION, addedToRelation);
-              entity.addEventListener(Connection.REMOVED_FROM_RELATION, removedFromRelation);
-          }
+               removeRelationListeners();
+               if ( selectedEntity != null ) {
+                       selectedEntity.removeEventListener(Connection.ADDED_TO_RELATION, addedToRelation);
+                       selectedEntity.removeEventListener(Connection.REMOVED_FROM_RELATION, removedFromRelation);
+               }
+
+               if ( entity == null ) {
+                       relationsGrid.dataProvider = null;
+               } else {
+                       resetRelationsGrid(entity);
+                       entity.addEventListener(Connection.ADDED_TO_RELATION, addedToRelation);
+                       entity.addEventListener(Connection.REMOVED_FROM_RELATION, removedFromRelation);
+               }
       }
+
+         public function addNewTag():void {
+               if (stack.selectedChild!=advancedContainer) { return; }
+               advancedTagGrid.addNewTag();
+         }
       
       private function addedToRelation(event:RelationMemberEvent):void {
          resetRelationsGrid(selectedEntity);
           }
       }
 
-      public function addNewTag():void {
-          if (stack.selectedChild!=advancedContainer || selectedEntity == null) { return; }
-          var newKey:String = "(new tag)";
-          var newTag:Tag = new Tag(selectedEntity, newKey, "(new value)");
-          tagDataProvider.addItem(newTag);
-          advancedTagGrid.editedItemPosition = {rowIndex: tagDataProvider.getItemIndex(newTag), columnIndex: 0};
-      }
-
-      public function removeTag():void {
-          var k:String = advancedTagGrid.selectedItem.key;
-          selectedEntity.setTag(k, null, MainUndoStack.getGlobalStack().addAction);
-      }
-      
       public function addToRelation():void {
           new RelationSelectPanel().init(selectedEntity,new Object());
       }
index 9319190..072d78a 100644 (file)
@@ -27,7 +27,7 @@ package net.systemeD.potlatch2.mapfeatures {
         private var xml:XML = null;
         private var _features:Array = null;
         private var _categories:Array = null;
-               private var _keys:Array = null;
+//             private var _keys:Array = null;
                private var _tags:Object = null;
 
         protected function loadFeatures():void {
@@ -46,18 +46,17 @@ package net.systemeD.potlatch2.mapfeatures {
 
             xml = new XML(URLLoader(event.target).data);
             _features = [];
-                       _keys = [];
-                       _tags = {};
+                       _tags = { relation:{}, way:{}, node:{} };
 
             for each(var feature:XML in xml.feature) {
                 f=new Feature(this,feature);
                                _features.push(f);
                                for each (var tag:Object in f.tags) {
-                                       if (!_tags[tag.k]) { _tags[tag.k]=new Object; _keys.push(tag.k); }
-                                       _tags[tag.k][tag.v]=true;
+                                       if (f.isType('line') || f.isType('area')) { addToTagList('way',tag); }
+                                       if (f.isType('relation'))                                 { addToTagList('relation',tag); }
+                                       if (f.isType('point'))                                    { addToTagList('node',tag); }
                                }
             }            
-                       _keys.sort();
 
             _categories = new Array();
             for each(var catXML:XML in xml.category) {
@@ -67,6 +66,12 @@ package net.systemeD.potlatch2.mapfeatures {
             dispatchEvent(new Event("featuresLoaded"));
         }
 
+               private function addToTagList(type:String,tag:Object):void {
+                       if (tag.v=='*') { return; }
+                       if (!_tags[type][tag.k]) { _tags[type][tag.k]=new Array(); }
+                       if (_tags[type][tag.k].indexOf(tag.v)==-1) { _tags[type][tag.k].push(tag.v); }
+               }
+
         public function hasLoaded():Boolean {
             return xml != null;
         }
@@ -144,15 +149,25 @@ package net.systemeD.potlatch2.mapfeatures {
         }
 
                [Bindable(event="featuresLoaded")]
-               public function getAutoCompleteKeys():Array {
-                       return _keys;
-               }
-               
-               public function getAutoCompleteValues(key:String):Array {
+               public function getAutoCompleteKeys(type:String):Array {
                        var list:Array=[];
-                       for (var v:String in _tags[key]) { list.push(v); }
+                       var a:Array=[];
+
+                       for (var k:String in _tags[type]) { list.push(k); }
                        list.sort();
-                       return list;
+
+                       for each (k in list) { a.push( { name: k } ); }
+                       return a;
+               }
+               
+               [Bindable(event="featuresLoaded")]
+               public function getAutoCompleteValues(type:String,key:String):Array {
+                       var a:Array=[];
+                       if (_tags[type][key]) {
+                               _tags[type][key].sort();
+                               for each (var v:String in _tags[type][key]) { a.push( { name: v } ); }
+                       }
+                       return a;
                }
                
     }