-
Amanda Ghassaei authoredAmanda Ghassaei authored
AppState.js 10.39 KiB
/**
* Created by aghassaei on 1/29/15.
*/
//a class to store global app state, model for navbar and menu wrapper
//never deallocated
define(['underscore', 'backbone', 'threeModel', 'three', 'plist', 'globals'], function(_, Backbone, three, THREE, plist, globals){
var AppState = Backbone.Model.extend({
defaults: {//menu and view/render/interaction states
currentNav:"navDesign",// design, sim, assemble
currentTab:"lattice",
lastNavTab: {},//last tab that one open in each of the main menus
menuIsVisible: true,
scriptIsVisible: false,
consoleIsVisible: false,
ribbonIsVisible: true,
basePlaneIsVisible:true,
highlighterIsVisible:true,
axesAreVisible: false,
//key bindings
shift: false,
deleteMode: false,
highlightMode: true,
extrudeMode: false,
cellMode: "cell",//supercell, cell, part, node, beam
cellsVisible: true,
superCellIndex: new THREE.Vector3(0,0,0),//offset of superCell adds
gikLength: 4,//this updates super cell range when using non-composite materials
superCellRange: new THREE.Vector3(1,1,1),
realisticColorScheme: false,
materialType: null,
materialClass: "mechanical",
stockSimulationPlaying: false,
manualSelectOrigin: false//mode that allows user ot select origin from existing cell
},
initialize: function(){
this.lattice = null;
_.bindAll(this, "_handleKeyStroke", "_handleScroll");
//bind events
$(document).bind('keydown', {state:true}, this._handleKeyStroke);
$(document).bind('keyup', {state:false}, this._handleKeyStroke);
$(document).bind('mousewheel', {}, this._handleScroll);//disable browser back scroll
this.listenTo(this, "change:currentTab", this._tabChanged);
this.listenTo(this, "change:currentNav", this._navChanged);
this.listenTo(this, "change:materialType", this._materialTypeChanged);
this.listenTo(this, "change:gikLength", this._gikLengthChanged);
this.downKeys = {};//track keypresses to prevent repeat keystrokeson hold
if (this.isMobile()) this.set("menuIsVisible", false);
},
isMobile: function() {
return (window.innerWidth <= 700);
},
setLattice: function(lattice){
//a little bit hacky, wait for lattice to init then pass reference
this.lattice = lattice;
},
///////////////////////////////////////////////////////////////////////////////
/////////////////////EVENTS////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
_tabChanged: function(){
var currentTab = this.get("currentTab");
if (currentTab != "animate") this.set("stockSimulationPlaying", false);
if (currentTab != "cam") this.set("manualSelectOrigin", false);
if (currentTab == "import" && this.lattice.get("connectionType") == "edgeRot") this.lattice.set("partType", "voxLowPoly");
this.get("lastNavTab")[this.get("currentNav")] = currentTab;//store tab
this._updateCellMode(currentTab);
},
_updateCellMode: function(currentTab){
// if (currentTab == "lattice" || currentTab == "import") this.set("cellMode", "cell");
//else if (currentTab == "import") this.set("cellMode", "cell");
//else if (currentTab == "sketch") this.set("cellMode", "cell");
if (currentTab == "part") this.set("cellMode", "part");
},
_navChanged: function(){
//update to last tab open in that section
var navSelection = this.get("currentNav");
var nextTab = this.get("lastNavTab")[navSelection] || _.keys(plist.allMenuTabs[navSelection])[0];
this.set("currentTab", nextTab, {silent:true});
if (navSelection == "navDesign") {
this.set("basePlaneIsVisible", true);
this.set("highlighterIsVisible", true);
} else if (navSelection == "navAssemble"){
require(['cam']);
}
},
_materialTypeChanged: function(){
var materialType = this.get("materialType");
//verify that correct class is in sync
if (materialType.substr(0,5) != "super") {
if (this.previous("materialType").substr(0,5) != "super") return;
//re init highlighter
require([this.lattice.getHighlighterFile()], function(HighlighterClass){
globals.highlighter = new HighlighterClass();
});
return;
}
//composite material
require(['superCellHighlighter'], function(SuperCellHighlighter){
globals.highlighter = new SuperCellHighlighter();
});
},
_gikLengthChanged: function(){
if (this.get("materialType").substr(0,5) != "super"){
this.set("superCellRange", new THREE.Vector3(this.get("gikLength"), 1, 1));
}
},
///////////////////////////////////////////////////////////////////////////////
/////////////////////KEY BINDINGS//////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
_handleKeyStroke: function(e){//receives keyup and keydown
if ($("input").is(':focus')) return;//we are typing in an input
if ($("textarea").is(':focus')) return;//we are typing in an input
var state = e.data.state;
var currentTab = this.get("currentTab");
this.set("shift", false);//just in case, this is getting all weird during other meta commands in the browser
if (e.ctrlKey || e.metaKey){
} else if (state) {
if (this.downKeys[e.keyCode]) return;
this.downKeys[e.keyCode] = true;
} else this.downKeys[e.keyCode] = false;
// console.log(e);
// console.log(e.keyCode);
switch(e.keyCode){
case 8://delete key - causes back nav in chrome, super annoying
e.preventDefault();
e.stopPropagation();
break;
case 16://shift
// this.set("shift", state);
break;
case 68://d delete mode
this.set("deleteMode", state);
break;
case 69://e
// if (currentTab != "sketch") return;
this.set("extrudeMode", state);
break;
case 80://p part mode
var cellMode = this.get("cellMode");
if (cellMode == "part") this.set("cellMode", "cell");
else if (cellMode == "cell") this.set("cellMode", "part");
break;
case 83://s save
if (e.ctrlKey || e.metaKey){//command
e.preventDefault();
if (e.shiftKey){
this.set("shift", false);
$("#saveAsModel").modal("show");
} else {
globals.fileSaver.save();
}
} else {
if (state) this.set("superCellIndex", this._incrementSuperCellIndex("y", this.get("superCellIndex").clone()));
}
break;
case 79://o open
if (e.ctrlKey || e.metaKey){//command
e.preventDefault();
$("#jsonInput").click();
}
break;
case 32://space bar (play/pause simulation)
e.preventDefault();
if (state && this.get("currentTab") == "animate") this.set("stockSimulationPlaying", !this.get("stockSimulationPlaying"));
break;
case 50://2-9
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57:
if (this.lattice.get("connectionType") != "gik") break;
if (state) {
this.set("gikLength", e.keyCode-48);
}
break;
case 87://w - increase supercell index
if (state) this.set("superCellIndex", this._incrementSuperCellIndex("x", this.get("superCellIndex").clone()));
break;
case 81://q - decrease supercell index
if (state) this.set("superCellIndex", this._decrementSuperCellIndex("x", this.get("superCellIndex").clone()));
break;
case 65://a - decrease supercell index
if (state) this.set("superCellIndex", this._decrementSuperCellIndex("y", this.get("superCellIndex").clone()));
break;
case 88://x - increase supercell index
if (state) this.set("superCellIndex", this._incrementSuperCellIndex("z", this.get("superCellIndex").clone()));
break;
case 90://z - decrease supercell index
if (state) this.set("superCellIndex", this._decrementSuperCellIndex("z", this.get("superCellIndex").clone()));
break;
default:
break;
}
},
_incrementSuperCellIndex: function(key, object){
object[key] += 1;
if (object[key] > this.get("superCellRange")[key]-1) object[key] = 0;
return object;
},
_decrementSuperCellIndex: function(key, object){
object[key] -= 1;
if (object[key] < 0) object[key] = this.get("superCellRange")[key]-1;
return object;
},
_handleScroll: function(e){//disable two finger swipe back
if (Math.abs(e.originalEvent.deltaX) > Math.abs(e.originalEvent.deltaY)) e.preventDefault();
}
});
return new AppState();//return singleton
});