source: subversion/applications/editors/potlatch2/potlatch2.mxml @ 24243

Last change on this file since 24243 was 24224, checked in by richard, 10 years ago

dial B for source tag

File size: 16.9 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application
3        xmlns:mx="http://www.adobe.com/2006/mxml"
4        xmlns:halcyon="net.systemeD.halcyon.*"
5        xmlns:potlatch2="net.systemeD.potlatch2.*"
6        layout="vertical"
7        horizontalScrollPolicy="off"
8        verticalScrollPolicy="off"
9        horizontalAlign="center"
10        addedToStage="initApp()">
11       
12        <mx:Style source="styles/Application.css"/>
13
14    <mx:Glow id="glowImage" duration="100"
15        alphaFrom="0.3" alphaTo="1.0"
16        blurXFrom="0.0" blurXTo="5.0"
17        blurYFrom="0.0" blurYTo="5.0"
18        color="0xFF8000"/>
19    <mx:Glow id="unglowImage" duration="100"
20        alphaFrom="1.0" alphaTo="0.3"
21        blurXFrom="5.0" blurXTo="0.0"
22        blurYFrom="5.0" blurYTo="0.0"
23        color="0xFF8000"/>
24    <mx:WipeLeft id="wipeOut" duration="250"/>
25    <mx:WipeRight id="wipeIn" duration="250"/>
26
27    <mx:ApplicationControlBar dock="true">
28        <mx:PopUpButton id="bgButton" label="Background" openAlways="true"
29            creationComplete="bgButton.popUp = new BackgroundSelector();"/>
30        <mx:PopUpButton id="styleButton" label="Map Style" openAlways="true"
31            creationComplete="styleButton.popUp = new StyleSelector();"/>
32                <mx:PopUpMenuButton id="gpsButton" itemClick="if (event.index==0) { trackLoader.load(); } else { new MyGpxDialog().init(); }">
33                        <mx:dataProvider>
34                                <mx:Array>
35                                        <mx:Object label="GPS data" />
36                                        <mx:Object label="My tracks" />
37                                </mx:Array>
38                        </mx:dataProvider>
39                </mx:PopUpMenuButton>
40        <mx:Spacer width="100%"/>
41        <mx:Button label="Undo" click="MainUndoStack.getGlobalStack().undo();"
42            enabled="{MainUndoStack.getGlobalStack().canUndo()}"/>
43        <mx:Button label="Redo" click="MainUndoStack.getGlobalStack().redo();"
44            enabled="{MainUndoStack.getGlobalStack().canRedo()}"/>
45        <mx:Spacer width="100%"/>
46        <mx:Button label="Help" click="new HelpDialog().init();" />
47        <mx:Button label="Options" click="new OptionsDialog().init();" />
48        <mx:Button label="Save" icon="@Embed('embedded/save.svg')" click="SaveManager.saveChanges();" id="saveButton"
49                        enabled="false"/>
50    </mx:ApplicationControlBar>
51   
52    <mx:HDividedBox width="100%" height="100%">
53
54          <!-- Tag viewer -->
55          <potlatch2:TagViewer width="25%" height="100%" id="tagViewer"/>
56
57      <mx:Canvas width="75%" height="100%">
58        <mx:Canvas id="map_area" resize="onResizeMap()"
59            top="0" left="0" width="100%" height="100%" dragEnter="dragEnterHandler(event);" dragDrop="dragDropHandler(event);">
60        </mx:Canvas>
61        <mx:Image source="@Embed('embedded/zoomIn.svg')" right="3" top="3" click="theMap.zoomIn();"
62            rollOverEffect="glowImage" rollOutEffect="unglowImage" toolTip="{'Zoom in - currently z'+getScale()}" />
63        <mx:Image source="@Embed('embedded/zoomOut.svg')" right="3" top="20" click="theMap.zoomOut();"
64            rollOverEffect="glowImage" rollOutEffect="unglowImage" toolTip="{'Zoom out - currently z'+getScale()}" />
65        <mx:TextArea id="dataWorking" text="" right="20" top="3" disabledColor="black" backgroundDisabledColor="0xFFFFEA" height="18"
66            enabled="false" borderThickness="0"
67            showEffect="{wipeIn}" hideEffect="{wipeOut}"/>
68
69    </mx:Canvas>
70
71    </mx:HDividedBox>
72
73        <mx:Script><![CDATA[
74                import net.systemeD.halcyon.*;
75                import net.systemeD.halcyon.connection.*;
76                import net.systemeD.potlatch2.*;
77                import net.systemeD.potlatch2.save.SaveManager;
78                import net.systemeD.potlatch2.controller.*;
79                import net.systemeD.potlatch2.help.*;
80                import net.systemeD.potlatch2.options.*;
81                import net.systemeD.potlatch2.utils.*;
82        import net.systemeD.potlatch2.mygpx.*;
83                import mx.managers.PopUpManager;
84                import flash.system.Security;
85                import flash.net.*;
86                import flash.events.MouseEvent;
87                import flash.display.Sprite;
88                import mx.core.IChildList;
89        import mx.containers.Canvas;
90                import mx.core.Application;
91        import mx.events.DragEvent;
92        import mx.managers.DragManager;
93        import mx.core.DragSource;
94        import mx.controls.Alert;
95
96        public var theMap:Map;
97        public var theController:EditController;
98                public var yahoo:Yahoo;
99                public var trackLoader:TrackLoader;
100                public var toolbox:Toolbox;
101
102                private var savecount:uint=0;
103                private var loadcount:uint=0;
104
105        include "version.as";
106
107                private function initApp():void {
108
109                        Globals.vars.map_area = map_area;
110                        Globals.vars.root = map_area.rawChildren;                       // set up global reference to root level
111                        var _root:IChildList = map_area.rawChildren;            // convenient local shorthand
112                        Globals.vars.nocache = loaderInfo.parameters['nocache'] == 'true';
113
114                        // populate sharedObject with loaderInfo parameters if supplied
115                        var obj:SharedObject = SharedObject.getLocal("user_state");
116                        var objChanged:Boolean = false;
117                        if (loaderInfo.parameters['tileurl']) {
118                                obj.setProperty('background_url',loaderInfo.parameters['tileurl']);
119                                obj.setProperty('background_name','Custom');
120                                objChanged=true;
121                        }
122                        if (loaderInfo.parameters['style']) {
123                                obj.setProperty('stylesheet_url',loaderInfo.parameters['style']);
124                                obj.setProperty('stylesheet_name','Custom');
125                                objChanged=true;
126                        }
127                        if (objChanged) { obj.flush(); }
128
129                        // load imagery and style XML
130                var request:DebugURLRequest = new DebugURLRequest("imagery.xml");
131                var loader:URLLoader = new URLLoader();
132                loader.addEventListener(Event.COMPLETE, onImageryLoad);
133                loader.load(request.request);
134
135                        var request2:DebugURLRequest = new DebugURLRequest("stylesheets.xml");
136                        var loader2:URLLoader = new URLLoader();
137                loader2.addEventListener(Event.COMPLETE, onStylesheetsLoad);
138                loader2.load(request2.request);
139
140                        // map backdrop object
141            var w:uint = map_area.width;
142            var h:uint = map_area.height;
143            var b:Sprite = new Sprite();
144            b.height=h; b.width=w;
145            b.graphics.beginFill(0xFFFFEA,100);
146            b.graphics.drawRect(0,0,w,h);
147            b.graphics.endFill();
148                        _root.addChild(b);
149
150                        // create map and Yahoo
151                        theMap=new Map(this.loaderInfo.parameters);
152                        theMap.backdrop=b;
153                        yahoo=new Yahoo(w,h,theMap);
154                        yahoo.hide();
155                        _root.addChild(yahoo);
156                        _root.addChild(theMap);
157            theMap.updateSize(w,h);
158                        theMap.addEventListener(MapEvent.SCALE, scaleHandler);
159
160                        // add mask for map
161                        var s:Sprite=new Sprite();
162                        s.graphics.beginFill(0xFFFFFF,100);
163                        s.graphics.drawRect(0,0,w,h);
164                        s.graphics.endFill();
165                        _root.addChild(s);
166                        theMap.mask=s;
167
168                        // mouse-up handler attached to stage, so the user can release outside the map
169                        stage.addEventListener(MouseEvent.MOUSE_UP, theMap.mouseUpHandler);
170                        Globals.vars.map_area.addEventListener(MouseEvent.MOUSE_MOVE, theMap.mouseMoveHandler);
171                        Globals.vars.map_area.addEventListener(MouseEvent.MOUSE_DOWN, theMap.mouseDownHandler);
172
173                        // keyboard event attached to stage
174                        stage.addEventListener(KeyboardEvent.KEY_UP, theMap.keyUpHandler);
175
176                        // position toolbox
177                        toolbox=Toolbox(PopUpManager.createPopUp(this,Toolbox,false));
178                        toolbox.init(theController);
179                        toolbox.x=stage.stageWidth-toolbox.width-15;
180                        toolbox.y=stage.stageHeight-toolbox.height-15;
181
182                        // add debug field
183                        var t:TextField=new TextField();
184                        t.width=500; t.height=150; t.border=true;
185                        t.multiline=true;
186                        _root.addChild(t);
187                        Globals.vars.debug=t;
188            t.visible = loaderInfo.parameters["show_debug"] == 'true';
189                        Globals.vars.root=theMap;       // just for the addDebug function
190
191            theController = new EditController(theMap, tagViewer, toolbox);
192            theController.setActive();
193           
194            var conn:Connection = Connection.getConnectionInstance();
195            conn.addEventListener(Connection.LOAD_STARTED, onDataStart);
196            conn.addEventListener(Connection.LOAD_COMPLETED, onDataComplete);
197            conn.addEventListener(Connection.SAVE_STARTED, onDataStart);
198            conn.addEventListener(Connection.SAVE_COMPLETED, onDataComplete);
199            conn.addEventListener(Connection.DATA_DIRTY, onDataDirty);
200            conn.addEventListener(Connection.DATA_CLEAN, onDataClean);
201                        conn.addEventListener(MapEvent.ERROR, onMapError);
202
203            // set the access token from saved cookie
204            var tokenObject:SharedObject = SharedObject.getLocal("access_token");
205            conn.setAccessToken(tokenObject.data["oauth_token"], tokenObject.data["oauth_token_secret"]);
206
207                        // create GPS trackloader
208                        trackLoader=new TrackLoader(theMap,conn.apiBase);
209
210            // Force authentication on startup, if required
211            // force_auth == force => checks for access token, and displays OAuth panel if needed
212            var force_auth:String = loaderInfo.parameters["force_auth"];
213            if (!conn.hasAccessToken() && force_auth == 'force') {
214              SaveManager.ensureAccess(onAccessChecked);
215            }
216
217            // show help dialog on startup, if required
218            // show_help == always => on every startup
219            // show_help == once => show on first startup only
220            var show_help:String = loaderInfo.parameters["show_help"];
221
222            if (show_help == 'always' || (show_help == 'once' && obj.data["help_shown"] != "true")) {
223              new HelpDialog().init();
224            }
225
226            // Check if Tiger highlighting should be enabled from saved object
227            Globals.vars.highlightTiger = obj.data['tiger_highlighted'];
228                }
229               
230                public function onMapError(event:MapEvent):void {
231                        Alert.show(event.params.message, 'Error', mx.controls.Alert.OK);
232                }
233
234        public function onResizeMap():void {
235            if ( theMap != null )
236                theMap.updateSize(map_area.width, map_area.height);
237
238                        if (toolbox) {
239                                toolbox.x=Math.min(toolbox.x,stage.stageWidth-toolbox.width-15);
240                                toolbox.y=Math.min(toolbox.y,stage.stageHeight-toolbox.height-15);
241                        }
242        }
243
244        private function onDataStart(event:Event):void {
245                        switch (event.type) {
246                                case Connection.LOAD_STARTED:   loadcount++; break;
247                                case Connection.SAVE_STARTED:   savecount++; break;
248                        }
249                        updateDataWorking();
250        }
251        private function onDataComplete(event:Event):void {
252                        switch (event.type) {
253                                case Connection.LOAD_COMPLETED: loadcount--; break;
254                                case Connection.SAVE_COMPLETED: savecount--; break;
255                        }
256            updateDataWorking();
257        }
258                private function updateDataWorking():void {
259                        if (loadcount>0 && savecount>0) { dataWorking.text="Loading/saving..."; }
260                        else if (loadcount>0)           { dataWorking.text="Loading data..."; }
261                        else if (savecount>0)           { dataWorking.text="Saving data..."; }
262                        else                            { dataWorking.text=""; }
263                        dataWorking.visible=(dataWorking.text!="");
264                }
265        private function onDataDirty(event:Event):void {
266                        saveButton.enabled=true;
267            if (ExternalInterface.available) {
268              ExternalInterface.call("markChanged", false);
269            }
270                }
271                private function onDataClean(event:Event):void {
272                        saveButton.enabled=false;
273            if (ExternalInterface.available) {
274              ExternalInterface.call("markChanged", true);
275            }
276                }
277               
278        private function onImageryLoad(event:Event):void {
279                        var xml:XML = new XML(URLLoader(event.target).data);
280                        var saved:Object;
281                        if (SharedObject.getLocal("user_state").data['background_url']) {
282                                saved={ name: SharedObject.getLocal("user_state").data['background_name'],
283                                                url:  SharedObject.getLocal("user_state").data['background_url' ] };
284                        } else {
285                                saved={};
286                        }
287
288                        var isSet:Boolean=false;
289            var backgroundSet:Boolean = false;
290
291            theController.imagery=new Array(
292                                { name: "None", url: "" },
293                                { name: "Yahoo", url: "yahoo", sourcetag: "Yahoo" } );
294                        for each(var set:XML in xml.set) {
295                                var obj:Object={};
296                                for (var a:String in set.children()) {
297                                        obj[set.child(a).name()]=set.child(a);
298                                }
299                theController.imagery.push(obj);
300                                if ((obj.url ==saved.url) ||
301                                    (obj.name==saved.name && obj.name!='Custom')) { isSet=true; }
302                        }
303
304            if (!isSet && saved.name && saved.url && saved.url!='' && saved.url!='yahoo') {
305                theController.imagery.push(saved);
306                isSet=true;
307            }
308
309                        for each (var bg:Object in theController.imagery) {
310                                if (bg.name==saved.name || bg.url==saved.url) {
311                                        setBackground(bg);
312                    backgroundSet = true;
313                                }
314                        }
315
316            // For most contributors it's useful to set the background to yahoo by default, I reckon, but lets make it a config
317            if (!backgroundSet && loaderInfo.parameters['yahoo_default'] == 'true') {
318                setBackground(theController.imagery[1]);
319            }
320                }
321               
322                public function setBackground(bg:Object):void {
323                        if (bg.url=='yahoo') { theMap.setBackground(''    ); yahoo.show(); }
324                                        else { theMap.setBackground(bg.url); yahoo.hide(); }
325                        theController.imagerySelected=bg;
326                        var obj:SharedObject = SharedObject.getLocal("user_state");
327                        obj.setProperty('background_url' ,String(bg.url));
328                        obj.setProperty('background_name',String(bg.name));
329                        obj.flush();
330                }
331
332                private function onStylesheetsLoad(event:Event):void {
333                        var xml:XML = new XML(URLLoader(event.target).data);
334                        var saved_url:String = SharedObject.getLocal("user_state").data['stylesheet_url'];
335                        var saved_name:String= SharedObject.getLocal("user_state").data['stylesheet_name'];
336                        var isInMenu:Boolean=false, isSet:Boolean=false;
337
338            // first, build the menu from the stylesheet list.
339            // Also ensure the saved_url is in the menu (might be either saved from before, or supplied via loaderInfo)
340            theController.stylesheets=new Array();
341                        for each(var set:XML in xml.stylesheet) {
342                                var obj:Object={};
343                                for (var a:String in set.children()) {
344                                        obj[set.child(a).name()]=set.child(a);
345                                }
346                theController.stylesheets.push(obj);
347                                if (obj.url==saved_url || (obj.name==saved_name && obj.name!='Custom')) { isInMenu=true; }
348                        }
349                        if (saved_url && !isInMenu) { theController.stylesheets.push({ name:saved_name, url:saved_url }); }
350
351            // pick a stylesheet to be set. It should be the saved one, if it is in the menu
352            // or alternatively the first one on the menu,
353            // or finally try 'potlatch.css'
354                        for each (var ss:Object in theController.stylesheets) {
355                                if (ss.name==saved_name || ss.url==saved_url) {
356                                        setStylesheet(ss.name, ss.url);
357                    isSet = true;
358                    break;
359                                }
360                        }
361            if (!isSet) {
362              if(theController.stylesheets.length > 0) {
363                var s:Object = theController.stylesheets[0];
364                setStylesheet(s.name, s.url);
365              } else {
366                //hit and hope. FIXME should this be an error state?
367                theController.stylesheets.push({ name:'Potlatch', url:'potlatch.css'});
368                setStylesheet('Potlatch','potlatch.css');
369              }
370            }
371                }
372
373                public function setStylesheet(name:String,url:String):void {
374                        theMap.setStyle(url);
375                        var obj:SharedObject = SharedObject.getLocal("user_state");
376                        obj.setProperty("stylesheet_url",url);
377                        obj.setProperty("stylesheet_name",name);
378                        obj.flush();
379                }
380
381                private function scaleHandler(event:MapEvent):void {
382                        dispatchEvent(new Event("rescale"));
383                }
384               
385                [Bindable(event="rescale")]
386                private function getScale():String {
387                        return String(theMap.scale);
388                }
389
390        private function dragEnterHandler(event:DragEvent):void {
391            // Get the drop target component from the event object.
392            var dropTarget:Canvas=event.currentTarget as Canvas;
393            // Accept the drag only if the user is dragging poi with tags
394            if (event.dragSource.hasFormat('tags'))
395            {
396                DragManager.acceptDragDrop(dropTarget);
397            }
398        }
399       
400        private function dragDropHandler(event:DragEvent):void {
401                        // Deselect the dragged icon
402                        if (event.dragSource.dataForFormat('container')) {
403                                event.dragSource.dataForFormat('container').selectedItem=-1;
404                        }
405
406                        // Get the tags
407            var tags:Array = event.dragSource.dataForFormat('tags') as Array;
408            var mapLoc:Point = Globals.vars.root.globalToLocal(new Point(event.stageX, event.stageY));
409            var lat:Number = Globals.vars.root.coord2lat(mapLoc.y);
410            var lon:Number = Globals.vars.root.coord2lon(mapLoc.x);
411           
412            var createAction:CompositeUndoableAction = new CompositeUndoableAction("Create POI");
413           
414            var node:Node = Connection.getConnectionInstance().createNode({}, lat, lon, createAction.push);
415            for each ( var tag:Object in tags ) {
416                node.setTag(tag.k, tag.v, createAction.push);
417            }
418                        Connection.getConnectionInstance().registerPOI(node);
419                        MainUndoStack.getGlobalStack().addAction(createAction);
420            theController.setState(new SelectedPOINode(node));
421        }
422
423        /* Called when forcing an initial access token check. */
424        private function onAccessChecked():void {
425            // Floaty panel message "You now have access";
426        }
427
428        ]]></mx:Script>
429
430</mx:Application>
431
Note: See TracBrowser for help on using the repository browser.