From 0e5824eecfa10184c53fc9e44952bd8c4cecf3c7 Mon Sep 17 00:00:00 2001
From: Amanda Ghassaei <amandaghassaei@gmail.com>
Date: Tue, 2 Jun 2015 16:42:03 -0700
Subject: [PATCH] menus

---
 js/main.js                       |   5 +-
 js/menus/AnimationMenuView.js    | 252 +++++++++++++++----------------
 js/menus/AssemblerMenuView.js    | 113 +++++++-------
 js/menus/CamMenuView.js          | 202 ++++++++++++-------------
 js/menus/ImportMenuView.js       | 211 +++++++++++++-------------
 js/menus/LatticeMenuView.js      |  12 +-
 js/menus/MaterialMenuView.js     |  34 ++---
 js/menus/MenuParentView.js       |  20 ++-
 js/menus/OptimizationMenuView.js |  31 ++--
 js/menus/PartMenuView.js         |  16 +-
 js/menus/PhysicsMenuView.js      |  38 +++--
 js/menus/ScriptMenuView.js       |  46 +++---
 js/menus/SendMenuView.js         |  29 ++--
 js/menus/SketchMenuView.js       |  55 ++++---
 14 files changed, 515 insertions(+), 549 deletions(-)

diff --git a/js/main.js b/js/main.js
index 4d3d355b..4d311b59 100644
--- a/js/main.js
+++ b/js/main.js
@@ -2,7 +2,7 @@
  * Created by aghassaei on 1/7/15.
  */
 
-requirejs.config({
+require.config({
     baseUrl: 'js',
     paths: {
         jquery: 'dependencies/jquery-2.1.3',
@@ -41,7 +41,6 @@ requirejs.config({
         animateMenu: 'menus/AnimationMenuView',
         sendMenu: 'menus/SendMenuView'
 
-
     },
     shim: {
         three: {
@@ -61,7 +60,7 @@ requirejs.config({
 });
 
 //init stuff
-requirejs(['appState', 'lattice', 'menuWrapper', 'navbar', 'ribbon', 'threeModel', 'threeView', 'flatUI'],
+require(['appState', 'lattice', 'menuWrapper', 'navbar', 'ribbon', 'threeModel', 'threeView', 'flatUI'],
     function(appState, lattice, MenuWrapper, Navbar, Ribbon, three, ThreeView){
 
     new MenuWrapper({model:appState});
diff --git a/js/menus/AnimationMenuView.js b/js/menus/AnimationMenuView.js
index 26bb2757..f8300b23 100644
--- a/js/menus/AnimationMenuView.js
+++ b/js/menus/AnimationMenuView.js
@@ -2,133 +2,133 @@
  * Created by aghassaei on 2/1/15.
  */
 
-
-AnimationMenuView = Backbone.View.extend({
-
-    el: "#menuContent",
-
-    events: {
-        "click #playStockSim":                                      "_playStockSim",
-        "click #pauseStockSim":                                     "_pauseStockSim",
-        "click #resetStockSim":                                     "_resetStockSim",
-        "click #animationMenuSave":                                 "_save",
-        "click .overrideEdits":                                     "_postProcess",
-        "slideStop #speedSlider":                                   "_changeSpeedSlider"
-    },
-
-    initialize: function(){
-
-        _.bindAll(this, "render", "_codeEdit", "_setEditorHeight");
-
-        //bind events
-        this.listenTo(this.model, "change:stockSimulationPlaying", this.render);
-        var self = this;
-        this.listenTo(globals.cam, "change", function(){
-            //ignore simLineNumber for render calls
-            if (_.isEqual(_.keys(globals.cam.changedAttributes()), ["simLineNumber"])) return;
-            self.render();
-        });
-        this.listenTo(globals.cam, "change:simLineNumber", this._drawGcodeHighlighter);
-        $(document).bind('keyup', {state:false}, this._codeEdit);
-        //this.$el.bind('resize', this._setEditorHeight);
-    },
-
-    _save: function(e){
-        e.preventDefault();
-        globals.cam.save();
-    },
-
-    _postProcess: function(e){
-        e.preventDefault();
-        globals.cam.postProcess();
-    },
-
-    _codeEdit: function(e){
-        var editor = $("#gcodeEditor");
-        if (!editor.is(":focus")) return;
-        e.preventDefault();
-        globals.cam.makeProgramEdits(editor.text());
-    },
-
-    _playStockSim: function(e){
-        e.preventDefault();
-        this.model.set("stockSimulationPlaying", true);
-    },
-
-    _pauseStockSim: function(e){
-        e.preventDefault();
-        this.model.set("stockSimulationPlaying", false);
-    },
-
-    _resetStockSim: function(e){
-        e.preventDefault();
-        globals.cam.resetSimulation();
-        this.render();
-    },
-
-    _changeSpeedSlider: function(e){
-        e.preventDefault();
-        globals.cam.set("simSpeed", Math.pow(2,$(e.target)[0].value));
-    },
-
-    _drawGcodeHighlighter: function(){
-        var lineNum = globals.cam.get("simLineNumber");
-        if (lineNum == 0) return;
-        var code = globals.cam.get("dataOut").split("\n");
-        code[lineNum] = "<span id='gcodeHighlighter'>" + code[lineNum] + " </span>";
-        var newText = code.join("\n");
-        var $editor = $('#gcodeEditor');
-        $editor.html(newText);
-        var $highlighter = $("#gcodeHighlighter");
-        if (!$editor.position() || !$highlighter.position()) return;//todo weird bug
-        var highlighterHeight = $highlighter.position().top - $editor.position().top;
-        var desiredHeight = $editor.height()/2;
-        if (highlighterHeight > desiredHeight) $editor.scrollTop($editor.scrollTop()+highlighterHeight-desiredHeight);
-    },
-
-    _setEditorHeight: function(){
-        var $editor = $('#gcodeEditor');
-        var height = this.$el.height()-$editor.position().top-50;
-        height = Math.max(height, 250);
-        $editor.css({height:height +"px"});
-    },
-
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "animate") return;
-        if ($("input[type=text]").is(":focus")) return;
-        if (globals.cam.get("needsPostProcessing") && !globals.cam.get("editsMadeToProgram")) globals.cam.postProcess();
-        this.$el.html(this.template(_.extend(this.model.toJSON(), globals.cam.toJSON())));
-        this._setEditorHeight();
-        this._drawGcodeHighlighter();//in case of code pause
-
-        $('#speedSlider').slider({
-            formatter: function(value) {
-                return Math.pow(2, value) + "X";
-            }
-        });
-    },
-
-    template: _.template('\
-        <% if (stockSimulationPlaying){ %>\
-        <a href="#" id="pauseStockSim" class=" btn btn-block btn-lg btn-warning">Pause</a>\
-        <% } else { %>\
-            <% if (simLineNumber != 0){ %>\
-                <a href="#" id="playStockSim" class=" btn btn-lg btn-halfWidth btn-success">Play</a>\
-                <a href="#" id="resetStockSim" class=" btn btn-lg btn-halfWidth pull-right btn-default">Reset</a><br/>\
+define(['jquery', 'underscore', 'menuParent', 'cam', 'lattice', 'plist'], function($, _, MenuParentView, cam){
+
+    return MenuParentView.extend({
+
+        events: {
+            "click #playStockSim":                                      "_playStockSim",
+            "click #pauseStockSim":                                     "_pauseStockSim",
+            "click #resetStockSim":                                     "_resetStockSim",
+            "click #animationMenuSave":                                 "_save",
+            "click .overrideEdits":                                     "_postProcess",
+            "slideStop #speedSlider":                                   "_changeSpeedSlider"
+        },
+
+        _initialize: function(){
+    
+            _.bindAll(this, "_codeEdit", "_setEditorHeight");
+
+            //bind events
+            this.listenTo(this.model, "change:stockSimulationPlaying", this.render);
+            var self = this;
+            this.listenTo(cam, "change", function(){
+                //ignore simLineNumber for render calls
+                if (_.isEqual(_.keys(cam.changedAttributes()), ["simLineNumber"])) return;
+                self.render();
+            });
+            this.listenTo(cam, "change:simLineNumber", this._drawGcodeHighlighter);
+            $(document).bind('keyup', {state:false}, this._codeEdit);
+            //this.$el.bind('resize', this._setEditorHeight);
+        },
+
+        _save: function(e){
+            e.preventDefault();
+            cam.save();
+        },
+
+        _postProcess: function(e){
+            e.preventDefault();
+            cam.postProcess();
+        },
+
+        _codeEdit: function(e){
+            var editor = $("#gcodeEditor");
+            if (!editor.is(":focus")) return;
+            e.preventDefault();
+            cam.makeProgramEdits(editor.text());
+        },
+
+        _playStockSim: function(e){
+            e.preventDefault();
+            this.model.set("stockSimulationPlaying", true);
+        },
+
+        _pauseStockSim: function(e){
+            e.preventDefault();
+            this.model.set("stockSimulationPlaying", false);
+        },
+
+        _resetStockSim: function(e){
+            e.preventDefault();
+            cam.resetSimulation();
+            this.render();
+        },
+
+        _changeSpeedSlider: function(e){
+            e.preventDefault();
+            cam.set("simSpeed", Math.pow(2,$(e.target)[0].value));
+        },
+
+        _drawGcodeHighlighter: function(){
+            var lineNum = cam.get("simLineNumber");
+            if (lineNum == 0) return;
+            var code = cam.get("dataOut").split("\n");
+            code[lineNum] = "<span id='gcodeHighlighter'>" + code[lineNum] + " </span>";
+            var newText = code.join("\n");
+            var $editor = $('#gcodeEditor');
+            $editor.html(newText);
+            var $highlighter = $("#gcodeHighlighter");
+            if (!$editor.position() || !$highlighter.position()) return;//todo weird bug
+            var highlighterHeight = $highlighter.position().top - $editor.position().top;
+            var desiredHeight = $editor.height()/2;
+            if (highlighterHeight > desiredHeight) $editor.scrollTop($editor.scrollTop()+highlighterHeight-desiredHeight);
+        },
+
+        _setEditorHeight: function(){
+            var $editor = $('#gcodeEditor');
+            var height = this.$el.height()-$editor.position().top-50;
+            height = Math.max(height, 250);
+            $editor.css({height:height +"px"});
+        },
+
+        _makeTemplateJSON: function(){
+            return _.extend(this.model.toJSON(), cam.toJSON());
+        },
+
+        _render: function(){
+            if (cam.get("needsPostProcessing") && !cam.get("editsMadeToProgram")) cam.postProcess();//todo this might need to go first?
+            this._setEditorHeight();
+            this._drawGcodeHighlighter();//in case of code pause
+
+            $('#speedSlider').slider({
+                formatter: function(value) {
+                    return Math.pow(2, value) + "X";
+                }
+            });
+        },
+
+        template: _.template('\
+            <% if (stockSimulationPlaying){ %>\
+            <a href="#" id="pauseStockSim" class=" btn btn-block btn-lg btn-warning">Pause</a>\
             <% } else { %>\
-                <a href="#" id="playStockSim" class=" btn btn-block btn-lg btn-success">Play</a>\
+                <% if (simLineNumber != 0){ %>\
+                    <a href="#" id="playStockSim" class=" btn btn-lg btn-halfWidth btn-success">Play</a>\
+                    <a href="#" id="resetStockSim" class=" btn btn-lg btn-halfWidth pull-right btn-default">Reset</a><br/>\
+                <% } else { %>\
+                    <a href="#" id="playStockSim" class=" btn btn-block btn-lg btn-success">Play</a>\
+                <% } %>\
+            <% } %>\
+            <input id="speedSlider" data-slider-id="speedSlider" type="text" data-slider-min="0" data-slider-max="6" data-slider-step="1" data-slider-value="<%= Math.log2(simSpeed) %>"/>\
+            <br/><a href="#" id="animationMenuSave" class=" btn btn-block btn-lg btn-default">Save</a><br/>\
+            <!--Assembly Time:&nbsp;&nbsp;<br/><br/>-->\
+            <% if (editsMadeToProgram && needsPostProcessing){ %>\
+            <div id="postWarning">You have made the following changes that require post processing:<br/>\
+            This will override edits you have made to the G-code.  OK to override? <a href="#" class="overrideEdits btn btn-block btn-lg btn-danger">OK</a></div>\
             <% } %>\
-        <% } %>\
-        <input id="speedSlider" data-slider-id="speedSlider" type="text" data-slider-min="0" data-slider-max="6" data-slider-step="1" data-slider-value="<%= Math.log2(simSpeed) %>"/>\
-        <br/><a href="#" id="animationMenuSave" class=" btn btn-block btn-lg btn-default">Save</a><br/>\
-        <!--Assembly Time:&nbsp;&nbsp;<br/><br/>-->\
-        <% if (editsMadeToProgram && needsPostProcessing){ %>\
-        <div id="postWarning">You have made the following changes that require post processing:<br/>\
-        This will override edits you have made to the G-code.  OK to override? <a href="#" class="overrideEdits btn btn-block btn-lg btn-danger">OK</a></div>\
-        <% } %>\
-        <div id="gcodeEditor"><%= dataOut %></div><br/>\
-        <a href="#" class="overrideEdits btn btn-block btn-lg btn-default">Undo Changes</a><br/>\
-        ')
+            <div id="gcodeEditor"><%= dataOut %></div><br/>\
+            <a href="#" class="overrideEdits btn btn-block btn-lg btn-default">Undo Changes</a><br/>\
+            ')
 
+    });
 });
diff --git a/js/menus/AssemblerMenuView.js b/js/menus/AssemblerMenuView.js
index f415aab4..4012e6d6 100644
--- a/js/menus/AssemblerMenuView.js
+++ b/js/menus/AssemblerMenuView.js
@@ -2,62 +2,59 @@
  * Created by aghassaei on 2/25/15.
  */
 
-
-AssemblerMenuView = Backbone.View.extend({
-
-    el: "#menuContent",
-
-    events: {
-    },
-
-    initialize: function(){
-
-        _.bindAll(this, "render", "_onKeyup");
-        this.listenTo(globals.cam, "change", this.render);
-        $(document).bind('keyup', {}, this._onKeyup);
-    },
-
-    _onKeyup: function(e){
-        if (this.model.get("currentTab") != "assembler") return;
-        if ($(".placementOrder").is(":focus")) this._updatePlacementOrder(e);
-    },
-
-    _updatePlacementOrder: function(e){
-        e.preventDefault();
-        var newVal = $(e.target).val();
-        if (newVal.length<3) return;//todo this isn't quite right
-        globals.cam.set("placementOrder", newVal);
-//        globals.cam.trigger("change:placementOrder");
-    },
-
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "assembler") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template(_.extend(this.model.toJSON(), globals.cam.toJSON(), globals.lattice.toJSON(), globals.plist)));
-    },
-
-    template: _.template('\
-        Machine: &nbsp;&nbsp;\
-            <div class="btn-group">\
-                <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allMachineTypes[cellType][connectionType][machineName] %><span class="caret"></span></button>\
-                <ul role="menu" class="dropdown-menu">\
-                    <% _.each(_.keys(allMachineTypes[cellType][connectionType]), function(key){ %>\
-                        <li><a class="assembler dropdownSelector" data-property="machineName" data-value="<%= key %>" href="#"><%= allMachineTypes[cellType][connectionType][key] %></a></li>\
-                    <% }); %>\
-                </ul>\
-            </div><br/><br/>\
-        Strategy: &nbsp;&nbsp;\
-            <div class="btn-group">\
-                <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allAssemblyStrategies[camStrategy] %><span class="caret"></span></button>\
-                <ul role="menu" class="dropdown-menu">\
-                    <% _.each(_.keys(allAssemblyStrategies), function(key){ %>\
-                        <li><a class="assembler dropdownSelector" data-property="camStrategy" data-value="<%= key %>" href="#"><%= allAssemblyStrategies[key] %></a></li>\
-                    <% }); %>\
-                </ul>\
-            </div><br/><br/>\
-            <% if (camStrategy == "raster"){ %>\
-        Raster Order: &nbsp;&nbsp;<input value="<%= placementOrder %>" placeholder="Placement Order" class="form-control placementOrder" type="text"><br/><br/>\
-        <% } %>\
-        ')
+define(['jquery', 'underscore', 'menuParent', 'cam', 'lattice', 'plist'], function($, _, MenuParentView, cam, lattice, plist){
+
+    return MenuParentView.extend({
+    
+        events: {
+        },
+    
+        _initialize: function(){
+    
+            _.bindAll(this, "_onKeyup");
+            this.listenTo(cam, "change", this.render);//todo handle this in wrapper
+            $(document).bind('keyup', {}, this._onKeyup);
+        },
+    
+        _onKeyup: function(e){
+            if (this.model.get("currentTab") != "assembler") return;
+            if ($(".placementOrder").is(":focus")) this._updatePlacementOrder(e);
+        },
+    
+        _updatePlacementOrder: function(e){
+            e.preventDefault();
+            var newVal = $(e.target).val();
+            if (newVal.length<3) return;//todo this isn't quite right
+            cam.set("placementOrder", newVal);
+    //        cam.trigger("change:placementOrder");
+        },
+
+        _makeTemplateJSON: function(){
+            return _.extend(this.model.toJSON(), cam.toJSON(), lattice.toJSON(), plist);
+        },
+    
+        template: _.template('\
+            Machine: &nbsp;&nbsp;\
+                <div class="btn-group">\
+                    <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allMachineTypes[cellType][connectionType][machineName] %><span class="caret"></span></button>\
+                    <ul role="menu" class="dropdown-menu">\
+                        <% _.each(_.keys(allMachineTypes[cellType][connectionType]), function(key){ %>\
+                            <li><a class="assembler dropdownSelector" data-property="machineName" data-value="<%= key %>" href="#"><%= allMachineTypes[cellType][connectionType][key] %></a></li>\
+                        <% }); %>\
+                    </ul>\
+                </div><br/><br/>\
+            Strategy: &nbsp;&nbsp;\
+                <div class="btn-group">\
+                    <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allAssemblyStrategies[camStrategy] %><span class="caret"></span></button>\
+                    <ul role="menu" class="dropdown-menu">\
+                        <% _.each(_.keys(allAssemblyStrategies), function(key){ %>\
+                            <li><a class="assembler dropdownSelector" data-property="camStrategy" data-value="<%= key %>" href="#"><%= allAssemblyStrategies[key] %></a></li>\
+                        <% }); %>\
+                    </ul>\
+                </div><br/><br/>\
+                <% if (camStrategy == "raster"){ %>\
+            Raster Order: &nbsp;&nbsp;<input value="<%= placementOrder %>" placeholder="Placement Order" class="form-control placementOrder" type="text"><br/><br/>\
+            <% } %>\
+            ')
+    });
 });
\ No newline at end of file
diff --git a/js/menus/CamMenuView.js b/js/menus/CamMenuView.js
index 2d3ba1ee..7abe47a1 100644
--- a/js/menus/CamMenuView.js
+++ b/js/menus/CamMenuView.js
@@ -2,118 +2,112 @@
  * Created by aghassaei on 1/26/15.
  */
 
+define(['jquery', 'underscore', 'menuParent', 'cam', 'lattice', 'plist'], function($, _, MenuParentView, cam, lattice, plist){
 
-CamMenuView = Backbone.View.extend({
+    return MenuParentView.extend({
 
-    el: "#menuContent",
+        events: {
+            "click #saveCam":                               "_save",
+            "click #manualSelectOrigin":                    "_selectOrigin"
+        },
 
-    events: {
-        "click #saveCam":                               "_save",
-        "click #manualSelectOrigin":                    "_selectOrigin"
-    },
 
+        _initialize: function(){
+            //bind events
+            this.listenTo(cam, "change", this.render);
+            this.listenTo(this.model, "change", this.render);
+            this.listenTo(lattice, "change", this.render);
+        },
 
-    initialize: function(){
+        _selectOrigin: function(e){
+            e.preventDefault();
+            this.model.set("manualSelectOrigin", !this.model.get("manualSelectOrigin"));
+        },
 
-        _.bindAll(this, "render");
-        //bind events
-        this.listenTo(globals.cam, "change", this.render);
-        this.listenTo(this.model, "change", this.render);
-        this.listenTo(globals.lattice, "change", this.render);
-    },
+        _save: function(e){
+            e.preventDefault();
+            cam.save();
+        },
 
-    _selectOrigin: function(e){
-        e.preventDefault();
-        globals.appState.set("manualSelectOrigin", !globals.appState.get("manualSelectOrigin"));
-    },
+        _makeTemplateJSON: function(){
+            var data = _.extend(this.model.toJSON(), cam.toJSON(), lattice.toJSON(), plist);
+            if (cam.get("stockPositionRelative")){
+                var relStockPos = {};
+                relStockPos.x = data.stockPosition.x - data.originPosition.x;
+                relStockPos.y = data.stockPosition.y - data.originPosition.y;
+                relStockPos.z = data.stockPosition.z - data.originPosition.z;
+                data.stockPosition = relStockPos;
+            }
+            if (!cam.get("rapidHeightRelative")){
+                data.rapidHeight = data.rapidHeight + data.originPosition.z;
+            }
+            return data;
+        },
 
-    _save: function(e){
-        e.preventDefault();
-        globals.cam.save();
-    },
-
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "cam") return;
-        if ($("input[type=text]").is(":focus")) return;
-
-        var data = _.extend(this.model.toJSON(), globals.cam.toJSON(), globals.lattice.toJSON(), globals.plist);
-        if (globals.cam.get("stockPositionRelative")){
-            var relStockPos = {};
-            relStockPos.x = data.stockPosition.x - data.originPosition.x;
-            relStockPos.y = data.stockPosition.y - data.originPosition.y;
-            relStockPos.z = data.stockPosition.z - data.originPosition.z;
-            data.stockPosition = relStockPos;
-        }
-        if (!globals.cam.get("rapidHeightRelative")){
-            data.rapidHeight = data.rapidHeight + data.originPosition.z;
-        }
-        this.$el.html(this.template(data));
-    },
-
-    template: _.template('\
-        CAM output: &nbsp;&nbsp;\
-            <div class="btn-group">\
-                <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allCamProcesses[machineName][camProcess] %><span class="caret"></span></button>\
-                <ul role="menu" class="dropdown-menu">\
-                    <% _.each(_.keys(allCamProcesses[machineName]), function(key){ %>\
-                        <li><a class="assembler dropdownSelector" data-property="camProcess" data-value="<%= key %>" href="#"><%= allCamProcesses[machineName][key] %></a></li>\
-                    <% }); %>\
-                </ul>\
-            </div><br/><br/>\
-         <a href="#" id="saveCam" class=" btn btn-block btn-lg btn-default">Process and Save</a><br/>\
-         Units: &nbsp;&nbsp;\
-            <div class="btn-group">\
-                <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allUnitTypes[units] %><span class="caret"></span></button>\
-                <ul role="menu" class="dropdown-menu">\
-                    <% _.each(_.keys(allUnitTypes), function(key){ %>\
-                        <li><a class="lattice dropdownSelector" data-property="units" data-value="<%= key %>" href="#"><%= allUnitTypes[key] %></a></li>\
-                    <% }); %>\
-                </ul>\
-            </div><br/><br/>\
-            Origin (xyz): &nbsp;&nbsp;<input data-property="originPosition" data-key="x" value="<%= originPosition.x %>" placeholder="X" class="form-control floatInput assembler" type="text">\
-            &nbsp;<input data-property="originPosition" data-key="y" value="<%= originPosition.y %>" placeholder="Y" class="form-control floatInput assembler" type="text">\
-            &nbsp;<input data-property="originPosition" data-key="z" value="<%= originPosition.z %>" placeholder="Z" class="form-control floatInput assembler" type="text">\
-            <% if (!(machineName == "handOfGod")){ %>\
-            <br/><a id="manualSelectOrigin" class=" btn btn-lg btn-default btn-imageCustom<% if (manualSelectOrigin){ %> btn-selected<% } %>"><img src="assets/imgs/cursor.png"></a>\
-            <label>&nbsp;&nbsp;&nbsp;Manually select origin from existing cell</label><br/><br/>\
-            <% if (!assembler.stockAttachedToEndEffector){ %>\
-            Stock (xyz): &nbsp;&nbsp;<input data-property="stockPosition" data-key="x" value="<%= stockPosition.x %>" placeholder="X" class="form-control floatInput assembler" type="text">\
-            &nbsp;<input data-property="stockPosition" data-key="y" value="<%= stockPosition.y %>" placeholder="Y" class="form-control floatInput assembler" type="text">\
-            &nbsp;<input data-property="stockPosition" data-key="z" value="<%= stockPosition.z %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/>\
-            <label class="checkbox" for="stockPosRel">\
-            <input id="stockPosRel" data-property="stockPositionRelative" type="checkbox" <% if (stockPositionRelative){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
-            <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
-            Stock position relative to Origin</label>\
-            <label class="checkbox" for="stockFixed">\
-            <input id="stockFixed" data-property="stockFixed" type="checkbox" <% if (stockFixed){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
-            <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
-            Fix stock relative to to Origin</label>\
-            <label class="checkbox" for="multipleStockPositions">\
-            <input id="multipleStockPositions" data-property="multipleStockPositions" type="checkbox" <% if (multipleStockPositions){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
-            <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
-            Multiple stock positions</label>\
-            <% if (multipleStockPositions){ %>\
-                Stock dimensions (xy): &nbsp;&nbsp;<input data-property="stockArraySize" data-key="x" value="<%= stockArraySize.x %>" placeholder="X" class="form-control intInput assembler" type="text">\
-                &nbsp;<input data-property="stockArraySize" data-key="y" value="<%= stockArraySize.y %>" placeholder="Y" class="form-control intInput assembler" type="text"><br/><br/>\
-                Stock separation: &nbsp;&nbsp;<input data-property="stockSeparation" value="<%= stockSeparation %>" placeholder="X" class="form-control floatInput assembler" type="text"><br/><br/>\
-            <% } %>\
-            <% } %>\
-            Clearance Height: &nbsp;&nbsp;<input data-property="rapidHeight" value="<%= rapidHeight %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/>\
-            <label class="checkbox" for="rapidPosRel">\
-            <input id="rapidPosRel" data-property="rapidHeightRelative" type="checkbox" <% if (rapidHeightRelative){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
-            <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
-            Clearance height relative to Origin</label>\
-            <% } else { %>\
-            <br/><br/>Stock Height: &nbsp;&nbsp;<input data-property="stockPosition" data-key="z" value="<%= stockPosition.z %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/><br/>\
-            <% } %>\
-            Approach Height: &nbsp;&nbsp;<input data-property="safeHeight" value="<%= safeHeight %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/><br/>\
-            Speeds (measured in <%= units %> per second):<br/><br/>\
-            Rapids (xy, z): &nbsp;&nbsp;<input data-property="rapidSpeeds" data-key="xy" value="<%= rapidSpeeds.xy %>" placeholder="XY" class="form-control floatInput assembler" type="text">\
-            &nbsp;<input data-property="rapidSpeeds" data-key="z" value="<%= rapidSpeeds.z %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/><br/>\
-            Feed Rate (xy, z): &nbsp;&nbsp;<input data-property="feedRate" data-key="xy" value="<%= feedRate.xy %>" placeholder="XY" class="form-control floatInput assembler" type="text">\
-            &nbsp;<input data-property="feedRate" data-key="z" value="<%= feedRate.z %>" placeholder="Z" class="form-control floatInput assembler" type="text">\
-        ')
+        template: _.template('\
+            CAM output: &nbsp;&nbsp;\
+                <div class="btn-group">\
+                    <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allCamProcesses[machineName][camProcess] %><span class="caret"></span></button>\
+                    <ul role="menu" class="dropdown-menu">\
+                        <% _.each(_.keys(allCamProcesses[machineName]), function(key){ %>\
+                            <li><a class="assembler dropdownSelector" data-property="camProcess" data-value="<%= key %>" href="#"><%= allCamProcesses[machineName][key] %></a></li>\
+                        <% }); %>\
+                    </ul>\
+                </div><br/><br/>\
+             <a href="#" id="saveCam" class=" btn btn-block btn-lg btn-default">Process and Save</a><br/>\
+             Units: &nbsp;&nbsp;\
+                <div class="btn-group">\
+                    <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allUnitTypes[units] %><span class="caret"></span></button>\
+                    <ul role="menu" class="dropdown-menu">\
+                        <% _.each(_.keys(allUnitTypes), function(key){ %>\
+                            <li><a class="lattice dropdownSelector" data-property="units" data-value="<%= key %>" href="#"><%= allUnitTypes[key] %></a></li>\
+                        <% }); %>\
+                    </ul>\
+                </div><br/><br/>\
+                Origin (xyz): &nbsp;&nbsp;<input data-property="originPosition" data-key="x" value="<%= originPosition.x %>" placeholder="X" class="form-control floatInput assembler" type="text">\
+                &nbsp;<input data-property="originPosition" data-key="y" value="<%= originPosition.y %>" placeholder="Y" class="form-control floatInput assembler" type="text">\
+                &nbsp;<input data-property="originPosition" data-key="z" value="<%= originPosition.z %>" placeholder="Z" class="form-control floatInput assembler" type="text">\
+                <% if (!(machineName == "handOfGod")){ %>\
+                <br/><a id="manualSelectOrigin" class=" btn btn-lg btn-default btn-imageCustom<% if (manualSelectOrigin){ %> btn-selected<% } %>"><img src="assets/imgs/cursor.png"></a>\
+                <label>&nbsp;&nbsp;&nbsp;Manually select origin from existing cell</label><br/><br/>\
+                <% if (!assembler.stockAttachedToEndEffector){ %>\
+                Stock (xyz): &nbsp;&nbsp;<input data-property="stockPosition" data-key="x" value="<%= stockPosition.x %>" placeholder="X" class="form-control floatInput assembler" type="text">\
+                &nbsp;<input data-property="stockPosition" data-key="y" value="<%= stockPosition.y %>" placeholder="Y" class="form-control floatInput assembler" type="text">\
+                &nbsp;<input data-property="stockPosition" data-key="z" value="<%= stockPosition.z %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/>\
+                <label class="checkbox" for="stockPosRel">\
+                <input id="stockPosRel" data-property="stockPositionRelative" type="checkbox" <% if (stockPositionRelative){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
+                <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
+                Stock position relative to Origin</label>\
+                <label class="checkbox" for="stockFixed">\
+                <input id="stockFixed" data-property="stockFixed" type="checkbox" <% if (stockFixed){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
+                <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
+                Fix stock relative to to Origin</label>\
+                <label class="checkbox" for="multipleStockPositions">\
+                <input id="multipleStockPositions" data-property="multipleStockPositions" type="checkbox" <% if (multipleStockPositions){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
+                <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
+                Multiple stock positions</label>\
+                <% if (multipleStockPositions){ %>\
+                    Stock dimensions (xy): &nbsp;&nbsp;<input data-property="stockArraySize" data-key="x" value="<%= stockArraySize.x %>" placeholder="X" class="form-control intInput assembler" type="text">\
+                    &nbsp;<input data-property="stockArraySize" data-key="y" value="<%= stockArraySize.y %>" placeholder="Y" class="form-control intInput assembler" type="text"><br/><br/>\
+                    Stock separation: &nbsp;&nbsp;<input data-property="stockSeparation" value="<%= stockSeparation %>" placeholder="X" class="form-control floatInput assembler" type="text"><br/><br/>\
+                <% } %>\
+                <% } %>\
+                Clearance Height: &nbsp;&nbsp;<input data-property="rapidHeight" value="<%= rapidHeight %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/>\
+                <label class="checkbox" for="rapidPosRel">\
+                <input id="rapidPosRel" data-property="rapidHeightRelative" type="checkbox" <% if (rapidHeightRelative){ %> checked="checked"<% } %> value="" data-toggle="checkbox" class="assembler custom-checkbox">\
+                <span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
+                Clearance height relative to Origin</label>\
+                <% } else { %>\
+                <br/><br/>Stock Height: &nbsp;&nbsp;<input data-property="stockPosition" data-key="z" value="<%= stockPosition.z %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/><br/>\
+                <% } %>\
+                Approach Height: &nbsp;&nbsp;<input data-property="safeHeight" value="<%= safeHeight %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/><br/>\
+                Speeds (measured in <%= units %> per second):<br/><br/>\
+                Rapids (xy, z): &nbsp;&nbsp;<input data-property="rapidSpeeds" data-key="xy" value="<%= rapidSpeeds.xy %>" placeholder="XY" class="form-control floatInput assembler" type="text">\
+                &nbsp;<input data-property="rapidSpeeds" data-key="z" value="<%= rapidSpeeds.z %>" placeholder="Z" class="form-control floatInput assembler" type="text"><br/><br/>\
+                Feed Rate (xy, z): &nbsp;&nbsp;<input data-property="feedRate" data-key="xy" value="<%= feedRate.xy %>" placeholder="XY" class="form-control floatInput assembler" type="text">\
+                &nbsp;<input data-property="feedRate" data-key="z" value="<%= feedRate.z %>" placeholder="Z" class="form-control floatInput assembler" type="text">\
+            ')
+    });
 });
 
 
diff --git a/js/menus/ImportMenuView.js b/js/menus/ImportMenuView.js
index cd0a6ef5..e6ddbdab 100644
--- a/js/menus/ImportMenuView.js
+++ b/js/menus/ImportMenuView.js
@@ -2,113 +2,110 @@
  * Created by aghassaei on 1/26/15.
  */
 
-
-ImportMenuView = Backbone.View.extend({
-
-    el: "#menuContent",
-
-    events: {
-        "change #importMenuUploadSTL":      "_uploadSTL",
-        "click .importMenuSelectMesh":      "_selectMesh",
-        "click #importMenuSelectWall":      "_buildWall",
-        "fileselect .btn-file :file":       "_readDataURL",
-        "click #removeFillGeo":             "_removeMesh",
-
-        "click #doSubtractGeo":             "_subtractGeo",
-        "click #doFillGeo":                 "_fillGeo"
-    },
-
-    initialize: function(){
-
-        this.fillGeometry = new FillGeometry();
-        this.listenTo(this.fillGeometry, "change", this.render);
-    },
-
-    _uploadSTL: function(e){//select a mesh to upload
-        e.preventDefault();
-        var input = $(e.target),
-        numFiles = input.get(0).files ? input.get(0).files.length : 1,
-        label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
-        input.trigger('fileselect', [numFiles, label, input.get(0).files]);
-        input.val("");
-    },
-
-    _selectMesh: function(e){//select mesh from dropdown list
-        e.preventDefault();
-        var filename = $(e.target).data("file");
-        this._loadMeshFromURL('assets/stls/' + filename, filename.split('/')[1]);
-    },
-
-    _buildWall: function(e){
-        e.preventDefault();
-        globals.lattice.addCellsInRange({min:{x:-5,y:-5,z:0}, max:{x:5,y:5,z:3}});
-    },
-
-    _readDataURL: function(event, numFiles, filename, files){
-        if (files.length>1) console.warn("too many files selected");
-        var reader = new FileReader();
-        reader.readAsDataURL(files[0]);
-        var self = this;
-        reader.onload = (function() {
-        return function(e) {
-            self._loadMeshFromURL(e.target.result, filename);
-        }
-        })();
-    },
-
-    _loadMeshFromURL: function(url, filename){
-        var self = this;
-        var loader = new THREE.STLLoader();
-  	    loader.load(url, function(geometry){
-            self.fillGeometry.buildNewMesh(geometry);
-            self.fillGeometry.set("filename", filename);
-        });
-    },
-
-    _subtractGeo: function(e){
-        e.preventDefault();
-        this.fillGeometry.subtractGeo();
-    },
-
-    _fillGeo: function(e){
-        e.preventDefault();
-        this.fillGeometry.fillGeo();
-    },
-
-    _removeMesh: function(e){
-        e.preventDefault();
-        this.fillGeometry.removeMesh();
-    },
-
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "import") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template(_.extend(this.model.toJSON(), this.fillGeometry.toJSON())));
-    },
-
-    template: _.template('\
-        Filename: &nbsp;&nbsp;<%= filename %><br/><br/>\
-        <% if (mesh){ %>\
-        Scale:<br/><br/>\
-        <a href="#" id="doFillGeo" class=" btn btn-block btn-lg btn-default">Fill Mesh</a><br/>\
-        <a href="#" id="removeFillGeo" class=" btn btn-block btn-lg btn-default">Remove Mesh</a><br/>\
-        <hr>\
-        <% } %>\
-        <a href="#" class=" btn btn-block btn-lg btn-danger clearCells">Clear All Cells</a><br/><br/>\
-        <br/><span class="btn btn-default btn-lg btn-file fullWidth">\
-            Upload STL<input id="importMenuUploadSTL" type="file">\
-       </span><br/>\
-       <div class="text-center">OR</div>\
-        <div class="btn-group fullWidth">\
-            <button data-toggle="dropdown" class="btn btn-lg btn-default dropdown-toggle fullWidth" type="button">Select Model <span class="caret"></span></button>\
-            <ul role="menu" class="dropdown-menu">\
-              <li><a class="importMenuSelectMesh" data-file="meshes-airbus/wingCrossSection.stl" href="#">Wing</a></li>\
-              <li><a id="importMenuSelectWall" href="#">Block</a></li>\
-            </ul>\
-        </div><!-- /btn-group -->\
-        ')
-
+define(['jquery', 'underscore', 'menuParent', 'lattice'], function($, _, MenuParentView, lattice){
+
+    return MenuParentView.extend({
+
+        events: {
+            "change #importMenuUploadSTL":      "_uploadSTL",
+            "click .importMenuSelectMesh":      "_selectMesh",
+            "click #importMenuSelectWall":      "_buildWall",
+            "fileselect .btn-file :file":       "_readDataURL",
+            "click #removeFillGeo":             "_removeMesh",
+
+            "click #doSubtractGeo":             "_subtractGeo",
+            "click #doFillGeo":                 "_fillGeo"
+        },
+
+        _initialize: function(){
+
+            this.fillGeometry = new FillGeometry();
+            this.listenTo(this.fillGeometry, "change", this.render);
+        },
+
+        _uploadSTL: function(e){//select a mesh to upload
+            e.preventDefault();
+            var input = $(e.target),
+            numFiles = input.get(0).files ? input.get(0).files.length : 1,
+            label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
+            input.trigger('fileselect', [numFiles, label, input.get(0).files]);
+            input.val("");
+        },
+
+        _selectMesh: function(e){//select mesh from dropdown list
+            e.preventDefault();
+            var filename = $(e.target).data("file");
+            this._loadMeshFromURL('assets/stls/' + filename, filename.split('/')[1]);
+        },
+
+        _buildWall: function(e){
+            e.preventDefault();
+            lattice.addCellsInRange({min:{x:-5,y:-5,z:0}, max:{x:5,y:5,z:3}});
+        },
+
+        _readDataURL: function(event, numFiles, filename, files){
+            if (files.length>1) console.warn("too many files selected");
+            var reader = new FileReader();
+            reader.readAsDataURL(files[0]);
+            var self = this;
+            reader.onload = (function() {
+            return function(e) {
+                self._loadMeshFromURL(e.target.result, filename);
+            }
+            })();
+        },
+
+        _loadMeshFromURL: function(url, filename){
+            var self = this;
+            var loader = new THREE.STLLoader();
+            loader.load(url, function(geometry){
+                self.fillGeometry.buildNewMesh(geometry);
+                self.fillGeometry.set("filename", filename);
+            });
+        },
+
+        _subtractGeo: function(e){
+            e.preventDefault();
+            this.fillGeometry.subtractGeo();
+        },
+
+        _fillGeo: function(e){
+            e.preventDefault();
+            this.fillGeometry.fillGeo();
+        },
+
+        _removeMesh: function(e){
+            e.preventDefault();
+            this.fillGeometry.removeMesh();
+        },
+
+        _makeTemplateJSON: function(){
+            return _.extend(this.model.toJSON(), this.fillGeometry.toJSON());
+        },
+
+        template: _.template('\
+            Filename: &nbsp;&nbsp;<%= filename %><br/><br/>\
+            <% if (mesh){ %>\
+            Scale:<br/><br/>\
+            <a href="#" id="doFillGeo" class=" btn btn-block btn-lg btn-default">Fill Mesh</a><br/>\
+            <a href="#" id="removeFillGeo" class=" btn btn-block btn-lg btn-default">Remove Mesh</a><br/>\
+            <hr>\
+            <% } %>\
+            <a href="#" class=" btn btn-block btn-lg btn-danger clearCells">Clear All Cells</a><br/><br/>\
+            <br/><span class="btn btn-default btn-lg btn-file fullWidth">\
+                Upload STL<input id="importMenuUploadSTL" type="file">\
+           </span><br/>\
+           <div class="text-center">OR</div>\
+            <div class="btn-group fullWidth">\
+                <button data-toggle="dropdown" class="btn btn-lg btn-default dropdown-toggle fullWidth" type="button">Select Model <span class="caret"></span></button>\
+                <ul role="menu" class="dropdown-menu">\
+                  <li><a class="importMenuSelectMesh" data-file="meshes-airbus/wingCrossSection.stl" href="#">Wing</a></li>\
+                  <li><a id="importMenuSelectWall" href="#">Block</a></li>\
+                </ul>\
+            </div><!-- /btn-group -->\
+            ')
+
+    });
 });
 
 //<a href="#" id="doSubtractGeo" class=" btn btn-block btn-lg btn-default">Subtract Mesh</a><br/>\
diff --git a/js/menus/LatticeMenuView.js b/js/menus/LatticeMenuView.js
index b9847bd2..15dfc667 100644
--- a/js/menus/LatticeMenuView.js
+++ b/js/menus/LatticeMenuView.js
@@ -10,18 +10,12 @@ define(['jquery', 'underscore', 'menuParent', 'lattice', 'plist'], function($, _
         },
 
 
-        initialize: function(){
-
-            _.bindAll(this, "render");
-            //bind events
+        _initialize: function(){
             this.listenTo(lattice, "change", this.render);
         },
 
-        render: function(){
-            if (this.model.changedAttributes()["currentNav"]) return;
-            if (this.model.get("currentTab") != "lattice") return;
-            if ($("input[type=text]").is(":focus")) return;
-            this.$el.html(this.template(_.extend(lattice.toJSON(), plist)));
+        _makeTemplateJSON: function(){
+            return _.extend(lattice.toJSON(), plist);
         },
 
         template: _.template('\
diff --git a/js/menus/MaterialMenuView.js b/js/menus/MaterialMenuView.js
index 7aa9d575..cdde55db 100644
--- a/js/menus/MaterialMenuView.js
+++ b/js/menus/MaterialMenuView.js
@@ -2,29 +2,25 @@
  * Created by aghassaei on 2/25/15.
  */
 
-MaterialMenuView = Backbone.View.extend({
+define(['jquery', 'underscore', 'menuParent'], function($, _, MenuParentView){
 
-    el: "#menuContent",
+    return MenuParentView.extend({
 
-    events: {
-    },
+        events: {
+        },
 
-    initialize: function(options){
+        _initialize: function(){
+        },
 
-        _.bindAll(this, "render");
-    },
+        _makeTemplateJSON: function(){
+            return null;
+        },
 
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "material") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template());
-    },
-
-    template: _.template('\
-        create materials and assign them to parts in the model\
-        <br/><br/>\
-        stiffness, elastic modulus\
-        ')
+        template: _.template('\
+            create materials and assign them to parts in the model\
+            <br/><br/>\
+            stiffness, elastic modulus\
+            ')
 
+    });
 });
\ No newline at end of file
diff --git a/js/menus/MenuParentView.js b/js/menus/MenuParentView.js
index 8d1a8712..f1630273 100644
--- a/js/menus/MenuParentView.js
+++ b/js/menus/MenuParentView.js
@@ -9,8 +9,26 @@ define(['backbone'], function(Backbone){
 
         el: "#menuContent",
 
-        destroy: function(){
+        initialize: function(){
+
+            _.bindAll(this, "render");
+
+            if (this._initialize) this._initialize();//call subclass
+        },
 
+        render: function(){
+            if (this.model.changedAttributes()["currentNav"]) return;
+            if ($("input[type=text]").is(":focus")) return;
+            this.$el.html(this.template(this._makeTemplateJSON()));
+            if (this._render) this._render();
+        },
+
+        destroy: function(){
+            this.stopListening();
+//            this.undelegateEvents();
+//            this.$el.removeData().unbind();
+//            this.remove();
+//            Backbone.View.prototype.remove.call(this);
         }
 
     });
diff --git a/js/menus/OptimizationMenuView.js b/js/menus/OptimizationMenuView.js
index def00e5e..7f5ab795 100644
--- a/js/menus/OptimizationMenuView.js
+++ b/js/menus/OptimizationMenuView.js
@@ -2,27 +2,22 @@
  * Created by aghassaei on 2/25/15.
  */
 
-OptimizationMenuView = Backbone.View.extend({
+define(['jquery', 'underscore', 'menuParent'], function($, _, MenuParentView){
 
-    el: "#menuContent",
+    return MenuParentView.extend({
 
-    events: {
-    },
+        events: {
+        },
 
-    initialize: function(options){
+        _initialize: function(){
+        },
 
-        _.bindAll(this, "render");
-    },
-
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "optimize") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template());
-    },
-
-    template: _.template('\
-        input stiffness requirements of structure\
-        ')
+        _makeTemplateJSON: function(){
+            return null;
+        },
 
+        template: _.template('\
+            input stiffness requirements of structure\
+            ')
+    });
 });
\ No newline at end of file
diff --git a/js/menus/PartMenuView.js b/js/menus/PartMenuView.js
index bfe19836..66d83a08 100644
--- a/js/menus/PartMenuView.js
+++ b/js/menus/PartMenuView.js
@@ -4,27 +4,19 @@
 
 define(['jquery', 'underscore', 'menuParent', 'lattice', 'plist'], function($, _, MenuParentView, lattice, plist){
 
-    return MenuParentView({
-
-        el: "#menuContent",
+    return MenuParentView.extend({
 
         events: {
         },
 
-        initialize: function(){
-
-            _.bindAll(this, "render");
-
+        _initialize: function(){
             //bind events
             this.listenTo(lattice, "change", this.render);
             this.listenTo(this.model, "change", this.render);
         },
 
-        render: function(){
-            if (this.model.changedAttributes()["currentNav"]) return;
-            if (this.model.get("currentTab") != "part") return;
-            if ($("input[type=text]").is(":focus")) return;
-            this.$el.html(this.template(_.extend(lattice.toJSON(), this.model.toJSON(), plist)));
+        _makeTemplateJSON: function(){
+            return _.extend(lattice.toJSON(), this.model.toJSON(), plist);
         },
 
         template: _.template('\
diff --git a/js/menus/PhysicsMenuView.js b/js/menus/PhysicsMenuView.js
index 9db79389..c88c361d 100644
--- a/js/menus/PhysicsMenuView.js
+++ b/js/menus/PhysicsMenuView.js
@@ -2,31 +2,27 @@
  * Created by aghassaei on 2/25/15.
  */
 
-PhysicsMenuView = Backbone.View.extend({
+define(['jquery', 'underscore', 'menuParent'], function($, _, MenuParentView){
 
-    el: "#menuContent",
+    return MenuParentView.extend({
 
-    events: {
-    },
+        events: {
+        },
 
-    initialize: function(options){
+        _initialize: function(){
+        },
 
-        _.bindAll(this, "render");
-    },
+        _makeTemplateJSON: function(){
+            return null;
+        },
 
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "physics") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template());
-    },
-
-    template: _.template('\
-        world physics: gravity, global forces\
-        <br/><br/>\
-        part connection stiffness\
-        <br/><br/>\
-        ground/fixed/boundary conditions definition\
-        ')
+        template: _.template('\
+            world physics: gravity, global forces\
+            <br/><br/>\
+            part connection stiffness\
+            <br/><br/>\
+            ground/fixed/boundary conditions definition\
+            ')
 
+    });
 });
\ No newline at end of file
diff --git a/js/menus/ScriptMenuView.js b/js/menus/ScriptMenuView.js
index 71ac975e..bc2e872d 100644
--- a/js/menus/ScriptMenuView.js
+++ b/js/menus/ScriptMenuView.js
@@ -2,35 +2,31 @@
  * Created by aghassaei on 1/26/15.
  */
 
-ScriptMenuView = Backbone.View.extend({
+define(['jquery', 'underscore', 'menuParent', 'plist'], function($, _, MenuParentView, plist){
 
-    el: "#menuContent",
+    return MenuParentView.extend({
 
-    events: {
-    },
+        events: {
+        },
 
-    initialize: function(){
+        _initialize: function(){
+        },
 
-        _.bindAll(this, "render");
-    },
+        _makeTemplateJSON: function(){
+            return plist;
+        },
 
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "script") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template(globals.plist));
-    },
-
-    template: _.template('\
-        <div class="btn-group fullWidth">\
-            <button data-toggle="dropdown" class="btn btn-default btn-lg dropdown-toggle fullWidth" type="button">Load Script<span class="caret"></span></button>\
-            <ul role="menu" class="dropdown-menu">\
-                <% _.each(_.keys(allScripts), function(key){ %>\
-                    <li><a data-type="<%= key %>" href="#"><%= allScripts[key] %></a></li>\
-                <% }); %>\
-            </ul>\
-        </div><br/><br/><!-- /btn-group -->\
-        <a href="#" class="clearCells btn btn-block btn-lg btn-danger">Clear All Cells</a><br/>\
-        ')
+        template: _.template('\
+            <div class="btn-group fullWidth">\
+                <button data-toggle="dropdown" class="btn btn-default btn-lg dropdown-toggle fullWidth" type="button">Load Script<span class="caret"></span></button>\
+                <ul role="menu" class="dropdown-menu">\
+                    <% _.each(_.keys(allScripts), function(key){ %>\
+                        <li><a data-type="<%= key %>" href="#"><%= allScripts[key] %></a></li>\
+                    <% }); %>\
+                </ul>\
+            </div><br/><br/><!-- /btn-group -->\
+            <a href="#" class="clearCells btn btn-block btn-lg btn-danger">Clear All Cells</a><br/>\
+            ')
 
+    });
 });
\ No newline at end of file
diff --git a/js/menus/SendMenuView.js b/js/menus/SendMenuView.js
index 73d0c21d..b8ace078 100644
--- a/js/menus/SendMenuView.js
+++ b/js/menus/SendMenuView.js
@@ -2,28 +2,23 @@
  * Created by aghassaei on 3/11/15.
  */
 
-SendMenuView = Backbone.View.extend({
+define(['jquery', 'underscore', 'menuParent', 'cam', 'lattice', 'plist'], function($, _, MenuParentView, cam, lattice, plist){
 
-    el: "#menuContent",
+    return MenuParentView.extend({
 
-    events: {
-    },
+        events: {
+        },
 
-    initialize: function(){
+        _initialize: function(){
+            //bind events
+        },
 
-        //bind events
+        _makeTemplateJSON: function(){
+            return null;
+        },
 
-        _.bindAll(this, "render");
-    },
 
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "send") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template(this.model.toJSON()));
-    },
-
-
-    template: _.template('realtime communication with machine')
+        template: _.template('realtime communication with machine')
 
+    });
 });
\ No newline at end of file
diff --git a/js/menus/SketchMenuView.js b/js/menus/SketchMenuView.js
index c8fbeb89..b0d2d754 100644
--- a/js/menus/SketchMenuView.js
+++ b/js/menus/SketchMenuView.js
@@ -2,42 +2,39 @@
  * Created by aghassaei on 1/26/15.
  */
 
+define(['jquery', 'underscore', 'menuParent'], function($, _, MenuParentView){
 
-SketchMenuView = Backbone.View.extend({
+    return MenuParentView.extend({
 
-    el: "#menuContent",
+        events: {
+            "slide #zHeightSlider":                           "_moveSketchPlane"
+        },
 
-    events: {
-        "slide #zHeightSlider":                           "_moveSketchPlane"
-    },
+        _initialize: function(){
 
-    initialize: function(){
+        },
 
-        _.bindAll(this, "render");
+        _moveSketchPlane: function(e){
+            globals.basePlane.set("zIndex", $(e.target).val());
+        },
 
-    },
+        _makeTemplateJSON: function(){
+            return globals.basePlane.toJSON();
+        },
 
-    _moveSketchPlane: function(e){
-        globals.basePlane.set("zIndex", $(e.target).val());
-    },
+        _render: function(){
+            $('#zHeightSlider').slider({
+                formatter: function(value) {
+                    return value;
+                }
+            });
+        },
 
-    render: function(){
-        if (this.model.changedAttributes()["currentNav"]) return;
-        if (this.model.get("currentTab") != "sketch") return;
-        if ($("input[type=text]").is(":focus")) return;
-        this.$el.html(this.template(globals.basePlane.toJSON()));
-
-        $('#zHeightSlider').slider({
-            formatter: function(value) {
-                return value;
-            }
-        });
-    },
-
-    template: _.template('\
-        Sketch Plane Height:&nbsp;&nbsp;<input id="zHeightSlider" data-slider-id="ex1Slider" type="text" data-slider-min="0" data-slider-max="20" data-slider-step="1" data-slider-value="<%= zIndex %>"/>\
-        <br/><br/>\
-        todo: Sketch and extrude/cut commands\
-        ')
+        template: _.template('\
+            Sketch Plane Height:&nbsp;&nbsp;<input id="zHeightSlider" data-slider-id="ex1Slider" type="text" data-slider-min="0" data-slider-max="20" data-slider-step="1" data-slider-value="<%= zIndex %>"/>\
+            <br/><br/>\
+            todo: Sketch and extrude/cut commands\
+            ')
 
+    });
 });
\ No newline at end of file
-- 
GitLab