From 67bd75f4ae70219f9e224186be2a650d5a59c754 Mon Sep 17 00:00:00 2001 From: Amanda Ghassaei <amandaghassaei@gmail.com> Date: Mon, 25 May 2015 11:12:46 -0700 Subject: [PATCH] global file saver --- index.html | 19 +++--- js/main.js | 5 +- js/menus/Navbar.js | 122 ++++++++++++++++++----------------- js/models/AllAppPLists.js | 2 +- js/models/AppState.js | 79 +++-------------------- js/models/GlobalFileSaver.js | 83 ++++++++++++++++++++++++ js/models/Lattice.js | 6 +- 7 files changed, 170 insertions(+), 146 deletions(-) create mode 100644 js/models/GlobalFileSaver.js diff --git a/index.html b/index.html index 489f83e8..59fdde42 100644 --- a/index.html +++ b/index.html @@ -67,6 +67,7 @@ <script src="js/cam/ShopbotExporter.js"></script> <script src="js/cam/GCodeExporter.js"></script> <script src="js/cam/TinyGExporter.js"></script> + <script src="js/models/GlobalFileSaver.js"></script> <!--views--> <script src="js/menus/MenuWrapperView.js"></script> @@ -107,22 +108,22 @@ <a href="#" class="dropdown-toggle" data-toggle="dropdown">File <b class="caret"></b></a> <span class="dropdown-arrow"></span> <ul class="dropdown-menu"> - <li><a id="saveJSON" href="#">Save JSON     (CTRL/⌘ + S)</a></li> + <li><a class="saveJSON" href="#">Save JSON     (CTRL/⌘ + S)</a></li> <li><a data-toggle="modal" data-target="#saveAsModel" href="#">Save JSON As...     (CTRL/⌘ + Shift + S)</a></li> <li><a class="importJSON" href="#">Open JSON...     (CTRL/⌘ + O)</a></li> <li class="dropdown-submenu"> <a tabindex="-1">Demo Files<span class="pull-right fui-arrow-right"></span></a> <ul class="dropdown-menu"> - <li><a data-file="oneBitBot.json" class="savedDemo" href="#">One Bit Assembly</a></li> + <li><a data-file="oneBitBot.json" class="loadDemo" href="#">One Bit Assembly</a></li> </ul></li> <li class="divider"></li> <li class="dropdown-submenu"> <a tabindex="-1">Load User Settings<span class="pull-right fui-arrow-right"></span></a> <ul class="dropdown-menu"> <!--<li><a id="resetDefaultSettings" href="#">Reset Settings</a></li>--> - <li><a data-file="ben.user" class="savedUserSettings" href="#">Ben</a></li> - <li><a data-file="matt.user" class="savedUserSettings" href="#">Matt</a></li> - <li><a data-file="will.user" class="savedUserSettings" href="#">Will</a></li> + <li><a data-file="ben.user" class="loadUser" href="#">Ben</a></li> + <li><a data-file="matt.user" class="loadUser" href="#">Matt</a></li> + <li><a data-file="will.user" class="loadUser" href="#">Will</a></li> <li><a class="importJSON" href="#">From File...</a></li> </ul> </li> @@ -164,11 +165,11 @@ <p class="modal-title" >Enter File Name</p> </div> <div class="modal-body"> - <input id="saveAsFileName" type="text" value="lattice" placeholder="Enter file name" class="form-control filename"> + <input id="saveAsFileName" type="text" value="file" placeholder="Enter file name" class="form-control filename"> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> - <button type="button" id="saveAsJSON" class="btn btn-primary">Save</button> + <button type="button" class="saveAsJSON btn btn-primary">Save</button> </div> </div> </div> @@ -182,11 +183,11 @@ <p class="modal-title" >Save User Settings</p> </div> <div class="modal-body"> - <input id="userSettingsFilename" type="text" value="lattice" placeholder="Enter file name" class="form-control filename"> + <input id="saveUserFileName" type="text" value="user" placeholder="Enter file name" class="form-control filename"> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> - <button type="button" id="saveUser" class="btn btn-primary">Save</button> + <button type="button" class="saveUser btn btn-primary">Save</button> </div> </div> </div> diff --git a/js/main.js b/js/main.js index 8171a5ce..68b781ba 100644 --- a/js/main.js +++ b/js/main.js @@ -12,12 +12,13 @@ $(function(){ // window.workers = persistentWorkers(8); //init global singletons - globals.plist = buildAppPList(); - globals.three = new ThreeModel(); + globals.three = ThreeModel(); + globals.plist = AppPList(); globals.appState = new AppState(); globals.lattice = new Lattice(); globals.lattice.delayedInit();//todo need this? globals.assembler = new Assembler({appState: globals.appState, lattice:globals.lattice}); + globals.fileSaver = GlobalFilesaver(); //ui new MenuWrapper({model: globals.appState}); diff --git a/js/menus/Navbar.js b/js/menus/Navbar.js index 20873867..e57f0480 100644 --- a/js/menus/Navbar.js +++ b/js/menus/Navbar.js @@ -11,33 +11,35 @@ NavBar = Backbone.View.extend({ el: "body", events: { - "click #showHideMenu": "_setMenuVis", + "click #showHideMenu": "_setMenuVisibility", "click .menuHoverControls": "_setNavSelection", - "click #saveJSON": "_save", - "click #saveAsJSON": "_saveAs", - "change #saveAsModel": "_saveAs",//detect enter key - "click #saveUser": "_saveUserSettings", "shown.bs.modal .modal": "_showModal", "hide.bs.modal .modal": "_hideModal", + + "click .saveJSON": "_save", + "click .saveAsJSON": "_saveAs", +// "change #saveAsModel": "_saveAs",//detect enter key + "click .saveUser": "_saveUser", + "click .importJSON": "_importJSON", "change #jsonInput": "_selectJSONFiles", - "click .savedUserSettings": "_loadSavedUser", - "click .savedDemo": "_loadDemo" + "click .loadUser": "_loadUser", + "click .loadDemo": "_loadDemo" }, initialize: function(){ - _.bindAll(this, "_setMenuVis", "_setNavSelection"); + _.bindAll(this, "_setMenuVisibility", "_setNavSelection"); this.listenTo(this.model, "change:menuIsVisible", this._updateShowHideButton); this.listenTo(this.model, "change:currentNav", this._updateNavSelectionUI); - this._uiStuff(); + this._logo(); this._updateShowHideButton(); this._updateNavSelectionUI(); }, - _setMenuVis: function(e){ + _setMenuVisibility: function(e){ e.preventDefault(); var state = this.model.get("menuIsVisible"); this.model.set("menuIsVisible", !state); @@ -73,6 +75,53 @@ NavBar = Backbone.View.extend({ }); }, + _logo: function(){ + var $logo = $("#logo"); + $logo.mouseover(function(){ + $logo.attr("src","assets/imgs/logo-active.png"); + }); + $logo.mouseout(function(){ + $logo.attr("src","assets/imgs/logo.png"); + }); + }, + + _deselectAllNavItems: function(){ + $(".open").removeClass("open");//no highlight + }, + + _showModal: function(e){ + var input = $(e.target).find("input.filename"); + input.focus(); + input.select(); + }, + + _hideModal: function(e){ + $(e.target).find("input.filename").blur(); + }, + + + + + + _save: function(e){ + e.preventDefault(); + globals.fileSaver.save(); + }, + + _saveAs: function(e){ + e.preventDefault(); + var fileName = $("#saveAsFileName").val(); + globals.fileSaver.save(fileName); + $('#saveAsModel').modal('hide'); + }, + + _saveUser: function(e){ + e.preventDefault(); + var fileName = $("#saveUserFileName").val(); + globals.fileSaver.saveUser(fileName); + $('#saveUserModel').modal('hide'); + }, + _importJSON: function(e){ e.preventDefault(); $("#jsonInput").click(); @@ -95,38 +144,19 @@ NavBar = Backbone.View.extend({ return function(e) { var extension = filename.substr(filename.length - 5); if (extension == ".json"){ - globals.appState.loadLatticeFromJSON(JSON.parse(e.target.result)); + globals.fileSaver.loadFile(JSON.parse(e.target.result)); } else if (extension == ".user"){ - globals.appState.loadUser(e.target.result); + globals.fileSaver.loadUser(JSON.parse(e.target.result)); } else console.warn("file type not recognized"); } })(); }, - _save: function(e){ - e.preventDefault(); - globals.appState.saveJSON(); - }, - - _saveAs: function(e){ - e.preventDefault(); - var fileName = $("#saveAsFileName").val(); - globals.appState.saveJSON(fileName); - $('#saveAsModel').modal('hide'); - }, - - _saveUserSettings: function(e){ - e.preventDefault(); - var fileName = $("#userSettingsFilename").val(); - globals.appState.saveUser(fileName); - $('#saveUserModel').modal('hide'); - }, - - _loadSavedUser: function(e){ + _loadUser: function(e){ e.preventDefault(); var url = "data/users/" + $(e.target).data("file"); $.getJSON( url, function(data) { - globals.appState.loadUser(data, true); + globals.fileSaver.loadUser(data); }); }, @@ -134,32 +164,8 @@ NavBar = Backbone.View.extend({ e.preventDefault(); var url = "data/demos/" + $(e.target).data("file"); $.getJSON( url, function(data) { - globals.appState.loadLatticeFromJSON(data); - }); - }, - - _showModal: function(e){ - var input = $(e.target).find("input.filename"); - input.focus(); - input.select(); - }, - - _hideModal: function(e){ - $(e.target).find("input.filename").blur(); - }, - - _uiStuff: function(){ - var $logo = $("#logo"); - $logo.mouseover(function(){ - $logo.attr("src","assets/imgs/logo-active.png"); - }); - $logo.mouseout(function(){ - $logo.attr("src","assets/imgs/logo.png"); + globals.fileSaver.loadFile(data); }); - }, - - _deselectAllNavItems: function(){ - $(".open").removeClass("open");//no highlight } }); \ No newline at end of file diff --git a/js/models/AllAppPLists.js b/js/models/AllAppPLists.js index b667c09a..322bc864 100644 --- a/js/models/AllAppPLists.js +++ b/js/models/AllAppPLists.js @@ -1,6 +1,6 @@ //all property lists for the app, these are "static" variables -function buildAppPList(){ +function AppPList(){ return { diff --git a/js/models/AppState.js b/js/models/AppState.js index e3f5609a..52bb59f2 100644 --- a/js/models/AppState.js +++ b/js/models/AppState.js @@ -40,11 +40,10 @@ AppState = Backbone.Model.extend({ //bind events $(document).bind('keydown', {state:true}, this._handleKeyStroke); $(document).bind('keyup', {state:false}, this._handleKeyStroke); - $(document).bind('mousewheel', {}, this._handleScroll); + $(document).bind('mousewheel', {}, this._handleScroll);//disable browser back scroll this.listenTo(this, "change:currentTab", this._tabChanged); - this.listenTo(this, "change:currentNav", this._updateCurrentTabForNav); - this.listenTo(this, "change:currentTab", this._updateCellMode); + this.listenTo(this, "change:currentNav", this._navChanged); this.downKeys = {};//track keypresses to prevent repeat keystrokeson hold @@ -52,9 +51,6 @@ AppState = Backbone.Model.extend({ }, isMobile: function() { -// var check = false; -// (function(a,b){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); -// return check; return (window.innerWidth <= 700); }, @@ -70,6 +66,7 @@ AppState = Backbone.Model.extend({ if (currentTab != "cam") this.set("manualSelectOrigin", false); if (currentTab == "import" && globals.lattice.get("connectionType") == "edgeRot") globals.lattice.set("partType", "voxLowPoly"); this._storeTab(this.get("currentNav"), currentTab); + this._updateCellMode(currentTab); }, _storeTab: function(currentNav, currentTab){ @@ -78,16 +75,15 @@ AppState = Backbone.Model.extend({ else if (currentNav == "navAssemble") this.set("lastAssembleTab", currentTab); }, - _updateCellMode: function(){ - var currentTab = this.get("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"); else if (currentTab == "part") this.set("cellMode", "part"); }, - //update to last tab open in that section - _updateCurrentTabForNav: function(){ + _navChanged: function(){ + //update to last tab open in that section var navSelection = this.get("currentNav"); if (navSelection == "navDesign") this.set("currentTab", this.get("lastDesignTab")); @@ -112,7 +108,7 @@ AppState = Backbone.Model.extend({ 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) { + } else if (state) { if (this.downKeys[e.keyCode]) return; this.downKeys[e.keyCode] = true; } else this.downKeys[e.keyCode] = false; @@ -145,7 +141,7 @@ AppState = Backbone.Model.extend({ this.set("shift", false); $("#saveAsModel").modal("show"); } else { - globals.appState.saveJSON(); + globals.fileSaver.save(); } } break; @@ -191,65 +187,6 @@ AppState = Backbone.Model.extend({ _handleScroll: function(e){//disable two finger swipe back if (Math.abs(e.originalEvent.deltaX) > Math.abs(e.originalEvent.deltaY)) e.preventDefault(); - }, - - //////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////SAVE//////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - - _saveFile: function(data, name, extension){ - var blob = new Blob([data], {type: "text/plain;charset=utf-8"}); - saveAs(blob, name + extension); - }, - - saveJSON: function(name){ - if (!name) name = "lattice"; - var data = JSON.stringify({ - lattice:this._getLatticeDataToSave(), - assembler: this._getAssemblerDataToSave() - }); - this._saveFile(data, name, ".json"); - }, - - _getAssemblerDataToSave: function(){ - var assemblerData = _.omit(globals.assembler.toJSON(), ["origin", "stock", "exporter", "appState", "lattice", "machine", "simLineNumber"]); - if (!globals.assembler.get("editsMadeToProgram")) assemblerData.dataOut = ""; - return assemblerData; - }, - - _getLatticeDataToSave: function(){ - return _.omit(globals.lattice.toJSONFull(), ["highlighter", "basePlane", "nodes", "appState"]); - }, - - loadLatticeFromJSON: function(data){ - globals.lattice.clearCells(); - this._setData(data, false); - globals.lattice._updateLatticeType(null, null, null, true); - globals.lattice.trigger("change:scale");//todo make this better - }, - - saveUser: function(name){ - var latticeData = _.omit(this._getLatticeDataToSave(), ["cells", "cellsMin", "cellsMax", "numCells"]); - var assemblerData = _.omit(this._getAssemblerDataToSave(), ["dataOut", "needsPostProcessing", "editsMadeToProgram"]); - var data = JSON.stringify({ - lattice:latticeData, - assembler:assemblerData - }); - this._saveFile(data, name, ".user"); - }, - - loadUser: function(data, isParsed){ - if (!isParsed) data = JSON.parse(data); - this._setData(data, false); - }, - - _setData: function(data, silent){ - _.each(_.keys(data.lattice), function(key){ - globals.lattice.set(key, data.lattice[key], {silent:silent}); - }); - _.each(_.keys(data.assembler), function(key){ - globals.assembler.set(key, data.assembler[key]); - }); } }); \ No newline at end of file diff --git a/js/models/GlobalFileSaver.js b/js/models/GlobalFileSaver.js new file mode 100644 index 00000000..23ed5feb --- /dev/null +++ b/js/models/GlobalFileSaver.js @@ -0,0 +1,83 @@ +/** + * Created by aghassaei on 5/25/15. + */ + + +function GlobalFilesaver(){ + + function _saveFile(data, name, extension){ + var blob = new Blob([data], {type: "text/plain;charset=utf-8"}); + saveAs(blob, name + extension); + } + + function save(name){ + if (!name || name == "" || name == undefined) name = "file"; + var data = JSON.stringify({ + lattice:_getLatticeDataToSave(), + assembler:_getAssemblerDataToSave() + }); + _saveFile(data, name, ".json"); + } + + function saveLattice(name){ + if (!name || name == "" || name == undefined) name = "lattice"; + var data = JSON.stringify({ + lattice:_getLatticeDataToSave() + }); + _saveFile(data, name, ".json"); + } + + function saveAssembler(){ + + } + + function saveUser(name){ + if (!name || name == "" || name == undefined) name = "user"; + var latticeData = _.omit(_getLatticeDataToSave(), ["cells", "cellsMin", "cellsMax", "numCells"]); + var assemblerData = _.omit(_getAssemblerDataToSave(), ["dataOut", "needsPostProcessing", "editsMadeToProgram"]); + var data = JSON.stringify({ + lattice:latticeData, + assembler:assemblerData + }); + _saveFile(data, name, ".user"); + } + + function _getAssemblerDataToSave(){ + var assemblerData = _.omit(globals.assembler.toJSON(), ["origin", "stock", "exporter", "appState", "lattice", "machine", "simLineNumber"]); + if (!globals.assembler.get("editsMadeToProgram")) assemblerData.dataOut = ""; + return assemblerData; + } + + function _getLatticeDataToSave(){ + return globals.lattice.attributes; + } + + function loadFile(data){//todo make this better + globals.lattice.clearCells(); + _setData(data, false); + globals.lattice._updateLatticeType(null, null, null, true); + globals.lattice.trigger("change:scale"); + } + + function loadUser(data){ + _setData(data, false); + } + + function _setData(data, silent){ + _.each(_.keys(data.lattice), function(key){ + globals.lattice.set(key, data.lattice[key], {silent:silent}); + }); + _.each(_.keys(data.assembler), function(key){ + globals.assembler.set(key, data.assembler[key]); + }); + } + + return {//return public methods + save: save, + saveLattice: saveLattice, +// saveAssembler: saveAssembler, + saveUser: saveUser, + loadFile: loadFile, + loadUser: loadUser + } +} \ No newline at end of file diff --git a/js/models/Lattice.js b/js/models/Lattice.js index 4d069f2b..c7ca2f44 100644 --- a/js/models/Lattice.js +++ b/js/models/Lattice.js @@ -605,11 +605,7 @@ Lattice = Backbone.Model.extend({ //////////////////////////////////////////////////////////////////////////////////// toJSON: function(){//a minimal toJSON for ui stuff - no need to parse all cells - return _.omit(this.attributes, ["cells", "nodes"]); + return _.omit(this.attributes, ["cells", "nodes"]);//omit makes a copy },//todo something weird here - toJSONFull: function(){//for saving only - it's ok to pass attributes - return this.attributes; - } - }); \ No newline at end of file -- GitLab