From 9bd5a71875be730eb92ef2427317bf4cbab1ee94 Mon Sep 17 00:00:00 2001 From: Teja Date: Thu, 29 Jan 2015 17:21:18 +0100 Subject: [PATCH] code cleanup, svgDPI introduced in settings --- .../plugins/lasercutterprofiles/__init__.py | 10 +- src/octoprint/plugins/svgtogcode/__init__.py | 26 +- .../plugins/svgtogcode/static/js/convert.js | 549 +++++++++--------- .../svgtogcode/static/js/svgtogcode.js | 43 -- .../svgtogcode/static/js/working_area.js | 453 ++++++++------- ...alog.jinja2 => svgtogcode_settings.jinja2} | 16 +- .../static/js/app/viewmodels/printerstate.js | 4 +- .../static/js/app/viewmodels/settings.js | 7 - 8 files changed, 547 insertions(+), 561 deletions(-) delete mode 100644 src/octoprint/plugins/svgtogcode/static/js/svgtogcode.js rename src/octoprint/plugins/svgtogcode/templates/{svgtogcode_settings_dialog.jinja2 => svgtogcode_settings.jinja2} (95%) diff --git a/src/octoprint/plugins/lasercutterprofiles/__init__.py b/src/octoprint/plugins/lasercutterprofiles/__init__.py index d9538836..8fdea7fb 100644 --- a/src/octoprint/plugins/lasercutterprofiles/__init__.py +++ b/src/octoprint/plugins/lasercutterprofiles/__init__.py @@ -197,16 +197,16 @@ class LaserCutterProfilesPlugin(octoprint.plugin.SettingsPlugin, ##~~ TemplatePlugin API def get_template_vars(self): - #selectedProfile = laserCutterProfileManager.get_current_or_default() - d = dict( - _settings_menu_entry="Laser cutter profiles", - ) + d = dict() return d def get_template_folder(self): import os return os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") + def get_template_configs(self): + return [dict(type = 'settings', name = "Machine Profiles")] + ##~~ BlueprintPlugin API def get_blueprint(self): @@ -226,6 +226,6 @@ def _sanitize_name(name): sanitized_name = sanitized_name.replace(" ", "_") return sanitized_name.lower() -__plugin_name__ = "Laser cutter profiles" +__plugin_name__ = "lasercutterprofiles" __plugin_version__ = "0.1" __plugin_implementations__ = [LaserCutterProfilesPlugin()] diff --git a/src/octoprint/plugins/svgtogcode/__init__.py b/src/octoprint/plugins/svgtogcode/__init__.py index 1445ae1e..87b88767 100644 --- a/src/octoprint/plugins/svgtogcode/__init__.py +++ b/src/octoprint/plugins/svgtogcode/__init__.py @@ -20,7 +20,8 @@ import octoprint.settings default_settings = { "defaultIntensity": 500, "defaultFeedrate": 300, - "debug_logging": False + "debug_logging": False, + "svgDPI": 90 } s = octoprint.plugin.plugin_settings("svgtogcode", defaults=default_settings) @@ -142,7 +143,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin, def get_assets(self): return { - "js": ["js/svgtogcode.js", "js/convert.js", "js/working_area.js", "js/lib/snap.svg-min.js"], + "js": [ "js/convert.js", "js/working_area.js", "js/lib/snap.svg-min.js"], "less": ["less/svgtogcode.less"], "css": ["css/svgtogcode.css", "css/mrbeam.css"] } @@ -153,14 +154,19 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin, return dict( defaultIntensity=s.get(["defaultIntensity"]), defaultFeedrate=s.get(["defaultFeedrate"]), + svgDPI=s.get(["svgDPI"]), debug_logging=s.getBoolean(["debug_logging"]) ) def on_settings_save(self, data): if "defaultIntensity" in data and data["defaultIntensity"]: - s.set(["defaultIntensity"], data["defaultIntensity"]) + intensity = min(max(data["defaultIntensity"], 1), 1000) + s.set(["defaultIntensity"], intensity) if "defaultFeedrate" in data and data["defaultFeedrate"]: - s.set(["defaultFeedrate"], data["defaultFeedrate"]) + feedrate = max(1,data["defaultFeedrate"]) + s.set(["defaultFeedrate"], feedrate) + if "svgDPI" in data and data["svgDPI"]: + s.set(["svgDPI"], data["svgDPI"]) if "debug_logging" in data: old_debug_logging = s.getBoolean(["debug_logging"]) new_debug_logging = data["debug_logging"] in octoprint.settings.valid_boolean_trues @@ -174,13 +180,15 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin, ##~~ TemplatePlugin API def get_template_vars(self): - return dict( - _settings_menu_entry="Svg GCode Converter" - ) + return dict() def get_template_folder(self): - import os - return os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") + #import os + #return os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") + return os.path.join(self._basefolder, "templates") + + def get_template_configs(self): + return [dict(type = 'settings', name = "Svg Conversion", custom_bindings = False)] ##~~ SlicerPlugin API diff --git a/src/octoprint/plugins/svgtogcode/static/js/convert.js b/src/octoprint/plugins/svgtogcode/static/js/convert.js index fd91df70..dd0a25c7 100644 --- a/src/octoprint/plugins/svgtogcode/static/js/convert.js +++ b/src/octoprint/plugins/svgtogcode/static/js/convert.js @@ -1,281 +1,292 @@ -function VectorConversionViewModel(params) { - var self = this; - - self.loginState = params[0]; - self.settings = params[1]; - self.state = params[2]; - self.workingArea = params[3]; - self.files = params[4]; - - self.target = undefined; - self.file = undefined; - self.data = undefined; - - self.defaultSlicer = undefined; - self.defaultProfile = undefined; - - self.gcodeFilename = ko.observable(); - self.laserIntensity = ko.observable(undefined); - self.laserSpeed = ko.observable(undefined); - self.maxSpeed = ko.observable(3000); - self.minSpeed = ko.observable(30); - self.title = ko.observable(undefined); - self.slicer = ko.observable(); - self.slicers = ko.observableArray(); - self.profile = ko.observable(); - self.profiles = ko.observableArray(); +$(function(){ - self.maxSpeed.subscribe(function(val){ - console.log("maxSpeed changed", val); - self._configureFeedrateSlider(); - }); - - // TODO check if still in use - self.show = function(target, file) { - self.target = target; - self.file = file; - self.title(_.sprintf(gettext("Converting %(filename)s"), {filename: self.file})); - self.gcodeFilename(self.file.substr(0, self.file.lastIndexOf("."))); - $("#dialog_vector_graphics_conversion").modal("show"); - }; - - // shows conversion dialog and extracts svg first - self.show_conversion_dialog = function() { - var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity(); - var speed = self.settings.settings.plugins.svgtogcode.defaultIntensity(); - self.laserIntensity(intensity); - self.laserSpeed(speed); + + function VectorConversionViewModel(params) { + var self = this; - self.svg = self.workingArea.getCompositionSVG(); + console.log('conversion', params); - // TODO: js svg conversion - self.title(gettext("Converting")); - var gcodeFile = self.create_gcode_filename(self.workingArea.placedDesigns()); - self.gcodeFilename(gcodeFile); - $("#dialog_vector_graphics_conversion").modal("show"); - }; - self.create_gcode_filename = function(placedDesigns){ - if(placedDesigns.length > 0){ - var filemap = {}; - for(var idx in placedDesigns){ - var design = placedDesigns[idx]; - var start = design.url.lastIndexOf('/')+1; - var end = design.url.lastIndexOf('.'); - var name = design.url.substring(start, end); - if(filemap[name] !== undefined) filemap[name] += 1; - else filemap[name] = 1; - } - var mostPlaced; - var placed = 0; - for(var name in filemap){ - if(filemap[name] > placed){ - mostPlaced = name; - placed = filemap[name]; + self.loginState = params[0]; + self.settings = params[1]; + self.state = params[2]; + self.workingArea = params[3]; + self.files = params[4]; + + self.target = undefined; + self.file = undefined; + self.data = undefined; + + self.defaultSlicer = undefined; + self.defaultProfile = undefined; + + self.gcodeFilename = ko.observable(); + self.laserIntensity = ko.observable(undefined); + self.laserSpeed = ko.observable(undefined); + self.maxSpeed = ko.observable(3000); + self.minSpeed = ko.observable(30); + self.title = ko.observable(undefined); + self.slicer = ko.observable(); + self.slicers = ko.observableArray(); + self.profile = ko.observable(); + self.profiles = ko.observableArray(); + + self.maxSpeed.subscribe(function(val){ + self._configureFeedrateSlider(); + }); + + // TODO check if still in use + self.show = function(target, file) { + self.target = target; + self.file = file; + self.title(_.sprintf(gettext("Converting %(filename)s"), {filename: self.file})); + self.gcodeFilename(self.file.substr(0, self.file.lastIndexOf("."))); + $("#dialog_vector_graphics_conversion").modal("show"); + }; + + // shows conversion dialog and extracts svg first + self.show_conversion_dialog = function() { + var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity(); + var speed = self.settings.settings.plugins.svgtogcode.defaultIntensity(); + self.laserIntensity(intensity); + self.laserSpeed(speed); + + self.svg = self.workingArea.getCompositionSVG(); + + // TODO: js svg conversion + self.title(gettext("Converting")); + var gcodeFile = self.create_gcode_filename(self.workingArea.placedDesigns()); + self.gcodeFilename(gcodeFile); + $("#dialog_vector_graphics_conversion").modal("show"); + }; + + self.create_gcode_filename = function(placedDesigns){ + if(placedDesigns.length > 0){ + var filemap = {}; + for(var idx in placedDesigns){ + var design = placedDesigns[idx]; + var start = design.url.lastIndexOf('/')+1; + var end = design.url.lastIndexOf('.'); + var name = design.url.substring(start, end); + if(filemap[name] !== undefined) filemap[name] += 1; + else filemap[name] = 1; } + var mostPlaced; + var placed = 0; + for(var name in filemap){ + if(filemap[name] > placed){ + mostPlaced = name; + placed = filemap[name]; + } + } + var uniqueDesigns = Object.keys(filemap).length; + var gcode_name = mostPlaced; + if(placed > 1) gcode_name += "." + placed + "x"; + if(uniqueDesigns > 1){ + gcode_name += "_"+(uniqueDesigns-1)+"more"; + } + return gcode_name + ".gco"; + } else { + return "tmp"+Date.now()+".gco"; // TODO: user should not deal with gcode anymore. go and laser it. } - var uniqueDesigns = Object.keys(filemap).length; - var gcode_name = mostPlaced; - if(placed > 1) gcode_name += "." + placed + "x"; - if(uniqueDesigns > 1){ - gcode_name += "_"+(uniqueDesigns-1)+"more"; + }; + + self.slicer.subscribe(function(newValue) { + self.profilesForSlicer(newValue); + }); + + self.enableConvertButton = ko.computed(function() { + if (self.laserIntensity() === undefined || self.laserSpeed() === undefined || self.gcodeFilename() === undefined) { + return false; + } else { + var tmpIntensity = self.laserIntensity(); + var tmpSpeed = self.laserSpeed(); + var tmpGcodeFilename = self.gcodeFilename().trim(); + return tmpGcodeFilename !== "" + && tmpIntensity > 0 && tmpIntensity <= 1000 // TODO no magic numbers here! + && tmpSpeed >= self.minSpeed() && tmpSpeed <= self.maxSpeed(); } - return gcode_name + ".gco"; - } else { - return "tmp"+Date.now()+".gco"; // TODO: user should not deal with gcode anymore. go and laser it. - } - }; - - self.slicer.subscribe(function(newValue) { - self.profilesForSlicer(newValue); - }); - - self.enableConvertButton = ko.computed(function() { - if (self.laserIntensity() === undefined || self.laserSpeed() === undefined || self.gcodeFilename() === undefined) { - return false; - } else { - var tmpIntensity = self.laserIntensity(); - var tmpSpeed = self.laserSpeed(); - var tmpGcodeFilename = self.gcodeFilename().trim(); - return tmpGcodeFilename !== "" - && tmpIntensity > 0 && tmpIntensity <= 1000 // TODO no magic numbers here! - && tmpSpeed >= self.minSpeed() && tmpSpeed <= self.maxSpeed(); - } - }); - - self.requestData = function() { - $.ajax({ - url: API_BASEURL + "slicing", - type: "GET", - dataType: "json", - success: self.fromResponse - }); - }; - - self.fromResponse = function(data) { - self.data = data; - - var selectedSlicer = undefined; - self.slicers.removeAll(); - _.each(_.values(data), function(slicer) { - var name = slicer.displayName; - if (name === undefined) { - name = slicer.key; - } - - if (slicer.default) { - selectedSlicer = slicer.key; - } - - self.slicers.push({ - key: slicer.key, - name: name - }); - }); - - if (selectedSlicer != undefined) { - self.slicer(selectedSlicer); - } - - self.defaultSlicer = selectedSlicer; - }; - - self.profilesForSlicer = function(key) { - if (key == undefined) { - key = self.slicer(); - } - if (key == undefined || !self.data.hasOwnProperty(key)) { - return; - } - var slicer = self.data[key]; - - var selectedProfile = undefined; - self.profiles.removeAll(); - _.each(_.values(slicer.profiles), function(profile) { - var name = profile.displayName; - if (name == undefined) { - name = profile.key; - } - - if (profile.default) { - selectedProfile = profile.key; - } - - self.profiles.push({ - key: profile.key, - name: name - }) - }); - - if (selectedProfile != undefined) { - self.profile(selectedProfile); - } - - self.defaultProfile = selectedProfile; - }; - - self.convert = function() { - var gcodeFilename = self._sanitize(self.gcodeFilename()); - if (!_.endsWith(gcodeFilename.toLowerCase(), ".gco") - && !_.endsWith(gcodeFilename.toLowerCase(), ".gcode") - && !_.endsWith(gcodeFilename.toLowerCase(), ".g")) { - gcodeFilename = gcodeFilename + ".gco"; - } - - var data = { - command: "convert", - "profile.speed": self.laserSpeed(), - "profile.intensity": self.laserIntensity(), - slicer: "svgtogcode", - gcode: gcodeFilename - }; - - if(self.svg !== undefined){ - data.svg = self.svg; - } - - $.ajax({ - url: API_BASEURL + "files/convert", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data) - }); - - $("#dialog_vector_graphics_conversion").modal("hide"); - - self.gcodeFilename(undefined); - //self.slicer(self.defaultSlicer); - //self.profile(self.defaultProfile); - }; - - self._sanitize = function(name) { - return name.replace(/[^a-zA-Z0-9\-_\.\(\) ]/g, "").replace(/ /g, "_"); - }; - - self.onStartup = function() { - self.requestData(); - self.state.conversion = self; // hack! injecting method to avoid circular dependency. - self.files.conversion = self; - self._configureIntensitySlider(); - self._configureFeedrateSlider(); - }; - - self._configureIntensitySlider = function() { - self.intensitySlider = $("#svgtogcode_intensity").slider({ - id: "svgtogcode_intensity_slider", - reversed: false, - selection: "after", - orientation: "horizontal", - min: 1, - max: 1000, - step: 1, - value: 500, - enabled: true, - formatter: function(value) { return "" + (value/10) +"%"; } - }).on("slideStop", function(ev){ - self.laserIntensity(ev.value); }); - - self.laserIntensity.subscribe(function(newVal){ - self.intensitySlider.slider('setValue', parseInt(newVal)); - }); - }; - self._configureFeedrateSlider = function() { - self.feedrateSlider = $("#svgtogcode_feedrate").slider({ - id: "svgtogcode_feedrate_slider", - reversed: false, - selection: "after", - orientation: "horizontal", - min: 0, - max: 1000, - step: 1, - value: 300, - enabled: true, - formatter: function(value) { return "" + Math.round(self._calcRealSpeed(value)) +"mm/min"; } - }); - - // use the class as a flag to avoid double binding of the slideStop event - if($("#svgtogcode_feedrate").attr('class') === 'uninitialized'){ // somehow hasClass(...) did not work ??? - self.feedrateSlider.on("slideStop", function(ev){ - self.laserSpeed(self._calcRealSpeed(ev.value)); + self.requestData = function() { + $.ajax({ + url: API_BASEURL + "slicing", + type: "GET", + dataType: "json", + success: self.fromResponse }); - $("#svgtogcode_feedrate").removeClass('uninitialized'); - } - - - - var speedSubscription = self.laserSpeed.subscribe(function(realVal){ - var val = (parseInt(realVal) - self.minSpeed()) / (self.maxSpeed() - self.minSpeed()); - self.feedrateSlider.slider('setValue', val); - speedSubscription.dispose(); // only do it once - }); - }; + }; + + self.fromResponse = function(data) { + self.data = data; + + var selectedSlicer = undefined; + self.slicers.removeAll(); + _.each(_.values(data), function(slicer) { + var name = slicer.displayName; + if (name === undefined) { + name = slicer.key; + } + + if (slicer.default) { + selectedSlicer = slicer.key; + } + + self.slicers.push({ + key: slicer.key, + name: name + }); + }); + + if (selectedSlicer != undefined) { + self.slicer(selectedSlicer); + } + + self.defaultSlicer = selectedSlicer; + }; + + self.profilesForSlicer = function(key) { + if (key == undefined) { + key = self.slicer(); + } + if (key == undefined || !self.data.hasOwnProperty(key)) { + return; + } + var slicer = self.data[key]; + + var selectedProfile = undefined; + self.profiles.removeAll(); + _.each(_.values(slicer.profiles), function(profile) { + var name = profile.displayName; + if (name == undefined) { + name = profile.key; + } + + if (profile.default) { + selectedProfile = profile.key; + } + + self.profiles.push({ + key: profile.key, + name: name + }) + }); + + if (selectedProfile != undefined) { + self.profile(selectedProfile); + } + + self.defaultProfile = selectedProfile; + }; + + self.convert = function() { + var gcodeFilename = self._sanitize(self.gcodeFilename()); + if (!_.endsWith(gcodeFilename.toLowerCase(), ".gco") + && !_.endsWith(gcodeFilename.toLowerCase(), ".gcode") + && !_.endsWith(gcodeFilename.toLowerCase(), ".g")) { + gcodeFilename = gcodeFilename + ".gco"; + } + + var data = { + command: "convert", + "profile.speed": self.laserSpeed(), + "profile.intensity": self.laserIntensity(), + slicer: "svgtogcode", + gcode: gcodeFilename + }; + + if(self.svg !== undefined){ + data.svg = self.svg; + } + + $.ajax({ + url: API_BASEURL + "files/convert", + type: "POST", + dataType: "json", + contentType: "application/json; charset=UTF-8", + data: JSON.stringify(data) + }); + + $("#dialog_vector_graphics_conversion").modal("hide"); + + self.gcodeFilename(undefined); + //self.slicer(self.defaultSlicer); + //self.profile(self.defaultProfile); + }; + + self._sanitize = function(name) { + return name.replace(/[^a-zA-Z0-9\-_\.\(\) ]/g, "").replace(/ /g, "_"); + }; + + self.onStartup = function() { + self.requestData(); + self.state.conversion = self; // hack! injecting method to avoid circular dependency. + self.files.conversion = self; + self._configureIntensitySlider(); + self._configureFeedrateSlider(); + }; + + self._configureIntensitySlider = function() { + self.intensitySlider = $("#svgtogcode_intensity").slider({ + id: "svgtogcode_intensity_slider", + reversed: false, + selection: "after", + orientation: "horizontal", + min: 1, + max: 1000, + step: 1, + value: 500, + enabled: true, + formatter: function(value) { return "" + (value/10) +"%"; } + }).on("slideStop", function(ev){ + self.laserIntensity(ev.value); + }); + + self.laserIntensity.subscribe(function(newVal){ + self.intensitySlider.slider('setValue', parseInt(newVal)); + }); + }; + + self._configureFeedrateSlider = function() { + self.feedrateSlider = $("#svgtogcode_feedrate").slider({ + id: "svgtogcode_feedrate_slider", + reversed: false, + selection: "after", + orientation: "horizontal", + min: 0, + max: 1000, + step: 1, + value: 300, + enabled: true, + formatter: function(value) { return "" + Math.round(self._calcRealSpeed(value)) +"mm/min"; } + }); + + // use the class as a flag to avoid double binding of the slideStop event + if($("#svgtogcode_feedrate").attr('class') === 'uninitialized'){ // somehow hasClass(...) did not work ??? + self.feedrateSlider.on("slideStop", function(ev){ + self.laserSpeed(self._calcRealSpeed(ev.value)); + }); + $("#svgtogcode_feedrate").removeClass('uninitialized'); + } + + + + var speedSubscription = self.laserSpeed.subscribe(function(realVal){ + var val = (parseInt(realVal) - self.minSpeed()) / (self.maxSpeed() - self.minSpeed()); + self.feedrateSlider.slider('setValue', val); + speedSubscription.dispose(); // only do it once + }); + }; + + self._calcRealSpeed = function(sliderVal){ + console.log(); + return self.minSpeed() + sliderVal/1000 * (self.maxSpeed() - self.minSpeed()); + }; + + } - self._calcRealSpeed = function(sliderVal){ - console.log(); - return self.minSpeed() + sliderVal/1000 * (self.maxSpeed() - self.minSpeed()); - }; + ADDITIONAL_VIEWMODELS.push([VectorConversionViewModel, "vectorConversionViewModel", + ["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "workingAreaViewModel", "gcodeFilesViewModel"], + document.getElementById("dialog_vector_graphics_conversion")]); -} \ No newline at end of file +}); diff --git a/src/octoprint/plugins/svgtogcode/static/js/svgtogcode.js b/src/octoprint/plugins/svgtogcode/static/js/svgtogcode.js deleted file mode 100644 index d0077218..00000000 --- a/src/octoprint/plugins/svgtogcode/static/js/svgtogcode.js +++ /dev/null @@ -1,43 +0,0 @@ -$(function() { - function SvgToGcodeViewModel(parameters) { - var self = this; - - self.loginState = parameters[0]; - self.settingsViewModel = parameters[1]; - self.slicingViewModel = parameters[2]; - - self.fileName = ko.observable(); - - self.placeholderName = ko.observable(); - self.placeholderDisplayName = ko.observable(); - self.placeholderDescription = ko.observable(); - - self.profileName = ko.observable(); - self.profileDisplayName = ko.observable(); - self.profileDescription = ko.observable(); - self.profileAllowOverwrite = ko.observable(true); - - - - - self.convertSVG2 = function(data) { - if (!data) { - return; - } - - return; - }; - - - - } - // view model class, parameters for constructor, container to bind to - //ADDITIONAL_VIEWMODELS.push([SvgToGcodeViewModel, ["loginStateViewModel", "settingsViewModel", "slicingViewModel"], null]); - ADDITIONAL_VIEWMODELS.push([WorkingAreaViewModel, "workingAreaViewModel", - ["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "gcodeFilesViewModel"], - document.getElementById("area_preview")]); - - ADDITIONAL_VIEWMODELS.push([VectorConversionViewModel, "vectorConversionViewModel", - ["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "workingAreaViewModel", "gcodeFilesViewModel"], - document.getElementById("dialog_vector_graphics_conversion")]); -}); \ No newline at end of file diff --git a/src/octoprint/plugins/svgtogcode/static/js/working_area.js b/src/octoprint/plugins/svgtogcode/static/js/working_area.js index fb5eaa33..770c50ab 100644 --- a/src/octoprint/plugins/svgtogcode/static/js/working_area.js +++ b/src/octoprint/plugins/svgtogcode/static/js/working_area.js @@ -1,234 +1,245 @@ -function WorkingAreaViewModel(params) { - var self = this; +$(function(){ - self.loginState = params[0]; - self.settings = params[1]; - self.state = params[2]; - self.files = params[3]; + function WorkingAreaViewModel(params) { + console.log('workingaera', params); + var self = this; - self.log = []; + self.loginState = params[0]; + self.settings = params[1]; + self.state = params[2]; + self.files = params[3]; + self.conversion = params[4]; - self.command = ko.observable(undefined); + self.log = []; - self.isErrorOrClosed = ko.observable(undefined); - self.isOperational = ko.observable(undefined); - self.isPrinting = ko.observable(undefined); - self.isPaused = ko.observable(undefined); - self.isError = ko.observable(undefined); - self.isReady = ko.observable(undefined); - self.isLoading = ko.observable(undefined); - - self.availableHeight = ko.observable(undefined); - self.availableWidth = ko.observable(undefined); - self.px2mm_factor = 1; // initial value - self.svgDPI = ko.observable(90); // TODO fetch from settings - self.workingAreaWidthMM = ko.observable(undefined); - self.workingAreaHeightMM = ko.observable(undefined); - self.hwRatio = ko.computed(function(){ - // y/x = 297/216 respectively 594/432 - var w = self.workingAreaWidthMM(); - var h = self.workingAreaHeightMM(); -// var h = self.settings.printerProfiles.currentProfileData().volume.depth(); -// var w = self.settings.printerProfiles.currentProfileData().volume.width(); - var ratio = h / w; - return ratio; - }, self); - - self.workingAreaDim = ko.computed(function(){ - var maxH = self.availableHeight(); - var maxW = self.availableWidth(); - var hwRatio = self.hwRatio(); - if( hwRatio > 0, maxH > 0, maxW > 0){ - var w = 0; - var h = 0; - if( maxH/maxW > hwRatio) { - w = maxW; - h = maxW * hwRatio; - } else { - w = maxH / hwRatio; - h = maxH; - } - var dim = [w,h]; - return dim; - } - }); - - self.workingAreaWidthPx = ko.computed(function(){ - var dim = self.workingAreaDim(); - return dim ? dim[0] : 1; - }, self); - - self.workingAreaHeightPx = ko.computed(function(){ - var dim = self.workingAreaDim(); - return dim ? dim[1] : 1; - }, self); - - self.px2mm_factor = ko.computed(function(){ - return self.workingAreaWidthMM() / self.workingAreaWidthPx(); - }); - - self.scaleMatrix = ko.computed(function(){ - var m = new Snap.Matrix(); - m.scale(25.4/self.svgDPI() * 1/self.px2mm_factor()); - return m; - }); - - self.placedDesigns = ko.observableArray([]); - - self.clear = function(){ - snap.selectAll('#userContent>*').remove(); - self.placedDesigns([]); - }; - - self.trigger_resize = function(){ - self.availableHeight(document.documentElement.clientHeight - $('body>nav').outerHeight() - $('footer>*').outerHeight() - 39); // magic number - self.availableWidth($('#workingarea div.span8').innerWidth()); - }; + self.command = ko.observable(undefined); - self.move_laser = function(el){ - var x = self.px2mm(event.offsetX); -// var y = self.px2mm(event.toElement.offsetHeight - event.offsetY); // toElement.offsetHeight is always 0 on svg>* elements ??? - var y = self.px2mm(event.toElement.ownerSVGElement.offsetHeight - event.offsetY); // hopefully this works across browsers - $.ajax({ - url: API_BASEURL + "printer/printhead", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({"command": "position", x:x, y:y}) - }); - }; - - - - self.crosshairX = function(){ - var pos = self.state.currentPos(); - return pos !== undefined ? (self.mm2px(pos.x) - 15) : -100; // subtract width/2; - - }; - self.crosshairY = function(){ - var h = document.getElementById('area_preview').clientHeight; - var pos = self.state.currentPos(); - return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2; - }; - - self.px2mm = function(val){ - return val * self.px2mm_factor(); - }; - - self.mm2px = function(val){ - return val / self.px2mm_factor(); - }; - - self.mm2svgUnits = function(val){ - return val * self.svgDPI()/25.4; - }; - - //self.getDivDimensions(); // init - - self.placeSVG = function(file) { - if (file && file["refs"] && file["refs"]["download"]) { - var url = file.refs.download.replace("downloads", "serve"); - self.loadSVG(url); - } - }; - - self.loadSVG = function(url){ - Snap.load(url, function (f) { - var namespaces = {}; - var root = f.select('svg').node.attributes; - for(var i = 0; i < root.length; i++){ - var attr = root[i]; - if(attr.name.indexOf("xmlns") === 0){ - namespaces[attr.name] = attr.value; + self.isErrorOrClosed = ko.observable(undefined); + self.isOperational = ko.observable(undefined); + self.isPrinting = ko.observable(undefined); + self.isPaused = ko.observable(undefined); + self.isError = ko.observable(undefined); + self.isReady = ko.observable(undefined); + self.isLoading = ko.observable(undefined); + + self.availableHeight = ko.observable(undefined); + self.availableWidth = ko.observable(undefined); + self.px2mm_factor = 1; // initial value + self.svgDPI = ko.observable(90); // TODO fetch from settings + self.workingAreaWidthMM = ko.observable(undefined); + self.workingAreaHeightMM = ko.observable(undefined); + self.hwRatio = ko.computed(function(){ + // y/x = 297/216 respectively 594/432 + var w = self.workingAreaWidthMM(); + var h = self.workingAreaHeightMM(); + // var h = self.settings.printerProfiles.currentProfileData().volume.depth(); + // var w = self.settings.printerProfiles.currentProfileData().volume.width(); + var ratio = h / w; + return ratio; + }, self); + + self.workingAreaDim = ko.computed(function(){ + var maxH = self.availableHeight(); + var maxW = self.availableWidth(); + var hwRatio = self.hwRatio(); + if( hwRatio > 0, maxH > 0, maxW > 0){ + var w = 0; + var h = 0; + if( maxH/maxW > hwRatio) { + w = maxW; + h = maxW * hwRatio; + } else { + w = maxH / hwRatio; + h = maxH; } + var dim = [w,h]; + return dim; } - - var newSvg = f.select("g"); - newSvg.attr(namespaces); - var id = self.generateId(url); - snap.select("#userContent").append(newSvg); - - newSvg.drag();// Making croc draggable. Go ahead drag it around! - // Obviously drag could take event handlers too - var ref = { - id : id, - url : url - }; - self.placedDesigns.push(ref); }); - }; - - self.init = function(){ - // init snap.svg - snap = Snap('#area_preview'); - self.px2mm_factor.subscribe(function(newVal){ - if(!isNaN(newVal)) - self.draw_coord_grid(); + + self.workingAreaWidthPx = ko.computed(function(){ + var dim = self.workingAreaDim(); + return dim ? dim[0] : 1; + }, self); + + self.workingAreaHeightPx = ko.computed(function(){ + var dim = self.workingAreaDim(); + return dim ? dim[1] : 1; + }, self); + + self.px2mm_factor = ko.computed(function(){ + return self.workingAreaWidthMM() / self.workingAreaWidthPx(); }); - }; - - self.draw_coord_grid = function(){ - var grid = snap.select('#coordGrid'); - if(grid.attr('fill') === 'none'){ - var w = self.mm2svgUnits(self.workingAreaWidthMM()); - var h = self.mm2svgUnits(self.workingAreaHeightMM()); - var max_lines = 20; - - var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10; - var yPatternOffset = self.mm2svgUnits(self.workingAreaHeightMM() % linedistMM); - var linedist = self.mm2svgUnits(linedistMM); - var marker = snap.circle(linedist/2, linedist/2, 1).attr({ - fill: "#000000", - stroke: "none", - strokeWidth: 1 - }); - - // dot pattern - var p = marker.pattern(0, 0, linedist, linedist); - p.attr({ - x: linedist/2, - y: linedist/2 + yPatternOffset - }); - - grid.attr({ - width: w, - height: h, - fill: p - }); - } - }; - - self.generateId = function(url){ - var idBase = '_'+url.substring(url.lastIndexOf('/')+1).replace('.', '-'); // _ at first place if filename starts with a digit - var suffix = 0; - var id = idBase + "-" + suffix; - while(snap.select('#'+id) !== null){ - suffix += 1; - id = idBase + suffix; - } - return id; - }; - - self.getCompositionSVG = function(){ - // TODO use lasercutterprofiles - var dpiFactor = self.svgDPI()/25.4; // convert mm to pix with 90dpi (inkscape default - TODO use 72 for illustrator svg and fetch from settings) - var w = dpiFactor * self.settings.printerProfiles.currentProfileData().volume.width; - var h = dpiFactor * self.settings.printerProfiles.currentProfileData().volume.depth; - - var tmpsvg = snap.select("#userContent").innerSVG(); // get working area - var svg = ''+ tmpsvg +''; - return svg; - }; - - self.onStartup = function(){ - self.files.workingArea = self; - $(window).resize(function(){ - self.trigger_resize(); + self.scaleMatrix = ko.computed(function(){ + var m = new Snap.Matrix(); + m.scale(25.4/self.svgDPI() * 1/self.px2mm_factor()); + return m; }); - self.trigger_resize(); // initialize - self.init(); - }; -} + + self.placedDesigns = ko.observableArray([]); + + self.clear = function(){ + snap.selectAll('#userContent>*').remove(); + self.placedDesigns([]); + }; + + self.trigger_resize = function(){ + self.availableHeight(document.documentElement.clientHeight - $('body>nav').outerHeight() - $('footer>*').outerHeight() - 39); // magic number + self.availableWidth($('#workingarea div.span8').innerWidth()); + }; + + self.move_laser = function(el){ + var x = self.px2mm(event.offsetX); + // var y = self.px2mm(event.toElement.offsetHeight - event.offsetY); // toElement.offsetHeight is always 0 on svg>* elements ??? + var y = self.px2mm(event.toElement.ownerSVGElement.offsetHeight - event.offsetY); // hopefully this works across browsers + $.ajax({ + url: API_BASEURL + "printer/printhead", + type: "POST", + dataType: "json", + contentType: "application/json; charset=UTF-8", + data: JSON.stringify({"command": "position", x:x, y:y}) + }); + }; + + self.crosshairX = function(){ + var pos = self.state.currentPos(); + return pos !== undefined ? (self.mm2px(pos.x) - 15) : -100; // subtract width/2; + + }; + self.crosshairY = function(){ + var h = document.getElementById('area_preview').clientHeight; + var pos = self.state.currentPos(); + return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2; + }; + + self.px2mm = function(val){ + return val * self.px2mm_factor(); + }; + + self.mm2px = function(val){ + return val / self.px2mm_factor(); + }; + + self.mm2svgUnits = function(val){ + return val * self.svgDPI()/25.4; + }; + + //self.getDivDimensions(); // init + + self.placeSVG = function(file) { + if (file && file["refs"] && file["refs"]["download"]) { + var url = file.refs.download.replace("downloads", "serve"); + self.loadSVG(url); + } + }; + + self.loadSVG = function(url){ + Snap.load(url, function (f) { + var namespaces = {}; + var root = f.select('svg').node.attributes; + for(var i = 0; i < root.length; i++){ + var attr = root[i]; + if(attr.name.indexOf("xmlns") === 0){ + namespaces[attr.name] = attr.value; + } + } + + var newSvg = f.select("g"); + newSvg.attr(namespaces); + var id = self.generateId(url); + snap.select("#userContent").append(newSvg); + + newSvg.drag();// Making croc draggable. Go ahead drag it around! + // Obviously drag could take event handlers too + var ref = { + id : id, + url : url + }; + self.placedDesigns.push(ref); + }); + }; + + self.init = function(){ + // init snap.svg + snap = Snap('#area_preview'); + self.px2mm_factor.subscribe(function(newVal){ + if(!isNaN(newVal)) + self.draw_coord_grid(); + }); + }; + + self.draw_coord_grid = function(){ + var grid = snap.select('#coordGrid'); + if(grid.attr('fill') === 'none'){ + var w = self.mm2svgUnits(self.workingAreaWidthMM()); + var h = self.mm2svgUnits(self.workingAreaHeightMM()); + var max_lines = 20; + + var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10; + var yPatternOffset = self.mm2svgUnits(self.workingAreaHeightMM() % linedistMM); + var linedist = self.mm2svgUnits(linedistMM); + + var marker = snap.circle(linedist/2, linedist/2, 1).attr({ + fill: "#000000", + stroke: "none", + strokeWidth: 1 + }); + + // dot pattern + var p = marker.pattern(0, 0, linedist, linedist); + p.attr({ + x: linedist/2, + y: linedist/2 + yPatternOffset + }); + + grid.attr({ + width: w, + height: h, + fill: p + }); + } + }; + + self.generateId = function(url){ + var idBase = '_'+url.substring(url.lastIndexOf('/')+1).replace('.', '-'); // _ at first place if filename starts with a digit + var suffix = 0; + var id = idBase + "-" + suffix; + while(snap.select('#'+id) !== null){ + suffix += 1; + id = idBase + suffix; + } + return id; + }; + + self.getCompositionSVG = function(){ + // TODO use lasercutterprofiles + var dpiFactor = self.svgDPI()/25.4; // convert mm to pix with 90dpi (inkscape default - TODO use 72 for illustrator svg and fetch from settings) + var w = dpiFactor * self.settings.printerProfiles.currentProfileData().volume.width; + var h = dpiFactor * self.settings.printerProfiles.currentProfileData().volume.depth; + + var tmpsvg = snap.select("#userContent").innerSVG(); // get working area + var svg = ''+ tmpsvg +''; + return svg; + }; + + self.onStartup = function(){ + self.files.workingArea = self; + self.conversion.workingArea = self; + $(window).resize(function(){ + self.trigger_resize(); + }); + self.trigger_resize(); // initialize + self.init(); + }; + } + + + // view model class, parameters for constructor, container to bind to + ADDITIONAL_VIEWMODELS.push([WorkingAreaViewModel, "workingAreaViewModel", + ["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "gcodeFilesViewModel", "vectorConversionViewModel"], + document.getElementById("area_preview")]); + +}); \ No newline at end of file diff --git a/src/octoprint/plugins/svgtogcode/templates/svgtogcode_settings_dialog.jinja2 b/src/octoprint/plugins/svgtogcode/templates/svgtogcode_settings.jinja2 similarity index 95% rename from src/octoprint/plugins/svgtogcode/templates/svgtogcode_settings_dialog.jinja2 rename to src/octoprint/plugins/svgtogcode/templates/svgtogcode_settings.jinja2 index 07044e44..5d179b20 100644 --- a/src/octoprint/plugins/svgtogcode/templates/svgtogcode_settings_dialog.jinja2 +++ b/src/octoprint/plugins/svgtogcode/templates/svgtogcode_settings.jinja2 @@ -1,17 +1,23 @@ -
+

{{ _('Default settings') }}

- +
- +
- +
- + +
+
+
+ +
+
diff --git a/src/octoprint/static/js/app/viewmodels/printerstate.js b/src/octoprint/static/js/app/viewmodels/printerstate.js index 6ef6593c..1f47508d 100644 --- a/src/octoprint/static/js/app/viewmodels/printerstate.js +++ b/src/octoprint/static/js/app/viewmodels/printerstate.js @@ -163,7 +163,7 @@ function PrinterStateViewModel(loginStateViewModel, timelapseViewModel, vectorCo if (data.file) { self.filename(data.file.name); self.filesize(data.file.size); - self.sd(data.file.origin == "sdcard"); + self.sd(data.file.origin === "sdcard"); } else { self.filename(undefined); self.filesize(undefined); @@ -174,7 +174,7 @@ function PrinterStateViewModel(loginStateViewModel, timelapseViewModel, vectorCo self.lastPrintTime(data.lastPrintTime); var result = []; - if (data.filament && typeof(data.filament) == "object" && _.keys(data.filament).length > 0) { + if (data.filament && typeof(data.filament) === "object" && _.keys(data.filament).length > 0) { for (var key in data.filament) { if (!_.startsWith(key, "tool") || !data.filament[key] || !data.filament[key].hasOwnProperty("length") || data.filament[key].length <= 0) continue; diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js index a3872f8e..24122c5b 100644 --- a/src/octoprint/static/js/app/viewmodels/settings.js +++ b/src/octoprint/static/js/app/viewmodels/settings.js @@ -65,7 +65,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV self.feature_sdAlwaysAvailable = ko.observable(undefined); self.feature_swallowOkAfterResend = ko.observable(undefined); self.feature_repetierTargetTemp = ko.observable(undefined); - self.feature_zaxis = ko.observable(undefined); self.feature_keyboardControl = ko.observable(undefined); self.serial_port = ko.observable(); @@ -90,9 +89,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV self.cura_path = ko.observable(undefined); self.cura_config = ko.observable(undefined); - self.svgtogcode_defaultIntensity = ko.observable(undefined); - self.svgtogcode_defaultFeedrate = ko.observable(undefined); - self.temperature_profiles = ko.observableArray(undefined); self.system_actions = ko.observableArray([]); @@ -150,7 +146,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV } else { ko.mapping.fromJS(response, self.settings); } - self.api_enabled(response.api.enabled); self.api_key(response.api.key); self.api_allowCrossOrigin(response.api.allowCrossOrigin); @@ -176,7 +171,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV self.feature_sdAlwaysAvailable(response.feature.sdAlwaysAvailable); self.feature_swallowOkAfterResend(response.feature.swallowOkAfterResend); self.feature_repetierTargetTemp(response.feature.repetierTargetTemp); - self.feature_zaxis(response.feature.zaxis); self.feature_keyboardControl(response.feature.keyboardControl); self.serial_port(response.serial.port); @@ -240,7 +234,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV "sdAlwaysAvailable": self.feature_sdAlwaysAvailable(), "swallowOkAfterResend": self.feature_swallowOkAfterResend(), "repetierTargetTemp": self.feature_repetierTargetTemp(), - "zaxis": self.feature_zaxis(), "keyboardControl": self.feature_keyboardControl() }, "serial": {