Namespacing for controllers and views

This commit is contained in:
Max Lynch
2013-09-23 00:07:41 -05:00
parent 63e268f171
commit c77128eeae
8 changed files with 339 additions and 329 deletions

View File

@ -20,7 +20,7 @@
<script src="../../js/events.js"></script> <script src="../../js/events.js"></script>
<script src="../../js/gestures.js"></script> <script src="../../js/gestures.js"></script>
<script src="../../js/controllers/sideMenuViewController.js"></script> <script src="../../js/controllers/sideMenuController.js"></script>
<script src="js/toderp.js"></script> <script src="js/toderp.js"></script>
<style> <style>

View File

@ -1,105 +1,108 @@
(function(ionic) { (function(ionic) {
NavController = function(opts) {
var _this = this;
this.navBar = opts.navBar; ionic.controllers = ionic.controllers || {};
this.content = opts.content;
this.controllers = opts.controllers || []; ionic.controllers.NavController = function(opts) {
var _this = this;
this.navBar = opts.navBar;
this.content = opts.content;
this.controllers = opts.controllers || [];
this._updateNavBar();
// TODO: Is this the best way?
this.navBar.shouldGoBack = function() {
_this.pop();
}
};
ionic.controllers.NavController.prototype = {
getControllers: function() {
return this.controllers;
},
getTopController: function() {
return this.controllers[this.controllers.length-1];
},
push: function(controller) {
var last = this.controllers[this.controllers.length - 1];
this.controllers.push(controller);
// Indicate we are switching controllers
var shouldSwitch = this.switchingController && this.switchingController(controller) || true;
// Return if navigation cancelled
if(shouldSwitch === false)
return;
// Actually switch the active controllers
// Remove the old one
//last && last.detach();
if(last) {
last.isVisible = false;
last.visibilityChanged && last.visibilityChanged();
}
// Grab the top controller on the stack
var next = this.controllers[this.controllers.length - 1];
// TODO: No DOM stuff here
//this.content.el.appendChild(next.el);
next.isVisible = true;
next.visibilityChanged && next.visibilityChanged();
this._updateNavBar(); this._updateNavBar();
// TODO: Is this the best way? return controller;
this.navBar.shouldGoBack = function() { },
_this.pop();
pop: function() {
var next, last;
// Make sure we keep one on the stack at all times
if(this.controllers.length < 2) {
return;
} }
};
NavController.prototype = { // Grab the controller behind the top one on the stack
getControllers: function() { last = this.controllers.pop();
return this.controllers; if(last) {
}, last.isVisible = false;
getTopController: function() { last.visibilityChanged && last.visibilityChanged();
return this.controllers[this.controllers.length-1]; }
},
push: function(controller) {
var last = this.controllers[this.controllers.length - 1];
this.controllers.push(controller); // Remove the old one
//last && last.detach();
// Indicate we are switching controllers next = this.controllers[this.controllers.length - 1];
var shouldSwitch = this.switchingController && this.switchingController(controller) || true;
// Return if navigation cancelled // TODO: No DOM stuff here
if(shouldSwitch === false) //this.content.el.appendChild(next.el);
return; next.isVisible = true;
next.visibilityChanged && next.visibilityChanged();
// Actually switch the active controllers // Switch to it (TODO: Animate or such things here)
// Remove the old one this._updateNavBar();
//last && last.detach();
if(last) {
last.isVisible = false;
last.visibilityChanged && last.visibilityChanged();
}
// Grab the top controller on the stack return last;
var next = this.controllers[this.controllers.length - 1]; },
// TODO: No DOM stuff here _updateNavBar: function() {
//this.content.el.appendChild(next.el); if(!this.getTopController()) {
next.isVisible = true; return;
next.visibilityChanged && next.visibilityChanged(); }
this._updateNavBar(); this.navBar.setTitle(this.getTopController().title);
return controller; if(this.controllers.length > 1) {
}, this.navBar.showBackButton(true);
} else {
this.navBar.showBackButton(false);
}
},
pop: function() { };
var next, last;
// Make sure we keep one on the stack at all times
if(this.controllers.length < 2) {
return;
}
// Grab the controller behind the top one on the stack
last = this.controllers.pop();
if(last) {
last.isVisible = false;
last.visibilityChanged && last.visibilityChanged();
}
// Remove the old one
//last && last.detach();
next = this.controllers[this.controllers.length - 1];
// TODO: No DOM stuff here
//this.content.el.appendChild(next.el);
next.isVisible = true;
next.visibilityChanged && next.visibilityChanged();
// Switch to it (TODO: Animate or such things here)
this._updateNavBar();
return last;
},
_updateNavBar: function() {
if(!this.getTopController()) {
return;
}
this.navBar.setTitle(this.getTopController().title);
if(this.controllers.length > 1) {
this.navBar.showBackButton(true);
} else {
this.navBar.showBackButton(false);
}
},
};
})(ionic = window.ionic || {}); })(ionic = window.ionic || {});

View File

@ -1,191 +1,193 @@
(function(ionic) { (function(ionic) {
SideMenuController = function(options) { ionic.controllers = ionic.controllers || {};
var _this = this;
ionic.controllers.SideMenuController = function(options) {
var _this = this;
this.left = options.left; this.left = options.left;
this.right = options.right; this.right = options.right;
this.content = options.content; this.content = options.content;
this._rightShowing = false; this._rightShowing = false;
this._leftShowing = false; this._leftShowing = false;
this.content.onDrag = function(e) { this.content.onDrag = function(e) {
_this._handleDrag(e); _this._handleDrag(e);
};
this.content.endDrag = function(e) {
_this._endDrag(e);
};
/*
// Bind release and drag listeners
window.ion.onGesture('release', function(e) {
_this._endDrag(e);
}, this.center);
window.ion.onGesture('drag', function(e) {
_this._handleDrag(e);
}, this.center);
*/
}; };
SideMenuController.prototype = { this.content.endDrag = function(e) {
toggleLeft: function() { _this._endDrag(e);
var openAmount = this.getOpenAmount(); };
if(openAmount > 0) {
this.openPercentage(0);
} else {
this.openPercentage(100);
}
},
toggleRight: function() {
var openAmount = this.getOpenAmount();
if(openAmount < 0) {
this.openPercentage(0);
} else {
this.openPercentage(-100);
}
},
getOpenAmount: function() {
return this.content.getTranslateX() || 0;
},
getOpenRatio: function() {
var amount = this.getOpenAmount();
if(amount >= 0) {
return amount / this.left.width;
}
return amount / this.right.width;
},
getOpenPercentage: function() {
return this.getOpenRatio() * 100;
},
openPercentage: function(percentage) {
var p = percentage / 100;
var maxLeft = this.left.width;
var maxRight = this.right.width;
if(percentage >= 0) {
this.openAmount(maxLeft * p);
} else {
this.openAmount(maxRight * p);
}
},
openAmount: function(amount) {
var maxLeft = this.left.width;
var maxRight = this.right.width;
// Check if we can move to that side, depending if the left/right panel is enabled /*
if((!this.left.isEnabled && amount > 0) || (!this.right.isEnabled && amount < 0)) { // Bind release and drag listeners
return; window.ion.onGesture('release', function(e) {
} _this._endDrag(e);
}, this.center);
if((this._leftShowing && amount > maxLeft) || (this._rightShowing && amount < -maxRight)) { window.ion.onGesture('drag', function(e) {
return; _this._handleDrag(e);
} }, this.center);
*/
};
this.content.setTranslateX(amount); ionic.controllers.SideMenuController.prototype = {
toggleLeft: function() {
if(amount >= 0) { var openAmount = this.getOpenAmount();
this._leftShowing = true; if(openAmount > 0) {
this._rightShowing = false; this.openPercentage(0);
} else {
// Push the z-index of the right menu down this.openPercentage(100);
this.right.pushDown();
// Bring the z-index of the left menu up
this.left.bringUp();
} else {
this._rightShowing = true;
this._leftShowing = false;
// Bring the z-index of the right menu up
this.right.bringUp();
// Push the z-index of the left menu down
this.left.pushDown();
}
},
snapToRest: function(e) {
// We want to animate at the end of this
this.content.enableAnimation();
this._isDragging = false;
// Check how much the panel is open after the drag, and
// what the drag velocity is
var ratio = this.getOpenRatio();
if(ratio == 0)
return;
var velocityThreshold = 0.3;
var velocityX = e.gesture.velocityX
var direction = e.gesture.direction;
// Less than half, going left
//if(ratio > 0 && ratio < 0.5 && direction == 'left' && velocityX < velocityThreshold) {
//this.openPercentage(0);
//}
// Going right, less than half, too slow (snap back)
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
this.openPercentage(0);
}
// Going left, more than half, too slow (snap back)
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
this.openPercentage(100);
}
// Going left, less than half, too slow (snap back)
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
this.openPercentage(0);
}
// Going right, more than half, too slow (snap back)
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
this.openPercentage(-100);
}
// Going right, more than half, or quickly (snap open)
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
this.openPercentage(100);
}
// Going left, more than half, or quickly (span open)
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
this.openPercentage(-100);
}
// Snap back for safety
else {
this.openPercentage(0);
}
},
_endDrag: function(e) {
this.snapToRest(e);
},
_initDrag: function(e) {
this.content.disableAnimation();
this._isDragging = true;
this._startX = 0;
this._offsetX = 0;
this._lastX = 0;
},
_handleDrag: function(e) {
if(!this._isDragging) {
this._initDrag(e);
this._startX = e.gesture.touches[0].pageX;
this._lastX = this._startX;
this._offsetX = this.getOpenAmount();
}
//console.log('Dragging page', this._startX, this._lastX, this._offsetX, e);
var newX = this._offsetX + (this._lastX - this._startX);
this.openAmount(newX);
this._lastX = e.gesture.touches[0].pageX;
} }
}; },
toggleRight: function() {
var openAmount = this.getOpenAmount();
if(openAmount < 0) {
this.openPercentage(0);
} else {
this.openPercentage(-100);
}
},
getOpenAmount: function() {
return this.content.getTranslateX() || 0;
},
getOpenRatio: function() {
var amount = this.getOpenAmount();
if(amount >= 0) {
return amount / this.left.width;
}
return amount / this.right.width;
},
getOpenPercentage: function() {
return this.getOpenRatio() * 100;
},
openPercentage: function(percentage) {
var p = percentage / 100;
var maxLeft = this.left.width;
var maxRight = this.right.width;
if(percentage >= 0) {
this.openAmount(maxLeft * p);
} else {
this.openAmount(maxRight * p);
}
},
openAmount: function(amount) {
var maxLeft = this.left.width;
var maxRight = this.right.width;
// Check if we can move to that side, depending if the left/right panel is enabled
if((!this.left.isEnabled && amount > 0) || (!this.right.isEnabled && amount < 0)) {
return;
}
if((this._leftShowing && amount > maxLeft) || (this._rightShowing && amount < -maxRight)) {
return;
}
this.content.setTranslateX(amount);
if(amount >= 0) {
this._leftShowing = true;
this._rightShowing = false;
// Push the z-index of the right menu down
this.right.pushDown();
// Bring the z-index of the left menu up
this.left.bringUp();
} else {
this._rightShowing = true;
this._leftShowing = false;
// Bring the z-index of the right menu up
this.right.bringUp();
// Push the z-index of the left menu down
this.left.pushDown();
}
},
snapToRest: function(e) {
// We want to animate at the end of this
this.content.enableAnimation();
this._isDragging = false;
// Check how much the panel is open after the drag, and
// what the drag velocity is
var ratio = this.getOpenRatio();
if(ratio == 0)
return;
var velocityThreshold = 0.3;
var velocityX = e.gesture.velocityX
var direction = e.gesture.direction;
// Less than half, going left
//if(ratio > 0 && ratio < 0.5 && direction == 'left' && velocityX < velocityThreshold) {
//this.openPercentage(0);
//}
// Going right, less than half, too slow (snap back)
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
this.openPercentage(0);
}
// Going left, more than half, too slow (snap back)
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
this.openPercentage(100);
}
// Going left, less than half, too slow (snap back)
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
this.openPercentage(0);
}
// Going right, more than half, too slow (snap back)
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
this.openPercentage(-100);
}
// Going right, more than half, or quickly (snap open)
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
this.openPercentage(100);
}
// Going left, more than half, or quickly (span open)
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
this.openPercentage(-100);
}
// Snap back for safety
else {
this.openPercentage(0);
}
},
_endDrag: function(e) {
this.snapToRest(e);
},
_initDrag: function(e) {
this.content.disableAnimation();
this._isDragging = true;
this._startX = 0;
this._offsetX = 0;
this._lastX = 0;
},
_handleDrag: function(e) {
if(!this._isDragging) {
this._initDrag(e);
this._startX = e.gesture.touches[0].pageX;
this._lastX = this._startX;
this._offsetX = this.getOpenAmount();
}
//console.log('Dragging page', this._startX, this._lastX, this._offsetX, e);
var newX = this._offsetX + (this._lastX - this._startX);
this.openAmount(newX);
this._lastX = e.gesture.touches[0].pageX;
}
};
})(ionic = window.ionic || {}); })(ionic = window.ionic || {});

View File

@ -1,6 +1,8 @@
(function(ionic) { (function(ionic) {
TabBarController = function(options) { ionic.controllers = ionic.controllers || {};
ionic.controllers.TabBarController = function(options) {
this.tabBar = options.tabBar; this.tabBar = options.tabBar;
this._bindEvents(); this._bindEvents();
@ -20,7 +22,7 @@ TabBarController = function(options) {
this.setSelectedController(0); this.setSelectedController(0);
}; };
TabBarController.prototype = { ionic.controllers.TabBarController.prototype = {
// Start listening for events on our tab bar // Start listening for events on our tab bar
_bindEvents: function() { _bindEvents: function() {
var _this = this; var _this = this;

View File

@ -1,42 +1,41 @@
(function(ionic) { (function(ionic) {
ionic.ui.NavBar = function(opts) {
this.el = opts.el;
NavBar = function(opts) { this._titleEl = this.el.querySelector('.title');
this.el = opts.el; };
this._titleEl = this.el.querySelector('.title'); ionic.ui.NavBar.prototype = {
}; shouldGoBack: function() {},
NavBar.prototype = { setTitle: function(title) {
shouldGoBack: function() {}, if(!this._titleEl) {
return;
}
this._titleEl.innerHTML = title;
},
setTitle: function(title) { showBackButton: function(shouldShow) {
if(!this._titleEl) { var _this = this;
return;
}
this._titleEl.innerHTML = title;
},
showBackButton: function(shouldShow) { if(!this._currentBackButton) {
var _this = this; var back = document.createElement('a');
back.className = 'button back';
back.innerHTML = 'Back';
if(!this._currentBackButton) { this._currentBackButton = back;
var back = document.createElement('a'); this._currentBackButton.onclick = function(event) {
back.className = 'button back'; _this.shouldGoBack && _this.shouldGoBack();
back.innerHTML = 'Back';
this._currentBackButton = back;
this._currentBackButton.onclick = function(event) {
_this.shouldGoBack && _this.shouldGoBack();
}
}
if(shouldShow && !this._currentBackButton.parentNode) {
// Prepend the back button
this.el.insertBefore(this._currentBackButton, this.el.firstChild);
} else if(!shouldShow && this._currentBackButton.parentNode) {
// Remove the back button if it's there
this._currentBackButton.parentNode.removeChild(this._currentBackButton);
} }
} }
};
if(shouldShow && !this._currentBackButton.parentNode) {
// Prepend the back button
this.el.insertBefore(this._currentBackButton, this.el.firstChild);
} else if(!shouldShow && this._currentBackButton.parentNode) {
// Remove the back button if it's there
this._currentBackButton.parentNode.removeChild(this._currentBackButton);
}
}
};
})(ionic = window.ionic || {}); })(ionic = window.ionic || {});

View File

@ -1,22 +1,25 @@
(function(ionic) { (function(ionic) {
SideMenu = function(opts) {
this.el = opts.el;
this.width = opts.width;
this.isEnabled = opts.isEnabled || true;
};
SideMenu.prototype = { ionic.ui = ionic.ui || {};
getFullWidth: function() {
return this.width; ionic.ui.SideMenu = function(opts) {
}, this.el = opts.el;
setIsEnabled: function(isEnabled) { this.width = opts.width;
this.isEnabled = isEnabled; this.isEnabled = opts.isEnabled || true;
}, };
bringUp: function() {
this.el.style.zIndex = 0; ionic.ui.SideMenu.prototype = {
}, getFullWidth: function() {
pushDown: function() { return this.width;
this.el.style.zIndex = -1; },
} setIsEnabled: function(isEnabled) {
}; this.isEnabled = isEnabled;
},
bringUp: function() {
this.el.style.zIndex = 0;
},
pushDown: function() {
this.el.style.zIndex = -1;
}
};
})(ionic = window.ionic || {}); })(ionic = window.ionic || {});

View File

@ -1,11 +1,13 @@
(function(ionic) { (function(ionic) {
TabBarItem = function(el) { ionic.ui = ionic.ui || {};
ionic.ui.TabBarItem = function(el) {
this.el = el; this.el = el;
this._buildItem(); this._buildItem();
}; };
TabBarItem.prototype = { ionic.ui.TabBarItem.prototype = {
// Factory for creating an item from a given javascript object // Factory for creating an item from a given javascript object
create: function(itemData) { create: function(itemData) {
var item = document.createElement('a'); var item = document.createElement('a');
@ -74,7 +76,7 @@ TabBarItem.prototype = {
} }
}; };
TabBar = function(opts) { ionic.ui.TabBar = function(opts) {
this.el = opts.el; this.el = opts.el;
this.items = []; this.items = [];
@ -82,7 +84,7 @@ TabBar = function(opts) {
this._buildItems(); this._buildItems();
}; };
TabBar.prototype = { ionic.ui.TabBar.prototype = {
// get all the items for the TabBar // get all the items for the TabBar
getItems: function() { getItems: function() {
return this.items; return this.items;

View File

@ -134,14 +134,13 @@
</section> </section>
<script src="../../js/ionic-events.js"></script> <script src="../../js/events.js"></script>
<script src="../../js/ionic-gestures.js"></script> <script src="../../js/gestures.js"></script>
<script src="../../js/controllers/ionic-tabcontroller.js"></script> <script src="../../js/controllers/tabBarController.js"></script>
<script> <script>
// Grab the sections // Grab the sections
var tab = document.getElementById('tab-bar'); var tab = document.getElementById('tab-bar');
var controller = new ion.controllers.TabController({ var controller = new ionic.controllers.TabController({
tab: tab tab: tab
}); });
</script> </script>