diff --git a/src/octoprint/printer/__init__.py b/src/octoprint/printer/__init__.py index a6f60373..8c93e66b 100644 --- a/src/octoprint/printer/__init__.py +++ b/src/octoprint/printer/__init__.py @@ -652,7 +652,7 @@ class Printer(): def getCurrentConnection(self): if self._comm is None: - return "Closed", None, None + return "Closed", None, None, None port, baudrate = self._comm.getConnection() printer_profile = self._printerProfileManager.get_current_or_default() diff --git a/src/octoprint/static/js/app/viewmodels/appearance.js b/src/octoprint/static/js/app/viewmodels/appearance.js index 5ee2b5dc..3bf4614e 100644 --- a/src/octoprint/static/js/app/viewmodels/appearance.js +++ b/src/octoprint/static/js/app/viewmodels/appearance.js @@ -1,20 +1,26 @@ function AppearanceViewModel(settingsViewModel) { var self = this; - self.name = settingsViewModel.appearance_name; - self.color = settingsViewModel.appearance_color; + self.settings = settingsViewModel; self.brand = ko.computed(function() { - if (self.name()) - return gettext("OctoPrint") + ": " + self.name(); + if (self.settings.printerProfiles.currentProfileData().name()) + return gettext("OctoPrint") + ": " + self.settings.printerProfiles.currentProfileData().name(); else return gettext("OctoPrint"); }); self.title = ko.computed(function() { - if (self.name()) - return self.name() + " [" + gettext("OctoPrint") + "]"; + if (self.settings.printerProfiles.currentProfileData().name()) + return self.settings.printerProfiles.currentProfileData().name() + " [" + gettext("OctoPrint") + "]"; else return gettext("OctoPrint"); }); + + self.color = ko.computed(function() { + if (self.settings.printerProfiles.currentProfileData().color()) + return self.settings.printerProfiles.currentProfileData().color(); + else + return "default"; + }); } diff --git a/src/octoprint/static/js/app/viewmodels/connection.js b/src/octoprint/static/js/app/viewmodels/connection.js index c6fee40a..99252162 100644 --- a/src/octoprint/static/js/app/viewmodels/connection.js +++ b/src/octoprint/static/js/app/viewmodels/connection.js @@ -114,7 +114,8 @@ function ConnectionViewModel(loginStateViewModel, settingsViewModel) { contentType: "application/json; charset=UTF-8", data: JSON.stringify(data), success: function(response) { - self.settings.requestData() + self.settings.requestData(); + self.settings.printerProfiles.requestData(); } }); } else { diff --git a/src/octoprint/static/js/app/viewmodels/gcode.js b/src/octoprint/static/js/app/viewmodels/gcode.js index 5c882465..4cb58aaa 100644 --- a/src/octoprint/static/js/app/viewmodels/gcode.js +++ b/src/octoprint/static/js/app/viewmodels/gcode.js @@ -95,27 +95,46 @@ function GcodeViewModel(loginStateViewModel, settingsViewModel) { self.reader_hideEmptyLayers.subscribe(self.synchronizeOptions); // subscribe to relevant printer settings... - self.settings.printer_extruderOffsets.subscribe(function() { - if (!self.enabled) return; - if (!self.settings.printer_extruderOffsets()) return; - - GCODE.ui.updateOptions({ - reader: { - toolOffsets: self.settings.printer_extruderOffsets() - } - }); - }); - self.settings.printer_bedDimensions.subscribe(function() { + self.settings.printerProfiles.currentProfileData.subscribe(function() { if (!self.enabled) return; - var bedDimensions = self.settings.printer_bedDimensions(); - if (!bedDimensions || (!bedDimensions.hasOwnProperty("x") && !bedDimensions.hasOwnProperty("y") && !bedDimensions.hasOwnProperty("r"))) return; + var currentProfileData = self.settings.printerProfiles.currentProfileData(); + if (!currentProfileData) return; - GCODE.ui.updateOptions({ - renderer: { - bed: bedDimensions + if (currentProfileData.extruder() && currentProfileData.extruder().extruderOffsets()) { + GCODE.ui.updateOptions({ + reader: { + toolOffsets: self.settings.printer_extruderOffsets() + } + }); + }; + + if (currentProfileData.volume() && currentProfileData.volume().width() && currentProfileData.volume().depth()) { + GCODE.ui.updateOptions({ + renderer: { + bed: bedDimensions + } + }); + }; + + if (currentProfileData.axes()) { + var invertX = false, invertY = false; + if (currentProfileData.axes().x()) { + invertX = currentProfileData.axes().x().inverted(); } - }); + if (currentProfileData.axes().y()) { + invertY = currentProfileData.axes().y().inverted(); + } + + GCODE.ui.updateOptions({ + renderer: { + invertAxes: { + x: invertX, + y: invertY + } + } + }); + } }); self.settings.printer_invertAxes.subscribe(function() { if (!self.enabled) return; diff --git a/src/octoprint/static/js/app/viewmodels/printerprofiles.js b/src/octoprint/static/js/app/viewmodels/printerprofiles.js index ddedefd8..a80d88fc 100644 --- a/src/octoprint/static/js/app/viewmodels/printerprofiles.js +++ b/src/octoprint/static/js/app/viewmodels/printerprofiles.js @@ -1,6 +1,34 @@ function PrinterProfilesViewModel() { var self = this; + self._cleanProfile = function() { + return { + id: "", + name: "", + model: "", + color: "default", + volume: { + formFactor: "rectangular", + width: 200, + depth: 200, + height: 200 + }, + heatedBed: false, + axes: { + x: {speed: 6000, inverted: false}, + y: {speed: 6000, inverted: false}, + z: {speed: 200, inverted: false}, + e: {speed: 300, inverted: false} + }, + extruder: { + count: 1, + offsets: [ + [0,0] + ] + } + } + }; + self.profiles = new ItemListHelper( "printerProfiles", { @@ -20,14 +48,19 @@ function PrinterProfilesViewModel() { self.defaultProfile = ko.observable(); self.currentProfile = ko.observable(); + self.currentProfileData = ko.observable(ko.mapping.fromJS(self._cleanProfile())); + + self.editorNew = ko.observable(false); + self.editorName = ko.observable(); self.editorColor = ko.observable(); self.editorIdentifier = ko.observable(); + self.editorModel = ko.observable(); - self.editorWidth = ko.observable(); - self.editorDepth = ko.observable(); - self.editorHeight = ko.observable(); - self.editorFormFactor = ko.observable(); + self.editorVolumeWidth = ko.observable(); + self.editorVolumeDepth = ko.observable(); + self.editorVolumeHeight = ko.observable(); + self.editorVolumeFormFactor = ko.observable(); self.editorHeatedBed = ko.observable(); @@ -42,6 +75,46 @@ function PrinterProfilesViewModel() { self.editorAxisXInverted = ko.observable(false); self.editorAxisYInverted = ko.observable(false); self.editorAxisZInverted = ko.observable(false); + self.editorAxisEInverted = ko.observable(false); + + self.availableColors = ko.observable([ + {key: "default", name: gettext("default")}, + {key: "red", name: gettext("red")}, + {key: "orange", name: gettext("orange")}, + {key: "yellow", name: gettext("yellow")}, + {key: "green", name: gettext("green")}, + {key: "blue", name: gettext("blue")}, + {key: "black", name: gettext("black")} + ]); + + self.koEditorExtruderOffsets = ko.computed(function() { + var extruderOffsets = self.editorExtruderOffsets(); + var numExtruders = self.editorExtruders(); + if (!numExtruders) { + numExtruders = 1; + } + + if (numExtruders > extruderOffsets.length) { + for (var i = extruderOffsets.length; i < numExtruders; i++) { + extruderOffsets[i] = { + x: ko.observable(0), + y: ko.observable(0) + } + } + self.editorExtruderOffsets(extruderOffsets); + } + + return extruderOffsets.slice(0, numExtruders); + }); + + self.makeDefault = function(data) { + var profile = { + id: data.id, + default: true + }; + + self.updateProfile(profile); + }; self.requestData = function() { $.ajax({ @@ -56,60 +129,39 @@ function PrinterProfilesViewModel() { var items = []; var defaultProfile = undefined; var currentProfile = undefined; + var currentProfileData = undefined; _.each(data.profiles, function(entry) { if (entry.default) { defaultProfile = entry.id; } if (entry.current) { currentProfile = entry.id; + currentProfileData = ko.mapping.fromJS(entry, self.currentProfileData); } - items.push({ - id: ko.observable(entry.id), - name: ko.observable(entry.name), - model: ko.observable(entry.model), - volume: { - width: ko.observable(entry.volume.width), - depth: ko.observable(entry.volume.depth), - height: ko.observable(entry.volume.height), - formFactor: ko.observable(entry.volume.formFactor) - }, - heatedBed: ko.observable(entry.heatedBed), - axes: { - x: { - speed: ko.observable(entry.axes.x.speed), - inverted: ko.observable(entry.axes.x.inverted) - }, - y: { - speed: ko.observable(entry.axes.y.speed), - inverted: ko.observable(entry.axes.y.inverted) - }, - z: { - speed: ko.observable(entry.axes.z.speed), - inverted: ko.observable(entry.axes.z.inverted) - }, - e: { - speed: ko.observable(entry.axes.e.speed), - inverted: ko.observable(entry.axes.e.inverted) - } - }, - isdefault: ko.observable(entry.default), - iscurrent: ko.observable(entry.current), - resource: ko.observable(entry.resource) - }); + entry["isdefault"] = ko.observable(entry.default); + entry["iscurrent"] = ko.observable(entry.current); + items.push(entry); }); self.profiles.updateItems(items); self.defaultProfile(defaultProfile); self.currentProfile(currentProfile); + self.currentProfileData(currentProfileData); }; - self.addProfile = function() { + self.addProfile = function(callback) { var profile = self._editorData(); $.ajax({ - url: API_BASEURL + "printerProfiles/" + profile.id, - type: "PUT", + url: API_BASEURL + "printerProfiles", + type: "POST", dataType: "json", contentType: "application/json; charset=UTF-8", - data: JSON.stringify({profile: profile}) + data: JSON.stringify({profile: profile}), + success: function() { + if (callback !== undefined) { + callback(); + } + self.requestData(); + } }); }; @@ -117,11 +169,12 @@ function PrinterProfilesViewModel() { $.ajax({ url: data.resource, type: "DELETE", - dataType: "json" + dataType: "json", + success: self.requestData }) }; - self.updateProfile = function(identifier, profile) { + self.updateProfile = function(profile, callback) { if (profile == undefined) { profile = self._editorData(); } @@ -131,20 +184,89 @@ function PrinterProfilesViewModel() { type: "PATCH", dataType: "json", contentType: "application/json; charset=UTF-8", - data: JSON.stringify({profile: profile}) + data: JSON.stringify({profile: profile}), + success: function() { + if (callback !== undefined) { + callback(); + } + self.requestData(); + } }); }; + self.showEditProfileDialog = function(data) { + var add = false; + if (data == undefined) { + data = self._cleanProfile(); + add = true; + } + + self.editorIdentifier(data.id); + self.editorName(data.name); + self.editorColor(data.color); + self.editorModel(data.model); + + self.editorVolumeWidth(data.volume.width); + self.editorVolumeDepth(data.volume.depth); + self.editorVolumeHeight(data.volume.height); + self.editorVolumeFormFactor(data.volume.formFactor); + + self.editorHeatedBed(data.volume.heatedBed); + + self.editorExtruders(data.extruder.count); + var offsets = []; + _.each(data.extruder.offsets, function(offset) { + offsets.push({ + x: ko.observable(offset[0]), + y: ko.observable(offset[1]) + }); + }); + self.editorExtruderOffsets(offsets); + + self.editorAxisXSpeed(data.axes.x.speed); + self.editorAxisXInverted(data.axes.x.inverted); + self.editorAxisYSpeed(data.axes.y.speed); + self.editorAxisYInverted(data.axes.y.inverted); + self.editorAxisZSpeed(data.axes.z.speed); + self.editorAxisZInverted(data.axes.z.inverted); + self.editorAxisESpeed(data.axes.e.speed); + self.editorAxisEInverted(data.axes.e.inverted); + + var editDialog = $("#settings_printerProfiles_editDialog"); + var confirmButton = $("button.btn-confirm", editDialog); + var dialogTitle = $("h3.modal-title", editDialog); + + dialogTitle.text(add ? gettext("Add Printer Profile") : _.sprintf(gettext("Edit Printer Profile \"%(name)s\""), {name: data.name})); + confirmButton.unbind("click"); + confirmButton.bind("click", function() { + self.confirmEditProfile(add); + }); + editDialog.modal("show"); + }; + + self.confirmEditProfile = function(add) { + var callback = function() { + $("#settings_printerProfiles_editDialog").modal("hide"); + }; + + if (add) { + self.addProfile(callback); + } else { + self.updateProfile(undefined, callback); + } + }; + self._editorData = function() { var profile = { + id: self.editorIdentifier(), name: self.editorName(), color: self.editorColor(), - id: self.editorIdentifier(), + model: self.editorModel(), volume: { - width: self.editorWidth(), - depth: self.editorDepth(), - height: self.editorHeight(), - type: self.editorFormFactor() + width: self.editorVolumeWidth(), + depth: self.editorVolumeDepth(), + height: self.editorVolumeHeight(), + type: self.editorVolumeFormFactor() }, heatedBed: self.editorHeatedBed(), extruder: { @@ -182,7 +304,6 @@ function PrinterProfilesViewModel() { return profile; }; - self.onStartup = function() { - self.requestData(); - }; + self.onSettingsShown = self.requestData; + self.onStartup = self.requestData; } \ No newline at end of file diff --git a/src/octoprint/templates/settings.jinja2 b/src/octoprint/templates/settings.jinja2 index 62a3022d..af130487 100644 --- a/src/octoprint/templates/settings.jinja2 +++ b/src/octoprint/templates/settings.jinja2 @@ -122,7 +122,7 @@ - +  |  @@ -130,6 +130,150 @@ + + + +