extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
208 lines (184 loc) • 6.88 kB
JavaScript
/**
* @class KitchenSink.controller.phone.Main
* @extends KitchenSink.controller.Main
*
* This is the Main controller subclass for the 'phone' profile. Most of the functionality required for this controller
* is provided by the KitchenSink.controller.Main superclass, but we do need to add a couple of refs and control
* statements to provide the different behavior for the phone.
*
* This provides a couple of capabilities that we need. Firstly it sets up a listener on the main
* navigation NestedList and redirects to the appropriate url for each view. For example, tapping on the 'Forms' item
* in the list will redirect to the url 'forms'.
*
* Secondly, we set up a route that listens for urls in the form above and calls the controller's showView function
* whenever one is detected. The showView function then just shows the appropriate view on the screen.
*
*/
Ext.define('KitchenSink.controller.phone.Main', {
extend: 'KitchenSink.controller.Main',
/**
* @private
*/
viewCache: [],
refs: {
toolbar: '#mainNavigationBar',
nav: '#cardPanel',
touchEvents: 'touchevents',
consoleButton: 'button[action=showConsole]'
},
control: {
nav: {
itemtap: 'onNavTap',
leafitemtap: 'onNavLeafTap',
back: 'onBackTap'
},
consoleButton: {
tap: 'showTouchEventConsole'
}
},
routes: {
':id' : 'showById'
},
/**
* This method is executed when the NestedList for navigation has been initialized. We want to
* check the hash on the URL and go to the correct list or leaf, accordingly.
*/
showById: function(id) {
var me = this,
nav = me.getNav(),
store = Ext.StoreMgr.get('Navigation'),
hash = (window.location.hash || '').substr(1),
node = hash.length ? store.getNodeById(hash) : store.getNodeById('All');
if (node !== null) {
me.record = node;
if (node.isLeaf()) {
me.showView(node);
}
else {
// go to the proper sublist
nav.goToNode(node);
}
}
},
/**
* This is called whenever the user taps on an item in the main navigation NestedList
*/
onNavTap: function(nestedList, list, index, target, record, e) {
// this just changes the hash on the URL
this.redirectTo(record.get('id'));
},
/**
* This is called whenever the user taps on a leaf item in the main navigation NestedList
*/
onNavLeafTap: function(nestedList, list, index, target, record, e) {
var me = this;
me.record = record;
me.showView(record, true);
},
/**
* @private
* We implement onSourceTap for Phone profile because the source view covers the entire screen.
*/
onSourceTap: function() {
var me = this,
overlay = me.getSourceOverlay(),
demo = me.currentDemo,
view = me.activeView,
cls, files, content;
me.burgerActions.destroy();
me.burgerActions = null;
if (demo) {
Ext.Viewport.animateActiveItem(overlay, { type: 'cover', direction: 'up'});
me.updateDetails(me.record);
//me.loadOverlayContent(demo, view);
}
},
/**
* @private
* In the kitchen sink we have a large number of dynamic views. If we were to keep all of them rendered
* we'd risk causing the browser to run out of memory, especially on older devices. If we destroy them as
* soon as we're done with them, the app can appear sluggish. Instead, we keep a small number of rendered
* views in a viewCache so that we can easily reuse recently used views while destroying those we haven't
* used in a while.
* @param {String} name The full class name of the view to create (e.g. "KitchenSink.view.Forms")
* @return {Ext.Component} The component, which may be from the cache
*/
createView: function (item) {
var me = this,
name = me.getViewName(item),
cache = me.viewCache,
ln = cache.length,
limit = item.get('limit') || 20,
view, i = 0, j, oldView;
for (; i < ln; i++) {
view = cache[i];
if (view.viewName === name) {
me.activeView = view;
return view;
}
}
if (ln >= limit) {
for (i = 0, j = 0; i < ln; i++) {
oldView = cache[i];
if (!oldView.isPainted()) {
oldView.destroy();
} else {
cache[j++] = oldView;
}
}
cache.length = j;
}
view = Ext.create(name);
view.viewName = name;
cache.push(view);
me.viewCache = cache;
me.activeView = view;
return view;
},
/**
* For a given Demo model instance, shows the appropriate view. This is the endpoint for all routes matching
* 'demo/:id', so is called automatically whenever the user navigates back or forward between demos.
* @param {KitchenSink.model.Demo} item The Demo model instance for which we want to show a view
*/
showView: function(item, direct) {
var me = this,
nav = me.getNav(),
title = item.get('text'),
view = me.createView(item),
layout = nav.getLayout(),
anim = item.get('animation'),
initialAnim = layout.getAnimation(),
newAnim;
if (nav.getDetailCard() !== view) {
if (anim) {
layout.setAnimation(anim);
newAnim = layout.getAnimation();
}
me.currentDemo = item;
nav.setDetailCard(view);
if (!direct) {
nav.goToLeaf(item);
}
if (newAnim) {
newAnim.on('animationend', function() {
layout.setAnimation(initialAnim);
}, me, { single: true });
}
}
me.getToolbar().setTitle(title);
},
/**
* This is called whenever the user hits the Back button on the main navigation NestedList. It hides the
* "View Source" button as we do no want to see that when we are in the NestedList itself
*/
onBackTap: function(nestedList, node) {
this.redirectTo(node.parentNode.get('id'));
},
/**
* This is called whenever the user hits the 'Console' button on the TouchEvents view. It just makes sure
* that the view is showing the console card.
*/
showTouchEventConsole: function(button) {
this.getTouchEvents().showConsole();
}
});