Add some ASDoc comments to mapfeature-related classes. Probably best if someone quick...
authorSteve Bennett <stevagewp@gmail.com>
Sat, 11 Dec 2010 12:14:35 +0000 (12:14 +0000)
committerSteve Bennett <stevagewp@gmail.com>
Sat, 11 Dec 2010 12:14:35 +0000 (12:14 +0000)
Also replaced a few tab characters with 4 spaces. Hope that's ok.

net/systemeD/potlatch2/CategorySelector.mxml
net/systemeD/potlatch2/TagGrid.mxml
net/systemeD/potlatch2/mapfeatures/Category.as
net/systemeD/potlatch2/mapfeatures/Feature.as
net/systemeD/potlatch2/mapfeatures/MapFeatures.as

index 15e05ea..128bd42 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <mx:VBox
-       xmlns:mx="http://www.adobe.com/2006/mxml" 
+       xmlns:mx="http://www.adobe.com/2006/mxml"
        xmlns:halcyon="net.systemeD.halcyon.*"
        backgroundColor="white" borderStyle="inset">
 
-  <mx:HBox horizontalGap="0"> 
+  <mx:HBox horizontalGap="0">
   <mx:ToggleButtonBar height="100%" dataProvider="{categoryStack}" direction="vertical" styleName="catToggleButtonBar"/>
   <mx:ViewStack id="categoryStack" width="100%" height="100%"
-      change="_formerIndex=event.newIndex;" 
+      change="_formerIndex=event.newIndex;"
       creationComplete="setSelectedFeature(_selectedType);">
       <mx:Repeater id="catRep" dataProvider="{MapFeatures.getInstance().getCategoriesForType(limit)}">
           <mx:VBox label="{catRep.currentItem.name}">
       </mx:Repeater>
   </mx:ViewStack>
   </mx:HBox>
-  
+
   <!-- mx:Label id="hoverInfo" text="Hover Info goes here"/>-->
-  
   <mx:Script><![CDATA[
+
+
       import net.systemeD.halcyon.connection.*;
       import net.systemeD.potlatch2.mapfeatures.*;
 
       import mx.controls.*;
       import mx.containers.*;
       import mx.events.IndexChangedEvent;
-      
+
+      /** Set briefly by ensureSelection() (presumably to avoid an event race condition). */
       private var settingSelection:Boolean = false;
       private var _selectedType:Feature;
       private var _limit:String;
       private var _formerIndex:int=0;
-      
+
       [Bindable(event="selectedType")]
+      /** The Feature type (eg, "residential road") currently selected. */
       public function get selectedType():Feature {
           return _selectedType;
       }
-      
+
       [Bindable(event="limitChanged")]
+      /** The type of features currently shown ("area", "node"...) */
       public function get limit():String {
           return _limit;
       }
-      
+
+      /** Determine which feature was clicked on, and set that as the currently selected type. */
       private function itemSelected(event:Event):void {
           _selectedType = Feature(TileList(event.currentTarget).selectedItem);
           if ( !settingSelection )
               dispatchEvent(new Event("selectedType"));
       }
-      
+
+      /** Set the current type of Features that will be shown ("area", "node"... )*/
       public function setLimitTypes(type:String):void {
           _limit = type;
           dispatchEvent(new Event("limitChanged"));
       }
-      
+
       /**
        * Set the selected feature displayed in the selector.
        *
        * The tab is switched to the first category the feature
        * is part of.
        *
+       * @param feature The feature to make selected.
        */
       public function setSelectedFeature(feature:Feature):void {
           _selectedType = feature;
-          
+
           // check whether stack built yet, if not we get called again when it's made
           if ( categoryStack == null )
               return;
 
           // set the tab to the selected item's category
-          // (we have to manually fire the IndexChangedEvent because Flex's ViewStack.as isn't competent 
+          // (we have to manually fire the IndexChangedEvent because Flex's ViewStack.as isn't competent
           //  enough to do it reliably. This is basically a direct crib from dispatchChangeEvent)
           var index:int=0;
           if ( feature != null ) {
           categoryStack.selectedIndex = index;
           categoryStack.dispatchEvent(event);
           _formerIndex=index;
-          
+
           // finalise the item selection
           ensureSelection();
       }
       public function setNoSelectedFeature():void {
-           _selectedType=null;
+           /*_selectedType=null;*/
+           setSelectedFeature(null);
          }
-      
+
       /**
        * Sets the selected feature on each category page to the current
        * value of _selectedType. If there is no selected feature then all
        *
        * Called both from setSelectedFeature, and category tab completion
        * (so that newly created tabs work as expected)
-       */   
+       */
       private function ensureSelection():void {
           settingSelection = true;
           for (var i:Number = 0; i < categoryStack.numChildren; i++) {
           }
           settingSelection = false;
       }
-      
+
   ]]></mx:Script>
 </mx:VBox>
 
index 5c21cb6..5f48986 100644 (file)
@@ -15,9 +15,9 @@
                <mx:DataGridColumn editable="true" dataField="key" headerText="Key">
                        <mx:itemEditor>
                                <mx:Component>
-                                       <controls:AutoComplete 
-                                               dataProvider="{MapFeatures.getInstance().getAutoCompleteKeys(outerDocument.getEntityType())}" 
-                                               labelField="name" 
+                                       <controls:AutoComplete
+                                               dataProvider="{MapFeatures.getInstance().getAutoCompleteKeys(outerDocument.getEntityType())}"
+                                               labelField="name"
                                                rowCount="10"
                                                restrict="&#x0020;-&#x10FFFF;"
                                                typedText="{outerDocument.selectedItem.key}">
@@ -32,9 +32,9 @@
                <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" 
+                                       <controls:AutoComplete
+                                               dataProvider="{MapFeatures.getInstance().getAutoCompleteValues(outerDocument.getEntityType(),outerDocument.selectedItem.key)}"
+                                               labelField="name"
                                                rowCount="10"
                                                restrict="&#x0020;-&#x10FFFF;"
                                                typedText="{outerDocument.selectedItem.value}">
@@ -49,7 +49,7 @@
                <mx:DataGridColumn width="12" editable="false">
                        <mx:itemRenderer>
                                <mx:Component>
-                                       <mx:Image source="@Embed('../../../embedded/delete_small.svg')" 
+                                       <mx:Image source="@Embed('../../../embedded/delete_small.svg')"
                                                click='event.stopPropagation();outerDocument.removeTag();'
                                                buttonMode="true" useHandCursor="true">
                                        </mx:Image>
@@ -66,6 +66,7 @@
                private var selectedEntity:Entity;
                private var tagDataProvider:ArrayCollection;
 
+               /** Assign a new selected Entity, and update editing controls appropriately. */
                public function init(entity:Entity):void {
                        if ( tagDataProvider == null ) {
                                tagDataProvider = new ArrayCollection();
@@ -85,6 +86,7 @@
                        for each(var tag:Tag in tags) { tagDataProvider.addItem(tag); }
                }
 
+               /** Create editing controls for a new key/value pair, with default values. */
                public function addNewTag():void {
                        var newKey:String = "(new tag)";
                        var newTag:Tag = new Tag(selectedEntity, newKey, "(new value)");
                        editedItemPosition = {rowIndex: tagDataProvider.getItemIndex(newTag), columnIndex: 0};
                }
 
+               /** Remove the selected tag from the selected entity. */
                public function removeTag():void {
                        var k:String = selectedItem.key;
                        selectedEntity.setTag(k, null, MainUndoStack.getGlobalStack().addAction);
                        updateTagDataProvider();
                }
-               
+
+               /** Return the type ("node", "way", "relation") of the selected entity. */
                public function getEntityType():String {
                        return selectedEntity.getType();
                }
index 956af13..4c67960 100644 (file)
@@ -3,10 +3,13 @@ package net.systemeD.potlatch2.mapfeatures {
     import flash.events.EventDispatcher;
     import flash.events.Event;
 
+        /** A Category is a (non-exclusive) grouping of related Features used to help the user find the map feature they are interested in using. */
        public class Category extends EventDispatcher {
         private var mapFeatures:MapFeatures;
+        /** The human-meaningful name of the category (eg, "Roads") */
         private var _name:String;
         private var _id:String;
+        /** The features that belong to this category. */
         private var _features:Array;
         private var _index:uint;
 
@@ -15,7 +18,7 @@ package net.systemeD.potlatch2.mapfeatures {
             this._name = name;
             this._id = id;
             this._index = globalIndex;
-            
+
             _features = new Array();
             for each( var feature:Feature in mapFeatures.features ) {
                 if ( feature.isInCategory(id) )
@@ -26,7 +29,7 @@ package net.systemeD.potlatch2.mapfeatures {
         public function get id():String {
             return _id;
         }
-        
+
         public function get index():uint {
             return _index;
         }
@@ -35,17 +38,18 @@ package net.systemeD.potlatch2.mapfeatures {
         public function get name():String {
             return _name;
         }
-        
+
         [Bindable(event="featuresChanged")]
         public function get features():Array {
             return _features;
         }
-        
+
         [Bindable(event="featuresChanged")]
+        /** Get an array of all features in this category that have the requested type, or possibly empty list. */
         public function getFeaturesForType(type:String):Array {
             if ( type == null || type == "" )
                 return []; //_features;
-                
+
             var filteredFeatures:Array = new Array();
             for each( var feature:Feature in _features ) {
                 if ( feature.isType(type) )
@@ -53,7 +57,7 @@ package net.systemeD.potlatch2.mapfeatures {
             }
             return filteredFeatures;
         }
-        
+
     }
 }
 
index 323392d..b7083ea 100644 (file)
@@ -6,16 +6,19 @@ package net.systemeD.potlatch2.mapfeatures {
     import flash.utils.ByteArray;
     import mx.core.BitmapAsset;
     import mx.graphics.codec.PNGEncoder;
-    
+
     import net.systemeD.halcyon.connection.Entity;
     import net.systemeD.potlatch2.utils.CachedDataLoader;
 
+        /** A "map feature" is sort of a template for a map entity. It consists of a few crucial key/value pairs that define the feature, so that
+         * entities can be recognised. It also contains optional keys, with associated editing controls, that are defined as being appropriate
+         * for the feature. */
        public class Feature extends EventDispatcher {
         private var mapFeatures:MapFeatures;
         private var _xml:XML;
         private static var variablesPattern:RegExp = /[$][{]([^}]+)[}]/g;
         private var _tags:Array;
-               private var _withins:Array;
+       private var _withins:Array;
         private var _editors:Array;
 
         [Embed(source="../../../../embedded/missing_icon.png")]
@@ -29,11 +32,11 @@ package net.systemeD.potlatch2.mapfeatures {
             parseConditions();
             parseEditors();
         }
-        
+
         private function parseConditions():void {
             _tags = [];
-                       _withins = [];
-            
+           _withins = [];
+
                        // parse tags
             for each(var tag:XML in definition.tag) {
                 _tags.push( { k:String(tag.@k), v:String(tag.@v)} );
@@ -48,30 +51,30 @@ package net.systemeD.potlatch2.mapfeatures {
                 _withins.push(obj);
             }
         }
-        
+
         private function parseEditors():void {
             _editors = new Array();
-            
+
             addEditors(definition);
-            
+
             _editors.sortOn(["sortOrder", "name"], [Array.DESCENDING | Array.NUMERIC, Array.CASEINSENSITIVE]);
         }
-        
+
         private function addEditors(xml:XML):void {
             var inputXML:XML;
-            
+
             for each(var inputSetRef:XML in xml.inputSet) {
                 var setName:String = String(inputSetRef.@ref);
                 for each (inputXML in mapFeatures.definition.inputSet.(@id==setName)) {
                     addEditors(inputXML);
                 }
             }
-            
+
             for each(inputXML in xml.input) {
                 addEditor(inputXML);
             }
         }
-        
+
         private function addEditor(inputXML:XML):void {
             var inputType:String = inputXML.@type;
             var presenceStr:String = inputXML.@presence;
@@ -83,22 +86,26 @@ package net.systemeD.potlatch2.mapfeatures {
                 _editors.push(editor);
             }
         }
-        
+
+        /** List of editing controls associated with this feature. */
         public function get editors():Array {
             return _editors;
         }
-        
+
+        /** The XML subtree that this feature was loaded from. */
         public function get definition():XML {
             return _xml;
         }
-    
+
         [Bindable(event="nameChanged")]
+        /** The human-readable name of the feature, or null if none. */
         public function get name():String {
                        if (_xml.attribute('name').length()>0) { return _xml.@name; }
                        return null;
         }
-    
+
         [Bindable(event="imageChanged")]
+        /** An icon for the feature. If none is defined, return default "missing icon". */
         public function get image():ByteArray {
             var icon:XMLList = _xml.icon;
             var imageURL:String = null;
@@ -116,20 +123,20 @@ package net.systemeD.potlatch2.mapfeatures {
             var bitmap:BitmapAsset = new missingIconCls() as BitmapAsset;
             return new PNGEncoder().encode(bitmap.bitmapData);
         }
-        
+
         private function imageLoaded(url:String, data:ByteArray):void {
             dispatchEvent(new Event("imageChanged"));
         }
-        
+
         public function htmlDetails(entity:Entity):String {
             var icon:XMLList = _xml.icon;
             return makeHTMLIcon(icon, entity);
-        }   
+        }
 
         public static function makeHTMLIcon(icon:XMLList, entity:Entity):String {
             if ( icon == null )
                 return "";
-            
+
             var txt:String = icon.children().toXMLString();
             var replaceTag:Function = function():String {
                 var value:String = entity.getTag(arguments[1]);
@@ -138,7 +145,7 @@ package net.systemeD.potlatch2.mapfeatures {
             txt = txt.replace(variablesPattern, replaceTag);
             return txt;
         }
-        
+
         public static function htmlEscape(str:String):String {
             var newStr:String = str.replace(/&/g, "&amp;");
             newStr = newStr.replace(/</g, "&lt;");
@@ -147,27 +154,31 @@ package net.systemeD.potlatch2.mapfeatures {
             newStr = newStr.replace(/'/g, "&apos;");   // '
             return newStr;
         }
-      
 
+        /** Whether this feature belongs to the given category or not, as defined by its definition in the XML file. */
         public function isInCategory(category:String):Boolean {
             var cats:XMLList = _xml.category;
             if ( cats.length() == 0 )
                 return false;
-                
+
             for each( var cat:XML in cats )
                 if ( cat.text()[0] == category )
                     return true;
             return false;
         }
-        
+
+
+        /** List of {k, v} pairs that define the feature. */
         public function get tags():Array {
             return _tags;
         }
 
+        /** List of "withins" which further restrict the applicability of the feature. Each within is a {entity, k, ?v, ?minimum, ?role} object. */
         public function get withins():Array {
             return _withins;
         }
-        
+
+        /** The first category that the feature belongs to, as defined by the order of the map features XML file. */
         public function findFirstCategory():Category {
             for each( var cat:Category in mapFeatures.categories ) {
                 if ( isInCategory(cat.id) )
@@ -175,7 +186,8 @@ package net.systemeD.potlatch2.mapfeatures {
             }
             return null;
         }
-        
+
+        /** Whether the feature is of the given type (point, line/area, relation). */
         public function isType(type:String):Boolean {
             if (type=='area') {
                            return (_xml.elements(type).length() > 0) || (_xml.elements('line').length() > 0);
@@ -183,11 +195,13 @@ package net.systemeD.potlatch2.mapfeatures {
                            return _xml.elements(type).length() > 0;
                        }
         }
-        
+
+        /** Whether there is a help string defined. */
         public function hasHelpURL():Boolean {
             return _xml.help.length() > 0;
         }
-        
+
+        /** The defined help string, if any. */
         public function get helpURL():String {
             return _xml.help;
         }
index 072d78a..1fd24f6 100644 (file)
@@ -13,9 +13,16 @@ package net.systemeD.potlatch2.mapfeatures {
     import net.systemeD.halcyon.connection.*;
        import net.systemeD.halcyon.DebugURLRequest;
 
+        /** All the information about all available map features that can be selected by the user or matched against entities in the map.
+        * The list of map features is populated from an XML file the first time the MapFeatures instance is accessed.
+        *
+        * <p>There are four "types" of features: point, line, area, relation. However, the autocomplete functions refer to these as node,
+        * way (line/area) and relation.</p>
+        */
        public class MapFeatures extends EventDispatcher {
         private static var instance:MapFeatures;
 
+        /** Instantiates MapFeatures by loading it if required. */
         public static function getInstance():MapFeatures {
             if ( instance == null ) {
                 instance = new MapFeatures();
@@ -30,6 +37,7 @@ package net.systemeD.potlatch2.mapfeatures {
 //             private var _keys:Array = null;
                private var _tags:Object = null;
 
+        /** Loads list of map features from XML file which it first retrieves. */
         protected function loadFeatures():void {
             var request:DebugURLRequest = new DebugURLRequest("map_features.xml");
             var loader:URLLoader = new URLLoader();
@@ -37,26 +45,28 @@ package net.systemeD.potlatch2.mapfeatures {
             loader.load(request.request);
         }
 
+        /** The loaded source XML file itself. */
         internal function get definition():XML {
             return xml;
         }
-        
+
+        /** Load XML file, then trawl over it, setting up convenient indexes into the list of map features. */
         private function onFeatureLoad(event:Event):void {
                        var f:Feature;
 
             xml = new XML(URLLoader(event.target).data);
             _features = [];
-                       _tags = { relation:{}, way:{}, node:{} };
+            _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 (f.isType('line') || f.isType('area')) { addToTagList('way',tag); }
-                                       if (f.isType('relation'))                                 { addToTagList('relation',tag); }
-                                       if (f.isType('point'))                                    { addToTagList('node',tag); }
-                               }
-            }            
+                _features.push(f);
+                for each (var tag:Object in f.tags) {
+                    if (f.isType('line') || f.isType('area')) { addToTagList('way',tag); }
+                    if (f.isType('relation'))                 { addToTagList('relation',tag); }
+                    if (f.isType('point'))                    { addToTagList('node',tag); }
+                }
+            }
 
             _categories = new Array();
             for each(var catXML:XML in xml.category) {
@@ -65,17 +75,25 @@ package net.systemeD.potlatch2.mapfeatures {
             }
             dispatchEvent(new Event("featuresLoaded"));
         }
-
+                /** Add one item to tagList index, which will end up being a list like: ["way"]["highway"]["residential"] */
                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); }
                }
 
+        /** Indicates whether the XML file has finished being loaded. */
         public function hasLoaded():Boolean {
             return xml != null;
         }
 
+        /** Find the first Feature (template) that matches the given Entity (actual existing object in the map).
+         *
+         * This is done to provide appropriate editing controls that correspond to the selected Entity.
+         *
+         * @param entity The Entity to try and match against.
+         * @return The first suitable Feature, or null. */
+
         public function findMatchingFeature(entity:Entity):Feature {
             if ( xml == null )
                 return null;
@@ -90,35 +108,41 @@ package net.systemeD.potlatch2.mapfeatures {
                     if ( !match ) break;
                 }
 
-                               // check for matching withins
-                               if (match) {
-                                       for each (var within:Object in feature.withins) {
-                                               match = entity.countParentObjects(within) >= (within.minimum ? within.minimum : 1);
-                                               if (!match) { break; }
-                                       }
-                               }
+               // check for matching withins
+                if (match) {
+                    for each (var within:Object in feature.withins) {
+                        match = entity.countParentObjects(within) >= (within.minimum ? within.minimum : 1);
+                        if (!match) { break; }
+                    }
+                }
 
                 if (match) {
                     return feature;
-                               }
+                }
             }
             return null;
         }
-        
+
         [Bindable(event="featuresLoaded")]
+        /** Array of every Category found in the map features file. */
         public function get categories():Array {
             if ( xml == null )
-                return null;        
+                return null;
             return _categories;
         }
 
         [Bindable(event="featuresLoaded")]
+        /** Categories that contain at least one Feature corresponding to a certain type, such as "area" or "point".
+        *
+        * @return Filtered Array of Category objects, possibly empty. null if XML file is not yet processed.
+        */
+
         public function getCategoriesForType(type:String):Array {
             if ( xml == null )
                 return null;
-            if ( type == null || type == "" )  
+            if ( type == null || type == "" )
                 return []; //_categories;
-                
+
             var filteredCategories:Array = new Array();
             for each( var cat:Category in _categories ) {
                 if ( cat.getFeaturesForType(type).length > 0 )
@@ -128,48 +152,66 @@ package net.systemeD.potlatch2.mapfeatures {
         }
 
         [Bindable(event="featuresLoaded")]
+        /** All features.
+        *
+        * @return null if XML file not yet processed. */
         public function get features():Array {
             if ( xml == null )
-                return null;            
+                return null;
             return _features;
         }
 
         [Bindable(event="featuresLoaded")]
+        /** All Features of type "point".
+        *
+        * @return null if XML file not yet processed.
+        */
+
         public function get pois():Array {
             if (xml == null )
                 return null;
             var pois:Array = [];
             var counter:int = 0;
             for each ( var feature:Feature in _features ) {
-              if (feature.isType("point")) {
-                pois.push(feature);
-              }
+                  if (feature.isType("point")) {
+                  pois.push(feature);
+                  }
             }
             return pois;
         }
 
-               [Bindable(event="featuresLoaded")]
-               public function getAutoCompleteKeys(type:String):Array {
-                       var list:Array=[];
-                       var a:Array=[];
+        [Bindable(event="featuresLoaded")]
+        /** A list of all Keys for all features of the given type, sorted.
+         * @example <listing version="3.0">getAutoCompleteKeys ("way")</listing>
+         * Returns: [{name: "building"}, {name: "highway"}...]
+         */
+        public function getAutoCompleteKeys(type:String):Array {
+            var list:Array=[];
+            var a:Array=[];
+
+            for (var k:String in _tags[type]) { list.push(k); }
+                list.sort();
+
+                for each (k in list) { a.push( { name: k } ); }
+                    return a;
+                }
 
-                       for (var k:String in _tags[type]) { list.push(k); }
-                       list.sort();
+        [Bindable(event="featuresLoaded")]
+        /** Get all the possible values that could go with a given key and type.
+        * TODO: Include values previously entered by the user, but not existent in XML file.
+        *
+        * @example <listing version="3.0">getAutoCompleteValues("way", "highway")</listing>
+        * Returns: [{name: "motorway"}, {name: "residential"}...]
+        */
+        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;
+        }
 
-                       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;
-               }
-               
     }
 
 }