Restyle drag-and-drop panel
[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
30                 <mx:VBox width="100%" height="5"/>
31         </mx:Repeater>
32
33         <fx:Script><![CDATA[
34
35         import net.systemeD.potlatch2.mapfeatures.*;
36         import mx.core.DragSource;
37         import mx.managers.DragManager;
38         import mx.controls.Image;
39         import mx.controls.Button;
40         import mx.controls.TileList;
41         import mx.controls.scrollClasses.*;
42
43         [Bindable] [Embed(source="../../../../embedded/CollapsiblePanelAssets.swf", symbol="CollapseButtonDown")] private var openIcon:Class;
44         [Bindable] [Embed(source="../../../../embedded/CollapsiblePanelAssets.swf", symbol="CollapseButtonOver")] private var closedIcon:Class;
45
46         [Bindable] public var dndPrompt:String="Add new points by dragging them onto the map";
47
48         private var inited:Object={};
49         private static const MINIMISED_ROWS:uint=2;             // we could perhaps set this by category (e.g. two for shopping, one for tourism...)
50         private static const MINIMISED:uint=0;
51         private static const MAXIMISED:uint=1;
52         private static const TOO_SMALL:uint=2;
53         private static const ICON_WIDTH:uint=24;
54         private static const ICON_HEIGHT:uint=24;
55
56         /** Start POI drag-and-drop. */
57         private function mouseDownHandler(event:MouseEvent):void {
58                 if (event.target is ScrollThumb || event.target is Button) return;
59
60                 var item:Feature=Feature(TileList(event.currentTarget).selectedItem);
61                 var dragInitiator:HBox = event.currentTarget.itemToItemRenderer(item);
62                 var dragSource:DragSource = new DragSource();
63                 dragSource.addData(item.tags, 'tags');
64                 dragSource.addData(event.currentTarget, 'container');
65
66                 var dragProxy:Image = new Image();
67                 dragProxy.source = item.dndimage;
68                 dragProxy.width = ICON_WIDTH;   // must set width and height explicitly
69                 dragProxy.height = ICON_HEIGHT; // for non-embedded images
70
71                 DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
72                 TileList(event.currentTarget).selectedItem=null;
73         }
74
75         /** Handle user's click on show/hide label. */
76         public function showHide(event:Event):void {
77                 // find out which tilelist was clicked
78                 var theHBox:HBox=event.currentTarget.parent;
79                 var pos:uint=theHBox.parent.getChildIndex(theHBox);
80                 var tilelist:TileList=TileList(theHBox.parent.getChildAt(pos+1));
81                 
82                 // now adjust the number of rows
83                 setHeight(tilelist,(isAtMaximumSize(tilelist)));
84         }
85
86         /** Set a POI grid to the correct size when it's created. Non-functional if called later. */
87         private function sizePOIGrid(event:Event):void {
88                 var tilelist:TileList=TileList(event.target);
89                 if (inited[tilelist]) { return; }
90                 inited[tilelist]=true;
91                 setHeight(tilelist,true);
92         }
93         
94         /** Set a POI grid to minimised or maximised state, and return the state it's been set to. */
95         private function setHeight(tilelist:TileList,minimise:Boolean):uint {
96                 // Set required state
97                 var rows:Number=rowsForAll(tilelist);
98                 var state:uint;
99                 if (rows<=MINIMISED_ROWS) { applyHeight(tilelist,rows); state=TOO_SMALL; }
100                 else if (minimise) { applyHeight(tilelist,MINIMISED_ROWS); state=MINIMISED; }
101                 else { applyHeight(tilelist,rows); state=MAXIMISED; }
102                 
103                 // Update the clickable label
104                 var pos:uint=tilelist.parent.getChildIndex(tilelist);
105                 var hbox:HBox=HBox(tilelist.parent.getChildAt(pos-1));
106                 var label:Label=Label(hbox.getChildAt(2));
107                 var button:Image=Image(hbox.getChildAt(3));
108                 switch (state) {
109                         case TOO_SMALL: label.text="";         button.visible=false; break;
110                         case MINIMISED: label.text="Show all"; button.source =closedIcon; break;
111                         case MAXIMISED: label.text="Collapse"; button.source =openIcon; break;
112                 }
113                 return state;
114         }
115         
116         /** Called by setHeight to actually apply the row height to the Flex TileList object. */
117         private function applyHeight(tilelist:TileList,rows:uint):void {
118                 tilelist.height=rows*(tilelist.rowHeight+1);
119         }
120         
121         /** Is the POI grid at its maximum size? */
122         private function isAtMaximumSize(tilelist:TileList):Boolean {
123                 var size:Number=tilelist.height/(tilelist.rowHeight+1);
124                 return (size==rowsForAll(tilelist));
125         }
126         
127         /** How many rows are required to show everything in this POI grid? */
128         private function rowsForAll(tilelist:TileList):Number {
129                 var rows:Number=tilelist.dataProvider.length/tilelist.columnCount;
130                 if (rows!=Math.floor(rows)) { rows=Math.floor(rows+1); }
131                 return rows;
132         }
133
134         ]]></fx:Script>
135
136 </mx:VBox>