diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 1b5de89c2b..6056745c75 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -451,27 +451,18 @@ class CuraApplication(QtApplication): @pyqtSlot(str) def discardOrKeepProfileChangesClosed(self, option): + global_stack = self.getGlobalContainerStack() if option == "discard": - global_stack = self.getGlobalContainerStack() - for extruder in self._extruder_manager.getMachineExtruders(global_stack.getId()): - extruder.getTop().clear() - global_stack.getTop().clear() + for extruder in global_stack.extruders.values(): + extruder.userChanges.clear() + global_stack.userChanges.clear() # if the user decided to keep settings then the user settings should be re-calculated and validated for errors # before slicing. To ensure that slicer uses right settings values elif option == "keep": - global_stack = self.getGlobalContainerStack() - for extruder in self._extruder_manager.getMachineExtruders(global_stack.getId()): - user_extruder_container = extruder.getTop() - if user_extruder_container: - user_extruder_container.update() - - user_global_container = global_stack.getTop() - if user_global_container: - user_global_container.update() - - # notify listeners that quality has changed (after user selected discard or keep) - self.getMachineManager().activeQualityChanged.emit() + for extruder in global_stack.extruders.values(): + extruder.userChanges.update() + global_stack.userChanges.update() @pyqtSlot(int) def messageBoxClosed(self, button): diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index e4c7f1608e..75b9cc98ac 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -18,6 +18,7 @@ class ExtruderOutputModel(QObject): hotendTemperatureChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() extruderConfigurationChanged = pyqtSignal() + isPreheatingChanged = pyqtSignal() def __init__(self, printer: "PrinterOutputModel", position, parent=None): super().__init__(parent) @@ -30,6 +31,21 @@ class ExtruderOutputModel(QObject): self._extruder_configuration = ExtruderConfigurationModel() self._extruder_configuration.position = self._position + self._is_preheating = False + + def getPrinter(self): + return self._printer + + def getPosition(self): + return self._position + + # Does the printer support pre-heating the bed at all + @pyqtProperty(bool, constant=True) + def canPreHeatHotends(self): + if self._printer: + return self._printer.canPreHeatHotends + return False + @pyqtProperty(QObject, notify = activeMaterialChanged) def activeMaterial(self) -> "MaterialOutputModel": return self._active_material @@ -82,3 +98,25 @@ class ExtruderOutputModel(QObject): if self._extruder_configuration.isValid(): return self._extruder_configuration return None + + def updateIsPreheating(self, pre_heating): + if self._is_preheating != pre_heating: + self._is_preheating = pre_heating + self.isPreheatingChanged.emit() + + @pyqtProperty(bool, notify=isPreheatingChanged) + def isPreheating(self): + return self._is_preheating + + ## Pre-heats the extruder before printer. + # + # \param temperature The temperature to heat the extruder to, in degrees + # Celsius. + # \param duration How long the bed should stay warm, in seconds. + @pyqtSlot(float, float) + def preheatHotend(self, temperature, duration): + self._printer._controller.preheatHotend(self, temperature, duration) + + @pyqtSlot() + def cancelPreheatHotend(self): + self._printer._controller.cancelPreheatHotend(self) \ No newline at end of file diff --git a/cura/PrinterOutput/GenericOutputController.py b/cura/PrinterOutput/GenericOutputController.py new file mode 100644 index 0000000000..a21425af92 --- /dev/null +++ b/cura/PrinterOutput/GenericOutputController.py @@ -0,0 +1,151 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from cura.PrinterOutput.PrinterOutputController import PrinterOutputController +from PyQt5.QtCore import QTimer + +MYPY = False +if MYPY: + from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel + from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel + + +class GenericOutputController(PrinterOutputController): + def __init__(self, output_device): + super().__init__(output_device) + + self._preheat_bed_timer = QTimer() + self._preheat_bed_timer.setSingleShot(True) + self._preheat_bed_timer.timeout.connect(self._onPreheatBedTimerFinished) + self._preheat_printer = None + + self._preheat_hotends_timer = QTimer() + self._preheat_hotends_timer.setSingleShot(True) + self._preheat_hotends_timer.timeout.connect(self._onPreheatHotendsTimerFinished) + self._preheat_hotends = set() + + self._output_device.printersChanged.connect(self._onPrintersChanged) + self._active_printer = None + + def _onPrintersChanged(self): + if self._active_printer: + self._active_printer.stateChanged.disconnect(self._onPrinterStateChanged) + self._active_printer.targetBedTemperatureChanged.disconnect(self._onTargetBedTemperatureChanged) + for extruder in self._active_printer.extruders: + extruder.targetHotendTemperatureChanged.disconnect(self._onTargetHotendTemperatureChanged) + + self._active_printer = self._output_device.activePrinter + if self._active_printer: + self._active_printer.stateChanged.connect(self._onPrinterStateChanged) + self._active_printer.targetBedTemperatureChanged.connect(self._onTargetBedTemperatureChanged) + for extruder in self._active_printer.extruders: + extruder.targetHotendTemperatureChanged.connect(self._onTargetHotendTemperatureChanged) + + def _onPrinterStateChanged(self): + if self._active_printer.state != "idle": + if self._preheat_bed_timer.isActive(): + self._preheat_bed_timer.stop() + self._preheat_printer.updateIsPreheating(False) + if self._preheat_hotends_timer.isActive(): + self._preheat_hotends_timer.stop() + for extruder in self._preheat_hotends: + extruder.updateIsPreheating(False) + self._preheat_hotends = set() + + def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed): + self._output_device.sendCommand("G91") + self._output_device.sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed)) + self._output_device.sendCommand("G90") + + def homeHead(self, printer): + self._output_device.sendCommand("G28 X") + self._output_device.sendCommand("G28 Y") + + def homeBed(self, printer): + self._output_device.sendCommand("G28 Z") + + def setJobState(self, job: "PrintJobOutputModel", state: str): + if state == "pause": + self._output_device.pausePrint() + job.updateState("paused") + elif state == "print": + self._output_device.resumePrint() + job.updateState("printing") + elif state == "abort": + self._output_device.cancelPrint() + pass + + def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: int): + self._output_device.sendCommand("M140 S%s" % temperature) + + def _onTargetBedTemperatureChanged(self): + if self._preheat_bed_timer.isActive() and self._preheat_printer.targetBedTemperature == 0: + self._preheat_bed_timer.stop() + self._preheat_printer.updateIsPreheating(False) + + def preheatBed(self, printer: "PrinterOutputModel", temperature, duration): + try: + temperature = round(temperature) # The API doesn't allow floating point. + duration = round(duration) + except ValueError: + return # Got invalid values, can't pre-heat. + + self.setTargetBedTemperature(printer, temperature=temperature) + self._preheat_bed_timer.setInterval(duration * 1000) + self._preheat_bed_timer.start() + self._preheat_printer = printer + printer.updateIsPreheating(True) + + def cancelPreheatBed(self, printer: "PrinterOutputModel"): + self.setTargetBedTemperature(printer, temperature=0) + self._preheat_bed_timer.stop() + printer.updateIsPreheating(False) + + def _onPreheatBedTimerFinished(self): + self.setTargetBedTemperature(self._preheat_printer, 0) + self._preheat_printer.updateIsPreheating(False) + + def setTargetHotendTemperature(self, printer: "PrinterOutputModel", position: int, temperature: int): + self._output_device.sendCommand("M104 S%s T%s" % (temperature, position)) + + def _onTargetHotendTemperatureChanged(self): + if not self._preheat_hotends_timer.isActive(): + return + + for extruder in self._active_printer.extruders: + if extruder in self._preheat_hotends and extruder.targetHotendTemperature == 0: + extruder.updateIsPreheating(False) + self._preheat_hotends.remove(extruder) + if not self._preheat_hotends: + self._preheat_hotends_timer.stop() + + def preheatHotend(self, extruder: "ExtruderOutputModel", temperature, duration): + position = extruder.getPosition() + number_of_extruders = len(extruder.getPrinter().extruders) + if position >= number_of_extruders: + return # Got invalid extruder nr, can't pre-heat. + + try: + temperature = round(temperature) # The API doesn't allow floating point. + duration = round(duration) + except ValueError: + return # Got invalid values, can't pre-heat. + + self.setTargetHotendTemperature(extruder.getPrinter(), position, temperature=temperature) + self._preheat_hotends_timer.setInterval(duration * 1000) + self._preheat_hotends_timer.start() + self._preheat_hotends.add(extruder) + extruder.updateIsPreheating(True) + + def cancelPreheatHotend(self, extruder: "ExtruderOutputModel"): + self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), temperature=0) + if extruder in self._preheat_hotends: + extruder.updateIsPreheating(False) + self._preheat_hotends.remove(extruder) + if not self._preheat_hotends and self._preheat_hotends_timer.isActive(): + self._preheat_hotends_timer.stop() + + def _onPreheatHotendsTimerFinished(self): + for extruder in self._preheat_hotends: + self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0) + self._preheat_hotends = set() diff --git a/cura/PrinterOutput/PrinterOutputController.py b/cura/PrinterOutput/PrinterOutputController.py index 1d658e79be..b5b0dd0be3 100644 --- a/cura/PrinterOutput/PrinterOutputController.py +++ b/cura/PrinterOutput/PrinterOutputController.py @@ -15,6 +15,7 @@ class PrinterOutputController: self.can_pause = True self.can_abort = True self.can_pre_heat_bed = True + self.can_pre_heat_hotends = True self.can_control_manually = True self._output_device = output_device @@ -33,6 +34,12 @@ class PrinterOutputController: def preheatBed(self, printer: "PrinterOutputModel", temperature, duration): Logger.log("w", "Preheat bed not implemented in controller") + def cancelPreheatHotend(self, extruder: "ExtruderOutputModel"): + Logger.log("w", "Cancel preheat hotend not implemented in controller") + + def preheatHotend(self, extruder: "ExtruderOutputModel", temperature, duration): + Logger.log("w", "Preheat hotend not implemented in controller") + def setHeadPosition(self, printer: "PrinterOutputModel", x, y, z, speed): Logger.log("w", "Set head position not implemented in controller") diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 712f9b5b1e..e936ace196 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -238,6 +238,13 @@ class PrinterOutputModel(QObject): return self._controller.can_pre_heat_bed return False + # Does the printer support pre-heating the bed at all + @pyqtProperty(bool, constant=True) + def canPreHeatHotends(self): + if self._controller: + return self._controller.can_pre_heat_hotends + return False + # Does the printer support pause at all @pyqtProperty(bool, constant=True) def canPause(self): diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 50c3c53734..9619329e59 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1269,6 +1269,13 @@ class MachineManager(QObject): if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: self._application.discardOrKeepProfileChanges() + @pyqtSlot() + def resetToUseDefaultQuality(self): + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._setQualityGroup(self._current_quality_group) + for stack in [self._global_container_stack] + list(self._global_container_stack.extruders.values()): + stack.userChanges.clear() + @pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged) def activeQualityChangesGroup(self): return self._current_quality_changes_group diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index 867a21702c..a337d8b04e 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -16,7 +16,8 @@ class SimpleModeSettingsManager(QObject): self._is_profile_user_created = False # True when profile was custom created by user self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized) - self._machine_manager.activeQualityChanged.connect(self._updateIsProfileUserCreated) + self._machine_manager.activeQualityGroupChanged.connect(self._updateIsProfileUserCreated) + self._machine_manager.activeQualityChangesGroupChanged.connect(self._updateIsProfileUserCreated) # update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts self._updateIsProfileCustomized() diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 1b3b7264a1..4b78a2a72a 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -1,17 +1,17 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import re # For escaping characters in the settings. +import json +import copy + from UM.Mesh.MeshWriter import MeshWriter from UM.Logger import Logger from UM.Application import Application from UM.Settings.InstanceContainer import InstanceContainer -from UM.Util import parseBool -from cura.Settings.ExtruderManager import ExtruderManager +from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch -import re #For escaping characters in the settings. -import json -import copy ## Writes g-code to a file. # @@ -45,6 +45,8 @@ class GCodeWriter(MeshWriter): def __init__(self): super().__init__() + self._application = Application.getInstance() + ## Writes the g-code for the entire scene to a stream. # # Note that even though the function accepts a collection of nodes, the @@ -94,7 +96,6 @@ class GCodeWriter(MeshWriter): return flat_container - ## Serialises a container stack to prepare it for writing at the end of the # g-code. # @@ -104,15 +105,21 @@ class GCodeWriter(MeshWriter): # \param settings A container stack to serialise. # \return A serialised string of the settings. def _serialiseSettings(self, stack): + container_registry = self._application.getContainerRegistry() + quality_manager = self._application.getQualityManager() + prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line. prefix_length = len(prefix) + quality_name = stack.qualityChanges.getName() + quality_type = stack.quality.getMetaDataEntry("quality_type") container_with_profile = stack.qualityChanges if container_with_profile.getId() == "empty_quality_changes": - Logger.log("e", "No valid quality profile found, not writing settings to g-code!") - return "" + # If the global quality changes is empty, create a new one + quality_name = container_registry.uniqueName(stack.quality.getName()) + container_with_profile = quality_manager._createQualityChanges(quality_type, quality_name, stack, None) - flat_global_container = self._createFlattenedContainerInstance(stack.getTop(), container_with_profile) + flat_global_container = self._createFlattenedContainerInstance(stack.userChanges, container_with_profile) # If the quality changes is not set, we need to set type manually if flat_global_container.getMetaDataEntry("type", None) is None: flat_global_container.addMetaDataEntry("type", "quality_changes") @@ -121,41 +128,47 @@ class GCodeWriter(MeshWriter): if flat_global_container.getMetaDataEntry("quality_type", None) is None: flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal")) - # Change the default defintion - default_machine_definition = "fdmprinter" - if parseBool(stack.getMetaDataEntry("has_machine_quality", "False")): - default_machine_definition = stack.getMetaDataEntry("quality_definition") - if not default_machine_definition: - default_machine_definition = stack.definition.getId() - flat_global_container.setMetaDataEntry("definition", default_machine_definition) + # Get the machine definition ID for quality profiles + machine_definition_id_for_quality = getMachineDefinitionIDForQualitySearch(stack.definition) + flat_global_container.setMetaDataEntry("definition", machine_definition_id_for_quality) serialized = flat_global_container.serialize() data = {"global_quality": serialized} - for extruder in sorted(stack.extruders.values(), key = lambda k: k.getMetaDataEntry("position")): + all_setting_keys = set(flat_global_container.getAllKeys()) + for extruder in sorted(stack.extruders.values(), key = lambda k: int(k.getMetaDataEntry("position"))): extruder_quality = extruder.qualityChanges if extruder_quality.getId() == "empty_quality_changes": - Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId()) - continue - flat_extruder_quality = self._createFlattenedContainerInstance(extruder.getTop(), extruder_quality) + # Same story, if quality changes is empty, create a new one + quality_name = container_registry.uniqueName(stack.quality.getName()) + extruder_quality = quality_manager._createQualityChanges(quality_type, quality_name, stack, None) + + flat_extruder_quality = self._createFlattenedContainerInstance(extruder.userChanges, extruder_quality) # If the quality changes is not set, we need to set type manually if flat_extruder_quality.getMetaDataEntry("type", None) is None: flat_extruder_quality.addMetaDataEntry("type", "quality_changes") # Ensure that extruder is set. (Can happen if we have empty quality changes). - if flat_extruder_quality.getMetaDataEntry("extruder", None) is None: - flat_extruder_quality.addMetaDataEntry("extruder", extruder.getBottom().getId()) + if flat_extruder_quality.getMetaDataEntry("position", None) is None: + flat_extruder_quality.addMetaDataEntry("position", extruder.getMetaDataEntry("position")) # Ensure that quality_type is set. (Can happen if we have empty quality changes). if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None: flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal")) - # Change the default defintion - flat_extruder_quality.setMetaDataEntry("definition", default_machine_definition) + # Change the default definition + flat_extruder_quality.setMetaDataEntry("definition", machine_definition_id_for_quality) extruder_serialized = flat_extruder_quality.serialize() data.setdefault("extruder_quality", []).append(extruder_serialized) + all_setting_keys.update(set(flat_extruder_quality.getAllKeys())) + + # Check if there is any profiles + if not all_setting_keys: + Logger.log("i", "No custom settings found, not writing settings to g-code.") + return "" + json_string = json.dumps(data) # Escape characters that have a special meaning in g-code comments. @@ -169,5 +182,5 @@ class GCodeWriter(MeshWriter): # Lines have 80 characters, so the payload of each line is 80 - prefix. for pos in range(0, len(escaped_string), 80 - prefix_length): - result += prefix + escaped_string[pos : pos + 80 - prefix_length] + "\n" + result += prefix + escaped_string[pos: pos + 80 - prefix_length] + "\n" return result diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 03a2ce1bf4..a2790dcf08 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -163,7 +163,16 @@ Item { id: addedSettingsModel; containerId: Cura.MachineManager.activeDefinitionId expanded: [ "*" ] - exclude: { + filter: + { + if (printSequencePropertyProvider.properties.value == "one_at_a_time") + { + return {"settable_per_meshgroup": true}; + } + return {"settable_per_mesh": true}; + } + exclude: + { var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]; if(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type == "support_mesh") @@ -375,7 +384,6 @@ Item { title: catalog.i18nc("@title:window", "Select Settings to Customize for this model") width: screenScaleFactor * 360 - property string labelFilter: "" property var additional_excluded_settings onVisibilityChanged: @@ -386,11 +394,33 @@ Item { // Set skip setting, it will prevent from resetting selected mesh_type contents.model.visibilityHandler.addSkipResetSetting(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type) listview.model.forceUpdate() + + updateFilter() } } + function updateFilter() + { + var new_filter = {}; + if (printSequencePropertyProvider.properties.value == "one_at_a_time") + { + new_filter["settable_per_meshgroup"] = true; + } + else + { + new_filter["settable_per_mesh"] = true; + } + + if(filterInput.text != "") + { + new_filter["i18n_label"] = "*" + filterInput.text; + } + + listview.model.filter = new_filter; + } + TextField { - id: filter + id: filterInput anchors { top: parent.top @@ -401,17 +431,7 @@ Item { placeholderText: catalog.i18nc("@label:textbox", "Filter..."); - onTextChanged: - { - if(text != "") - { - listview.model.filter = {"settable_per_mesh": true, "i18n_label": "*" + text} - } - else - { - listview.model.filter = {"settable_per_mesh": true} - } - } + onTextChanged: settingPickDialog.updateFilter() } CheckBox @@ -437,7 +457,7 @@ Item { anchors { - top: filter.bottom; + top: filterInput.bottom; left: parent.left; right: parent.right; bottom: parent.bottom; @@ -449,10 +469,6 @@ Item { { id: definitionsModel; containerId: Cura.MachineManager.activeDefinitionId - filter: - { - "settable_per_mesh": true - } visibilityHandler: UM.SettingPreferenceVisibilityHandler {} expanded: [ "*" ] exclude: @@ -484,6 +500,7 @@ Item { } } } + Component.onCompleted: settingPickDialog.updateFilter() } } @@ -507,6 +524,16 @@ Item { storeIndex: 0 } + UM.SettingPropertyProvider + { + id: printSequencePropertyProvider + + containerStackId: Cura.MachineManager.activeMachineId + key: "print_sequence" + watchedProperties: [ "value" ] + storeIndex: 0 + } + SystemPalette { id: palette; } Component diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index ff930e2c31..1bfdbd4117 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -60,7 +60,7 @@ class RemovableDriveOutputDevice(OutputDevice): if len(file_formats) == 0: Logger.log("e", "There are no file formats available to write with!") - raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("There are no file formats available to write with!")) + raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("@info:status", "There are no file formats available to write with!")) # Just take the first file format available. if file_handler is not None: diff --git a/plugins/UM3NetworkPrinting/ClusterUM3PrinterOutputController.py b/plugins/UM3NetworkPrinting/ClusterUM3PrinterOutputController.py index 4615cd62dc..076c4584af 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3PrinterOutputController.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3PrinterOutputController.py @@ -13,6 +13,7 @@ class ClusterUM3PrinterOutputController(PrinterOutputController): def __init__(self, output_device): super().__init__(output_device) self.can_pre_heat_bed = False + self.can_pre_heat_hotends = False self.can_control_manually = False def setJobState(self, job: "PrintJobOutputModel", state: str): diff --git a/plugins/USBPrinting/USBPrinterOutputController.py b/plugins/USBPrinting/USBPrinterOutputController.py deleted file mode 100644 index f189ed5876..0000000000 --- a/plugins/USBPrinting/USBPrinterOutputController.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from cura.PrinterOutput.PrinterOutputController import PrinterOutputController -from PyQt5.QtCore import QTimer - -MYPY = False -if MYPY: - from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel - from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel - - -class USBPrinterOutputController(PrinterOutputController): - def __init__(self, output_device): - super().__init__(output_device) - - self._preheat_bed_timer = QTimer() - self._preheat_bed_timer.setSingleShot(True) - self._preheat_bed_timer.timeout.connect(self._onPreheatBedTimerFinished) - self._preheat_printer = None - - def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed): - self._output_device.sendCommand("G91") - self._output_device.sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed)) - self._output_device.sendCommand("G90") - - def homeHead(self, printer): - self._output_device.sendCommand("G28 X") - self._output_device.sendCommand("G28 Y") - - def homeBed(self, printer): - self._output_device.sendCommand("G28 Z") - - def setJobState(self, job: "PrintJobOutputModel", state: str): - if state == "pause": - self._output_device.pausePrint() - job.updateState("paused") - elif state == "print": - self._output_device.resumePrint() - job.updateState("printing") - elif state == "abort": - self._output_device.cancelPrint() - pass - - def preheatBed(self, printer: "PrinterOutputModel", temperature, duration): - try: - temperature = round(temperature) # The API doesn't allow floating point. - duration = round(duration) - except ValueError: - return # Got invalid values, can't pre-heat. - - self.setTargetBedTemperature(printer, temperature=temperature) - self._preheat_bed_timer.setInterval(duration * 1000) - self._preheat_bed_timer.start() - self._preheat_printer = printer - printer.updateIsPreheating(True) - - def cancelPreheatBed(self, printer: "PrinterOutputModel"): - self.preheatBed(printer, temperature=0, duration=0) - self._preheat_bed_timer.stop() - printer.updateIsPreheating(False) - - def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: int): - self._output_device.sendCommand("M140 S%s" % temperature) - - def _onPreheatBedTimerFinished(self): - self.setTargetBedTemperature(self._preheat_printer, 0) - self._preheat_printer.updateIsPreheating(False) \ No newline at end of file diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 14098b66f8..24feedd628 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -10,9 +10,9 @@ from UM.PluginRegistry import PluginRegistry from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel +from cura.PrinterOutput.GenericOutputController import GenericOutputController from .AutoDetectBaudJob import AutoDetectBaudJob -from .USBPrinterOutputController import USBPrinterOutputController from .avr_isp import stk500v2, intelHex from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty @@ -240,7 +240,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): container_stack = Application.getInstance().getGlobalContainerStack() num_extruders = container_stack.getProperty("machine_extruder_count", "value") # Ensure that a printer is created. - self._printers = [PrinterOutputModel(output_controller=USBPrinterOutputController(self), number_of_extruders=num_extruders)] + self._printers = [PrinterOutputModel(output_controller=GenericOutputController(self), number_of_extruders=num_extruders)] self._printers[0].updateName(container_stack.getName()) self.setConnectionState(ConnectionState.connected) self._update_thread.start() @@ -372,7 +372,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): elapsed_time = int(time() - self._print_start_time) print_job = self._printers[0].activePrintJob if print_job is None: - print_job = PrintJobOutputModel(output_controller = USBPrinterOutputController(self), name= Application.getInstance().getPrintInformation().jobName) + print_job = PrintJobOutputModel(output_controller = GenericOutputController(self), name= Application.getInstance().getPrintInformation().jobName) print_job.updateState("printing") self._printers[0].updateActivePrintJob(print_job) diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 75b756c71e..08be4b8d34 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -6,7 +6,7 @@ "visible": true, "manufacturer": "BQ", "author": "BQ", - "file_formats": "text/x-code", + "file_formats": "text/x-gcode", "platform": "bq_hephestos_platform.stl", "platform_offset": [ 0, -82, 0] }, diff --git a/resources/definitions/seemecnc_artemis.def.json b/resources/definitions/seemecnc_artemis.def.json index 88a1b28de6..0b31abfa41 100644 --- a/resources/definitions/seemecnc_artemis.def.json +++ b/resources/definitions/seemecnc_artemis.def.json @@ -25,6 +25,7 @@ "machine_nozzle_size": { "default_value": 0.5 }, "machine_shape": { "default_value": "elliptic" }, "machine_width": { "default_value": 290 }, + "material_diameter": { "default_value": 1.75 }, "relative_extrusion": { "default_value": false }, "retraction_amount": { "default_value": 3.2 }, "retraction_combing": { "default_value": "off" }, diff --git a/resources/definitions/seemecnc_v32.def.json b/resources/definitions/seemecnc_v32.def.json index 5932403bc5..3f46c1540a 100644 --- a/resources/definitions/seemecnc_v32.def.json +++ b/resources/definitions/seemecnc_v32.def.json @@ -25,6 +25,7 @@ "machine_nozzle_size": { "default_value": 0.5 }, "machine_shape": { "default_value": "elliptic" }, "machine_width": { "default_value": 265 }, + "material_diameter": { "default_value": 1.75 }, "relative_extrusion": { "default_value": false }, "retraction_amount": { "default_value": 3.2 }, "retraction_combing": { "default_value": "off" }, diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index a7141262a9..56c86f1034 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -12,9 +12,20 @@ Item property alias color: background.color property var extruderModel property var position: index - //width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.floor(extrudersGrid.width / 2 - UM.Theme.getSize("sidebar_lining_thin").width / 2) implicitWidth: parent.width implicitHeight: UM.Theme.getSize("sidebar_extruder_box").height + + UM.SettingPropertyProvider + { + id: extruderTemperature + containerStackId: Cura.ExtruderManager.extruderIds[position] + key: "material_print_temperature" + watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"] + storeIndex: 0 + + property var resolve: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId ? properties.resolve : "None" + } + Rectangle { id: background @@ -34,12 +45,11 @@ Item { id: extruderTargetTemperature text: Math.round(extruderModel.targetHotendTemperature) + "°C" - //text: (connectedPrinter != null && connectedPrinter.hotendIds[index] != null && connectedPrinter.targetHotendTemperatures[index] != null) ? Math.round(connectedPrinter.targetHotendTemperatures[index]) + "°C" : "" font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_inactive") anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width - anchors.bottom: extruderTemperature.bottom + anchors.bottom: extruderCurrentTemperature.bottom MouseArea //For tooltip. { @@ -52,7 +62,7 @@ Item { base.showTooltip( base, - {x: 0, y: extruderTargetTemperature.mapToItem(base, 0, -parent.height / 4).y}, + {x: 0, y: extruderTargetTemperature.mapToItem(base, 0, Math.floor(-parent.height / 4)).y}, catalog.i18nc("@tooltip", "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off.") ); } @@ -65,9 +75,8 @@ Item } Label //Temperature indication. { - id: extruderTemperature + id: extruderCurrentTemperature text: Math.round(extruderModel.hotendTemperature) + "°C" - //text: (connectedPrinter != null && connectedPrinter.hotendIds[index] != null && connectedPrinter.hotendTemperatures[index] != null) ? Math.round(connectedPrinter.hotendTemperatures[index]) + "°C" : "" color: UM.Theme.getColor("text") font: UM.Theme.getFont("large") anchors.right: extruderTargetTemperature.left @@ -76,7 +85,7 @@ Item MouseArea //For tooltip. { - id: extruderTemperatureTooltipArea + id: extruderCurrentTemperatureTooltipArea hoverEnabled: true anchors.fill: parent onHoveredChanged: @@ -85,8 +94,8 @@ Item { base.showTooltip( base, - {x: 0, y: parent.mapToItem(base, 0, -parent.height / 4).y}, - catalog.i18nc("@tooltip", "The current temperature of this extruder.") + {x: 0, y: parent.mapToItem(base, 0, Math.floor(-parent.height / 4)).y}, + catalog.i18nc("@tooltip", "The current temperature of this hotend.") ); } else @@ -97,6 +106,272 @@ Item } } + Rectangle //Input field for pre-heat temperature. + { + id: preheatTemperatureControl + color: !enabled ? UM.Theme.getColor("setting_control_disabled") : showError ? UM.Theme.getColor("setting_validation_error_background") : UM.Theme.getColor("setting_validation_ok") + property var showError: + { + if(extruderTemperature.properties.maximum_value != "None" && extruderTemperature.properties.maximum_value < Math.floor(preheatTemperatureInput.text)) + { + return true; + } else + { + return false; + } + } + enabled: + { + if (extruderModel == null) + { + return false; //Can't preheat if not connected. + } + if (!connectedPrinter.acceptsCommands) + { + return false; //Not allowed to do anything. + } + if (connectedPrinter.activePrinter && connectedPrinter.activePrinter.activePrintJob) + { + if((["printing", "pre_print", "resuming", "pausing", "paused", "error", "offline"]).indexOf(connectedPrinter.activePrinter.activePrintJob.state) != -1) + { + return false; //Printer is in a state where it can't react to pre-heating. + } + } + return true; + } + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : preheatTemperatureInputMouseArea.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") + anchors.right: preheatButton.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("monitor_preheat_temperature_control").width + height: UM.Theme.getSize("monitor_preheat_temperature_control").height + visible: extruderModel != null ? enabled && extruderModel.canPreHeatHotends && !extruderModel.isPreheating : true + Rectangle //Highlight of input field. + { + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("setting_control_highlight") + opacity: preheatTemperatureControl.hovered ? 1.0 : 0 + } + MouseArea //Change cursor on hovering. + { + id: preheatTemperatureInputMouseArea + hoverEnabled: true + anchors.fill: parent + cursorShape: Qt.IBeamCursor + + onHoveredChanged: + { + if (containsMouse) + { + base.showTooltip( + base, + {x: 0, y: preheatTemperatureInputMouseArea.mapToItem(base, 0, 0).y}, + catalog.i18nc("@tooltip of temperature input", "The temperature to pre-heat the hotend to.") + ); + } + else + { + base.hideTooltip(); + } + } + } + Label + { + id: unit + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.verticalCenter: parent.verticalCenter + + text: "°C"; + color: UM.Theme.getColor("setting_unit") + font: UM.Theme.getFont("default") + } + TextInput + { + id: preheatTemperatureInput + font: UM.Theme.getFont("default") + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") + selectByMouse: true + maximumLength: 5 + enabled: parent.enabled + validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex. + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.right: unit.left + anchors.verticalCenter: parent.verticalCenter + renderType: Text.NativeRendering + + Component.onCompleted: + { + if (!extruderTemperature.properties.value) + { + text = ""; + } + else + { + text = extruderTemperature.properties.value; + } + } + } + } + + Button //The pre-heat button. + { + id: preheatButton + height: UM.Theme.getSize("setting_control").height + visible: extruderModel != null ? extruderModel.canPreHeatHotends: true + enabled: + { + if (!preheatTemperatureControl.enabled) + { + return false; //Not connected, not authenticated or printer is busy. + } + if (extruderModel.isPreheating) + { + return true; + } + if (extruderTemperature.properties.minimum_value != "None" && Math.floor(preheatTemperatureInput.text) < Math.floor(extruderTemperature.properties.minimum_value)) + { + return false; //Target temperature too low. + } + if (extruderTemperature.properties.maximum_value != "None" && Math.floor(preheatTemperatureInput.text) > Math.floor(extruderTemperature.properties.maximum_value)) + { + return false; //Target temperature too high. + } + if (Math.floor(preheatTemperatureInput.text) == 0) + { + return false; //Setting the temperature to 0 is not allowed (since that cancels the pre-heating). + } + return true; //Preconditions are met. + } + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: UM.Theme.getSize("default_margin").width + style: ButtonStyle { + background: Rectangle + { + border.width: UM.Theme.getSize("default_lining").width + implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2) + border.color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_border"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active_border"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_border"); + } + else + { + return UM.Theme.getColor("action_button_border"); + } + } + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered"); + } + else + { + return UM.Theme.getColor("action_button"); + } + } + Behavior on color + { + ColorAnimation + { + duration: 50 + } + } + + Label + { + id: actualLabel + anchors.centerIn: parent + color: + { + if(!control.enabled) + { + return UM.Theme.getColor("action_button_disabled_text"); + } + else if(control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + else + { + return UM.Theme.getColor("action_button_text"); + } + } + font: UM.Theme.getFont("action_button") + text: + { + if(extruderModel == null) + { + return "" + } + if(extruderModel.isPreheating ) + { + return catalog.i18nc("@button Cancel pre-heating", "Cancel") + } else + { + return catalog.i18nc("@button", "Pre-heat") + } + } + } + } + } + + onClicked: + { + if (!extruderModel.isPreheating) + { + extruderModel.preheatHotend(preheatTemperatureInput.text, 900); + } + else + { + extruderModel.cancelPreheatHotend(); + } + } + + onHoveredChanged: + { + if (hovered) + { + base.showTooltip( + base, + {x: 0, y: preheatButton.mapToItem(base, 0, 0).y}, + catalog.i18nc("@tooltip of pre-heat", "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print.") + ); + } + else + { + base.hideTooltip(); + } + } + } + Rectangle //Material colour indication. { id: materialColor diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index bc89da2251..385977141c 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -114,21 +114,24 @@ Item { return false; //Not allowed to do anything. } - if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "pre_print" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "paused" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline") + if (connectedPrinter.activePrinter && connectedPrinter.activePrinter.activePrintJob) { - return false; //Printer is in a state where it can't react to pre-heating. + if((["printing", "pre_print", "resuming", "pausing", "paused", "error", "offline"]).indexOf(connectedPrinter.activePrinter.activePrintJob.state) != -1) + { + return false; //Printer is in a state where it can't react to pre-heating. + } } return true; } border.width: UM.Theme.getSize("default_lining").width border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : preheatTemperatureInputMouseArea.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.right: preheatButton.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.bottom: parent.bottom anchors.bottomMargin: UM.Theme.getSize("default_margin").height - width: UM.Theme.getSize("setting_control").width - height: UM.Theme.getSize("setting_control").height - visible: printerModel != null ? printerModel.canPreHeatBed: true + width: UM.Theme.getSize("monitor_preheat_temperature_control").width + height: UM.Theme.getSize("monitor_preheat_temperature_control").height + visible: printerModel != null ? enabled && printerModel.canPreHeatBed && !printerModel.isPreheating : true Rectangle //Highlight of input field. { anchors.fill: parent @@ -159,18 +162,29 @@ Item } } } + Label + { + id: unit + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.verticalCenter: parent.verticalCenter + + text: "°C"; + color: UM.Theme.getColor("setting_unit") + font: UM.Theme.getFont("default") + } TextInput { id: preheatTemperatureInput font: UM.Theme.getFont("default") color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") selectByMouse: true - maximumLength: 10 + maximumLength: 5 enabled: parent.enabled validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex. anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width - anchors.right: parent.right + anchors.right: unit.left anchors.verticalCenter: parent.verticalCenter renderType: Text.NativeRendering diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 92af6e9cc9..7baf13ca97 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -186,22 +186,34 @@ Column { background: Item { - Rectangle + function buttonBackgroundColor(index) { - anchors.fill: parent - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : - control.hovered ? UM.Theme.getColor("action_button_hovered_border") : - UM.Theme.getColor("action_button_border") - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : - control.hovered ? UM.Theme.getColor("action_button_hovered") : - UM.Theme.getColor("action_button") - Behavior on color { ColorAnimation { duration: 50; } } + var extruder = Cura.MachineManager.getExtruder(index) + if (extruder.isEnabled) { + return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : + control.hovered ? UM.Theme.getColor("action_button_hovered") : + UM.Theme.getColor("action_button") + } else { + return UM.Theme.getColor("action_button_disabled") + } + } + + function buttonBorderColor(index) + { + var extruder = Cura.MachineManager.getExtruder(index) + if (extruder.isEnabled) { + return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : + control.hovered ? UM.Theme.getColor("action_button_hovered_border") : + UM.Theme.getColor("action_button_border") + } else { + return UM.Theme.getColor("action_button_disabled_border") + } } function buttonColor(index) { var extruder = Cura.MachineManager.getExtruder(index); - if (extruder.isEnabled) { + if (extruder.isEnabled) + { return ( control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") : control.hovered ? UM.Theme.getColor("action_button_hovered_text") : @@ -211,10 +223,20 @@ Column } } + Rectangle + { + anchors.fill: parent + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: buttonBorderColor(index) + color: buttonBackgroundColor(index) + Behavior on color { ColorAnimation { duration: 50; } } + } + Item { id: extruderButtonFace anchors.centerIn: parent + width: { var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0; var iconWidth = extruderIconItem.width; diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 41ecb529eb..aa6f3ce1de 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -19,7 +19,7 @@ Item property Action configureSettings; property variant minimumPrintTime: PrintInformation.minimumPrintTime; property variant maximumPrintTime: PrintInformation.maximumPrintTime; - property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 + property bool settingsEnabled: extrudersEnabledCount.properties.value == 1 Component.onCompleted: PrintInformation.enabled = true Component.onDestruction: PrintInformation.enabled = false @@ -111,7 +111,6 @@ Item // Set selected value if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) { - // set to -1 when switching to user created profile so all ticks are clickable if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { qualityModel.qualitySliderActiveIndex = -1 @@ -474,18 +473,7 @@ Item onClicked: { // if the current profile is user-created, switch to a built-in quality - if (Cura.SimpleModeSettingsManager.isProfileUserCreated) - { - if (Cura.QualityProfilesDropDownMenuModel.rowCount() > 0) - { - var item = Cura.QualityProfilesDropDownMenuModel.getItem(0); - Cura.MachineManager.activeQualityGroup = item.quality_group; - } - } - if (Cura.SimpleModeSettingsManager.isProfileCustomized) - { - discardOrKeepProfileChangesDialog.show() - } + Cura.MachineManager.resetToUseDefaultQuality() } onEntered: { @@ -594,7 +582,9 @@ Item // Update value only if the Recomended mode is Active, // Otherwise if I change the value in the Custom mode the Recomended view will try to repeat // same operation - if (UM.Preferences.getValue("cura/active_mode") == 0) { + var active_mode = UM.Preferences.getValue("cura/active_mode") + + if (active_mode == 0 || active_mode == "simple") { Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue) } } diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 80a5eec09c..5fbe36fcdb 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -84,16 +84,16 @@ "tab_background": [39, 44, 48, 255], "action_button": [39, 44, 48, 255], - "action_button_text": [255, 255, 255, 101], + "action_button_text": [255, 255, 255, 200], "action_button_border": [255, 255, 255, 30], "action_button_hovered": [39, 44, 48, 255], "action_button_hovered_text": [255, 255, 255, 255], "action_button_hovered_border": [255, 255, 255, 30], "action_button_active": [39, 44, 48, 30], "action_button_active_text": [255, 255, 255, 255], - "action_button_active_border": [255, 255, 255, 30], + "action_button_active_border": [255, 255, 255, 100], "action_button_disabled": [39, 44, 48, 255], - "action_button_disabled_text": [255, 255, 255, 101], + "action_button_disabled_text": [255, 255, 255, 80], "action_button_disabled_border": [255, 255, 255, 30], "scrollbar_background": [39, 44, 48, 0], diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index c0b71ac618..4f4b2306a8 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -411,6 +411,8 @@ "save_button_save_to_button": [0.3, 2.7], "save_button_specs_icons": [1.4, 1.4], + "monitor_preheat_temperature_control": [4.5, 2.0], + "modal_window_minimum": [60.0, 45], "license_window_minimum": [45, 45], "wizard_progress": [10.0, 0.0],