pcottle.learnGitBranching/src/js/views/multiView.js
2012-12-24 13:47:39 -08:00

159 lines
4.1 KiB
JavaScript

var GitError = require('../util/errors').GitError;
var _ = require('underscore');
var Q = require('q');
// horrible hack to get localStorage Backbone plugin
var Backbone = (!require('../util').isBrowser()) ? require('backbone') : window.Backbone;
var ModalTerminal = require('../views').ModalTerminal;
var ContainedBase = require('../views').ContainedBase;
var ConfirmCancelView = require('../views').ConfirmCancelView;
var LeftRightView = require('../views').LeftRightView;
var ModalAlert = require('../views').ModalAlert;
var KeyboardListener = require('../util/keyboard').KeyboardListener;
var MultiView = Backbone.View.extend({
tagName: 'div',
className: 'multiView',
// ms to debounce the nav functions
navEventDebounce: 750,
deathTime: 700,
// a simple mapping of what childViews we support
typeToConstructor: {
ModalAlert: ModalAlert
},
initialize: function(options) {
options = options || {};
this.childViewJSONs = options.childViews || [{
type: 'ModalAlert',
options: {
markdown: 'Woah wtf!!'
}
}, {
type: 'ModalAlert',
options: {
markdown: 'Im second'
}
}];
this.deferred = options.deferred;
this.childViews = [];
this.currentIndex = 0;
this.navEvents = _.clone(Backbone.Events);
this.navEvents.on('negative', this.getNegFunc(), this);
this.navEvents.on('positive', this.getPosFunc(), this);
this.keyboardListener = new KeyboardListener({
events: this.navEvents,
aliasMap: {
left: 'negative',
right: 'positive',
enter: 'positive'
}
});
this.render();
this.start();
},
getPosFunc: function() {
return _.debounce(_.bind(function() {
this.navForward();
}, this), this.navEventDebounce, true);
},
getNegFunc: function() {
return _.debounce(_.bind(function() {
this.navBackward();
}, this), this.navEventDebounce, true);
},
navForward: function() {
if (this.currentIndex === this.childViews.length - 1) {
this.hideViewIndex(this.currentIndex);
this.finish();
return;
}
this.navIndexChange(1);
},
navBackward: function() {
if (this.currentIndex === 0) {
return;
}
this.navIndexChange(-1);
},
navIndexChange: function(delta) {
this.hideViewIndex(this.currentIndex);
this.currentIndex += delta;
this.showViewIndex(this.currentIndex);
},
hideViewIndex: function(index) {
this.childViews[index].hide();
},
showViewIndex: function(index) {
this.childViews[index].show();
},
finish: function() {
this.keyboardListener.mute();
if (this.deferred) {
this.deferred.resolve();
} else {
console.warn('no promise to resolve');
require('../app').getUI().modalEnd();
}
setTimeout(_.bind(function() {
_.each(this.childViews, function(childView) {
childView.tearDown();
});
}, this), this.deathTime);
},
start: function() {
this.showViewIndex(this.currentIndex);
if (!this.deferred) {
console.warn('not part of a promise chain');
require('../app').getUI().modalStart();
}
},
createChildView: function(viewJSON) {
var type = viewJSON.type;
if (!this.typeToConstructor[type]) {
throw new Error('no constructor for type "' + type + '"');
}
var view = new this.typeToConstructor[type](viewJSON.options);
return view;
},
addNavToView: function(view, index) {
var leftRight = new LeftRightView({
events: this.navEvents,
// we want the arrows to be on the same level as the content (not
// beneath), so we go one level up with getDestination()
destination: view.getDestination(),
showLeft: (index !== 0),
lastNav: (index === this.childViewJSONs.length - 1)
});
},
render: function() {
// go through each and render... show the first
_.each(this.childViewJSONs, function(childViewJSON, index) {
var childView = this.createChildView(childViewJSON);
this.childViews.push(childView);
this.addNavToView(childView, index);
}, this);
}
});
exports.MultiView = MultiView;