1 // ==========================================================================
  2 // Project:   The M-Project - Mobile HTML5 Application Framework
  3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
  4 //            (c) 2011 panacoda GmbH. All rights reserved.
  5 // Creator:   Dominik
  6 // Date:      27.10.2010
  7 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
  8 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
  9 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
 10 // ==========================================================================
 11 
 12 /* Available transitions for page changes */
 13 M.TRANSITION = {};
 14 M.TRANSITION.NONE = 'none';
 15 M.TRANSITION.SLIDE = 'slide';
 16 M.TRANSITION.SLIDEUP = 'slideup';
 17 M.TRANSITION.SLIDEDOWN = 'slidedown';
 18 M.TRANSITION.POP = 'pop';
 19 M.TRANSITION.FADE = 'fade';
 20 M.TRANSITION.FLIP = 'flip';
 21 
 22 m_require('core/foundation/observable.js');
 23 
 24 /**
 25  * @class
 26  *
 27  * The root class for every controller.
 28  *
 29  * Controllers, respectively their properties, are observables. Views can observe them.
 30  *
 31  * @extends M.Object
 32  */
 33 M.Controller = M.Object.extend(
 34 /** @scope M.Controller.prototype */ {
 35 
 36     /**
 37      * The type of this object.
 38      *
 39      * @type String
 40      */
 41     type: 'M.Controller',
 42 
 43     /**
 44      * Makes the controller's properties observable.
 45      */
 46     observable: null,
 47 
 48     /**
 49      * Switch the active tab in the application. This includes both activating this tab
 50      * visually and switching the page.
 51      *
 52      * @param {M.TabBarItemView} tab The tab to be activated.
 53      */
 54     switchToTab: function(tab) {
 55         if(!(tab.parentView && tab.parentView.type === 'M.TabBarView')) {
 56             M.Logger.log('Please provide a valid tab bar item to the switchToTab method.', M.WARN);
 57             return;
 58         }
 59         var currentTab = tab.parentView.activeTab;
 60         var newPage = M.ViewManager.getPage(tab.page);
 61 
 62         /* store the active tab in tab bar view */
 63         tab.parentView.setActiveTab(tab);
 64 
 65         if(tab === currentTab) {
 66             var currentPage = M.ViewManager.getCurrentPage();
 67             if(currentPage !== newPage) {
 68                 this.switchToPage(newPage, null, YES, NO);
 69             }
 70         } else {
 71             this.switchToPage(newPage, M.TRANSITION.NONE, NO, YES);
 72         }
 73     },
 74 
 75     /**
 76      * Switch the active page in the application.
 77      *
 78      * @param {Object|String} page The page to be displayed or its name.
 79      * @param {String} transition The transition that should be used. Default: horizontal slide
 80      * @param {Boolean} isBack YES will cause a reverse-direction transition. Default: NO
 81      * @param {Boolean} updateHistory Update the browser history. Default: YES
 82      */
 83     switchToPage: function(page, transition, isBack, updateHistory) {
 84         var timeStart = M.Date.now();
 85         page = page && typeof(page) === 'object' ? page : M.ViewManager.getPage(page);
 86 
 87         if(page) {
 88             transition = transition ? transition : M.TRANSITION.SLIDE;
 89             isBack = isBack !== undefined ? isBack : NO;
 90             updateHistory = updateHistory !== undefined ? updateHistory : YES;
 91 
 92             /* Now do the page change by using a jquery mobile method and pass the properties */
 93             if(page.type === 'M.PageView') {
 94                 $.mobile.changePage($('#' + page.id), {
 95                     transition: M.Application.getConfig('useTransitions') ? transition : M.TRANSITION.NONE,
 96                     reverse: M.Application.getConfig('useTransitions') ? isBack : NO,
 97                     changeHash: updateHistory,
 98                     showLoadMsg: NO
 99                 });
100             }
101 
102             /* Save the current page in the view manager */
103             M.ViewManager.setCurrentPage(page);
104         } else {
105             M.Logger.log('Page "' + page + '" not found', M.ERR);
106         }
107     },
108 
109     /**
110      * This method initializes the notification of all observers, that observe the property behind 'key'.
111      *
112      * @param {String} key The key of the property to be changed.
113      * @param {Object|String} value The value to be set.
114      */
115     set: function(key, value) {
116         var keyPath = key.split('.');
117 
118         if(keyPath.length === 1) {
119             this[key] = value;
120         } else {
121             var t = (this[keyPath[0]] = this[keyPath[0]] ? this[keyPath[0]] : {});
122             for(var i = 1; i < keyPath.length - 1; i++) {
123                 t = (t[keyPath[i]] = t[keyPath[i]] ? t[keyPath[i]] : {});
124             }
125 
126             t[keyPath[keyPath.length - 1]] = value;
127         }
128 
129         if(!this.observable) {
130             return;
131         }
132 
133         this.observable.notifyObservers(key);
134     }
135 
136 });