Merge pull request #39 from stevage/fix-tram-route-editor
[potlatch2.git] / net / systemeD / potlatch2 / panels / DragAndDropPanel.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <mx:VBox width="100%" height="100%" horizontalScrollPolicy="off" styleName="dndPanelVbox"
4     xmlns:fx="http://ns.adobe.com/mxml/2009"
5         xmlns:controls="net.systemeD.controls.*"
6         xmlns:mx="library://ns.adobe.com/flex/mx">
7
8         <mx:Text id="dndPanelText" text="{dndPrompt}" width="100%" styleName="helpInfo" />
9         <mx:Repeater id="dndRep" dataProvider="{MapFeatures.getInstance().getCategoriesForType('point')}" styleName="dndRepeater">
10                 <mx:HBox width="100%" styleName="dndPanelCategory">
11                         <mx:Label text="{dndRep.currentItem.name}:" styleName="dndPanelCategoryLabel"/>
12                         <mx:Spacer width="100%" />
13                         <mx:Label click="showHide(event)" text="" />
14                         <mx:Image click="showHide(event)" source="{closedIcon}" />
15                 </mx:HBox>
16
17                 <mx:TileList dataProvider="{dndRep.currentItem.getFeaturesForType('point', true)}" width="100%" height="1"
18                              id="tl" dragEnabled="true" mouseDown="mouseDownHandler(event)" verticalScrollPolicy="off" 
19                              rowHeight="32" columnWidth="100" updateComplete="sizePOIGrid(event)" styleName="dndPanelTileList">
20                         <mx:itemRenderer>
21                                 <fx:Component>
22                                         <mx:HBox toolTip="{data.name}" horizontalScrollPolicy="off" >
23                                                 <mx:Image id="foo" source="{data.dndimage}" height="24" width="24" toolTip="{data.name}" />
24                                                 <mx:Label text="{data.name}" />
25                                         </mx:HBox>
26                                 </fx:Component>
27                         </mx:itemRenderer>
28                 </mx:TileList>
29         </mx:Repeater>
30
31         <fx:Script><![CDATA[
32
33         import net.systemeD.potlatch2.mapfeatures.*;
34         import mx.core.DragSource;
35         import mx.managers.DragManager;
36         import mx.controls.Image;
37         import mx.controls.Button;
38         import mx.controls.TileList;
39         import mx.controls.scrollClasses.*;
40
41         [Bindable] [Embed(source="../../../../embedded/CollapsiblePanelAssets.swf", symbol="CollapseButtonDown")] private var openIcon:Class;
42         [Bindable] [Embed(source="../../../../embedded/CollapsiblePanelAssets.swf", symbol="CollapseButtonOver")] private var closedIcon:Class;
43
44         [Bindable] public var dndPrompt:String="Add new points by dragging them onto the map";
45
46         private var inited:Object={};
47         private static const MINIMISED_ROWS:uint=2;             // we could perhaps set this by category (e.g. two for shopping, one for tourism...)
48         private static const MINIMISED:uint=0;
49         private static const MAXIMISED:uint=1;
50         private static const TOO_SMALL:uint=2;
51         private static const ICON_WIDTH:uint=24;
52         private static const ICON_HEIGHT:uint=24;
53
54         /** Start POI drag-and-drop. */
55         private function mouseDownHandler(event:MouseEvent):void {
56                 if (event.target is ScrollThumb || event.target is Button) return;
57
58                 var item:Feature=Feature(TileList(event.currentTarget).selectedItem);
59                 var dragInitiator:HBox = event.currentTarget.itemToItemRenderer(item);
60                 var dragSource:DragSource = new DragSource();
61                 dragSource.addData(item.tags, 'tags');
62                 dragSource.addData(event.currentTarget, 'container');
63
64                 var dragProxy:Image = new Image();
65                 dragProxy.source = item.dndimage;
66                 dragProxy.width = ICON_WIDTH;   // must set width and height explicitly
67                 dragProxy.height = ICON_HEIGHT; // for non-embedded images
68
69                 DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
70                 TileList(event.currentTarget).selectedItem=null;
71         }
72
73         /** Handle user's click on show/hide label. */
74         public function showHide(event:Event):void {
75                 // find out which tilelist was clicked
76                 var theHBox:HBox=event.currentTarget.parent;
77                 var pos:uint=theHBox.parent.getChildIndex(theHBox);
78                 var tilelist:TileList=TileList(theHBox.parent.getChildAt(pos+1));
79                 
80                 // now adjust the number of rows
81                 setHeight(tilelist,(isAtMaximumSize(tilelist)));
82         }
83
84         /** Set a POI grid to the correct size when it's created. Non-functional if called later. */
85         private function sizePOIGrid(event:Event):void {
86                 var tilelist:TileList=TileList(event.target);
87                 if (inited[tilelist]) { return; }
88                 inited[tilelist]=true;
89                 setHeight(tilelist,true);
90         }
91         
92         /** Set a POI grid to minimised or maximised state, and return the state it's been set to. */
93         private function setHeight(tilelist:TileList,minimise:Boolean):uint {
94                 // Set required state
95                 var rows:Number=rowsForAll(tilelist);
96                 var state:uint;
97                 if (rows<=MINIMISED_ROWS) { applyHeight(tilelist,rows); state=TOO_SMALL; }
98                 else if (minimise) { applyHeight(tilelist,MINIMISED_ROWS); state=MINIMISED; }
99                 else { applyHeight(tilelist,rows); state=MAXIMISED; }
100                 
101                 // Update the clickable label
102                 var pos:uint=tilelist.parent.getChildIndex(tilelist);
103                 var hbox:HBox=HBox(tilelist.parent.getChildAt(pos-1));
104                 var label:Label=Label(hbox.getChildAt(2));
105                 var button:Image=Image(hbox.getChildAt(3));
106                 switch (state) {
107                         case TOO_SMALL: label.text="";         button.visible=false; break;
108                         case MINIMISED: label.text="Show all"; button.source =closedIcon; break;
109                         case MAXIMISED: label.text="Collapse"; button.source =openIcon; break;
110                 }
111                 return state;
112         }
113         
114         /** Called by setHeight to actually apply the row height to the Flex TileList object. */
115         private function applyHeight(tilelist:TileList,rows:uint):void {
116                 tilelist.height=rows*(tilelist.rowHeight+1);
117         }
118         
119         /** Is the POI grid at its maximum size? */
120         private function isAtMaximumSize(tilelist:TileList):Boolean {
121                 var size:Number=tilelist.height/(tilelist.rowHeight+1);
122                 return (size==rowsForAll(tilelist));
123         }
124         
125         /** How many rows are required to show everything in this POI grid? */
126         private function rowsForAll(tilelist:TileList):Number {
127                 var rows:Number=tilelist.dataProvider.length/tilelist.columnCount;
128                 if (rows!=Math.floor(rows)) { rows=Math.floor(rows+1); }
129                 return rows;
130         }
131
132         ]]></fx:Script>
133
134 </mx:VBox>