source: Dev/branches/rest-dojo-ui/client/dojox/layout/ExpandoPane.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 7.8 KB
Line 
1define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/declare","dojo/_base/array",
2        "dojo/_base/connect","dojo/_base/event","dojo/_base/fx","dojo/dom-style",
3        "dojo/dom-class","dojo/dom-geometry","dojo/text!./resources/ExpandoPane.html",
4        "dijit/layout/ContentPane","dijit/_TemplatedMixin","dijit/_Contained","dijit/_Container"],
5  function(kernel,lang,declare,arrayUtil,connectUtil,eventUtil,baseFx,domStyle,domClass,domGeom,
6                template,ContentPane,TemplatedMixin,Contained,Container) {
7/*=====
8var ContentPane = dijit.layout.ContentPane;
9var TemplatedMixin = dijit._TemplatedMixin;
10var Contained = dijit._Contained;
11var Container = dijit._Container;
12  =====*/
13kernel.experimental("dojox.layout.ExpandoPane"); // just to show it can be done?
14
15return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contained, Container],{
16        // summary: An experimental collapsing-pane for dijit.layout.BorderContainer
17        //
18        // description:
19        //              Works just like a ContentPane inside of a borderContainer. Will expand/collapse on
20        //              command, and supports having Layout Children as direct descendants
21        //
22
23        //maxHeight: "",
24        //maxWidth: "",
25        //splitter: false,
26        attributeMap: lang.delegate(ContentPane.prototype.attributeMap, {
27                title: { node: "titleNode", type: "innerHTML" }
28        }),
29       
30        templateString: template,
31
32        // easeOut: String|Function
33        //              easing function used to hide pane
34        easeOut: "dojo._DefaultEasing", // FIXME: This won't work with globalless AMD
35       
36        // easeIn: String|Function
37        //              easing function use to show pane
38        easeIn: "dojo._DefaultEasing", // FIXME: This won't work with globalless AMD
39       
40        // duration: Integer
41        //              duration to run show/hide animations
42        duration: 420,
43
44        // startExpanded: Boolean
45        //              Does this widget start in an open (true) or closed (false) state
46        startExpanded: true,
47
48        // previewOpacity: Float
49        //              A value from 0 .. 1 indicating the opacity to use on the container
50        //              when only showing a preview
51        previewOpacity: 0.75,
52       
53        // previewOnDblClick: Boolean
54        //              If true, will override the default behavior of a double-click calling a full toggle.
55        //              If false, a double-click will cause the preview to popup
56        previewOnDblClick: false,
57
58        baseClass: "dijitExpandoPane",
59
60        postCreate: function(){
61                this.inherited(arguments);
62                this._animConnects = [];
63
64                this._isHorizontal = true;
65               
66                if(lang.isString(this.easeOut)){
67                        this.easeOut = lang.getObject(this.easeOut);
68                }
69                if(lang.isString(this.easeIn)){
70                        this.easeIn = lang.getObject(this.easeIn);
71                }
72       
73                var thisClass = "", rtl = !this.isLeftToRight();
74                if(this.region){
75                        switch(this.region){
76                                case "trailing" :
77                                case "right" :
78                                        thisClass = rtl ? "Left" : "Right";
79                                        break;
80                                case "leading" :
81                                case "left" :
82                                        thisClass = rtl ? "Right" : "Left";
83                                        break;
84                                case "top" :
85                                        thisClass = "Top";
86                                        break;
87                                case "bottom" :
88                                        thisClass = "Bottom";
89                                        break;
90                        }
91                        domClass.add(this.domNode, "dojoxExpando" + thisClass);
92                        domClass.add(this.iconNode, "dojoxExpandoIcon" + thisClass);
93                        this._isHorizontal = /top|bottom/.test(this.region);
94                }
95                domStyle.set(this.domNode, {
96                        overflow: "hidden",
97                        padding:0
98                });
99               
100                this.connect(this.domNode, "ondblclick", this.previewOnDblClick ? "preview" : "toggle");
101               
102                if(this.previewOnDblClick){
103                        this.connect(this.getParent(), "_layoutChildren", lang.hitch(this, function(){
104                                this._isonlypreview = false;
105                        }));
106                }
107               
108        },
109       
110        _startupSizes: function(){
111               
112                this._container = this.getParent();
113                this._closedSize = this._titleHeight = domGeom.getMarginBox(this.titleWrapper).h;
114               
115                if(this.splitter){
116                        // find our splitter and tie into it's drag logic
117                        var myid = this.id;
118                        arrayUtil.forEach(dijit.registry.toArray(), function(w){
119                                if(w && w.child && w.child.id == myid){
120                                        this.connect(w,"_stopDrag","_afterResize");
121                                }
122                        }, this);
123                }
124               
125                this._currentSize = domGeom.getContentBox(this.domNode);        // TODO: can compute this from passed in value to resize(), see _LayoutWidget for example
126                this._showSize = this._currentSize[(this._isHorizontal ? "h" : "w")];
127                this._setupAnims();
128
129                if(this.startExpanded){
130                        this._showing = true;
131                }else{
132                        this._showing = false;
133                        this._hideWrapper();
134                        this._hideAnim.gotoPercent(99,true);
135                }
136               
137                this._hasSizes = true;
138        },
139       
140        _afterResize: function(e){
141                var tmp = this._currentSize;                                            // the old size
142                this._currentSize = domGeom.getMarginBox(this.domNode); // the new size
143                var n = this._currentSize[(this._isHorizontal ? "h" : "w")]
144                if(n > this._titleHeight){
145                        if(!this._showing){
146                                this._showing = !this._showing;
147                                this._showEnd();
148                        }
149                        this._showSize = n;
150                        this._setupAnims();
151                }else{
152                        this._showSize = tmp[(this._isHorizontal ? "h" : "w")];
153                        this._showing = false;
154                        this._hideWrapper();
155                        this._hideAnim.gotoPercent(89,true);
156                }
157               
158        },
159       
160        _setupAnims: function(){
161                // summary: Create the show and hide animations
162                arrayUtil.forEach(this._animConnects, connectUtil.disconnect);
163               
164                var _common = {
165                                node:this.domNode,
166                                duration:this.duration
167                        },
168                        isHorizontal = this._isHorizontal,
169                        showProps = {},
170                        hideProps = {},
171                        dimension = isHorizontal ? "height" : "width"
172                ;
173
174                showProps[dimension] = {
175                        end: this._showSize
176                };
177                hideProps[dimension] = {
178                        end: this._closedSize
179                };
180               
181                this._showAnim = baseFx.animateProperty(lang.mixin(_common,{
182                        easing:this.easeIn,
183                        properties: showProps
184                }));
185                this._hideAnim = baseFx.animateProperty(lang.mixin(_common,{
186                        easing:this.easeOut,
187                        properties: hideProps
188                }));
189
190                this._animConnects = [
191                        connectUtil.connect(this._showAnim, "onEnd", this, "_showEnd"),
192                        connectUtil.connect(this._hideAnim, "onEnd", this, "_hideEnd")
193                ];
194        },
195       
196        preview: function(){
197                // summary: Expand this pane in preview mode (does not affect surrounding layout)
198
199                if(!this._showing){
200                        this._isonlypreview = !this._isonlypreview;
201                }
202                this.toggle();
203        },
204
205        toggle: function(){
206                // summary: Toggle this pane's visibility
207                if(this._showing){
208                        this._hideWrapper();
209                        this._showAnim && this._showAnim.stop();
210                        this._hideAnim.play();
211                }else{
212                        this._hideAnim && this._hideAnim.stop();
213                        this._showAnim.play();
214                }
215                this._showing = !this._showing;
216        },
217       
218        _hideWrapper: function(){
219                // summary: Set the Expando state to "closed"
220                domClass.add(this.domNode, "dojoxExpandoClosed");
221               
222                domStyle.set(this.cwrapper,{
223                        visibility: "hidden",
224                        opacity: "0",
225                        overflow: "hidden"
226                });
227        },
228       
229        _showEnd: function(){
230                // summary: Common animation onEnd code - "unclose"
231                domStyle.set(this.cwrapper, {
232                        opacity: 0,
233                        visibility:"visible"
234                });
235                baseFx.anim(this.cwrapper, {
236                        opacity: this._isonlypreview ? this.previewOpacity : 1
237                }, 227);
238                domClass.remove(this.domNode, "dojoxExpandoClosed");
239                if(!this._isonlypreview){
240                        setTimeout(lang.hitch(this._container, "layout"), 15);
241                }else{
242                        this._previewShowing = true;
243                        this.resize();
244                }
245        },
246       
247        _hideEnd: function(){
248                // summary: Callback for the hide animation - "close"
249
250                // every time we hide, reset the "only preview" state
251                if(!this._isonlypreview){
252                        setTimeout(lang.hitch(this._container, "layout"), 25);
253                }else{
254                        this._previewShowing = false;
255                }
256                this._isonlypreview = false;
257               
258        },
259       
260        resize: function(/* Object? */newSize){
261                // summary:
262                //              we aren't a layout widget, but need to act like one:
263                // newSize: Object
264                //              The size object to resize to
265
266                if(!this._hasSizes){ this._startupSizes(newSize); }
267               
268                // compute size of container (ie, size left over after title bar)
269                var currentSize = domGeom.getMarginBox(this.domNode);
270                this._contentBox = {
271                        w: newSize && "w" in newSize ? newSize.w : currentSize.w,
272                        h: (newSize && "h" in newSize ? newSize.h : currentSize.h) - this._titleHeight
273                };
274                domStyle.set(this.containerNode, "height", this._contentBox.h + "px");
275
276                if(newSize){
277                        domGeom.setMarginBox(this.domNode, newSize);
278                }
279
280                this._layoutChildren();
281        },
282       
283        _trap: function(e){
284                // summary: Trap stray events
285                eventUtil.stop(e);
286        }
287});
288});
Note: See TracBrowser for help on using the repository browser.