8 platform: Ti.getPlatform(), |
8 platform: Ti.getPlatform(), |
9 name: Ti.API.Application.getName(), |
9 name: Ti.API.Application.getName(), |
10 version: Ti.API.Application.getVersion(), |
10 version: Ti.API.Application.getVersion(), |
11 ti_version: Ti.getVersion(), |
11 ti_version: Ti.getVersion(), |
12 architecture: Ti.Platform.getArchitecture(), |
12 architecture: Ti.Platform.getArchitecture(), |
|
13 copyright: Ti.App.getCopyright(), |
13 |
14 |
14 // Declared windows, for easy referencing |
15 // Declared windows, for easy referencing |
15 window: {}, |
16 window: {}, |
16 |
17 |
17 // Very first run of Dasycllus? |
18 // Very first run of Dasycllus? |
18 firstrun: false, |
19 firstrun: false, |
19 |
20 |
20 // Persistent storage DB handle. |
21 // Persistent storage DB handle. |
21 db: null, |
22 db: null, |
22 |
23 |
23 // The current TF server we'll be connected to; |
24 // The primary main tray menu. |
|
25 menu: null, |
|
26 |
|
27 // The current TF server we're connected to. |
|
28 // |
24 // uri: http://localhost:8080/ |
29 // uri: http://localhost:8080/ |
25 // version: Thingfish 0.5.0 (build ...) |
30 // version: Thingfish 0.5.0 (build ...) |
26 // |
31 // |
27 tf: null, |
32 tf: new can.Observe({ |
|
33 uri: null, |
|
34 version: null |
|
35 }), |
|
36 |
|
37 |
|
38 // Actions to perform at startup. |
|
39 // |
|
40 init: function() { |
|
41 var D = this; |
|
42 |
|
43 D.initDB(); |
|
44 D.window.main = Ti.UI.getMainWindow(); |
|
45 D.initMenu(); |
|
46 |
|
47 // Thingfish server object event handlers. |
|
48 // |
|
49 D.tf.bind( 'uri', D.initTF ); |
|
50 var server_uri = D.getPref( 'server_uri' ); |
|
51 if ( server_uri ) D.tf.attr( 'uri', server_uri ); |
|
52 |
|
53 // Main window event handlers. |
|
54 // |
|
55 D.window.main.addEventListener( 'moved', function() { D.saveWindowState(); }); |
|
56 D.window.main.addEventListener( 'resized', function() { |
|
57 D.delay( function() { |
|
58 D.saveWindowState(); |
|
59 }, |
|
60 500, true ); |
|
61 }); |
|
62 $( document ).contextmenu( function() { D.window.main.setContextMenu( D.menu ); }); |
|
63 |
|
64 // Each Tide window is an environment unto itself. There is a global |
|
65 // key/val namespace, though. Make the 'D' namespace accessible to other windows here. |
|
66 Ti.API.set( 'D', D ); |
|
67 }, |
|
68 |
|
69 |
|
70 // Determine if we should be running in developer mode. |
|
71 // This requires that the user has previously enabled it in preferences, |
|
72 // and the --debug command line option was passed. |
|
73 // |
|
74 devmode: function() { |
|
75 return Ti.App.getArguments()[0] == "--debug" && this.getBoolPref( 'devmode' ); |
|
76 }, |
|
77 |
|
78 |
|
79 // Event handler for changing the Thingfish server URI. |
|
80 // Sanity check and instantiate appropriate Model(s). |
|
81 // |
|
82 initTF: function( event, uri, old_uri ) { |
|
83 var serverOk = function( data, status, xhr ) { |
|
84 var info = xhr.getResponseHeader( 'x-thingfish' ); |
|
85 if ( ! info ) { |
|
86 D.tf.attr( 'version', null ); |
|
87 D.notify( 'Unable to connect.', 'Not a Thingfish server?' ); |
|
88 return; |
|
89 } |
|
90 |
|
91 D.tf.attr( 'version', data.version ) |
|
92 D.notify( 'Connected.', info ); |
|
93 |
|
94 // FIXME: models? |
|
95 }; |
|
96 |
|
97 try { |
|
98 $.ajax({ |
|
99 url: uri + '/serverinfo', |
|
100 async: false, |
|
101 success: serverOk, |
|
102 error: function( xhr, status, err ) { |
|
103 D.tf.attr( 'version', null ); |
|
104 D.notify( 'Unable to connect.', err ? err : 'Network error.' ); |
|
105 }, |
|
106 dataType: 'json' |
|
107 }); |
|
108 } |
|
109 catch( err ) { |
|
110 console.log( err ); |
|
111 }; |
|
112 }, |
28 |
113 |
29 |
114 |
30 // Open a handle to the local database, initializing it |
115 // Open a handle to the local database, initializing it |
31 // if necessary and performing rudamentary upwards migrations. |
116 // if necessary and performing rudamentary upwards migrations. |
32 // |
117 // |
145 notification.show(); |
230 notification.show(); |
146 return notification; |
231 return notification; |
147 }, |
232 }, |
148 |
233 |
149 |
234 |
150 // Attempt a connection to a remote Thingfish server, and |
235 // Record the main window position and state. |
151 // populate the D.tf variable. |
236 // |
152 // |
237 saveWindowState: function() { |
153 checkServer: function( uri ) { |
238 var w = this.window.main; |
154 this.tf = null; |
239 var x = w.getX(); |
155 |
240 var y = w.getY(); |
156 var serverOk = function( data, status, xhr ) { |
241 var width = w.getWidth(); |
157 var info = xhr.getResponseHeader( 'x-thingfish' ); |
242 var height = w.getHeight(); |
158 if ( info ) { |
243 |
159 D.tf = { |
244 var hiddenMenu = this.menu.getItemAt( 2 ).getSubmenu().getItemAt( 0 ); |
160 uri: uri, |
245 var fullScreenMenu = this.menu.getItemAt( 2 ).getSubmenu().getItemAt( 1 ); |
161 version: data.version |
246 |
162 }; |
247 var pos = this.getPref( 'window_pos' ); |
163 D.notify( 'Connected.', info ); |
248 pos = Ti.JSON.parse( pos ); |
|
249 |
|
250 // first time |
|
251 // |
|
252 if ( ! pos ) { |
|
253 pos = { |
|
254 x: x, |
|
255 y: y, |
|
256 width: width, |
|
257 height: height, |
|
258 fullscreen: false, |
|
259 hidden: false |
|
260 }; |
|
261 } |
|
262 |
|
263 if ( w.isVisible() ) { |
|
264 pos.hidden = false; |
|
265 fullScreenMenu.enable(); |
|
266 } |
|
267 else { |
|
268 pos.hidden = true; |
|
269 fullScreenMenu.disable(); |
|
270 } |
|
271 |
|
272 if ( w.isFullScreen() ) { |
|
273 pos.fullscreen = true; |
|
274 hiddenMenu.disable(); |
|
275 } |
|
276 else { |
|
277 pos.fullscreen = false; |
|
278 hiddenMenu.enable(); |
|
279 } |
|
280 |
|
281 if ( ! pos.fullscreen ) { |
|
282 pos.x = x; |
|
283 pos.y = y; |
|
284 pos.width = width; |
|
285 pos.height = height; |
|
286 } |
|
287 |
|
288 this.setPref( 'window_pos', Ti.JSON.stringify(pos) ); |
|
289 }, |
|
290 |
|
291 |
|
292 // Set the main window according to previously saved values. |
|
293 // |
|
294 setWindowState: function() { |
|
295 var w = this.window.main; |
|
296 var pos = this.getPref( 'window_pos' ); |
|
297 |
|
298 var hiddenMenu = this.menu.getItemAt( 2 ).getSubmenu().getItemAt( 0 ); |
|
299 var fullScreenMenu = this.menu.getItemAt( 2 ).getSubmenu().getItemAt( 1 ); |
|
300 |
|
301 pos = Ti.JSON.parse( pos ); |
|
302 if ( ! pos ) return; |
|
303 |
|
304 if ( pos.fullscreen ) { |
|
305 w.setFullscreen( true ); |
|
306 hiddenMenu.disable(); |
|
307 } |
|
308 else { |
|
309 |
|
310 console.log( "Moving to x:" + pos.x + ", y:" + pos.y ); |
|
311 console.log( "Sizing to w:" + pos.width + ", h:" + pos.height ); |
|
312 w.moveTo( pos.x, pos.y ); |
|
313 w.setSize( pos.width, pos.height ); |
|
314 |
|
315 hiddenMenu.enable(); |
|
316 |
|
317 if ( pos.hidden ) { |
|
318 w.hide(); |
|
319 fullScreenMenu.disable(); |
164 } |
320 } |
165 else { |
321 else { |
166 D.notify( 'Unable to connect.', 'Not a Thingfish server?' ); |
322 w.show(); |
167 } |
323 fullScreenMenu.enable(); |
168 }; |
324 } |
169 |
325 } |
170 $.ajax({ |
326 |
171 url: uri, |
327 this.saveWindowState(); |
172 sync: false, |
|
173 success: serverOk, |
|
174 error: function( xhr, status, err ) { |
|
175 D.notify( 'Unable to connect.', err ); |
|
176 }, |
|
177 dataType: 'json' |
|
178 }); |
|
179 }, |
328 }, |
180 |
329 |
181 |
330 |
182 // Build the main menu. |
331 // Build the main menu. |
183 // |
332 // |
184 setupMenu: function() { |
333 initMenu: function() { |
185 var menu = Ti.UI.createMenu(); |
334 this.menu = Ti.UI.createMenu(); |
186 var yep = Ti.UI.createMenuItem( 'Yep' ); |
335 var tray = Ti.UI.addTray( 'app://img/tray_icon.png' ); |
187 |
336 |
188 yep.addItem( 'About', function() { |
337 // windows |
|
338 // --------------------------------------------------------------- |
|
339 this.menu.addItem( 'About', function() { |
189 if ( D.window.about && D.window.about.isVisible() ) { |
340 if ( D.window.about && D.window.about.isVisible() ) { |
190 D.window.about.focus(); |
341 D.window.about.focus(); |
191 } |
342 } |
192 else { |
343 else { |
193 D.window.about = D.window.main.createWindow( 'app://window/about.html' ); |
344 D.window.about = D.window.main.createWindow( 'app://window/about.html' ); |
194 D.window.about.setTopMost( true ); |
345 D.window.about.setTopMost( true ); |
195 D.window.about.open(); |
346 D.window.about.open(); |
196 } |
347 } |
197 }); |
348 }); |
198 |
349 |
199 yep.addItem( 'Preferences', function() { |
350 this.menu.addItem( 'Preferences', function() { |
200 if ( D.window.prefs && D.window.prefs.isVisible() ) { |
351 if ( D.window.prefs && D.window.prefs.isVisible() ) { |
201 D.window.prefs.focus(); |
352 D.window.prefs.focus(); |
202 } |
353 } |
203 else { |
354 else { |
204 D.window.prefs = D.window.main.createWindow( 'app://window/prefs.html' ); |
355 D.window.prefs = D.window.main.createWindow( 'app://window/prefs.html' ); |
205 D.window.prefs.open(); |
356 D.window.prefs.open(); |
206 } |
357 } |
207 }); |
358 }); |
208 |
359 |
209 yep.addItem( 'Toggle Full Screen', function() { |
360 // view menu |
|
361 // --------------------------------------------------------------- |
|
362 var viewMenu = Ti.UI.createMenuItem( 'View' ); |
|
363 |
|
364 viewMenu.addItem( 'Toggle Hidden', function() { |
|
365 if ( D.window.main.isVisible() ) { |
|
366 D.window.main.hide(); |
|
367 } |
|
368 else { |
|
369 D.window.main.show(); |
|
370 } |
|
371 D.saveWindowState(); |
|
372 }); |
|
373 |
|
374 viewMenu.addItem( 'Toggle Full Screen', function() { |
210 D.window.main.setFullscreen( ! D.window.main.isFullscreen() ); |
375 D.window.main.setFullscreen( ! D.window.main.isFullscreen() ); |
211 }); |
376 D.saveWindowState(); |
212 |
377 }); |
213 menu.appendItem( yep ); |
378 |
214 Ti.UI.setMenu( menu ); |
379 this.menu.appendItem( viewMenu ); |
|
380 |
|
381 // other |
|
382 // -------------------------------------------------------------- |
|
383 if ( this.getBoolPref('devmode') ) { |
|
384 this.menu.addItem( 'Restart', function() { |
|
385 Ti.App.restart(); |
|
386 }); |
|
387 } |
|
388 |
|
389 tray.setMenu( this.menu ); |
|
390 Ti.UI.setDockMenu( this.menu ); |
|
391 // D.window.main.setContextMenu( this.menu ); |
|
392 // Ti.UI.setMenu( menu ); |
215 }, |
393 }, |
216 |
394 |
217 |
395 |
218 /*###################################################################### |
396 /*###################################################################### |
219 ### M O D E L S |
397 ### M O D E L S |
220 ######################################################################*/ |
398 ######################################################################*/ |
221 |
399 |
222 // A Thingfish asset. |
400 // // A Thingfish asset. |
223 // |
401 // // |
224 initModel: function() { |
402 // initModel: function() { |
225 D.Asset = can.Model({ |
403 // D.Asset = can.Model({ |
226 id : 'oid', |
404 // id : 'oid', |
227 findAll: 'GET ' + D.tf.uri + '/', |
405 // findAll: 'GET ' + D.tf.uri + '/', |
228 findOne: 'GET ' + D.tf.uri + '/{oid}', |
406 // findOne: 'GET ' + D.tf.uri + '/{oid}', |
229 create : 'POST ' + D.tf.uri + '/', |
407 // create : 'POST ' + D.tf.uri + '/', |
230 update : 'PUT ' + D.tf.uri + '/{oid}', |
408 // update : 'PUT ' + D.tf.uri + '/{oid}', |
231 destroy: 'DELETE ' + D.tf.uri + '/{oid}', |
409 // destroy: 'DELETE ' + D.tf.uri + '/{oid}', |
232 |
410 |
233 // TODO: other metadata hooks? diff model? |
411 // // TODO: other metadata hooks? diff model? |
234 metadata: 'GET ' + D.tf.uri + '/{oid}/metadata', |
412 // metadata: 'GET ' + D.tf.uri + '/{oid}/metadata', |
235 |
413 |
236 }, {}). |
414 // }, {}). |
237 bind( 'created', function( ev, asset ) { |
415 // bind( 'created', function( ev, asset ) { |
238 console.debug( "Created a new asset " + asset.id ); |
416 // console.debug( "Created a new asset " + asset.id ); |
239 }). |
417 // }). |
240 bind( 'updated', function( ev, asset ) { |
418 // bind( 'updated', function( ev, asset ) { |
241 console.debug( "Updated asset " + asset.id ); |
419 // console.debug( "Updated asset " + asset.id ); |
242 }). |
420 // }). |
243 bind( 'destroyed', function( ev, asset ) { |
421 // bind( 'destroyed', function( ev, asset ) { |
244 console.debug( "Removed asset " + asset.id ); |
422 // console.debug( "Removed asset " + asset.id ); |
245 } |
423 // } |
246 ); |
424 // ); |
247 }, |
425 // }, |
248 }; |
426 }; |
249 |
427 |
250 |
|
251 // Initialization. |
|
252 // |
|
253 D.window.main = Ti.UI.getMainWindow(); |
|
254 D.setupMenu(); |
|
255 D.initDB(); |
|
256 |
|