Merge branch 'master' into history
[potlatch2.git] / net / systemeD / controls / CollapsiblePanel.as
1 /*
2
3 The MIT License
4
5 Copyright (c) 2007-2008 Ali Rantakari of hasseg.org
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 THE SOFTWARE.
24
25 */
26
27 package net.systemeD.controls {
28         
29         import flash.events.*;
30         import mx.effects.AnimateProperty;
31         import mx.events.*;
32         import mx.containers.Panel;
33         import mx.core.ScrollPolicy;
34         
35         /**
36         * The icon designating a "closed" state
37         */
38         [Style(name="closedIcon", property="closedIcon", type="Object")]
39         
40         /**
41         * The icon designating an "open" state
42         */
43         [Style(name="openIcon", property="openIcon", type="Object")]
44         
45         /**
46         * This is a Panel that can be collapsed and expanded by clicking on the header.
47         * 
48         * @author Ali Rantakari
49         */
50         public class CollapsiblePanel extends Panel {
51                 
52
53
54                 private var _creationComplete:Boolean = false;
55                 private var _open:Boolean = true;
56                 private var _openAnim:AnimateProperty;
57                 
58                 
59                 
60                 /**
61                 * Constructor
62                 * 
63                 */
64                 public function CollapsiblePanel(aOpen:Boolean = true):void
65                 {
66                         super();
67                         open = aOpen;
68                         this.addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
69                 }
70                 
71                 
72                 
73                 
74                 
75                 
76                 
77                 
78                 // BEGIN: event handlers                                ------------------------------------------------------------
79                 
80                 private function creationCompleteHandler(event:FlexEvent):void
81                 {
82                         this.horizontalScrollPolicy = ScrollPolicy.OFF;
83                         this.verticalScrollPolicy = ScrollPolicy.OFF;
84                         
85                         _openAnim = new AnimateProperty(this);
86                         _openAnim.duration = 300;
87                         _openAnim.property = "height";
88                         
89                         titleBar.addEventListener(MouseEvent.CLICK, headerClickHandler);
90                         
91                         _creationComplete = true;
92                 }
93                 
94                 private function headerClickHandler(event:MouseEvent):void { toggleOpen(); }
95                 
96                 private function callUpdateOpenOnCreationComplete(event:FlexEvent):void { updateOpen(); }
97                 
98                 // --end--: event handlers                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99                 
100                 
101                 
102                 
103                 
104                 
105                 
106                 
107                 // BEGIN: private methods                               ------------------------------------------------------------
108                 
109                 // sets the height of the component without animation, based
110                 // on the _open variable
111                 private function updateOpen():void
112                 {
113                         if (!_open) height = closedHeight;
114                         else height = openHeight;
115                         setTitleIcon();
116                 }
117                 
118                 // the height that the component should be when open
119                 private function get openHeight():Number {
120                         return measuredHeight;
121                 }
122                 
123                 // the height that the component should be when closed
124                 private function get closedHeight():Number {
125                         var hh:Number = getStyle("headerHeight");
126                         if (hh <= 0 || isNaN(hh)) hh = titleBar.height;
127                         return hh;
128                 }
129                 
130                 // sets the correct title icon
131                 private function setTitleIcon():void
132                 {
133                         if (!_open) this.titleIcon = getStyle("closedIcon");
134                         else this.titleIcon = getStyle("openIcon");
135                 }
136                 
137                 // --end--: private methods                     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138                 
139                 
140                 
141                 
142                 
143                 
144                 
145                 
146                 // BEGIN: public methods                                ------------------------------------------------------------
147                 
148                 
149                 
150                 /**
151                 * Collapses / expands this block (with animation)
152                 */
153                 public function toggleOpen():void 
154                 {
155                         if (_creationComplete && !_openAnim.isPlaying) {
156                                 
157                                 _openAnim.fromValue = _openAnim.target.height;
158                                 if (!_open) {
159                                         _openAnim.toValue = openHeight;
160                                         _open = true;
161                                         dispatchEvent(new Event(Event.OPEN));
162                                 }else{
163                                         _openAnim.toValue = _openAnim.target.closedHeight;
164                                         _open = false;
165                                         dispatchEvent(new Event(Event.CLOSE));
166                                 }
167                                 setTitleIcon();
168                                 _openAnim.play();
169                                 
170                         }
171                         
172                 }
173                 
174                 
175                 /**
176                 * Whether the block is in a expanded (open) state or not
177                 */
178                 public function get open():Boolean {
179                         return _open;
180                 }
181                 /**
182                 * @private
183                 */
184                 public function set open(aValue:Boolean):void {
185                         _open = aValue;
186                         if (_creationComplete) updateOpen();
187                         else this.addEventListener(FlexEvent.CREATION_COMPLETE, callUpdateOpenOnCreationComplete, false, 0, true);
188                 }
189                 
190                 
191                 /**
192                 * @private
193                 */
194                 override public function invalidateSize():void {
195                         super.invalidateSize();
196                         if (_creationComplete)
197                                 if (_open && !_openAnim.isPlaying) this.height = openHeight;
198                 }
199                 
200                 
201                 // --end--: public methods                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202                 
203                 
204         }
205
206 }
207