source: Dev/trunk/src/client/dojox/layout/RadioGroup.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 8.8 KB
Line 
1define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/lang","dojo/_base/query",
2                "dijit/_Widget","dijit/_Templated","dijit/_Contained","dijit/layout/StackContainer",
3                "dojo/fx/easing","dojo/_base/fx","dojo/dom-construct","dojo/dom-class"],function(
4        kernel,declare,html,lang,query,Widget,Templated,Contained,StackContainer,easing,baseFx,domConstruct,domClass){
5
6kernel.experimental("dojox.layout.RadioGroup");
7
8/*=====
9return {
10        // summary:
11        //              dojox.layout.RadioGroup - an experimental (probably poorly named) Layout widget extending StackContainer
12        //              that accepts ContentPanes as children, and applies aesthetically pleasing responsive transition animations
13        //              attached to :hover of the Buttons created.
14
15        // FIXME: take the Buttons out of the root template, and allow layoutAlign or similar attrib to use a different
16        //      template, or build the template dynamically?
17        };
18=====*/
19var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
20        // summary:
21        //              A Container that turns its Layout Children into a single Pane and transitions between states
22        //              onHover of the button
23
24        // duration: Integer
25        //              used for Fade and Slide RadioGroup's, the duration to run the transition animation. does not affect anything
26        //              in default RadioGroup
27        duration: 750,
28
29        // hasButtons: Boolean
30        //              toggles internal button making on or off
31        hasButtons: false,
32
33        // buttonClass: String
34        //              The full declared className of the Button widget to use for hasButtons
35        buttonClass: "dojox.layout._RadioButton",
36       
37        // templateString: String
38        //              the template for our container
39        templateString: '<div class="dojoxRadioGroup">'
40                        +'      <div dojoAttachPoint="buttonHolder" style="display:none;">'
41                        +'              <table class="dojoxRadioButtons"><tbody><tr class="dojoxRadioButtonRow" dojoAttachPoint="buttonNode"></tr></tbody></table>'
42                        +'      </div>'
43                        +'      <div class="dojoxRadioView" dojoAttachPoint="containerNode"></div>'
44                        +'</div>',
45
46        startup: function(){
47                // summary:
48                //              scan the container for children, and make "tab buttons" for them
49                this.inherited(arguments);
50                this._children = this.getChildren();
51                this._buttons = this._children.length;
52                this._size = html.coords(this.containerNode);
53                if(this.hasButtons){
54                        html.style(this.buttonHolder, "display", "block");
55                }
56        },
57
58        _setupChild: function(/* dijit._Widget */child){
59                // summary:
60                //              Creates a hover button for a child node of the RadioGroup
61                html.style(child.domNode, "position", "absolute");
62                if(this.hasButtons){
63                       
64                        var tmp = this.buttonNode.appendChild(domConstruct.create('td'));
65                        var n = domConstruct.create("div", null, tmp),
66                                _Button = lang.getObject(this.buttonClass),
67                                tmpw = new _Button({
68                                        label: child.title,
69                                        page: child
70                                }, n)
71                        ;
72                       
73                        lang.mixin(child, { _radioButton: tmpw });
74                        tmpw.startup();
75                }
76                child.domNode.style.display = "none";
77        },
78       
79        removeChild: function(child){
80                if(this.hasButtons && child._radioButton){
81                        child._radioButton.destroy();
82                        delete child._radioButton;
83                }
84                this.inherited(arguments);
85        },
86       
87        // FIXME: shouldn't have to rewriting these, need to take styling out of _showChild and _hideChild
88        //              and use classes on the domNode in _transition or something similar (in StackContainer)
89        _transition: function(/*dijit._Widget*/ newWidget, /*dijit._Widget*/ oldWidget){
90                // summary:
91                //              called when StackContainer receives a selectChild call, used to transition the panes.
92                this._showChild(newWidget);
93                if(oldWidget){
94                        this._hideChild(oldWidget);
95                }
96                // Size the new widget, in case this is the first time it's being shown,
97                // or I have been resized since the last time it was shown.
98                // page must be visible for resizing to work
99                if(this.doLayout && newWidget.resize){
100                        newWidget.resize(this._containerContentBox || this._contentBox);
101                }
102        },
103
104        _showChild: function(/*dijit._Widget*/ page){
105                // summary:
106                //              show the selected child widget
107                var children = this.getChildren();
108                page.isFirstChild = (page == children[0]);
109                page.isLastChild = (page == children[children.length-1]);
110                page.selected = true;
111
112                page.domNode.style.display="";
113
114                if(page._onShow){
115                        page._onShow(); // trigger load in ContentPane
116                }else if(page.onShow){
117                        page.onShow();
118                }
119        },
120
121        _hideChild: function(/*dijit._Widget*/ page){
122                // summary:
123                //              hide the specified child widget
124                page.selected = false;
125                page.domNode.style.display="none";
126                if(page.onHide){
127                        page.onHide();
128                }
129        }
130
131});
132
133declare("dojox.layout.RadioGroupFade", RadioGroup, {
134        // summary:
135        //              An extension on a stock RadioGroup, that fades the panes.
136
137        _hideChild: function(page){
138                // summary:
139                //              hide the specified child widget
140                baseFx.fadeOut({
141                        node:page.domNode,
142                        duration:this.duration,
143                        onEnd: lang.hitch(this,"inherited", arguments, arguments)
144                }).play();
145        },
146
147        _showChild: function(page){
148                // summary:
149                //              show the specified child widget
150                this.inherited(arguments);
151                html.style(page.domNode, "opacity", 0);
152                baseFx.fadeIn({
153                        node:page.domNode,
154                        duration:this.duration
155                }).play();
156        }
157});
158
159declare("dojox.layout.RadioGroupSlide", RadioGroup, {
160        // summary:
161        //              A Sliding Radio Group
162        // description:
163        //              An extension on a stock RadioGroup widget, sliding the pane
164        //              into view from being hidden. The entry direction is randomized
165        //              on each view
166        //
167
168        // easing: Function
169        //              A hook to override the default easing of the pane slides.
170        easing: "dojo.fx.easing.backOut",
171
172        // zTop: Integer
173        //              A z-index to apply to the incoming pane
174        zTop: 99,
175       
176        constructor: function(){
177                if(lang.isString(this.easing)){
178                        this.easing = lang.getObject(this.easing);
179                }
180        },
181       
182        _positionChild: function(page){
183                // summary:
184                //              set the child out of view immediately after being hidden
185
186                // FIXME: is there a real "size" floating around always?
187                if(!this._size){ return; }
188               
189                // there should be a contest: obfuscate this function as best you can.
190                var rA = true, rB = true;
191                switch(page.slideFrom){
192                        case "bottom" : rB = !rB; break;
193                        case "right" :  rA = !rA; rB = !rB; break;
194                        case "top" :    break;
195                        case "left" :   rA = !rA; break;
196                        default:
197                                rA = Math.round(Math.random());
198                                rB = Math.round(Math.random());
199                                break;
200                }
201                var prop = rA ? "top" : "left",
202                        val = (rB ? "-" : "") + (this._size[rA ? "h" : "w" ] + 20) + "px";
203                       
204                html.style(page.domNode, prop, val);
205
206        },
207
208        _showChild: function(page){
209                // summary:
210                //              Slide in the selected child widget
211               
212                var children = this.getChildren();
213                page.isFirstChild = (page == children[0]);
214                page.isLastChild = (page == children[children.length-1]);
215                page.selected = true;
216
217                html.style(page.domNode,{
218                        zIndex: this.zTop, display:""
219                });
220
221                if(this._anim && this._anim.status()=="playing"){
222                        this._anim.gotoPercent(100,true);
223                }
224               
225                this._anim = baseFx.animateProperty({
226                        node:page.domNode,
227                        properties: {
228                                left: 0,
229                                top: 0
230                        },
231                        duration: this.duration,
232                        easing: this.easing,
233                        onEnd: lang.hitch(page, function(){
234                                if(this.onShow){ this.onShow(); }
235                                if(this._onShow){ this._onShow(); }
236                        }),
237                        beforeBegin: lang.hitch(this, "_positionChild", page)
238                });
239                this._anim.play();
240        },
241
242        _hideChild: function(page){
243                // summary:
244                //              reset the position of the hidden pane out of sight
245
246                page.selected = false;
247                page.domNode.style.zIndex = this.zTop - 1;
248                if(page.onHide){
249                        page.onHide();
250                }
251
252        }
253       
254});
255
256declare("dojox.layout._RadioButton",[Widget,Templated,Contained],{
257        // summary:
258        //              The Buttons for a RadioGroup
259        // description:
260        //              A private widget used to manipulate the StackContainer (RadioGroup*). Don't create directly.
261       
262        // label: String
263        //              the Text Label of the button
264        label: "",
265
266        // domNode to tell parent to select
267        page: null,
268
269        templateString: '<div dojoAttachPoint="focusNode" class="dojoxRadioButton"><span dojoAttachPoint="titleNode" class="dojoxRadioButtonLabel">${label}</span></div>',
270       
271        startup: function(){
272                // summary:
273                //              start listening to mouseOver
274                this.connect(this.domNode, "onmouseenter", "_onMouse");
275        },
276       
277        _onMouse: function(/* Event */e){
278                // summary:
279                //              set the selected child on hover, and set our hover state class
280                this.getParent().selectChild(this.page);
281                this._clearSelected();
282                domClass.add(this.domNode,"dojoxRadioButtonSelected");
283
284        },
285
286        _clearSelected: function(){
287                // summary:
288                //              remove hover state class from sibling Buttons. This is easier (and more reliable)
289                //              than setting up an additional connection to onMouseOut
290               
291                // FIXME: this relies on the template being [div][span]node[/span][/div]
292                query(".dojoxRadioButtonSelected", this.domNode.parentNode.parentNode)
293                        .removeClass("dojoxRadioButtonSelected")
294                ;
295        }
296       
297});
298
299lang.extend(Widget,{
300        // slideFrom: String
301        //              A parameter needed by RadioGroupSlide only. An optional paramter to force
302        //              the ContentPane to slide in from a set direction. Defaults
303        //              to "random", or specify one of "top", "left", "right", "bottom"
304        //              to slideFrom top, left, right, or bottom.
305        slideFrom: "random"
306})
307});
Note: See TracBrowser for help on using the repository browser.