source: Dev/trunk/src/client/dojox/mobile/ScreenSizeAware.js

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

Added Dojo 1.9.3 release.

File size: 8.1 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/array",
4        "dojo/_base/config",
5        "dojo/_base/connect",
6        "dojo/_base/declare",
7        "dojo/_base/lang",
8        "dojo/_base/window",
9        "dojo/dom",
10        "dijit/registry"
11], function(kernel, array, config, connect, declare, lang, win, dom, registry){
12
13        // module:
14        //              dojox/mobile/ScreenSizeAware
15
16        kernel.experimental("dojox.mobile.ScreenSizeAware"); // should consider support for other UI layout patterns
17
18        var cls = declare("dojox.mobile.ScreenSizeAware", null, {
19                // summary:
20                //              A module to make a screen size aware application.
21                // description:
22                //              This module helps for creating applications that transform their
23                //              UI layout according to the screen size. It assumes that the
24                //              application consists of two horizontally split panes, and the
25                //              left pane has a list widget. If you require this module in such an
26                //              application, in a tablet-sized screen, the application shows a horizontally
27                //              split view whose left pane is a list widget.
28                //              In a phone-sized screen, the application shows a list widget that fills the screen.
29                //
30                // example:
31                // |    <span data-dojo-type="dojox.mobile.ScreenSizeAware"></span>
32                // |    <div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
33                // |      <div data-dojo-type="dojox.mobile.Container" style="width:300px;">
34                // |        <div id="leftView" data-dojo-type="dojox.mobile.ScrollableView">
35                // |          <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Left Pane</h1>
36                // |          <ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='stateful:true'>
37                // |            <li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='label:"View1", moveTo:"view1"'></li>
38                // |            ....
39                // |          </ul>
40                // |        </div>
41                // |      </div>
42                // |      <div data-dojo-type="dojox.mobile.Container">
43                // |        <div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
44                // |          <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"leftView"'>Right Pane</h1>
45                // |          ....
46                // |        </div>
47                // |      </div>
48                // |    </div>
49
50                // splitterId: String
51                //              The id of the FixedSplitter.
52                splitterId: "",
53
54                // leftPaneId: String
55                //              The id of the left pane.
56                leftPaneId: "",
57
58                // rightPaneId: String
59                //              The id of the right pane.
60                rightPaneId: "",
61
62                // leftViewId: String
63                //              The id of the left View.
64                leftViewId: "",
65
66                // leftListId: String
67                //              The id of the list widget in the left view.
68                leftListId: "",
69
70                constructor: function(/*Object?*/options){
71                        // summary:
72                        //              Creates a new instance of the class.
73                        // options:
74                        //              Contains properties to be set.
75                        if (options){
76                                lang.mixin(this, options);
77                        }
78                        connect.subscribe("/dojox/mobile/screenSize/tablet", this, function(dim){
79                                this.transformUI("tablet");
80                        });
81                        connect.subscribe("/dojox/mobile/screenSize/phone", this, function(dim){
82                                this.transformUI("phone");
83                        });
84                },
85
86                init: function(){
87                        // summary:
88                        //              Initializes the application.
89                        if(this._initialized){ return; }
90                        this._initialized = true;
91
92                        // analyze the page structure
93                        this.splitter = this.splitterId ? registry.byId(this.splitterId) :
94                                array.filter(registry.findWidgets(win.body()),
95                                        function(c){ return c.declaredClass.indexOf("Splitter") !== -1; })[0];
96                        if(!this.splitter){
97                                console.error("Splitter not found.");
98                                return;
99                        }
100
101                        this.leftPane = this.leftPaneId ? registry.byId(this.leftPaneId) :
102                                this.splitter.getChildren()[0];
103                        if(!this.leftPane){
104                                console.error("Left pane not found.");
105                                return;
106                        }
107
108                        this.rightPane = this.rightPaneId ? registry.byId(this.rightPaneId) :
109                                this.splitter.getChildren()[1];
110                        if(!this.rightPane){
111                                console.error("Right pane not found.");
112                                return;
113                        }
114
115                        this.leftView = this.leftViewId ? registry.byId(this.leftViewId) :
116                                array.filter(registry.findWidgets(this.leftPane.containerNode),
117                                        function(c){ return c.declaredClass.indexOf("View") !== -1; })[0];
118                        if(!this.leftView){
119                                console.error("Left view not found.");
120                                return;
121                        }
122
123                        this.leftList = this.leftListId ? registry.byId(this.leftListId) :
124                                array.filter(registry.findWidgets(this.leftView.containerNode),
125                                        function(c){ return c.declaredClass.indexOf("List") !== -1 ||
126                                                                 c.declaredClass.indexOf("IconContainer") !== -1; })[0];
127                        if(!this.leftList){
128                                console.error("Left list not found.");
129                                return;
130                        }
131                },
132
133                isPhone: function(){
134                        // summary:
135                        //              Returns true if the current mode set by transformUI(mode) is "phone".
136                        return this._currentMode === "phone"; // Boolean
137                },
138
139                getShowingView: function(){
140                        // summary:
141                        //              Returns the view currently shown.
142                        var firstView =
143                                array.filter(this.rightPane.getChildren(), function(c){ return c.declaredClass.indexOf("View") !== -1; })[0];
144                        if(!firstView){ return null; }
145                        return firstView.getShowingView() ||
146                                array.filter(this.rightPane.getChildren(), function(c){ return c.selected; })[0] ||
147                                firstView;
148                },
149
150                updateStateful: function(){
151                        // summary:
152                        //              Updates the stateful property of the list widget in the left-side pane.
153                        this.leftList.set("stateful", !this.isPhone());
154                },
155
156                getDestinationId: function(item){
157                        // summary:
158                        //              Returns the id of the target view of the given item.
159                        return item.moveTo;
160                },
161
162                updateBackButton: function(){
163                        // summary:
164                        //              Updates the back button.
165                        array.forEach(this.leftList.getChildren(), function(item){
166                                var id = this.getDestinationId(item);
167                                var view = registry.byId(id);
168                                if(view){
169                                        var heading = array.filter(view.getChildren(), function(c){ return c.declaredClass.indexOf("Heading") !== -1; })[0];
170                                        if(heading.backButton){
171                                                heading.backButton.domNode.style.display = this.isPhone() ? "" : "none";
172                                        }
173                                        if(heading.backBtnNode){ // TODO: remove this block later
174                                                heading.backBtnNode.style.display = this.isPhone() ? "" : "none";
175                                        }
176                                }
177                        }, this);
178                },
179
180                updateTransition: function(){
181                        // summary:
182                        //              Updates the transition property of the items in the left-side widget.
183                        var transition = this.isPhone() ? "slide" : "none";
184                        array.forEach(this.leftList.getChildren(), function(item){
185                                item.set("transition", transition);
186                        });
187                },
188
189                moveList: function(){
190                        // summary:
191                        //              Places the list widget. If the current mode is "phone", it
192                        //              places the list widget in the right pane, otherwise in the left pane.
193                        var to = this.isPhone() ? this.rightPane: this.leftPane;
194                        to.containerNode.appendChild(this.leftView.domNode);
195                },
196
197                showLeftView: function(){
198                        // summary:
199                        //              Shows the left-side view.
200                        this.leftPane.domNode.style.display = this.isPhone() ? "none" : "";
201                        this.leftView.show();
202                },
203
204                showRightView: function(){
205                        // summary:
206                        //              Shows the right-side view.
207                        if(this.isPhone()){ return; }
208                        var view = this.getShowingView();
209                        if(view){
210                                view.show();
211                        }else{
212                                this.leftItemSelected();
213                        }
214                },
215
216                updateSelectedItem: function(){
217                        // summary:
218                        //              Updates the selected item.
219                        var id;
220                        var view = this.getShowingView();
221                        if(view && !this.isPhone()){
222                                id = view.id;
223                        }
224                        if(id){
225                                var items = array.filter(this.leftList.getChildren(),
226                                        function(item){ return this.getDestinationId(item) === id; }, this);
227                                if(items && items.length > 0){
228                                        items[0].set("selected", true);
229                                }
230                        }else{
231                                this.leftList.deselectAll && this.leftList.deselectAll();
232                        }
233                },
234
235                leftItemSelected: function(/*Event*/ /*===== e =====*/){
236                        // summary:
237                        //              Function called when an item in the left-side list is selected.
238                },
239
240                transformUI: function(/*String*/mode){
241                        // summary:
242                        //              Applies an UI mode.
243                        // mode:
244                        //              If this argument is "phone", sets the UI in phone mode, otherwise
245                        //              in tablet mode.         
246                        this.init();
247                        if(mode === this._currentMode){ return; }
248                        this._currentMode = mode;
249                        this.updateStateful();
250                        this.updateBackButton();
251                        this.updateTransition();
252                        this.moveList();
253                        this.showLeftView();
254                        this.showRightView();
255                        this.updateSelectedItem();
256                }
257        });
258
259        cls._instance = null;
260        cls.getInstance = function(){
261                if(!cls._instance){
262                        cls._instance = new cls();
263                }
264                return cls._instance;
265        };
266
267        return cls;
268});
Note: See TracBrowser for help on using the repository browser.