refactor EntityUI, better stylesheet selection, etc.
authorRichard Fairhurst <richard@systemed.net>
Fri, 18 Jun 2010 09:51:30 +0000 (09:51 +0000)
committerRichard Fairhurst <richard@systemed.net>
Fri, 18 Jun 2010 09:51:30 +0000 (09:51 +0000)
15 files changed:
TODO.txt
net/systemeD/halcyon/EntityUI.as
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/NodeUI.as
net/systemeD/halcyon/WayUI.as
net/systemeD/halcyon/styleparser/Style.as
net/systemeD/potlatch2/BackgroundDialog.mxml
net/systemeD/potlatch2/BackgroundSelector.mxml
net/systemeD/potlatch2/EditController.as
net/systemeD/potlatch2/StyleSelector.mxml
net/systemeD/potlatch2/TagViewer.mxml
net/systemeD/potlatch2/options/OptionsDialog.mxml
potlatch2.mxml
resources/potlatch2.html
resources/stylesheets.xml [new file with mode: 0755]

index 28a8441..b998935 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -41,7 +41,6 @@ Potlatch 2: main outstanding issues
 == UI ==
 
 * Escape should rewind the entity to how it was before the current ControllerState. (Record a position in the undo stack when exiting a ControllerState, and escape would rewind to that)
-* Stylesheets should be pulled from an XML file in exactly the same way as background layers
 * Potlatch 1-style "floaty warnings"
 * Custom imagery dialog fixes
 * Ctrl-clicking two areas (one inside the other) should create a multipolygon
@@ -53,6 +52,7 @@ Potlatch 2: main outstanding issues
 * Bug: when drawing way, escape ends drawing. Should revert to previous way.
 * i18n
 * Multiple selection
+* Options should be remembered via SharedObjects
 
 == Miscellaneous data model ==
 
@@ -60,6 +60,8 @@ Potlatch 2: main outstanding issues
 
 == Rendering (Halcyon) ==
 
+* StyleList and everything that iterates over it needs to cope with arbitrary sublayers
+* Occasionally way selected highlight appears in black, not yellow
 * halcyon_viewer needs updating for new tileurl stuff
 * { interactive: no; } - stop items being clicked on (and their maxwidth being taken into account)
 * Shields
index 38fc3c4..14578e7 100644 (file)
@@ -7,10 +7,11 @@ package net.systemeD.halcyon {
        import net.systemeD.halcyon.Globals;
        import net.systemeD.halcyon.styleparser.StyleList;
        import net.systemeD.halcyon.styleparser.RuleSet;
-    import net.systemeD.halcyon.connection.EntityEvent;
+    import net.systemeD.halcyon.connection.*;
 
        public class EntityUI {
 
+               protected var entity:Entity;
                protected var sprites:Array=new Array();                // instances in display list
         protected var listenSprite:Sprite=new Sprite();        // clickable sprite to receive events
                protected var stateClasses:Object=new Object(); // special context-sensitive classes, e.g. :hover
@@ -35,7 +36,15 @@ package net.systemeD.halcyon {
                        gridFitType: GridFitType.NONE
                };
 
-               public function EntityUI() {
+               public function EntityUI(entity:Entity, paint:MapPaint, interactive:Boolean) {
+                       this.entity=entity;
+                       this.paint=paint;
+                       this.interactive=interactive;
+            entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
+                       entity.addEventListener(Connection.ADDED_TO_RELATION, relationAdded);
+                       entity.addEventListener(Connection.REMOVED_FROM_RELATION, relationRemoved);
+                       entity.addEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
+                       entity.addEventListener(Connection.RESUME_REDRAW, resumeRedraw);
                        listenSprite.addEventListener(MouseEvent.CLICK, mouseEvent);
                        listenSprite.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
                        listenSprite.addEventListener(MouseEvent.ROLL_OVER, mouseEvent);
@@ -45,6 +54,42 @@ package net.systemeD.halcyon {
                        listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
                }
 
+
+               // -----------------------------------------------------------------
+               // Event listeners
+               
+               protected function attachRelationListeners():void {
+                   var relations:Array = entity.parentRelations;
+            for each(var relation:Relation in relations ) {
+                relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
+            }
+               }
+
+               private function relationAdded(event:RelationMemberEvent):void {
+                   event.relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
+                   redraw();
+               }
+               
+               private function relationRemoved(event:RelationMemberEvent):void {
+                   event.relation.removeEventListener(Connection.TAG_CHANGED, relationTagChanged);
+                   redraw();
+               }
+               
+        protected function tagChanged(event:TagEvent):void {
+            redraw();
+        }
+
+        protected function relationTagChanged(event:TagEvent):void {
+            redraw();
+        }
+               
+        protected function mouseEvent(event:MouseEvent):void {
+                       paint.map.entityMouseEvent(event, entity);
+        }
+
+
+               // -----------------------------------------------------------------
+
                // Add object (stroke/fill/roadname) to layer sprite
                
                protected function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
@@ -86,9 +131,6 @@ package net.systemeD.halcyon {
             listenSprite.mouseEnabled = true;
                }
 
-        protected function mouseEvent(event:MouseEvent):void {
-        }
-
         public function setHighlight(stateType:String, isOn:*):void {
             if ( isOn && stateClasses[stateType] == null ) {
                 stateClasses[stateType] = isOn;
@@ -104,6 +146,10 @@ package net.systemeD.halcyon {
                        return tags;
                }
                
+               public function toString():String {
+                       return "[EntityUI "+entity+"]";
+               }
+
                // Redraw control
                
                public function redraw(sl:StyleList=null):Boolean {
index 19c701c..155c3e2 100755 (executable)
@@ -66,8 +66,8 @@ package net.systemeD.halcyon {
 
                public var backdrop:Object;                                             // reference to backdrop sprite
                public var tileset:TileSet;                                             // 900913 tile background
-               private var tileurl:String='';                                  // internal tile URL and priority - allows setting before tileset inited
-               private var tileprio:uint=0;                                    //  | 
+               private var tileurl:String='';                                  // internal tile URL
+               private var styleurl:String='';                                 // internal style URL
                public var showall:Boolean=true;                                // show all objects, even if unstyled?
                
                public var connection:Connection;                               // server connection
@@ -108,19 +108,18 @@ package net.systemeD.halcyon {
                                // parameters sent from HTML
                                init(initparams['lat'],
                                         initparams['lon'],
-                                        initparams['zoom'],
-                                        initparams['style']);
+                                        initparams['zoom']);
 
                        } else {
                                // somewhere innocuous
-                               init(53.09465,-2.56495,17,"test.css?d="+Math.random());
+                               init(53.09465,-2.56495,17);
                        }
                }
 
                // ------------------------------------------------------------------------------------------
                // Initialise map at a given lat/lon
 
-        public function init(startlat:Number,startlon:Number,startscale:uint=0,style:String=null):void {
+        public function init(startlat:Number,startlon:Number,startscale:uint=0):void {
                        while (numChildren) { removeChildAt(0); }
 
                        tileset=new TileSet(this);                                      // 0 - 900913 background
@@ -134,9 +133,9 @@ package net.systemeD.halcyon {
                        addChild(paint);                                                        //   |
                        paint.isBackground=false;                                       //   |
 
-                       if (style) {
+                       if (styleurl) {                                                         // if we've only just set up paint, then setStyle won't have created the RuleSet
                                paint.ruleset=new RuleSet(MINSCALE,MAXSCALE,redraw,redrawPOIs);
-                               paint.ruleset.loadFromCSS(style);
+                               paint.ruleset.loadFromCSS(styleurl);
                        }
                        if (startscale>0) { scale=startscale; }
 
@@ -242,8 +241,7 @@ package net.systemeD.halcyon {
         private function newPOICreated(event:EntityEvent):void {
             var node:Node = event.entity as Node;
                        if (!node.within(edge_l,edge_r,edge_t,edge_b)) { return; }
-                       var nodeui:NodeUI=paint.createNodeUI(node);
-                       nodeui.redraw();
+                       paint.createNodeUI(node);
         }
 
                private function wayRenumbered(event:EntityRenumberedEvent):void {
@@ -323,18 +321,17 @@ package net.systemeD.halcyon {
                        addDebug("lon "+coord2lon(mouseX)+", lat "+coord2lat(mouseY));
                }
                
-               public function setStyle(style:String):void {
-                       if (style) {
+               public function setStyle(url:String):void {
+                       styleurl=url;
+                       if (paint) { 
                                paint.ruleset=new RuleSet(MINSCALE,MAXSCALE,redraw,redrawPOIs);
-                               paint.ruleset.loadFromCSS(style);
+                               paint.ruleset.loadFromCSS(url);
                        }
         }
 
-               public function setBackground(url:String,priority:int):Boolean {
-                       if (priority<tileprio) { return false; }
-                       tileurl=url; tileprio=priority;
+               public function setBackground(url:String):void {
+                       tileurl=url;
                        if (tileset) { tileset.init(url, url!=''); }
-                       return true;
                }
 
                public function setDimming(dim:Boolean):void {
index 6a7bf87..be74693 100644 (file)
@@ -8,29 +8,25 @@ package net.systemeD.halcyon {
        import flash.text.TextFormat;
        import flash.geom.Matrix;
        import flash.geom.Point;
-    import net.systemeD.halcyon.connection.Node;
-    import net.systemeD.halcyon.connection.Connection;
        import net.systemeD.halcyon.styleparser.*;
+    import net.systemeD.halcyon.connection.*;
        import net.systemeD.halcyon.Globals;
        
        public class NodeUI extends EntityUI {
                
-        private var node:Node;
                public var loaded:Boolean=false;
                private var iconname:String='';                         // name of icon
                private var heading:Number=0;                           // heading within way
                private var rotation:Number=0;                          // rotation applied to this POI
 
-               public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, interactive:Boolean=true) {
-                       super();
-                       this.node = node;
-                       this.paint = paint;
+               public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, interactive:Boolean=true, sl:StyleList=null) {
+                       super(node,paint,interactive);
                        this.heading = heading;
-                       this.interactive = interactive;
-                       node.addEventListener(Connection.NODE_MOVED, nodeMoved);
-                       node.addEventListener(Connection.NODE_DELETED, nodeDeleted);
-                       node.addEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
-                       node.addEventListener(Connection.RESUME_REDRAW, resumeRedraw);
+            entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
+                       entity.addEventListener(Connection.NODE_MOVED, nodeMoved);
+                       entity.addEventListener(Connection.NODE_DELETED, nodeDeleted);
+            attachRelationListeners();
+                       redraw(sl);
                }
                
                public function nodeMoved(event:Event):void {
@@ -43,14 +39,14 @@ package net.systemeD.halcyon {
                
                override public function doRedraw(sl:StyleList):Boolean {
                        if (!paint.ready) { return false; }
-                       if (node.deleted) { return false; }
+                       if (entity.deleted) { return false; }
 
-                       var tags:Object = node.getTagsCopy();
+                       var tags:Object = entity.getTagsCopy();
                        tags=applyStateClasses(tags);
-                       if (!node.hasParentWays) { tags[':poi']='yes'; }
-                       if (!sl) { sl=paint.ruleset.getStyles(this.node,tags); }
+                       if (!entity.hasParentWays) { tags[':poi']='yes'; }
+                       if (!sl) { sl=paint.ruleset.getStyles(entity,tags); }
 
-                       var inWay:Boolean=node.hasParentWays;
+                       var inWay:Boolean=entity.hasParentWays;
                        var hasStyles:Boolean=sl.hasStyles();
                        
                        removeSprites(); iconname='';
@@ -93,7 +89,8 @@ package net.systemeD.halcyon {
                                                } else if (paint.ruleset.images[s.icon_image]) {
                                                        // 'load' icon (actually just from library)
                                                        var loader:Loader = new Loader();
-                                                       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { loadedIcon(e,sublayer); } );
+                                                       loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { 
+                                                               loadedIcon(e,sublayer); } );
                                                        loader.loadBytes(paint.ruleset.images[s.icon_image]);
                                                        iconname=s.icon_image;
                                                }
@@ -157,10 +154,6 @@ package net.systemeD.halcyon {
                        updatePosition();
                }
 
-        override protected function mouseEvent(event:MouseEvent):void {
-                       paint.map.entityMouseEvent(event, node);
-        }
-
                private function updatePosition():void {
                        if (!loaded) { return; }
 
@@ -171,7 +164,7 @@ package net.systemeD.halcyon {
                                var m:Matrix=new Matrix();
                                m.translate(-d.width/2,-d.height/2);
                                m.rotate(rotation);
-                               m.translate(paint.map.lon2coord(node.lon),paint.map.latp2coord(node.latp));
+                               m.translate(paint.map.lon2coord(Node(entity).lon),paint.map.latp2coord(Node(entity).latp));
                                d.transform.matrix=m;
                        }
                }
index 2d4617a..291fb48 100755 (executable)
@@ -13,7 +13,6 @@ package net.systemeD.halcyon {
 
        public class WayUI extends EntityUI {
 
-        private var way:Way;
                public var pathlength:Number;                           // length of path
                public var patharea:Number;                                     // area of path
                public var centroid_x:Number;                           // centroid
@@ -26,48 +25,24 @@ package net.systemeD.halcyon {
                private const NODESIZE:uint=6;
 
                public function WayUI(way:Way, paint:MapPaint, interactive:Boolean=true) {
-                       super();
-                       this.way = way;
-                       this.paint = paint;
-                       this.ruleset = ruleset;
-                       this.interactive = interactive;
-            init();
-            way.addEventListener(Connection.TAG_CHANGED, wayTagChanged);
-            way.addEventListener(Connection.WAY_NODE_ADDED, wayNodeAdded);
-            way.addEventListener(Connection.WAY_NODE_REMOVED, wayNodeRemoved);
-            way.addEventListener(Connection.WAY_REORDERED, wayReordered);
-                       way.addEventListener(Connection.WAY_DELETED, wayDeleted);
-            way.addEventListener(Connection.WAY_DRAGGED, wayDragged);
-                       way.addEventListener(Connection.ADDED_TO_RELATION, wayRelationAdded);
-                       way.addEventListener(Connection.REMOVED_FROM_RELATION, wayRelationRemoved);
-                       way.addEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
-                       way.addEventListener(Connection.RESUME_REDRAW, resumeRedraw);
+                       super(way,paint,interactive);
+            entity.addEventListener(Connection.WAY_NODE_ADDED, wayNodeAdded);
+            entity.addEventListener(Connection.WAY_NODE_REMOVED, wayNodeRemoved);
+            entity.addEventListener(Connection.WAY_REORDERED, wayReordered);
+                       entity.addEventListener(Connection.WAY_DELETED, wayDeleted);
+            entity.addEventListener(Connection.WAY_DRAGGED, wayDragged);
             attachNodeListeners();
             attachRelationListeners();
+            recalculate();
+                       redraw();
                }
                
                private function attachNodeListeners():void {
+                       var way:Way=entity as Way;
             for (var i:uint = 0; i < way.length; i++ ) {
                 way.getNode(i).addEventListener(Connection.NODE_MOVED, nodeMoved);
             }
                }
-
-               private function attachRelationListeners():void {
-                   var relations:Array = way.parentRelations;
-            for each(var relation:Relation in relations ) {
-                relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
-            }
-               }
-               
-               private function wayRelationAdded(event:RelationMemberEvent):void {
-                   event.relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
-                   redraw();
-               }
-               
-               private function wayRelationRemoved(event:RelationMemberEvent):void {
-                   event.relation.removeEventListener(Connection.TAG_CHANGED, relationTagChanged);
-                   redraw();
-               }
                
                private function wayNodeAdded(event:WayNodeEvent):void {
                    event.node.addEventListener(Connection.NODE_MOVED, nodeMoved);
@@ -82,12 +57,6 @@ package net.systemeD.halcyon {
                    redraw();
                }
                    
-        private function wayTagChanged(event:TagEvent):void {
-            redraw();
-        }
-        private function relationTagChanged(event:TagEvent):void {
-            redraw();
-        }
         private function nodeMoved(event:NodeMovedEvent):void {
                        recalculate();
             redraw();
@@ -102,13 +71,6 @@ package net.systemeD.halcyon {
                        offsetSprites(event.xDelta,event.yDelta);
                }
 
-               private function init():void {
-                       recalculate();
-                       redraw();
-                       // updateBbox(lon, lat);
-                       // ** various other stuff
-               }
-
                override public function suspendRedraw(event:EntityEvent):void {
                        super.suspendRedraw(event);
                        recalculateDue=false;
@@ -130,6 +92,8 @@ package net.systemeD.halcyon {
                        var lx:Number, ly:Number, sc:Number;
                        var node:Node, latp:Number, lon:Number;
                        var cx:Number=0, cy:Number=0;
+                       var way:Way=entity as Way;
+                       
                        pathlength=0;
                        patharea=0;
                        if (way.length==0) { return; }
@@ -172,13 +136,13 @@ package net.systemeD.halcyon {
 
                override public function doRedraw(sl:StyleList):Boolean {
                        removeSprites();
-                       if (way.length==0) { return false; }
+                       if (Way(entity).length==0) { return false; }
                        if (!paint.ready) { return false; }
 
             // Copy tags object, and add states
-            var tags:Object = way.getTagsCopy();
+            var tags:Object = entity.getTagsCopy();
                        tags=applyStateClasses(tags);
-                       if (way.isArea()) { tags[':area']='yes'; }
+                       if (Way(entity).isArea()) { tags[':area']='yes'; }
 
                        // Which layer?
                        layer=0;
@@ -188,9 +152,9 @@ package net.systemeD.halcyon {
                        var maxwidth:Number=4;
 
                        // Iterate through each sublayer, drawing any styles on that layer
-                       if (!sl) { sl=paint.ruleset.getStyles(this.way, tags); }
+                       if (!sl) { sl=paint.ruleset.getStyles(entity, tags); }
                        var drawn:Boolean;
-                       var multis:Array=way.findParentRelationsOfType('multipolygon','outer');
+                       var multis:Array=entity.findParentRelationsOfType('multipolygon','outer');
                        var inners:Array=[];
                        for each (var m:Relation in multis) {
                                inners=inners.concat(m.findMembersByRole('inner'));
@@ -199,8 +163,8 @@ package net.systemeD.halcyon {
                                if (sl.shapeStyles[sublayer]) {
                                        var s:ShapeStyle=sl.shapeStyles[sublayer];
                                        var stroke:Shape, fill:Shape, casing:Shape, roadname:Sprite;
-                                       var x0:Number=paint.map.lon2coord(way.getNode(0).lon);
-                                       var y0:Number=paint.map.latp2coord(way.getNode(0).latp);
+                                       var x0:Number=paint.map.lon2coord(Way(entity).getNode(0).lon);
+                                       var y0:Number=paint.map.latp2coord(Way(entity).getNode(0).latp);
 
                                        // Stroke
                                        if (s.width)  {
@@ -216,7 +180,7 @@ package net.systemeD.halcyon {
                                        }
 
                                        // Fill
-                                       if ((s.fill_color || s.fill_image) && way.findParentRelationsOfType('multipolygon','inner').length==0) {
+                                       if ((s.fill_color || s.fill_image) && entity.findParentRelationsOfType('multipolygon','inner').length==0) {
                                                fill=new Shape(); addToLayer(fill,FILLSPRITE);
                                                fill.graphics.moveTo(x0,y0);
                                                if (s.fill_image) { new WayBitmapFiller(this,fill.graphics,s); }
@@ -264,8 +228,8 @@ package net.systemeD.halcyon {
                        var r:Number;
                        var nodetags:Object;
                        var nodeSelected:int=stateClasses["nodeSelected"];
-                       for (var i:uint = 0; i < way.length; i++) {
-                var node:Node = way.getNode(i);
+                       for (var i:uint = 0; i < Way(entity).length; i++) {
+                var node:Node = Way(entity).getNode(i);
                                nodetags=node.getTagsCopy();
                                if (i==0) { nodetags['_heading']= heading[i]; }
                                     else { nodetags['_heading']=(heading[i]+heading[i-1])/2; }
@@ -275,10 +239,11 @@ package net.systemeD.halcyon {
                                if (node.numParentWays>1) { nodetags[':junction']='yes'; }
                                sl=paint.ruleset.getStyles(node,nodetags);
                                if (sl.hasStyles()) {
-                                       if (!paint.nodeuis[node.id]) {
-                                               paint.nodeuis[node.id]=new NodeUI(node,paint,r);
+                                       if (paint.nodeuis[node.id]) {
+                                               paint.nodeuis[node.id].redraw(sl);
+                                       } else {
+                                               paint.nodeuis[node.id]=new NodeUI(node,paint,r,true,sl);
                                        }
-                                       paint.nodeuis[node.id].redraw(sl);
                                } else if (paint.nodeuis[node.id]) {
                                        paint.nodeuis[node.id].removeSprites();
                                        delete paint.nodeuis[node.id];
@@ -303,7 +268,7 @@ package net.systemeD.halcyon {
                // Draw solid polyline
                
                public function solidLines(g:Graphics,inners:Array):void {
-                       solidLine(g,this.way);
+                       solidLine(g,entity as Way);
                        for each (var w:Way in inners) { solidLine(g,w); }
                }
 
@@ -319,6 +284,7 @@ package net.systemeD.halcyon {
                // Draw dashed polyline
                
                private function dashedLine(g:Graphics,dashes:Array):Array {
+                       var way:Way=entity as Way;
                        var segments:Array=[];
                        var draw:Boolean=false, dashleft:Number=0, dc:Array=new Array();
                        var a:Number, xc:Number, yc:Number;
@@ -403,6 +369,7 @@ package net.systemeD.halcyon {
                // inspired by senocular's Path.as
                
                private function pointAt(t:Number):Array {
+                       var way:Way=entity as Way;
                        var totallen:Number = t*pathlength;
                        var curlen:Number = 0;
                        var dx:Number, dy:Number, seglen:Number;
@@ -481,6 +448,7 @@ package net.systemeD.halcyon {
                }
                
                public function getNodeAt(x:Number, y:Number):Node {
+                       var way:Way=entity as Way;
                        for (var i:uint = 0; i < way.length; i++) {
                 var node:Node = way.getNode(i);
                 var nodeX:Number = paint.map.lon2coord(node.lon);
@@ -495,14 +463,9 @@ package net.systemeD.halcyon {
                // ------------------------------------------------------------------------------------------
                // Interaction
 
-        override protected function mouseEvent(event:MouseEvent):void {
-                       paint.map.entityMouseEvent(event, way);
-        }
-
                public function hitTest(x:Number, y:Number):Way {
-                       if (hitzone.hitTestPoint(x,y,true)) { return way; }
+                       if (hitzone.hitTestPoint(x,y,true)) { return entity as Way; }
                        return null;
                }
-
        }
 }
index d35f136..dd60fe3 100755 (executable)
@@ -90,5 +90,13 @@ package net.systemeD.halcyon.styleparser {
                        }
                        return false;
                }
+
+               public function toString():String {
+                       var str:String='';
+            for each (var k:String in this.properties) {
+                               if (this.hasOwnProperty(k)) { str+=k+"="+this[k]+"; "; }
+                       }
+                       return str;
+        }
        }
 }
index 22b9988..c8efd81 100644 (file)
@@ -2,10 +2,10 @@
 <mx:TitleWindow
         xmlns:mx="http://www.adobe.com/2006/mxml" 
         layout="vertical" showCloseButton="true"
-        horizontalAlign="center" title="Background imagery"
+        horizontalAlign="center" 
         width="500" height="300" verticalGap="0">
 
-  <mx:DataGrid editable="true" width="100%" height="100%" id="imageryGrid">
+  <mx:DataGrid editable="true" width="100%" height="100%" id="dataGrid">
     <mx:columns>
         <mx:DataGridColumn editable="true" dataField="label" headerText="Name"/>
         <mx:DataGridColumn editable="true" dataField="data" headerText="URL"/>
@@ -13,7 +13,7 @@
   </mx:DataGrid>        
 
   <mx:HBox horizontalAlign="right" width="100%">
-    <mx:LinkButton label="Delete" click="removeSource()" enabled="{imageryGrid.selectedItem != null? true : false}"/>
+    <mx:LinkButton label="Delete" click="removeSource()" enabled="{dataGrid.selectedItem != null? true : false}"/>
     <mx:LinkButton label="Add" click="addNewSource()"/>
   </mx:HBox>
 
@@ -26,7 +26,7 @@
                - editable bbox for each layer
                - ability to use this dialogue to select as well as edit
                - automatically select imagery once you've edited it (i.e. itemEditEnd)
-               - save/load imagery sets into OSM preferences
+               - edits should stick around, either in SharedObjects or OSM preferences
        */
 
     import mx.managers.PopUpManager;
        import mx.collections.ArrayCollection;
        import mx.controls.List;
 
-       public var imageryCollection:ArrayCollection = new ArrayCollection(Application.application.theController.imagery);
+       public var dataCollection:ArrayCollection;
        private var menu:List;
 
-    public function init(menu:List):void {
+    public function init(title:String, menu:List, source:Array):void {
+               this.title=title;
                this.menu=menu;
+               dataCollection=new ArrayCollection(source);
         PopUpManager.addPopUp(this, Application(Application.application), true);
         PopUpManager.centerPopUp(this);
         this.addEventListener(CloseEvent.CLOSE, backgroundDialog_close);
-               imageryGrid.dataProvider=imageryCollection;
+               dataGrid.dataProvider=dataCollection;
     }
     
     private function backgroundDialog_close(evt:CloseEvent):void {
     }
 
        private function addNewSource():void {
-               imageryCollection.addItemAt( {label:'(new name)',data:'(new URL)'} , imageryCollection.length);
-               imageryGrid.validateNow();
-               imageryGrid.verticalScrollPosition=imageryGrid.maxVerticalScrollPosition;
-               imageryGrid.editedItemPosition = {rowIndex: imageryCollection.length-1, columnIndex: 0};
+               dataCollection.addItemAt( {label:'(new name)',data:'(new URL)'} , dataCollection.length);
+               dataGrid.validateNow();
+               dataGrid.verticalScrollPosition=dataGrid.maxVerticalScrollPosition;
+               dataGrid.editedItemPosition = {rowIndex: dataCollection.length-1, columnIndex: 0};
        }
        private function removeSource():void {
-               imageryCollection.removeItemAt(imageryGrid.selectedIndex);
+               dataCollection.removeItemAt(dataGrid.selectedIndex);
        }
 
   ]]>
index fba2dd1..3e01311 100644 (file)
@@ -11,7 +11,7 @@
            change="Application.application.theMap.setDimming(dim.selected); Application.application.yahoo.alpha = dim.selected ? 0.5 : 1" />
 
        <mx:HBox>
-       <mx:Button label="Edit..." click="new BackgroundDialog().init(background);" />
+       <mx:Button label="Edit..." click="new BackgroundDialog().init('Background imagery',background,Application.application.theController.imagery);" />
        <mx:Button label="Vector file" click="new VectorSourceDialog().init();" />
        </mx:HBox>
 
index 099697c..ec93c13 100644 (file)
@@ -19,6 +19,8 @@ package net.systemeD.potlatch2 {
                private var keys:Object={};
                public var clipboards:Object={};
                public var imagery:Array=[];
+               public var stylesheets:Array=[];
+               public var cursorsEnabled:Boolean=true;
 
                [Embed(source="../../../embedded/pen.png")]             public var pen:Class;
                [Embed(source="../../../embedded/pen_x.png")]           public var pen_x:Class;
@@ -112,7 +114,7 @@ package net.systemeD.potlatch2 {
 
                public function setCursor(cursor:Class):void {
                        CursorManager.removeAllCursors();
-                       if (cursor) { CursorManager.setCursor(cursor,2,-4,0); }
+                       if (cursor && cursorsEnabled) { CursorManager.setCursor(cursor,2,-4,0); }
                }
 
     }
index b2e5609..89e4f39 100644 (file)
@@ -4,25 +4,17 @@
        paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10"
        horizontalAlign="left" backgroundColor="white" borderStyle="inset">
        
-       <mx:List width="100%" height="100%" id="mapStyle" change="updateMapStyle();"> 
-           <!-- This should be pulled in from an XML file rather than sitting in the source -->
-           <mx:dataProvider>
-               <mx:Object label="Potlatch" data="potlatch.css" />
-               <mx:Object label="Wireframe" data="wireframe.css" />
-           </mx:dataProvider>
-       </mx:List>
+       <mx:List width="100%" height="100%" id="mapStyle" 
+               change="Application.application.setStylesheet(mapStyle.selectedItem.label, mapStyle.selectedItem.data);"
+               dataProvider="{Application.application.theController.stylesheets}" />
+
+       <mx:Button label="Edit..." click="new BackgroundDialog().init('Map style',mapStyle,Application.application.theController.stylesheets);" />
 
        <mx:Script><![CDATA[
                import net.systemeD.halcyon.*;
                import net.systemeD.halcyon.connection.*;
                import net.systemeD.potlatch2.*;
-
-               private function updateMapStyle():void {
-            var theMap:Map = Globals.vars.root;
-                       var style:String=mapStyle.selectedItem.data;
-                       theMap.setStyle(style);
-               }
-
+               import mx.core.*;
     ]]></mx:Script>    
 </mx:VBox>
 
index 4506de0..56397fa 100644 (file)
           var undoStack:Function = MainUndoStack.getGlobalStack().addAction;
           var action:CompositeUndoableAction = new CompositeUndoableAction(
                   "Set "+selectedEntity.getType()+" "+selectedEntity.id+" to "+newFeature.name);
+                 selectedEntity.suspend();
 
           // remove tags from the current feature
           if ( feature != null ) {
               }
           }
           
+                 selectedEntity.resume();
           undoStack(action);
           popupChange.close();
       }
index 1caba57..d7367b9 100644 (file)
@@ -14,6 +14,7 @@
         PopUpManager.centerPopUp(this);
         this.addEventListener(CloseEvent.CLOSE, optionsDialog_close);
                tbcheck.selected=Application.application.toolbox.visible;
+               cursorcheck.selected=Application.application.theController.cursorsEnabled;
     }
     
     private function optionsDialog_close(evt:CloseEvent):void {
@@ -25,6 +26,9 @@
        <mx:CheckBox width="100%" label="Show toolbox" selected="true" id="tbcheck"
            change="Application.application.toolbox.toggle()" />
 
+       <mx:CheckBox width="100%" label="Use custom cursors" selected="true" id="cursorcheck"
+           change="Application.application.theController.cursorsEnabled=cursorcheck.selected" />
+
   <mx:ControlBar>
     <mx:Spacer width="100%"/>
     <mx:Button label="Ok" click="PopUpManager.removePopUp(this);"/>
index e22bdd3..34a1667 100755 (executable)
                        Globals.vars.root = map_area.rawChildren;                       // set up global reference to root level
                        var _root:IChildList = map_area.rawChildren;            // convenient local shorthand
 
+                       // populate sharedObject with loaderInfo parameters if supplied
+                       var obj:SharedObject = SharedObject.getLocal("user_state");
+                       var objChanged:Boolean = false;
+                       if (loaderInfo.parameters['tileurl']) {
+                               obj.setProperty('background_url',loaderInfo.parameters['tileurl']); 
+                               obj.setProperty('background_name','Custom'); 
+                               objChanged=true;
+                       }
+                       if (loaderInfo.parameters['style']) { 
+                               obj.setProperty('stylesheet_url',loaderInfo.parameters['style']);
+                               obj.setProperty('stylesheet_name','Custom');
+                               objChanged=true; 
+                       }
+                       if (objChanged) { obj.flush(); }
+
+                       // load imagery and style XML
+               var request:URLRequest = new URLRequest("imagery.xml?"+Math.random());
+               var loader:URLLoader = new URLLoader();
+               loader.addEventListener(Event.COMPLETE, onImageryLoad);
+               loader.load(request);
+
+                       var request2:URLRequest = new URLRequest("stylesheets.xml?"+Math.random());
+                       var loader2:URLLoader = new URLLoader();
+               loader2.addEventListener(Event.COMPLETE, onStylesheetsLoad);
+               loader2.load(request2);
+
                        // map backdrop object
             var w:uint = map_area.width;
             var h:uint = map_area.height;
                        _root.addChild(yahoo);
                        _root.addChild(theMap);
             theMap.updateSize(w,h);
-                       if (loaderInfo.parameters['tileurl']) {
-                               setBackground('custom',loaderInfo.parameters['tileurl'],2);
-                       }
 
                        // add mask for map
                        var s:Sprite=new Sprite();
                        // keyboard event attached to stage
                        stage.addEventListener(KeyboardEvent.KEY_UP, theMap.keyUpHandler);
 
-                       // load imagery XML
-               var request:URLRequest = new URLRequest("imagery.xml?"+Math.random());
-               var loader:URLLoader = new URLLoader();
-               loader.addEventListener(Event.COMPLETE, onImageryLoad);
-               loader.load(request);
-
                        // position toolbox
                        toolbox=Toolbox(PopUpManager.createPopUp(this,Toolbox,false));
                        toolbox.init(theController);
                
         private function onImageryLoad(event:Event):void {
                        var xml:XML = new XML(URLLoader(event.target).data);
-
-                       // create menu
+                       var saved_url:String = SharedObject.getLocal("user_state").data['background_url'];
+                       var saved_name:String= SharedObject.getLocal("user_state").data['background_name'];
+                       var xml_url:String, xml_name:String, isSet:Boolean=false;
             theController.imagery=new Array(
                                { label: "None", data: "" },
                                { label: "Yahoo", data: "yahoo" } );
                        for each(var set:XML in xml.set) {
-                theController.imagery.push({ label:set.child("name"), data:set.child("url") });
+                               xml_url= set.child("url");
+                               xml_name=set.child("name");
+                theController.imagery.push({ label:xml_name, data:xml_url });
+                               if (xml_url==saved_url || (xml_name==saved_name && xml_name!='Custom')) { isSet=true; }
                        }
+                       if (!isSet) { theController.imagery.push({ label:saved_name, data:saved_url }); }
 
-                       // set imagery from shared object
-                       var previous:String = SharedObject.getLocal("user_state").data['background'];
                        for each (var bg:Object in theController.imagery) {
-                               if (bg['label']==previous) { 
-                                       setBackground(bg['label'], bg['data'], 1);
+                               if (bg['label']==saved_nameĀ || bg['data']==saved_url) {
+                                       setBackground(bg['label'], bg['data']);
                                }
                        }
                }
-
-               public function setBackground(name:String,url:String,priority:uint=2):void {
+               
+               public function setBackground(name:String,url:String):void {
                        // ** this should take an object with all parameters (source tag, etc.)
-                       var set:Boolean;
-                       if (url=='yahoo') {
-                               set=theMap.setBackground('',2);
-                               yahoo.show();
-                       } else {
-                               set=theMap.setBackground(url,priority)
-                               yahoo.hide();
+                       if (url=='yahoo') { theMap.setBackground('') ; yahoo.show(); }
+                                    else { theMap.setBackground(url); yahoo.hide(); }
+                       var obj:SharedObject = SharedObject.getLocal("user_state");
+                       obj.setProperty("background_url",url );
+                       obj.setProperty("background_name",name);
+                       obj.flush();
+               }
+
+               private function onStylesheetsLoad(event:Event):void {
+                       var xml:XML = new XML(URLLoader(event.target).data);
+                       var saved_url:String = SharedObject.getLocal("user_state").data['stylesheet_url'];
+                       var saved_name:String= SharedObject.getLocal("user_state").data['stylesheet_name'];
+                       var xml_url:String, xml_name:String, isSet:Boolean=false;
+                       if (!saved_url) { saved_url='potlatch.css'; saved_name='Potlatch'; }
+                       
+                       // create menu
+            theController.stylesheets=new Array();
+                       for each(var set:XML in xml.stylesheet) {
+                               xml_url= set.child("url");
+                               xml_name=set.child("name");
+                theController.stylesheets.push({ label:xml_name, data:xml_url });
+                               if (xml_url==saved_url || (xml_name==saved_name && xml_name!='Custom')) { isSet=true; }
                        }
-                       if (set) {
-                               var obj:SharedObject = SharedObject.getLocal("user_state");
-                               obj.setProperty("background", name);
-                               obj.flush();
+                       if (!isSet) { theController.stylesheets.push({ label:saved_name, data:saved_url }); }
+
+                       for each (var bg:Object in theController.stylesheets) {
+                               if (bg['label']==saved_nameĀ || bg['data']==saved_url) { 
+                                       setStylesheet(bg['label'], bg['data']);
+                               }
                        }
                }
 
+               public function setStylesheet(name:String,url:String):void {
+                       theMap.setStyle(url);
+                       var obj:SharedObject = SharedObject.getLocal("user_state");
+                       obj.setProperty("stylesheet_url",url);
+                       obj.setProperty("stylesheet_name",name);
+                       obj.flush();
+               }
+
+
         private function dragEnterHandler(event:DragEvent):void {
             // Get the drop target component from the event object.
             var dropTarget:Canvas=event.currentTarget as Canvas;
index 8cb1ad7..5ff82a6 100644 (file)
@@ -27,7 +27,7 @@
         fo.addVariable("oauth_consumer_key", "fiM1IoqnKJk4JCfcl63DA");
         fo.addVariable("oauth_consumer_secret", "7fYgJK9M4vB1CvBZ6jEsPGxYK9UD1hEnI6NqTxNGs");
         fo.addVariable("serverName", "api06 Test On Dev");
-       fo.addVariable("style","potlatch.css?d="+Math.round(Math.random()*1000));
+//     fo.addVariable("style","potlatch.css?d="+Math.round(Math.random()*1000));
        fo.write("map");
 
 
diff --git a/resources/stylesheets.xml b/resources/stylesheets.xml
new file mode 100755 (executable)
index 0000000..baefd56
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<stylesheets>
+       <stylesheet>
+               <name>Potlatch</name>
+               <url>potlatch.css</url>
+       </stylesheet>
+       <stylesheet>
+               <name>Wireframe</name>
+               <url>wireframe.css</url>
+       </stylesheet>
+</stylesheets>