]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * @class KitchenSink.controller.Main\r | |
3 | * @extends Ext.app.Controller\r | |
4 | *\r | |
5 | * This is an abstract base class that is extended by both the phone and tablet versions. This controller is\r | |
6 | * never directly instantiated, it just provides a set of common functionality that the phone and tablet\r | |
7 | * subclasses both extend.\r | |
8 | */\r | |
9 | Ext.define('KitchenSink.controller.Main', {\r | |
10 | extend: 'Ext.app.Controller',\r | |
11 | \r | |
12 | requires: [\r | |
13 | 'Ext.Deferred'\r | |
14 | ],\r | |
15 | \r | |
16 | config: {\r | |
17 | /**\r | |
18 | * @private\r | |
19 | */\r | |
20 | viewCache: [],\r | |
21 | \r | |
22 | refs: {\r | |
23 | nav: '#mainNestedList',\r | |
24 | main: 'mainview',\r | |
25 | toolbar: '#mainNavigationBar',\r | |
26 | sourceButton: 'button[action=viewSource]',\r | |
27 | themeToggleButton: 'button[action=toggleTheme]',\r | |
28 | \r | |
29 | \r | |
30 | sourceOverlay: {\r | |
31 | selector: 'sourceoverlay',\r | |
32 | xtype: 'sourceoverlay',\r | |
33 | autoCreate: true\r | |
34 | }\r | |
35 | },\r | |
36 | \r | |
37 | control: {\r | |
38 | sourceButton: {\r | |
39 | tap: 'onSourceTap'\r | |
40 | },\r | |
41 | themeToggleButton: {\r | |
42 | tap: 'onThemeToggleTap'\r | |
43 | },\r | |
44 | nav: {\r | |
45 | itemtap: 'onNavTap',\r | |
46 | leafitemtap: 'onNavLeafTap'\r | |
47 | \r | |
48 | }\r | |
49 | },\r | |
50 | \r | |
51 | routes: {\r | |
52 | 'demo/:id': 'showViewById',\r | |
53 | 'menu/:id': 'showMenuById',\r | |
54 | '': 'showMenuById'\r | |
55 | },\r | |
56 | \r | |
57 | /**\r | |
58 | * @cfg {Ext.data.Model} currentDemo The Demo that is currently loaded. This is set whenever showViewById\r | |
59 | * is called and used by functions like onSourceTap to fetch the source code for the current demo.\r | |
60 | */\r | |
61 | currentDemo: undefined\r | |
62 | },\r | |
63 | \r | |
64 | /**\r | |
65 | * Finds a given view by ID and shows it. End-point of the "demo/:id" route\r | |
66 | */\r | |
67 | showViewById: function (id) {\r | |
68 | var nav = this.getNav(),\r | |
69 | view = nav.getStore().getNodeById(id);\r | |
70 | \r | |
71 | this.showView(view);\r | |
72 | this.setCurrentDemo(view);\r | |
73 | this.hideSheets();\r | |
74 | },\r | |
75 | \r | |
76 | isProfile: function(item) {\r | |
77 | var profileName = item.get('profileName'),\r | |
78 | ret = false;\r | |
79 | \r | |
80 | if (profileName !== undefined) {\r | |
81 | window.location = profileName ? (location.pathname + '?profile=' + profileName) : '';\r | |
82 | ret = true;\r | |
83 | }\r | |
84 | \r | |
85 | return ret;\r | |
86 | },\r | |
87 | \r | |
88 | /**\r | |
89 | * Shows the source code for the {@link #currentDemo} in an overlay\r | |
90 | */\r | |
91 | onSourceTap: function () {\r | |
92 | var me = this,\r | |
93 | overlay = this.getSourceOverlay(),\r | |
94 | demo = this.getCurrentDemo(),\r | |
95 | view = this.activeView,\r | |
96 | cls, files, content;\r | |
97 | \r | |
98 | if (demo) {\r | |
99 | if (!overlay.getParent()) {\r | |
100 | Ext.Viewport.add(overlay);\r | |
101 | }\r | |
102 | \r | |
103 | overlay.show();\r | |
104 | \r | |
105 | if (view.$cachedContent) {\r | |
106 | me.setOverlayContent(overlay, view.$cachedContent);\r | |
107 | } else {\r | |
108 | overlay.setMasked({\r | |
109 | xtype: 'loadmask',\r | |
110 | message: 'Loading Source'\r | |
111 | });\r | |
112 | \r | |
113 | cls = demo.get('view') || demo.get('text');\r | |
114 | cls = cls.replace(/\./g, '/');\r | |
115 | \r | |
116 | files = [this.getFileContent({\r | |
117 | type: 'View',\r | |
118 | path: 'modern/src/view/' + cls + '.js'\r | |
119 | })];\r | |
120 | \r | |
121 | content = view.otherContent;\r | |
122 | if (content) {\r | |
123 | content.forEach(function(content) {\r | |
124 | files.push(this.getFileContent(Ext.apply({}, content)));\r | |
125 | }, this);\r | |
126 | }\r | |
127 | \r | |
128 | Ext.Deferred.all(files).then(function(values) {\r | |
129 | values.forEach(function(item) {\r | |
130 | item.title = item.type;\r | |
131 | delete item.type;\r | |
132 | });\r | |
133 | me.setOverlayContent(overlay, values);\r | |
134 | overlay.unmask();\r | |
135 | \r | |
136 | view.self.prototype.$cachedContent = values;\r | |
137 | });\r | |
138 | }\r | |
139 | }\r | |
140 | },\r | |
141 | \r | |
142 | setOverlayContent: function(overlay, items) {\r | |
143 | overlay.removeAll();\r | |
144 | overlay.add(items);\r | |
145 | overlay.getTabBar().setHidden(items.length === 1);\r | |
146 | },\r | |
147 | \r | |
148 | getFileContent: function(options) {\r | |
149 | return Ext.Ajax.request({\r | |
150 | url: options.path\r | |
151 | }).then(function(response) {\r | |
152 | return {\r | |
153 | type: options.type,\r | |
154 | html: response.responseText\r | |
155 | };\r | |
156 | }, function() {\r | |
157 | return null;\r | |
158 | });\r | |
159 | },\r | |
160 | \r | |
161 | onThemeToggleTap: function() {\r | |
162 | if (Ext.theme.name === 'Tizen') {\r | |
163 | if (!KitchenSink.app.getThemeVariationTransitionCls()) {\r | |
164 | KitchenSink.app.setThemeVariationTransitionCls("tizenThemeTransition");\r | |
165 | }\r | |
166 | \r | |
167 | if (KitchenSink.app.getThemeVariation() === "light") {\r | |
168 | KitchenSink.app.setThemeVariation("dark");\r | |
169 | } else {\r | |
170 | KitchenSink.app.setThemeVariation("light");\r | |
171 | }\r | |
172 | }\r | |
173 | \r | |
174 | },\r | |
175 | \r | |
176 | /**\r | |
177 | * @private\r | |
178 | * In the kitchen sink we have a large number of dynamic views. If we were to keep all of them rendered\r | |
179 | * we'd risk causing the browser to run out of memory, especially on older devices. If we destroy them as\r | |
180 | * soon as we're done with them, the app can appear sluggish. Instead, we keep a small number of rendered\r | |
181 | * views in a viewCache so that we can easily reuse recently used views while destroying those we haven't\r | |
182 | * used in a while.\r | |
183 | * @param {String} name The full class name of the view to create (e.g. "KitchenSink.view.Forms")\r | |
184 | * @return {Ext.Component} The component, which may be from the cache\r | |
185 | */\r | |
186 | createView: function (item) {\r | |
187 | var name = this.getViewName(item),\r | |
188 | cache = this.getViewCache(),\r | |
189 | ln = cache.length,\r | |
190 | limit = item.get('limit') || 20,\r | |
191 | view, i = 0, j, oldView;\r | |
192 | \r | |
193 | for (; i < ln; i++) {\r | |
194 | view = cache[i];\r | |
195 | if (view.viewName === name) {\r | |
196 | this.activeView = view;\r | |
197 | return view;\r | |
198 | }\r | |
199 | }\r | |
200 | \r | |
201 | if (ln >= limit) {\r | |
202 | for (i = 0, j = 0; i < ln; i++) {\r | |
203 | oldView = cache[i];\r | |
204 | if (!oldView.isPainted()) {\r | |
205 | oldView.destroy();\r | |
206 | } else {\r | |
207 | cache[j++] = oldView;\r | |
208 | }\r | |
209 | }\r | |
210 | cache.length = j;\r | |
211 | }\r | |
212 | \r | |
213 | view = Ext.create(name);\r | |
214 | view.viewName = name;\r | |
215 | cache.push(view);\r | |
216 | this.setViewCache(cache);\r | |
217 | \r | |
218 | this.activeView = view;\r | |
219 | \r | |
220 | return view;\r | |
221 | },\r | |
222 | \r | |
223 | /**\r | |
224 | * @private\r | |
225 | * Returns the full class name of the view to construct for a given Demo\r | |
226 | * @param {KitchenSink.model.Demo} item The demo\r | |
227 | * @return {String} The full class name of the view\r | |
228 | */\r | |
229 | getViewName: function (item) {\r | |
230 | var name = item.get('view') || item.get('text'),\r | |
231 | ns = 'KitchenSink.view.';\r | |
232 | \r | |
233 | if (name == 'TouchEvents') {\r | |
234 | if (this.getApplication().getCurrentProfile().getName() === 'Tablet') {\r | |
235 | return ns + 'tablet.' + name;\r | |
236 | } else {\r | |
237 | return ns + 'phone.' + name;\r | |
238 | }\r | |
239 | } else {\r | |
240 | return ns + name;\r | |
241 | }\r | |
242 | },\r | |
243 | \r | |
244 | /**\r | |
245 | * we iterate over all of the floating sheet components and make sure they're hidden when we\r | |
246 | * navigate to a new view. This stops things like Picker overlays staying visible when you hit\r | |
247 | * the browser's back button\r | |
248 | */\r | |
249 | hideSheets: function () {\r | |
250 | Ext.each(Ext.ComponentQuery.query('sheet, #editorPanel'), function (sheet) {\r | |
251 | if(sheet instanceof Ext.Menu) {\r | |
252 | Ext.Viewport.hideMenu(sheet);\r | |
253 | }else {\r | |
254 | sheet.setHidden(true);\r | |
255 | }\r | |
256 | });\r | |
257 | }\r | |
258 | });\r |