--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox
+ xmlns:mx="http://www.adobe.com/2006/mxml"
+ xmlns:halcyon="net.systemeD.halcyon.*">
+
+ <mx:HBox horizontalGap="0">
+ <mx:ToggleButtonBar height="100%" dataProvider="{categoryStack}" direction="vertical"/>
+ <mx:ViewStack id="categoryStack" width="100%" height="100%">
+ <mx:Repeater id="catRep" dataProvider="{MapFeatures.getInstance().categories}">
+ <mx:VBox label="{catRep.currentItem.name}">
+ <mx:TileList dataProvider="{catRep.currentItem.features}"
+ width="100%" height="100%" change="itemSelected(event);">
+ <mx:itemRenderer>
+ <mx:Component>
+ <mx:VBox width="100" height="75"
+ horizontalScrollPolicy="off" verticalScrollPolicy="off"
+ horizontalAlign="center" verticalGap="0">
+ <mx:Image source="{data.image}" height="100%" verticalAlign="middle"/>
+ <mx:Text text="{data.name}"/>
+ </mx:VBox>
+ </mx:Component>
+ </mx:itemRenderer>
+ </mx:TileList>
+ </mx:VBox>
+ </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.halcyon.mapfeatures.*;
+
+ import mx.controls.*;
+
+ private var _selectedType:Feature;
+
+ [Bindable(event="selectedType")]
+ public function get selectedType():Feature {
+ return _selectedType;
+ }
+
+ private function itemSelected(event:Event):void {
+ _selectedType = Feature(TileList(event.currentTarget).selectedItem);
+ dispatchEvent(new Event("selectedType"));
+ }
+ ]]></mx:Script>
+</mx:VBox>
+
creationComplete="loadFeatures()">
<mx:ViewStack id="stack" width="100%" height="100%">
-
<mx:VBox width="100%" height="100%" label="Simple">
<mx:HBox borderStyle="inset" verticalAlign="middle" width="100%" paddingLeft="3" id="iconContainer">
<mx:Image id="iconImage"/>
- <mx:Text condenseWhite="true" width="100%" id="iconText"/>
+ <mx:VBox width="100%" verticalGap="1">
+ <mx:PopUpButton id="popupChange" creationComplete="initFeatureBox()" openAlways="true" width="100%"/>
+ <mx:Text condenseWhite="true" width="100%" id="iconText"/>
+ </mx:VBox>
<mx:LinkButton label="?" click="openDescription()" id="helpLabel"/>
</mx:HBox>
</mx:VBox>
import net.systemeD.halcyon.connection.*;
import net.systemeD.halcyon.mapfeatures.*;
- import mx.collections.*
-
+ import mx.collections.*;
+ import mx.containers.*;
+ import mx.events.*;
+ import mx.core.*;
+ import mx.managers.PopUpManager;
+ import flash.geom.Point;
+
private var mapFeatures:MapFeatures;
private var selectedEntity:Entity;
- private var variablesPattern:RegExp = /[$][{]([^}]+)[}]/g;
private var collection:ArrayCollection;
+ private var tw:CategorySelector = null;
+ private var feature:Feature = null;
public function setEntity(entity:Entity):void {
if ( selectedEntity != entity ) {
}
private function refreshFeatureIcon():void {
- var feature:XML = mapFeatures.findMatchingFeature(selectedEntity);
+ feature = mapFeatures.findMatchingFeature(selectedEntity);
if ( feature != null )
setFeatureIcon(selectedEntity, feature);
else
blankFeatureIcon(selectedEntity);
}
- private function setFeatureIcon(entity:Entity, feature:XML):void {
+ private function setFeatureIcon(entity:Entity, feature:Feature):void {
blankFeatureIcon(entity);
+
+ iconImage.source = feature.image;
- var icon:XMLList = feature.icon;
- if ( icon.length == 0 )
- return;
-
- if ( icon[0].hasOwnProperty("@image") ) {
- iconImage.source = icon.@image;
- }
-
- var txt:String = icon.children().toXMLString();
- var replaceTag:Function = function():String {
- var value:String = entity.getTag(arguments[1]);
- return value == null ? "" : value;
- };
- txt = txt.replace(variablesPattern, replaceTag);
- iconText.htmlText = "<i>"+feature.@name+"</i><br/>" + txt;
+ var txt:String = feature.htmlDetails(entity);
+ iconText.htmlText = txt;
+ popupChange.label = feature.name;
}
private function blankFeatureIcon(entity:Entity):void {
iconText.htmlText = entity == null ?
"<i>Nothing selected</i>" :
"<b>Not recognised</b><br/>Try looking at the tags under the advanced properties";
+ popupChange.label = "unknown";
}
private function checkAdvanced():void {
var k:String = advancedTagGrid.selectedItem.key;
selectedEntity.setTag(k, null);
}
+
+ public function initFeatureBox():void {
+ tw = new CategorySelector();
+ tw.addEventListener("selectedType", changeFeatureType);
+ popupChange.popUp = tw;
+ }
+
+ public function changeFeatureType(event:Event):void {
+ if ( selectedEntity == null )
+ return;
+
+ // remove tags from the current feature
+ if ( feature != null ) {
+ for each( var tag:Object in feature.tags ) {
+ selectedEntity.setTag(tag["k"], null);
+ }
+ }
+
+ // set tags for new feature
+ for each( var tag:Object in tw.selectedType.tags ) {
+ selectedEntity.setTag(tag["k"], tag["v"]);
+ }
+
+ trace("w000t "+tw.selectedType);
+ popupChange.close();
+ }
]]></mx:Script>
</mx:VBox>
private var _id:Number;
private var _version:uint;
private var tags:Object = {};
+ private var modified:Boolean = false;
public function Entity(id:Number, version:uint, tags:Object) {
this._id = id;
this._version = version;
this.tags = tags;
+ modified = id < 0;
}
public function get id():Number {
delete tags[key];
else
tags[key] = value;
+ modified = true;
dispatchEvent(new TagEvent(Connection.TAG_CHANGE, this, key, key, old, value));
}
}
if ( oldKey != newKey ) {
delete tags[oldKey];
tags[newKey] = value;
+ modified = true;
dispatchEvent(new TagEvent(Connection.TAG_CHANGE, this, oldKey, newKey, value, value));
}
}
return copy;
}
- public function getType():String {
- return '';
- }
+ public function get isDirty():Boolean {
+ return modified;
+ }
+
+ public function markClean():void {
+ modified = false;
+ }
+
+ protected function markDirty():void {
+ modified = true;
+ }
+
+ public function getType():String {
+ return '';
+ }
}
--- /dev/null
+package net.systemeD.halcyon.mapfeatures {
+
+ import flash.events.EventDispatcher;
+ import flash.events.Event;
+
+ public class Category extends EventDispatcher {
+ private var mapFeatures:MapFeatures;
+ private var _name:String;
+ private var _id:String;
+ private var _features:Array;
+
+ public function Category(mapFeatures:MapFeatures, name:String, id:String) {
+ this.mapFeatures = mapFeatures;
+ this._name = name;
+ this._id = id;
+
+ _features = new Array();
+ for each( var feature:Feature in mapFeatures.features ) {
+ if ( feature.isInCategory(id) )
+ _features.push(feature);
+ }
+ }
+
+ public function get id():String {
+ return _id;
+ }
+
+ [Bindable(event="categoryChange")]
+ public function get name():String {
+ return _name;
+ }
+
+ [Bindable(event="featuresChanged")]
+ public function get features():Array {
+ return _features;
+ }
+ }
+}
+
+
--- /dev/null
+package net.systemeD.halcyon.mapfeatures {
+
+ import flash.events.EventDispatcher;
+ import flash.events.Event;
+ import net.systemeD.halcyon.connection.Entity;
+
+ public class Feature extends EventDispatcher {
+ private var mapFeatures:MapFeatures;
+ private var _xml:XML;
+ private static var variablesPattern:RegExp = /[$][{]([^}]+)[}]/g;
+ private var _tags:Array;
+
+ public function Feature(_xml:XML) {
+ this._xml = _xml;
+ _tags = new Array();
+
+ for each(var tag:XML in definition.tag) {
+ var tagObj:Object = new Object();
+ tagObj["k"] = tag.@k;
+ tagObj["v"] = tag.@v;
+ _tags.push(tagObj);
+ }
+
+ }
+
+ public function get definition():XML {
+ return _xml;
+ }
+
+ [Bindable(event="nameChanged")]
+ public function get name():String {
+ return _xml.@name;
+ }
+
+ [Bindable(event="imageChanged")]
+ public function get image():String {
+ var icon:XMLList = _xml.icon;
+
+ if ( icon.length() > 0 && icon[0].hasOwnProperty("@image") )
+ return icon[0].@image;
+ else
+ return null;
+ }
+
+ public function htmlDetails(entity:Entity):String {
+ var icon:XMLList = _xml.icon;
+ if ( icon == null )
+ return "";
+
+ var txt:String = icon.children().toXMLString();
+ var replaceTag:Function = function():String {
+ var value:String = entity.getTag(arguments[1]);
+ return value == null ? "" : value;
+ };
+ txt = txt.replace(variablesPattern, replaceTag);
+ return txt;
+ }
+
+ 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;
+ }
+
+ public function get tags():Array {
+ return _tags;
+ }
+ }
+}
+
package net.systemeD.halcyon.mapfeatures {
+ import flash.events.EventDispatcher;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import net.systemeD.halcyon.connection.*;
- public class MapFeatures {
+ public class MapFeatures extends EventDispatcher {
private static var instance:MapFeatures;
public static function getInstance():MapFeatures {
private var xml:XML = null;
+ private var _features:Array = null;
+ private var _categories:Array = null;
protected function loadFeatures():void {
var request:URLRequest = new URLRequest("map_features.xml");
private function onFeatureLoad(event:Event):void {
xml = new XML(URLLoader(event.target).data);
+
+ _features = new Array();
+ for each(var feature:XML in xml.feature) {
+ _features.push(new Feature(feature));
+ }
+ _categories = new Array();
+ for each(var catXML:XML in xml.category) {
+ if ( catXML.child("category").length() == 0 )
+ _categories.push(new Category(this, catXML.@name, catXML.@id));
+ }
+ dispatchEvent(new Event("featuresLoaded"));
}
public function hasLoaded():Boolean {
return xml != null;
}
- public function findMatchingFeature(entity:Entity):XML {
+ public function findMatchingFeature(entity:Entity):Feature {
if ( xml == null )
return null;
- for each(var feature:XML in xml.feature) {
+ for each(var feature:Feature in features) {
// check for matching tags
var match:Boolean = true;
- for each(var tag:XML in feature.tag) {
- var entityTag:String = entity.getTag(tag.@k);
- match = entityTag == tag.@v || (entityTag != null && tag.@v == "*");
+ for each(var tag:Object in feature.tags) {
+ var entityTag:String = entity.getTag(tag.k);
+ match = entityTag == tag.v || (entityTag != null && tag.v == "*");
if ( !match ) break;
}
if ( match )
}
return null;
}
+
+ [Bindable(event="featuresLoaded")]
+ public function get categories():Array {
+ if ( xml == null )
+ return null;
+ return _categories;
+ }
+
+ [Bindable(event="featuresLoaded")]
+ public function get features():Array {
+ if ( xml == null )
+ return null;
+ return _features;
+ }
+
}
}
<mapFeatures>
+ <!-- Categories -->
+
+ <category name="Roads" id="roads">
+ </category>
+
+ <category name="Paths" id="paths">
+ </category>
+
+ <category name="Transport" id="transport">
+ </category>
+
+ <category name="Water" id="water">
+ </category>
+
+ <category name="Natural" id="natural">
+ </category>
+
+ <category name="Admin" id="admin">
+ </category>
+
<!-- Roads -->
<feature name="Motorway">
+ <category>roads</category>
<icon image="features/highway__motorway.png">
<font size="16pt"><b>${ref}</b></font><br/>
</icon>
</feature>
<feature name="Motorway link" icon="features/motorway_link.png">
+ <category>roads</category>
<line/>
<tag k="highway" v="motorway_link"/>
</feature>
<feature name="Trunk Road">
+ <category>roads</category>
<icon image="features/highway__trunk.png">
<font size="16pt"><b>${ref}</b></font><br/>
<font size="10pt">${name}</font>
</feature>
<feature name="Primary Road">
+ <category>roads</category>
<icon>
<font size="16pt"><b>${ref}</b></font><br/>
<font size="10pt">${name}</font>
</feature>
<feature name="Secondary Road">
+ <category>roads</category>
<icon>
<font size="16pt"><b>${ref}</b></font><br/>
<font size="10pt">${name}</font>
</feature>
<feature name="Tertiary Road">
+ <category>roads</category>
<icon>
<font size="14pt"><b>${name}</b></font><br/>
<font size="10pt">${ref}</font>
</feature>
<feature name="Residential Road">
+ <category>roads</category>
<icon image="features/highway__residential.png">
<font size="14pt"><b>${name}</b></font><br/>
<font size="6pt">${postal_code}</font>
</feature>
<feature name="Road">
+ <category>roads</category>
<icon image="features/highway__unclassified.png">
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Service Road">
+ <category>roads</category>
<icon image="features/highway__service.png">
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Unknown Road">
+ <category>roads</category>
<icon>
<font size="10pt">This road has not been given a specific type. It's a road, and that's all that's known.</font>
</icon>
</feature>
<feature name="Living Street">
+ <category>roads</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Track">
+ <category>roads</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Pedestrian Road">
+ <category>roads</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
<!-- Paths -->
<feature name="Cycle Path">
+ <category>paths</category>
<icon>
${name} <i>${ncn_ref} ${rcn_ref} ${lcn_ref} ${ref}</i>
</icon>
</feature>
<feature name="Foot Path">
+ <category>paths</category>
<icon>
${name} <i>${ref}</i>
</icon>
</feature>
<feature name="Bridleway">
+ <category>paths</category>
<icon>
</icon>
</feature>
<feature name="Steps">
+ <category>paths</category>
<icon>
</icon>
<!-- Waterway -->
<feature name="Stream">
+ <category>water</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="River">
+ <category>water</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Canal">
+ <category>water</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Dam">
+ <category>water</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
<!-- Railways -->
<feature name="Railway Line">
+ <category>transport</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Tram Line">
+ <category>transport</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
</feature>
<feature name="Subway Line">
+ <category>transport</category>
<icon>
<font size="14pt"><b>${name}</b></font>
</icon>
<tag k="railway" v="subway"/>
</feature>
- <feature name="Tram Line">
- <icon>
- <font size="14pt"><b>${name}</b></font>
- </icon>
-
- <line/>
- <tag k="railway" v="tram"/>
- </feature>
-
<!-- building -->