mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-14 04:26:05 +08:00
Merge branch 'master' into feature_support_eraser_ux
This commit is contained in:
commit
d1d1307e6e
@ -1,9 +1,6 @@
|
|||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
#Type hinting.
|
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QTimer
|
from PyQt5.QtCore import QObject, QTimer
|
||||||
from PyQt5.QtNetwork import QLocalServer
|
from PyQt5.QtNetwork import QLocalServer
|
||||||
from PyQt5.QtNetwork import QLocalSocket
|
from PyQt5.QtNetwork import QLocalSocket
|
||||||
@ -68,6 +65,8 @@ from cura.Machines.Models.QualityManagementModel import QualityManagementModel
|
|||||||
from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
|
from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
|
||||||
from cura.Machines.Models.MachineManagementModel import MachineManagementModel
|
from cura.Machines.Models.MachineManagementModel import MachineManagementModel
|
||||||
|
|
||||||
|
from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
|
||||||
|
|
||||||
from cura.Machines.MachineErrorChecker import MachineErrorChecker
|
from cura.Machines.MachineErrorChecker import MachineErrorChecker
|
||||||
|
|
||||||
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
|
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
|
||||||
@ -91,7 +90,6 @@ from cura.Settings.UserChangesModel import UserChangesModel
|
|||||||
from cura.Settings.ExtrudersModel import ExtrudersModel
|
from cura.Settings.ExtrudersModel import ExtrudersModel
|
||||||
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
||||||
from cura.Settings.ContainerManager import ContainerManager
|
from cura.Settings.ContainerManager import ContainerManager
|
||||||
from cura.Settings.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
|
|
||||||
|
|
||||||
from cura.ObjectsModel import ObjectsModel
|
from cura.ObjectsModel import ObjectsModel
|
||||||
|
|
||||||
@ -101,7 +99,6 @@ from PyQt5.QtGui import QColor, QIcon
|
|||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType
|
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType
|
||||||
|
|
||||||
from configparser import ConfigParser
|
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
import numpy
|
import numpy
|
||||||
@ -226,6 +223,7 @@ class CuraApplication(QtApplication):
|
|||||||
self._object_manager = None
|
self._object_manager = None
|
||||||
self._build_plate_model = None
|
self._build_plate_model = None
|
||||||
self._multi_build_plate_model = None
|
self._multi_build_plate_model = None
|
||||||
|
self._setting_visibility_presets_model = None
|
||||||
self._setting_inheritance_manager = None
|
self._setting_inheritance_manager = None
|
||||||
self._simple_mode_settings_manager = None
|
self._simple_mode_settings_manager = None
|
||||||
self._cura_scene_controller = None
|
self._cura_scene_controller = None
|
||||||
@ -381,10 +379,6 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
preferences.setDefault("local_file/last_used_type", "text/x-gcode")
|
preferences.setDefault("local_file/last_used_type", "text/x-gcode")
|
||||||
|
|
||||||
default_visibility_profile = SettingVisibilityPresetsModel.getInstance().getItem(0)
|
|
||||||
|
|
||||||
preferences.setDefault("general/visible_settings", ";".join(default_visibility_profile["settings"]))
|
|
||||||
|
|
||||||
self.applicationShuttingDown.connect(self.saveSettings)
|
self.applicationShuttingDown.connect(self.saveSettings)
|
||||||
self.engineCreatedSignal.connect(self._onEngineCreated)
|
self.engineCreatedSignal.connect(self._onEngineCreated)
|
||||||
|
|
||||||
@ -457,27 +451,18 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def discardOrKeepProfileChangesClosed(self, option):
|
def discardOrKeepProfileChangesClosed(self, option):
|
||||||
|
global_stack = self.getGlobalContainerStack()
|
||||||
if option == "discard":
|
if option == "discard":
|
||||||
global_stack = self.getGlobalContainerStack()
|
for extruder in global_stack.extruders.values():
|
||||||
for extruder in self._extruder_manager.getMachineExtruders(global_stack.getId()):
|
extruder.userChanges.clear()
|
||||||
extruder.getTop().clear()
|
global_stack.userChanges.clear()
|
||||||
global_stack.getTop().clear()
|
|
||||||
|
|
||||||
# if the user decided to keep settings then the user settings should be re-calculated and validated for errors
|
# 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
|
# before slicing. To ensure that slicer uses right settings values
|
||||||
elif option == "keep":
|
elif option == "keep":
|
||||||
global_stack = self.getGlobalContainerStack()
|
for extruder in global_stack.extruders.values():
|
||||||
for extruder in self._extruder_manager.getMachineExtruders(global_stack.getId()):
|
extruder.userChanges.update()
|
||||||
user_extruder_container = extruder.getTop()
|
global_stack.userChanges.update()
|
||||||
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()
|
|
||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def messageBoxClosed(self, button):
|
def messageBoxClosed(self, button):
|
||||||
@ -687,6 +672,11 @@ class CuraApplication(QtApplication):
|
|||||||
self._print_information = PrintInformation.PrintInformation()
|
self._print_information = PrintInformation.PrintInformation()
|
||||||
self._cura_actions = CuraActions.CuraActions(self)
|
self._cura_actions = CuraActions.CuraActions(self)
|
||||||
|
|
||||||
|
# Initialize setting visibility presets model
|
||||||
|
self._setting_visibility_presets_model = SettingVisibilityPresetsModel(self)
|
||||||
|
default_visibility_profile = self._setting_visibility_presets_model.getItem(0)
|
||||||
|
Preferences.getInstance().setDefault("general/visible_settings", ";".join(default_visibility_profile["settings"]))
|
||||||
|
|
||||||
# Detect in which mode to run and execute that mode
|
# Detect in which mode to run and execute that mode
|
||||||
if self.getCommandLineOption("headless", False):
|
if self.getCommandLineOption("headless", False):
|
||||||
self.runWithoutGUI()
|
self.runWithoutGUI()
|
||||||
@ -769,6 +759,10 @@ class CuraApplication(QtApplication):
|
|||||||
def hasGui(self):
|
def hasGui(self):
|
||||||
return self._use_gui
|
return self._use_gui
|
||||||
|
|
||||||
|
@pyqtSlot(result = QObject)
|
||||||
|
def getSettingVisibilityPresetsModel(self, *args) -> SettingVisibilityPresetsModel:
|
||||||
|
return self._setting_visibility_presets_model
|
||||||
|
|
||||||
def getMachineErrorChecker(self, *args) -> MachineErrorChecker:
|
def getMachineErrorChecker(self, *args) -> MachineErrorChecker:
|
||||||
return self._machine_error_checker
|
return self._machine_error_checker
|
||||||
|
|
||||||
@ -895,11 +889,11 @@ class CuraApplication(QtApplication):
|
|||||||
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
|
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
|
||||||
|
|
||||||
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
||||||
|
qmlRegisterType(SettingVisibilityPresetsModel, "Cura", 1, 0, "SettingVisibilityPresetsModel")
|
||||||
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
|
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
|
||||||
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
|
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
|
||||||
qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
|
qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
|
||||||
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager)
|
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager)
|
||||||
qmlRegisterSingletonType(SettingVisibilityPresetsModel, "Cura", 1, 0, "SettingVisibilityPresetsModel", SettingVisibilityPresetsModel.createSettingVisibilityPresetsModel)
|
|
||||||
|
|
||||||
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
|
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
|
||||||
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
|
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
|
||||||
|
176
cura/Machines/Models/SettingVisibilityPresetsModel.py
Normal file
176
cura/Machines/Models/SettingVisibilityPresetsModel.py
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
import os
|
||||||
|
import urllib.parse
|
||||||
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot
|
||||||
|
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.Qt.ListModel import ListModel
|
||||||
|
from UM.Preferences import Preferences
|
||||||
|
from UM.Resources import Resources
|
||||||
|
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError
|
||||||
|
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
|
class SettingVisibilityPresetsModel(ListModel):
|
||||||
|
IdRole = Qt.UserRole + 1
|
||||||
|
NameRole = Qt.UserRole + 2
|
||||||
|
SettingsRole = Qt.UserRole + 3
|
||||||
|
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.addRoleName(self.IdRole, "id")
|
||||||
|
self.addRoleName(self.NameRole, "name")
|
||||||
|
self.addRoleName(self.SettingsRole, "settings")
|
||||||
|
|
||||||
|
self._populate()
|
||||||
|
basic_item = self.items[1]
|
||||||
|
basic_visibile_settings = ";".join(basic_item["settings"])
|
||||||
|
|
||||||
|
self._preferences = Preferences.getInstance()
|
||||||
|
# Preference to store which preset is currently selected
|
||||||
|
self._preferences.addPreference("cura/active_setting_visibility_preset", "basic")
|
||||||
|
# Preference that stores the "custom" set so it can always be restored (even after a restart)
|
||||||
|
self._preferences.addPreference("cura/custom_visible_settings", basic_visibile_settings)
|
||||||
|
self._preferences.preferenceChanged.connect(self._onPreferencesChanged)
|
||||||
|
|
||||||
|
self._active_preset_item = self._getItem(self._preferences.getValue("cura/active_setting_visibility_preset"))
|
||||||
|
# Initialize visible settings if it is not done yet
|
||||||
|
visible_settings = self._preferences.getValue("general/visible_settings")
|
||||||
|
if not visible_settings:
|
||||||
|
self._preferences.setValue("general/visible_settings", ";".join(self._active_preset_item["settings"]))
|
||||||
|
|
||||||
|
self.activePresetChanged.emit()
|
||||||
|
|
||||||
|
def _getItem(self, item_id: str) -> Optional[dict]:
|
||||||
|
result = None
|
||||||
|
for item in self.items:
|
||||||
|
if item["id"] == item_id:
|
||||||
|
result = item
|
||||||
|
break
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _populate(self):
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
items = []
|
||||||
|
for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset):
|
||||||
|
try:
|
||||||
|
mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path)
|
||||||
|
except MimeTypeNotFoundError:
|
||||||
|
Logger.log("e", "Could not determine mime type of file %s", file_path)
|
||||||
|
continue
|
||||||
|
|
||||||
|
item_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_path)))
|
||||||
|
if not os.path.isfile(file_path):
|
||||||
|
Logger.log("e", "[%s] is not a file", file_path)
|
||||||
|
continue
|
||||||
|
|
||||||
|
parser = ConfigParser(allow_no_value = True) # accept options without any value,
|
||||||
|
try:
|
||||||
|
parser.read([file_path])
|
||||||
|
if not parser.has_option("general", "name") or not parser.has_option("general", "weight"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
settings = []
|
||||||
|
for section in parser.sections():
|
||||||
|
if section == 'general':
|
||||||
|
continue
|
||||||
|
|
||||||
|
settings.append(section)
|
||||||
|
for option in parser[section].keys():
|
||||||
|
settings.append(option)
|
||||||
|
|
||||||
|
items.append({
|
||||||
|
"id": item_id,
|
||||||
|
"name": catalog.i18nc("@action:inmenu", parser["general"]["name"]),
|
||||||
|
"weight": parser["general"]["weight"],
|
||||||
|
"settings": settings,
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
Logger.logException("e", "Failed to load setting preset %s", file_path)
|
||||||
|
|
||||||
|
items.sort(key = lambda k: (int(k["weight"]), k["id"]))
|
||||||
|
# Put "custom" at the top
|
||||||
|
items.insert(0, {"id": "custom",
|
||||||
|
"name": "Custom selection",
|
||||||
|
"weight": -100,
|
||||||
|
"settings": []})
|
||||||
|
|
||||||
|
self.setItems(items)
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def setActivePreset(self, preset_id: str):
|
||||||
|
if preset_id == self._active_preset_item["id"]:
|
||||||
|
Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
preset_item = None
|
||||||
|
for item in self.items:
|
||||||
|
if item["id"] == preset_id:
|
||||||
|
preset_item = item
|
||||||
|
break
|
||||||
|
if preset_item is None:
|
||||||
|
Logger.log("w", "Tried to set active preset to unknown id [%s]", preset_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
need_to_save_to_custom = self._active_preset_item["id"] == "custom" and preset_id != "custom"
|
||||||
|
if need_to_save_to_custom:
|
||||||
|
# Save the current visibility settings to custom
|
||||||
|
current_visibility_string = self._preferences.getValue("general/visible_settings")
|
||||||
|
if current_visibility_string:
|
||||||
|
self._preferences.setValue("cura/custom_visible_settings", current_visibility_string)
|
||||||
|
|
||||||
|
new_visibility_string = ";".join(preset_item["settings"])
|
||||||
|
if preset_id == "custom":
|
||||||
|
# Get settings from the stored custom data
|
||||||
|
new_visibility_string = self._preferences.getValue("cura/custom_visible_settings")
|
||||||
|
if new_visibility_string is None:
|
||||||
|
new_visibility_string = self._preferences.getValue("general/visible_settings")
|
||||||
|
self._preferences.setValue("general/visible_settings", new_visibility_string)
|
||||||
|
|
||||||
|
self._preferences.setValue("cura/active_setting_visibility_preset", preset_id)
|
||||||
|
self._active_preset_item = preset_item
|
||||||
|
self.activePresetChanged.emit()
|
||||||
|
|
||||||
|
activePresetChanged = pyqtSignal()
|
||||||
|
|
||||||
|
@pyqtProperty(str, notify = activePresetChanged)
|
||||||
|
def activePreset(self) -> str:
|
||||||
|
return self._active_preset_item["id"]
|
||||||
|
|
||||||
|
def _onPreferencesChanged(self, name: str):
|
||||||
|
if name != "general/visible_settings":
|
||||||
|
return
|
||||||
|
|
||||||
|
# Find the preset that matches with the current visible settings setup
|
||||||
|
visibility_string = self._preferences.getValue("general/visible_settings")
|
||||||
|
if not visibility_string:
|
||||||
|
return
|
||||||
|
|
||||||
|
visibility_set = set(visibility_string.split(";"))
|
||||||
|
matching_preset_item = None
|
||||||
|
for item in self.items:
|
||||||
|
if item["id"] == "custom":
|
||||||
|
continue
|
||||||
|
if set(item["settings"]) == visibility_set:
|
||||||
|
matching_preset_item = item
|
||||||
|
break
|
||||||
|
|
||||||
|
if matching_preset_item is None:
|
||||||
|
# The new visibility setup is "custom" should be custom
|
||||||
|
if self._active_preset_item["id"] == "custom":
|
||||||
|
# We are already in custom, just save the settings
|
||||||
|
self._preferences.setValue("cura/custom_visible_settings", visibility_string)
|
||||||
|
else:
|
||||||
|
self._active_preset_item = self.items[0] # 0 is custom
|
||||||
|
self.activePresetChanged.emit()
|
||||||
|
else:
|
||||||
|
self._active_preset_item = matching_preset_item
|
||||||
|
self.activePresetChanged.emit()
|
@ -18,6 +18,7 @@ class ExtruderOutputModel(QObject):
|
|||||||
hotendTemperatureChanged = pyqtSignal()
|
hotendTemperatureChanged = pyqtSignal()
|
||||||
activeMaterialChanged = pyqtSignal()
|
activeMaterialChanged = pyqtSignal()
|
||||||
extruderConfigurationChanged = pyqtSignal()
|
extruderConfigurationChanged = pyqtSignal()
|
||||||
|
isPreheatingChanged = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, printer: "PrinterOutputModel", position, parent=None):
|
def __init__(self, printer: "PrinterOutputModel", position, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -30,6 +31,21 @@ class ExtruderOutputModel(QObject):
|
|||||||
self._extruder_configuration = ExtruderConfigurationModel()
|
self._extruder_configuration = ExtruderConfigurationModel()
|
||||||
self._extruder_configuration.position = self._position
|
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)
|
@pyqtProperty(QObject, notify = activeMaterialChanged)
|
||||||
def activeMaterial(self) -> "MaterialOutputModel":
|
def activeMaterial(self) -> "MaterialOutputModel":
|
||||||
return self._active_material
|
return self._active_material
|
||||||
@ -82,3 +98,25 @@ class ExtruderOutputModel(QObject):
|
|||||||
if self._extruder_configuration.isValid():
|
if self._extruder_configuration.isValid():
|
||||||
return self._extruder_configuration
|
return self._extruder_configuration
|
||||||
return None
|
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)
|
151
cura/PrinterOutput/GenericOutputController.py
Normal file
151
cura/PrinterOutput/GenericOutputController.py
Normal file
@ -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()
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
|
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
|
||||||
|
|
||||||
@ -254,6 +256,9 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
self._last_manager_create_time = time()
|
self._last_manager_create_time = time()
|
||||||
self._manager.authenticationRequired.connect(self._onAuthenticationRequired)
|
self._manager.authenticationRequired.connect(self._onAuthenticationRequired)
|
||||||
|
|
||||||
|
machine_manager = CuraApplication.getInstance().getMachineManager()
|
||||||
|
machine_manager.checkCorrectGroupName(self.getId(), self.name)
|
||||||
|
|
||||||
def _registerOnFinishedCallback(self, reply: QNetworkReply, onFinished: Optional[Callable[[Any, QNetworkReply], None]]) -> None:
|
def _registerOnFinishedCallback(self, reply: QNetworkReply, onFinished: Optional[Callable[[Any, QNetworkReply], None]]) -> None:
|
||||||
if onFinished is not None:
|
if onFinished is not None:
|
||||||
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
|
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = onFinished
|
||||||
|
@ -15,6 +15,7 @@ class PrinterOutputController:
|
|||||||
self.can_pause = True
|
self.can_pause = True
|
||||||
self.can_abort = True
|
self.can_abort = True
|
||||||
self.can_pre_heat_bed = True
|
self.can_pre_heat_bed = True
|
||||||
|
self.can_pre_heat_hotends = True
|
||||||
self.can_control_manually = True
|
self.can_control_manually = True
|
||||||
self._output_device = output_device
|
self._output_device = output_device
|
||||||
|
|
||||||
@ -33,6 +34,12 @@ class PrinterOutputController:
|
|||||||
def preheatBed(self, printer: "PrinterOutputModel", temperature, duration):
|
def preheatBed(self, printer: "PrinterOutputModel", temperature, duration):
|
||||||
Logger.log("w", "Preheat bed not implemented in controller")
|
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):
|
def setHeadPosition(self, printer: "PrinterOutputModel", x, y, z, speed):
|
||||||
Logger.log("w", "Set head position not implemented in controller")
|
Logger.log("w", "Set head position not implemented in controller")
|
||||||
|
|
||||||
|
@ -238,6 +238,13 @@ class PrinterOutputModel(QObject):
|
|||||||
return self._controller.can_pre_heat_bed
|
return self._controller.can_pre_heat_bed
|
||||||
return False
|
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
|
# Does the printer support pause at all
|
||||||
@pyqtProperty(bool, constant=True)
|
@pyqtProperty(bool, constant=True)
|
||||||
def canPause(self):
|
def canPause(self):
|
||||||
|
@ -173,12 +173,13 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
plugin_registry = PluginRegistry.getInstance()
|
plugin_registry = PluginRegistry.getInstance()
|
||||||
extension = file_name.split(".")[-1]
|
extension = file_name.split(".")[-1]
|
||||||
|
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if not global_container_stack:
|
if not global_stack:
|
||||||
return
|
return
|
||||||
|
|
||||||
machine_extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
|
machine_extruders = []
|
||||||
machine_extruders.sort(key = lambda k: k.getMetaDataEntry("position"))
|
for position in sorted(global_stack.extruders):
|
||||||
|
machine_extruders.append(global_stack.extruders[position])
|
||||||
|
|
||||||
for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
|
for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
|
||||||
if meta_data["profile_reader"][0]["extension"] != extension:
|
if meta_data["profile_reader"][0]["extension"] != extension:
|
||||||
@ -200,13 +201,18 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
|
|
||||||
# First check if this profile is suitable for this machine
|
# First check if this profile is suitable for this machine
|
||||||
global_profile = None
|
global_profile = None
|
||||||
|
extruder_profiles = []
|
||||||
if len(profile_or_list) == 1:
|
if len(profile_or_list) == 1:
|
||||||
global_profile = profile_or_list[0]
|
global_profile = profile_or_list[0]
|
||||||
else:
|
else:
|
||||||
for profile in profile_or_list:
|
for profile in profile_or_list:
|
||||||
if not profile.getMetaDataEntry("position"):
|
if not profile.getMetaDataEntry("position"):
|
||||||
global_profile = profile
|
global_profile = profile
|
||||||
break
|
else:
|
||||||
|
extruder_profiles.append(profile)
|
||||||
|
extruder_profiles = sorted(extruder_profiles, key = lambda x: int(x.getMetaDataEntry("position")))
|
||||||
|
profile_or_list = [global_profile] + extruder_profiles
|
||||||
|
|
||||||
if not global_profile:
|
if not global_profile:
|
||||||
Logger.log("e", "Incorrect profile [%s]. Could not find global profile", file_name)
|
Logger.log("e", "Incorrect profile [%s]. Could not find global profile", file_name)
|
||||||
return { "status": "error",
|
return { "status": "error",
|
||||||
@ -227,7 +233,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
# Get the expected machine definition.
|
# Get the expected machine definition.
|
||||||
# i.e.: We expect gcode for a UM2 Extended to be defined as normal UM2 gcode...
|
# i.e.: We expect gcode for a UM2 Extended to be defined as normal UM2 gcode...
|
||||||
profile_definition = getMachineDefinitionIDForQualitySearch(machine_definition)
|
profile_definition = getMachineDefinitionIDForQualitySearch(machine_definition)
|
||||||
expected_machine_definition = getMachineDefinitionIDForQualitySearch(global_container_stack.definition)
|
expected_machine_definition = getMachineDefinitionIDForQualitySearch(global_stack.definition)
|
||||||
|
|
||||||
# And check if the profile_definition matches either one (showing error if not):
|
# And check if the profile_definition matches either one (showing error if not):
|
||||||
if profile_definition != expected_machine_definition:
|
if profile_definition != expected_machine_definition:
|
||||||
@ -251,8 +257,8 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
if len(profile_or_list) == 1:
|
if len(profile_or_list) == 1:
|
||||||
global_profile = profile_or_list[0]
|
global_profile = profile_or_list[0]
|
||||||
extruder_profiles = []
|
extruder_profiles = []
|
||||||
for idx, extruder in enumerate(global_container_stack.extruders.values()):
|
for idx, extruder in enumerate(global_stack.extruders.values()):
|
||||||
profile_id = ContainerRegistry.getInstance().uniqueName(global_container_stack.getId() + "_extruder_" + str(idx + 1))
|
profile_id = ContainerRegistry.getInstance().uniqueName(global_stack.getId() + "_extruder_" + str(idx + 1))
|
||||||
profile = InstanceContainer(profile_id)
|
profile = InstanceContainer(profile_id)
|
||||||
profile.setName(quality_name)
|
profile.setName(quality_name)
|
||||||
profile.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
profile.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
@ -264,12 +270,12 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
if idx == 0:
|
if idx == 0:
|
||||||
# move all per-extruder settings to the first extruder's quality_changes
|
# move all per-extruder settings to the first extruder's quality_changes
|
||||||
for qc_setting_key in global_profile.getAllKeys():
|
for qc_setting_key in global_profile.getAllKeys():
|
||||||
settable_per_extruder = global_container_stack.getProperty(qc_setting_key,
|
settable_per_extruder = global_stack.getProperty(qc_setting_key,
|
||||||
"settable_per_extruder")
|
"settable_per_extruder")
|
||||||
if settable_per_extruder:
|
if settable_per_extruder:
|
||||||
setting_value = global_profile.getProperty(qc_setting_key, "value")
|
setting_value = global_profile.getProperty(qc_setting_key, "value")
|
||||||
|
|
||||||
setting_definition = global_container_stack.getSettingDefinition(qc_setting_key)
|
setting_definition = global_stack.getSettingDefinition(qc_setting_key)
|
||||||
new_instance = SettingInstance(setting_definition, profile)
|
new_instance = SettingInstance(setting_definition, profile)
|
||||||
new_instance.setProperty("value", setting_value)
|
new_instance.setProperty("value", setting_value)
|
||||||
new_instance.resetState() # Ensure that the state is not seen as a user state.
|
new_instance.resetState() # Ensure that the state is not seen as a user state.
|
||||||
@ -286,7 +292,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
for profile_index, profile in enumerate(profile_or_list):
|
for profile_index, profile in enumerate(profile_or_list):
|
||||||
if profile_index == 0:
|
if profile_index == 0:
|
||||||
# This is assumed to be the global profile
|
# This is assumed to be the global profile
|
||||||
profile_id = (global_container_stack.getBottom().getId() + "_" + name_seed).lower().replace(" ", "_")
|
profile_id = (global_stack.getBottom().getId() + "_" + name_seed).lower().replace(" ", "_")
|
||||||
|
|
||||||
elif profile_index < len(machine_extruders) + 1:
|
elif profile_index < len(machine_extruders) + 1:
|
||||||
# This is assumed to be an extruder profile
|
# This is assumed to be an extruder profile
|
||||||
|
@ -210,6 +210,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
|||||||
item = {
|
item = {
|
||||||
"id": "",
|
"id": "",
|
||||||
"name": catalog.i18nc("@menuitem", "Not overridden"),
|
"name": catalog.i18nc("@menuitem", "Not overridden"),
|
||||||
|
"enabled": True,
|
||||||
"color": "#ffffff",
|
"color": "#ffffff",
|
||||||
"index": -1,
|
"index": -1,
|
||||||
"definition": ""
|
"definition": ""
|
||||||
|
@ -10,7 +10,6 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
|||||||
from UM.Signal import Signal
|
from UM.Signal import Signal
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
|
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
|
||||||
import UM.FlameProfiler
|
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
from UM import Util
|
from UM import Util
|
||||||
|
|
||||||
@ -24,7 +23,6 @@ from UM.Settings.SettingFunction import SettingFunction
|
|||||||
from UM.Signal import postponeSignals, CompressTechnique
|
from UM.Signal import postponeSignals, CompressTechnique
|
||||||
|
|
||||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
||||||
from cura.Machines.VariantManager import VariantType
|
|
||||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||||
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||||
@ -147,6 +145,7 @@ class MachineManager(QObject):
|
|||||||
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
|
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
|
||||||
activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed
|
activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed
|
||||||
stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed
|
stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed
|
||||||
|
numberExtrudersEnabledChanged = pyqtSignal() # Emitted when the number of extruders that are enabled changed
|
||||||
|
|
||||||
blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly
|
blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly
|
||||||
|
|
||||||
@ -470,13 +469,13 @@ class MachineManager(QObject):
|
|||||||
@pyqtProperty(str, notify = outputDevicesChanged)
|
@pyqtProperty(str, notify = outputDevicesChanged)
|
||||||
def activeMachineNetworkKey(self) -> str:
|
def activeMachineNetworkKey(self) -> str:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
return self._global_container_stack.getMetaDataEntry("um_network_key")
|
return self._global_container_stack.getMetaDataEntry("um_network_key", "")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@pyqtProperty(str, notify = outputDevicesChanged)
|
@pyqtProperty(str, notify = outputDevicesChanged)
|
||||||
def activeMachineNetworkGroupName(self) -> str:
|
def activeMachineNetworkGroupName(self) -> str:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
return self._global_container_stack.getMetaDataEntry("connect_group_name")
|
return self._global_container_stack.getMetaDataEntry("connect_group_name", "")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify = globalContainerChanged)
|
@pyqtProperty(QObject, notify = globalContainerChanged)
|
||||||
@ -662,12 +661,22 @@ class MachineManager(QObject):
|
|||||||
if other_machine_stacks:
|
if other_machine_stacks:
|
||||||
self.setActiveMachine(other_machine_stacks[0]["id"])
|
self.setActiveMachine(other_machine_stacks[0]["id"])
|
||||||
|
|
||||||
|
metadata = ContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0]
|
||||||
|
network_key = metadata["um_network_key"] if "um_network_key" in metadata else None
|
||||||
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id)
|
containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id)
|
||||||
for container in containers:
|
for container in containers:
|
||||||
ContainerRegistry.getInstance().removeContainer(container["id"])
|
ContainerRegistry.getInstance().removeContainer(container["id"])
|
||||||
ContainerRegistry.getInstance().removeContainer(machine_id)
|
ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||||
|
|
||||||
|
# If the printer that is being removed is a network printer, the hidden printers have to be also removed
|
||||||
|
if network_key:
|
||||||
|
metadata_filter = {"um_network_key": network_key}
|
||||||
|
hidden_containers = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||||
|
if hidden_containers:
|
||||||
|
# This reuses the method and remove all printers recursively
|
||||||
|
self.removeMachine(hidden_containers[0].getId())
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = globalContainerChanged)
|
@pyqtProperty(bool, notify = globalContainerChanged)
|
||||||
def hasMaterials(self) -> bool:
|
def hasMaterials(self) -> bool:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
@ -872,7 +881,13 @@ class MachineManager(QObject):
|
|||||||
for position, extruder in self._global_container_stack.extruders.items():
|
for position, extruder in self._global_container_stack.extruders.items():
|
||||||
if extruder.isEnabled:
|
if extruder.isEnabled:
|
||||||
extruder_count += 1
|
extruder_count += 1
|
||||||
definition_changes_container.setProperty("extruders_enabled_count", "value", extruder_count)
|
if self.numberExtrudersEnabled != extruder_count:
|
||||||
|
definition_changes_container.setProperty("extruders_enabled_count", "value", extruder_count)
|
||||||
|
self.numberExtrudersEnabledChanged.emit()
|
||||||
|
|
||||||
|
@pyqtProperty(int, notify = numberExtrudersEnabledChanged)
|
||||||
|
def numberExtrudersEnabled(self):
|
||||||
|
return self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value")
|
||||||
|
|
||||||
@pyqtProperty(str, notify = extruderChanged)
|
@pyqtProperty(str, notify = extruderChanged)
|
||||||
def defaultExtruderPosition(self):
|
def defaultExtruderPosition(self):
|
||||||
@ -1193,6 +1208,26 @@ class MachineManager(QObject):
|
|||||||
if machine.getMetaDataEntry(key) == value:
|
if machine.getMetaDataEntry(key) == value:
|
||||||
machine.setMetaDataEntry(key, new_value)
|
machine.setMetaDataEntry(key, new_value)
|
||||||
|
|
||||||
|
## This method checks if the name of the group stored in the definition container is correct.
|
||||||
|
# After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group
|
||||||
|
# then all the container stacks are updated, both the current and the hidden ones.
|
||||||
|
def checkCorrectGroupName(self, device_id: str, group_name: str):
|
||||||
|
if self._global_container_stack and device_id == self.activeMachineNetworkKey:
|
||||||
|
# Check if the connect_group_name is correct. If not, update all the containers connected to the same printer
|
||||||
|
if self.activeMachineNetworkGroupName != group_name:
|
||||||
|
metadata_filter = {"um_network_key": self.activeMachineNetworkKey}
|
||||||
|
hidden_containers = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||||
|
for container in hidden_containers:
|
||||||
|
container.setMetaDataEntry("connect_group_name", group_name)
|
||||||
|
|
||||||
|
## This method checks if there is an instance connected to the given network_key
|
||||||
|
def existNetworkInstances(self, network_key: str) -> bool:
|
||||||
|
metadata_filter = {"um_network_key": network_key}
|
||||||
|
containers = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||||
|
if containers:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
@pyqtSlot("QVariant")
|
@pyqtSlot("QVariant")
|
||||||
def setGlobalVariant(self, container_node):
|
def setGlobalVariant(self, container_node):
|
||||||
self.blurSettings.emit()
|
self.blurSettings.emit()
|
||||||
@ -1242,6 +1277,13 @@ class MachineManager(QObject):
|
|||||||
if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
|
if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
|
||||||
self._application.discardOrKeepProfileChanges()
|
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)
|
@pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged)
|
||||||
def activeQualityChangesGroup(self):
|
def activeQualityChangesGroup(self):
|
||||||
return self._current_quality_changes_group
|
return self._current_quality_changes_group
|
||||||
|
@ -1,136 +0,0 @@
|
|||||||
# Copyright (c) 2018 Ultimaker B.V.
|
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
|
||||||
|
|
||||||
import os
|
|
||||||
import urllib
|
|
||||||
from configparser import ConfigParser
|
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl
|
|
||||||
|
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Qt.ListModel import ListModel
|
|
||||||
from UM.Preferences import Preferences
|
|
||||||
from UM.Resources import Resources
|
|
||||||
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError
|
|
||||||
|
|
||||||
import cura.CuraApplication
|
|
||||||
|
|
||||||
|
|
||||||
class SettingVisibilityPresetsModel(ListModel):
|
|
||||||
IdRole = Qt.UserRole + 1
|
|
||||||
NameRole = Qt.UserRole + 2
|
|
||||||
SettingsRole = Qt.UserRole + 4
|
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.addRoleName(self.IdRole, "id")
|
|
||||||
self.addRoleName(self.NameRole, "name")
|
|
||||||
self.addRoleName(self.SettingsRole, "settings")
|
|
||||||
|
|
||||||
self._populate()
|
|
||||||
|
|
||||||
self._preferences = Preferences.getInstance()
|
|
||||||
self._preferences.addPreference("cura/active_setting_visibility_preset", "custom") # Preference to store which preset is currently selected
|
|
||||||
self._preferences.addPreference("cura/custom_visible_settings", "") # Preference that stores the "custom" set so it can always be restored (even after a restart)
|
|
||||||
self._preferences.preferenceChanged.connect(self._onPreferencesChanged)
|
|
||||||
|
|
||||||
self._active_preset = self._preferences.getValue("cura/active_setting_visibility_preset")
|
|
||||||
if self.find("id", self._active_preset) < 0:
|
|
||||||
self._active_preset = "custom"
|
|
||||||
|
|
||||||
self.activePresetChanged.emit()
|
|
||||||
|
|
||||||
|
|
||||||
def _populate(self):
|
|
||||||
items = []
|
|
||||||
for item in Resources.getAllResourcesOfType(cura.CuraApplication.CuraApplication.ResourceTypes.SettingVisibilityPreset):
|
|
||||||
try:
|
|
||||||
mime_type = MimeTypeDatabase.getMimeTypeForFile(item)
|
|
||||||
except MimeTypeNotFoundError:
|
|
||||||
Logger.log("e", "Could not determine mime type of file %s", item)
|
|
||||||
continue
|
|
||||||
|
|
||||||
id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(item)))
|
|
||||||
|
|
||||||
if not os.path.isfile(item):
|
|
||||||
continue
|
|
||||||
|
|
||||||
parser = ConfigParser(allow_no_value=True) # accept options without any value,
|
|
||||||
|
|
||||||
try:
|
|
||||||
parser.read([item])
|
|
||||||
|
|
||||||
if not parser.has_option("general", "name") and not parser.has_option("general", "weight"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
settings = []
|
|
||||||
for section in parser.sections():
|
|
||||||
if section == 'general':
|
|
||||||
continue
|
|
||||||
|
|
||||||
settings.append(section)
|
|
||||||
for option in parser[section].keys():
|
|
||||||
settings.append(option)
|
|
||||||
|
|
||||||
items.append({
|
|
||||||
"id": id,
|
|
||||||
"name": parser["general"]["name"],
|
|
||||||
"weight": parser["general"]["weight"],
|
|
||||||
"settings": settings
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
Logger.log("e", "Failed to load setting preset %s: %s", file_path, str(e))
|
|
||||||
|
|
||||||
|
|
||||||
items.sort(key = lambda k: (k["weight"], k["id"]))
|
|
||||||
self.setItems(items)
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def setActivePreset(self, preset_id):
|
|
||||||
if preset_id != "custom" and self.find("id", preset_id) == -1:
|
|
||||||
Logger.log("w", "Tried to set active preset to unknown id %s", preset_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
if preset_id == "custom" and self._active_preset == "custom":
|
|
||||||
# Copy current visibility set to custom visibility set preference so it can be restored later
|
|
||||||
visibility_string = self._preferences.getValue("general/visible_settings")
|
|
||||||
self._preferences.setValue("cura/custom_visible_settings", visibility_string)
|
|
||||||
|
|
||||||
self._preferences.setValue("cura/active_setting_visibility_preset", preset_id)
|
|
||||||
|
|
||||||
self._active_preset = preset_id
|
|
||||||
self.activePresetChanged.emit()
|
|
||||||
|
|
||||||
activePresetChanged = pyqtSignal()
|
|
||||||
|
|
||||||
@pyqtProperty(str, notify = activePresetChanged)
|
|
||||||
def activePreset(self):
|
|
||||||
return self._active_preset
|
|
||||||
|
|
||||||
def _onPreferencesChanged(self, name):
|
|
||||||
if name != "general/visible_settings":
|
|
||||||
return
|
|
||||||
|
|
||||||
if self._active_preset != "custom":
|
|
||||||
return
|
|
||||||
|
|
||||||
# Copy current visibility set to custom visibility set preference so it can be restored later
|
|
||||||
visibility_string = self._preferences.getValue("general/visible_settings")
|
|
||||||
self._preferences.setValue("cura/custom_visible_settings", visibility_string)
|
|
||||||
|
|
||||||
|
|
||||||
# Factory function, used by QML
|
|
||||||
@staticmethod
|
|
||||||
def createSettingVisibilityPresetsModel(engine, js_engine):
|
|
||||||
return SettingVisibilityPresetsModel.getInstance()
|
|
||||||
|
|
||||||
## Get the singleton instance for this class.
|
|
||||||
@classmethod
|
|
||||||
def getInstance(cls) -> "SettingVisibilityPresetsModel":
|
|
||||||
# Note: Explicit use of class name to prevent issues with inheritance.
|
|
||||||
if not SettingVisibilityPresetsModel.__instance:
|
|
||||||
SettingVisibilityPresetsModel.__instance = cls()
|
|
||||||
return SettingVisibilityPresetsModel.__instance
|
|
||||||
|
|
||||||
__instance = None # type: "SettingVisibilityPresetsModel"
|
|
@ -16,7 +16,8 @@ class SimpleModeSettingsManager(QObject):
|
|||||||
self._is_profile_user_created = False # True when profile was custom created by user
|
self._is_profile_user_created = False # True when profile was custom created by user
|
||||||
|
|
||||||
self._machine_manager.activeStackValueChanged.connect(self._updateIsProfileCustomized)
|
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
|
# update on create as the activeQualityChanged signal is emitted before this manager is created when Cura starts
|
||||||
self._updateIsProfileCustomized()
|
self._updateIsProfileCustomized()
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# 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.Mesh.MeshWriter import MeshWriter
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
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.
|
## Writes g-code to a file.
|
||||||
#
|
#
|
||||||
@ -45,6 +45,8 @@ class GCodeWriter(MeshWriter):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
self._application = Application.getInstance()
|
||||||
|
|
||||||
## Writes the g-code for the entire scene to a stream.
|
## Writes the g-code for the entire scene to a stream.
|
||||||
#
|
#
|
||||||
# Note that even though the function accepts a collection of nodes, the
|
# Note that even though the function accepts a collection of nodes, the
|
||||||
@ -94,7 +96,6 @@ class GCodeWriter(MeshWriter):
|
|||||||
|
|
||||||
return flat_container
|
return flat_container
|
||||||
|
|
||||||
|
|
||||||
## Serialises a container stack to prepare it for writing at the end of the
|
## Serialises a container stack to prepare it for writing at the end of the
|
||||||
# g-code.
|
# g-code.
|
||||||
#
|
#
|
||||||
@ -104,15 +105,21 @@ class GCodeWriter(MeshWriter):
|
|||||||
# \param settings A container stack to serialise.
|
# \param settings A container stack to serialise.
|
||||||
# \return A serialised string of the settings.
|
# \return A serialised string of the settings.
|
||||||
def _serialiseSettings(self, stack):
|
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 = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line.
|
||||||
prefix_length = len(prefix)
|
prefix_length = len(prefix)
|
||||||
|
|
||||||
|
quality_name = stack.qualityChanges.getName()
|
||||||
|
quality_type = stack.quality.getMetaDataEntry("quality_type")
|
||||||
container_with_profile = stack.qualityChanges
|
container_with_profile = stack.qualityChanges
|
||||||
if container_with_profile.getId() == "empty_quality_changes":
|
if container_with_profile.getId() == "empty_quality_changes":
|
||||||
Logger.log("e", "No valid quality profile found, not writing settings to g-code!")
|
# If the global quality changes is empty, create a new one
|
||||||
return ""
|
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 the quality changes is not set, we need to set type manually
|
||||||
if flat_global_container.getMetaDataEntry("type", None) is None:
|
if flat_global_container.getMetaDataEntry("type", None) is None:
|
||||||
flat_global_container.addMetaDataEntry("type", "quality_changes")
|
flat_global_container.addMetaDataEntry("type", "quality_changes")
|
||||||
@ -121,41 +128,47 @@ class GCodeWriter(MeshWriter):
|
|||||||
if flat_global_container.getMetaDataEntry("quality_type", None) is None:
|
if flat_global_container.getMetaDataEntry("quality_type", None) is None:
|
||||||
flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal"))
|
flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal"))
|
||||||
|
|
||||||
# Change the default defintion
|
# Get the machine definition ID for quality profiles
|
||||||
default_machine_definition = "fdmprinter"
|
machine_definition_id_for_quality = getMachineDefinitionIDForQualitySearch(stack.definition)
|
||||||
if parseBool(stack.getMetaDataEntry("has_machine_quality", "False")):
|
flat_global_container.setMetaDataEntry("definition", machine_definition_id_for_quality)
|
||||||
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)
|
|
||||||
|
|
||||||
serialized = flat_global_container.serialize()
|
serialized = flat_global_container.serialize()
|
||||||
data = {"global_quality": serialized}
|
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
|
extruder_quality = extruder.qualityChanges
|
||||||
if extruder_quality.getId() == "empty_quality_changes":
|
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())
|
# Same story, if quality changes is empty, create a new one
|
||||||
continue
|
quality_name = container_registry.uniqueName(stack.quality.getName())
|
||||||
flat_extruder_quality = self._createFlattenedContainerInstance(extruder.getTop(), extruder_quality)
|
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 the quality changes is not set, we need to set type manually
|
||||||
if flat_extruder_quality.getMetaDataEntry("type", None) is None:
|
if flat_extruder_quality.getMetaDataEntry("type", None) is None:
|
||||||
flat_extruder_quality.addMetaDataEntry("type", "quality_changes")
|
flat_extruder_quality.addMetaDataEntry("type", "quality_changes")
|
||||||
|
|
||||||
# Ensure that extruder is set. (Can happen if we have empty quality changes).
|
# Ensure that extruder is set. (Can happen if we have empty quality changes).
|
||||||
if flat_extruder_quality.getMetaDataEntry("extruder", None) is None:
|
if flat_extruder_quality.getMetaDataEntry("position", None) is None:
|
||||||
flat_extruder_quality.addMetaDataEntry("extruder", extruder.getBottom().getId())
|
flat_extruder_quality.addMetaDataEntry("position", extruder.getMetaDataEntry("position"))
|
||||||
|
|
||||||
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
||||||
if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None:
|
if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None:
|
||||||
flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal"))
|
flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal"))
|
||||||
|
|
||||||
# Change the default defintion
|
# Change the default definition
|
||||||
flat_extruder_quality.setMetaDataEntry("definition", default_machine_definition)
|
flat_extruder_quality.setMetaDataEntry("definition", machine_definition_id_for_quality)
|
||||||
|
|
||||||
extruder_serialized = flat_extruder_quality.serialize()
|
extruder_serialized = flat_extruder_quality.serialize()
|
||||||
data.setdefault("extruder_quality", []).append(extruder_serialized)
|
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)
|
json_string = json.dumps(data)
|
||||||
|
|
||||||
# Escape characters that have a special meaning in g-code comments.
|
# 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.
|
# Lines have 80 characters, so the payload of each line is 80 - prefix.
|
||||||
for pos in range(0, len(escaped_string), 80 - prefix_length):
|
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
|
return result
|
||||||
|
@ -163,7 +163,16 @@ Item {
|
|||||||
id: addedSettingsModel;
|
id: addedSettingsModel;
|
||||||
containerId: Cura.MachineManager.activeDefinitionId
|
containerId: Cura.MachineManager.activeDefinitionId
|
||||||
expanded: [ "*" ]
|
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" ];
|
var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ];
|
||||||
|
|
||||||
if(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type == "support_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")
|
title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
|
||||||
width: screenScaleFactor * 360
|
width: screenScaleFactor * 360
|
||||||
|
|
||||||
property string labelFilter: ""
|
|
||||||
property var additional_excluded_settings
|
property var additional_excluded_settings
|
||||||
|
|
||||||
onVisibilityChanged:
|
onVisibilityChanged:
|
||||||
@ -386,11 +394,33 @@ Item {
|
|||||||
// Set skip setting, it will prevent from resetting selected mesh_type
|
// Set skip setting, it will prevent from resetting selected mesh_type
|
||||||
contents.model.visibilityHandler.addSkipResetSetting(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type)
|
contents.model.visibilityHandler.addSkipResetSetting(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type)
|
||||||
listview.model.forceUpdate()
|
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 {
|
TextField {
|
||||||
id: filter
|
id: filterInput
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
@ -401,17 +431,7 @@ Item {
|
|||||||
|
|
||||||
placeholderText: catalog.i18nc("@label:textbox", "Filter...");
|
placeholderText: catalog.i18nc("@label:textbox", "Filter...");
|
||||||
|
|
||||||
onTextChanged:
|
onTextChanged: settingPickDialog.updateFilter()
|
||||||
{
|
|
||||||
if(text != "")
|
|
||||||
{
|
|
||||||
listview.model.filter = {"settable_per_mesh": true, "i18n_label": "*" + text}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
listview.model.filter = {"settable_per_mesh": true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox
|
CheckBox
|
||||||
@ -437,7 +457,7 @@ Item {
|
|||||||
|
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: filter.bottom;
|
top: filterInput.bottom;
|
||||||
left: parent.left;
|
left: parent.left;
|
||||||
right: parent.right;
|
right: parent.right;
|
||||||
bottom: parent.bottom;
|
bottom: parent.bottom;
|
||||||
@ -449,10 +469,6 @@ Item {
|
|||||||
{
|
{
|
||||||
id: definitionsModel;
|
id: definitionsModel;
|
||||||
containerId: Cura.MachineManager.activeDefinitionId
|
containerId: Cura.MachineManager.activeDefinitionId
|
||||||
filter:
|
|
||||||
{
|
|
||||||
"settable_per_mesh": true
|
|
||||||
}
|
|
||||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||||
expanded: [ "*" ]
|
expanded: [ "*" ]
|
||||||
exclude:
|
exclude:
|
||||||
@ -484,6 +500,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component.onCompleted: settingPickDialog.updateFilter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,6 +524,16 @@ Item {
|
|||||||
storeIndex: 0
|
storeIndex: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UM.SettingPropertyProvider
|
||||||
|
{
|
||||||
|
id: printSequencePropertyProvider
|
||||||
|
|
||||||
|
containerStackId: Cura.MachineManager.activeMachineId
|
||||||
|
key: "print_sequence"
|
||||||
|
watchedProperties: [ "value" ]
|
||||||
|
storeIndex: 0
|
||||||
|
}
|
||||||
|
|
||||||
SystemPalette { id: palette; }
|
SystemPalette { id: palette; }
|
||||||
|
|
||||||
Component
|
Component
|
||||||
|
@ -60,7 +60,7 @@ class RemovableDriveOutputDevice(OutputDevice):
|
|||||||
|
|
||||||
if len(file_formats) == 0:
|
if len(file_formats) == 0:
|
||||||
Logger.log("e", "There are no file formats available to write with!")
|
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.
|
# Just take the first file format available.
|
||||||
if file_handler is not None:
|
if file_handler is not None:
|
||||||
|
@ -13,6 +13,7 @@ class ClusterUM3PrinterOutputController(PrinterOutputController):
|
|||||||
def __init__(self, output_device):
|
def __init__(self, output_device):
|
||||||
super().__init__(output_device)
|
super().__init__(output_device)
|
||||||
self.can_pre_heat_bed = False
|
self.can_pre_heat_bed = False
|
||||||
|
self.can_pre_heat_hotends = False
|
||||||
self.can_control_manually = False
|
self.can_control_manually = False
|
||||||
|
|
||||||
def setJobState(self, job: "PrintJobOutputModel", state: str):
|
def setJobState(self, job: "PrintJobOutputModel", state: str):
|
||||||
|
@ -147,6 +147,10 @@ class DiscoverUM3Action(MachineAction):
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@pyqtSlot(str, result = bool)
|
||||||
|
def existsKey(self, key) -> bool:
|
||||||
|
return Application.getInstance().getMachineManager().existNetworkInstances(network_key = key)
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def loadConfigurationFromPrinter(self):
|
def loadConfigurationFromPrinter(self):
|
||||||
machine_manager = Application.getInstance().getMachineManager()
|
machine_manager = Application.getInstance().getMachineManager()
|
||||||
|
@ -5,6 +5,7 @@ import QtQuick 2.2
|
|||||||
import QtQuick.Controls 1.1
|
import QtQuick.Controls 1.1
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Window 2.1
|
import QtQuick.Window 2.1
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
|
||||||
Cura.MachineAction
|
Cura.MachineAction
|
||||||
{
|
{
|
||||||
@ -33,15 +34,34 @@ Cura.MachineAction
|
|||||||
{
|
{
|
||||||
var printerKey = base.selectedDevice.key
|
var printerKey = base.selectedDevice.key
|
||||||
var printerName = base.selectedDevice.name // TODO To change when the groups have a name
|
var printerName = base.selectedDevice.name // TODO To change when the groups have a name
|
||||||
if(manager.getStoredKey() != printerKey)
|
if (manager.getStoredKey() != printerKey)
|
||||||
{
|
{
|
||||||
manager.setKey(printerKey)
|
// Check if there is another instance with the same key
|
||||||
manager.setGroupName(printerName) // TODO To change when the groups have a name
|
if (!manager.existsKey(printerKey))
|
||||||
completed()
|
{
|
||||||
|
manager.setKey(printerKey)
|
||||||
|
manager.setGroupName(printerName) // TODO To change when the groups have a name
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
existingConnectionDialog.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageDialog
|
||||||
|
{
|
||||||
|
id: existingConnectionDialog
|
||||||
|
title: catalog.i18nc("@window:title", "Existing Connection")
|
||||||
|
icon: StandardIcon.Information
|
||||||
|
text: catalog.i18nc("@message:text", "There is an instance already connected to this group")
|
||||||
|
detailedText: catalog.i18nc("@message:description", "You can't connect two instances to the same group. Please use the other instance or connect to another group.")
|
||||||
|
standardButtons: StandardButton.Ok
|
||||||
|
modality: Qt.ApplicationModal
|
||||||
|
}
|
||||||
|
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
@ -82,6 +82,9 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||||||
self._zero_conf_browser.cancel()
|
self._zero_conf_browser.cancel()
|
||||||
self._zero_conf_browser = None # Force the old ServiceBrowser to be destroyed.
|
self._zero_conf_browser = None # Force the old ServiceBrowser to be destroyed.
|
||||||
|
|
||||||
|
for instance_name in list(self._discovered_devices):
|
||||||
|
self._onRemoveDevice(instance_name)
|
||||||
|
|
||||||
self._zero_conf = Zeroconf()
|
self._zero_conf = Zeroconf()
|
||||||
self._zero_conf_browser = ServiceBrowser(self._zero_conf, u'_ultimaker._tcp.local.',
|
self._zero_conf_browser = ServiceBrowser(self._zero_conf, u'_ultimaker._tcp.local.',
|
||||||
[self._appendServiceChangedRequest])
|
[self._appendServiceChangedRequest])
|
||||||
|
@ -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)
|
|
@ -10,9 +10,9 @@ from UM.PluginRegistry import PluginRegistry
|
|||||||
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
|
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
|
||||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||||
|
from cura.PrinterOutput.GenericOutputController import GenericOutputController
|
||||||
|
|
||||||
from .AutoDetectBaudJob import AutoDetectBaudJob
|
from .AutoDetectBaudJob import AutoDetectBaudJob
|
||||||
from .USBPrinterOutputController import USBPrinterOutputController
|
|
||||||
from .avr_isp import stk500v2, intelHex
|
from .avr_isp import stk500v2, intelHex
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
|
||||||
@ -240,7 +240,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
container_stack = Application.getInstance().getGlobalContainerStack()
|
container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
num_extruders = container_stack.getProperty("machine_extruder_count", "value")
|
num_extruders = container_stack.getProperty("machine_extruder_count", "value")
|
||||||
# Ensure that a printer is created.
|
# 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._printers[0].updateName(container_stack.getName())
|
||||||
self.setConnectionState(ConnectionState.connected)
|
self.setConnectionState(ConnectionState.connected)
|
||||||
self._update_thread.start()
|
self._update_thread.start()
|
||||||
@ -372,7 +372,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
elapsed_time = int(time() - self._print_start_time)
|
elapsed_time = int(time() - self._print_start_time)
|
||||||
print_job = self._printers[0].activePrintJob
|
print_job = self._printers[0].activePrintJob
|
||||||
if print_job is None:
|
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")
|
print_job.updateState("printing")
|
||||||
self._printers[0].updateActivePrintJob(print_job)
|
self._printers[0].updateActivePrintJob(print_job)
|
||||||
|
|
||||||
|
@ -208,14 +208,9 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
machine_variant_map = {}
|
machine_variant_map = {}
|
||||||
|
|
||||||
variant_manager = CuraApplication.getInstance().getVariantManager()
|
variant_manager = CuraApplication.getInstance().getVariantManager()
|
||||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
|
||||||
|
|
||||||
root_material_id = self.getMetaDataEntry("base_file") # if basefile is self.getId, this is a basefile.
|
root_material_id = self.getMetaDataEntry("base_file") # if basefile is self.getId, this is a basefile.
|
||||||
material_group = material_manager.getMaterialGroup(root_material_id)
|
all_containers = registry.findInstanceContainers(base_file = root_material_id)
|
||||||
|
|
||||||
all_containers = []
|
|
||||||
for node in [material_group.root_material_node] + material_group.derived_material_node_list:
|
|
||||||
all_containers.append(node.getContainer())
|
|
||||||
|
|
||||||
for container in all_containers:
|
for container in all_containers:
|
||||||
definition_id = container.getMetaDataEntry("definition")
|
definition_id = container.getMetaDataEntry("definition")
|
||||||
@ -242,7 +237,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
|
|
||||||
for definition_id, container in machine_container_map.items():
|
for definition_id, container in machine_container_map.items():
|
||||||
definition_id = container.getMetaDataEntry("definition")
|
definition_id = container.getMetaDataEntry("definition")
|
||||||
definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = definition_id)[0]
|
definition_metadata = registry.findDefinitionContainersMetadata(id = definition_id)[0]
|
||||||
|
|
||||||
product = definition_id
|
product = definition_id
|
||||||
for product_name, product_id_list in product_id_map.items():
|
for product_name, product_id_list in product_id_map.items():
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"visible": true,
|
"visible": true,
|
||||||
"manufacturer": "BQ",
|
"manufacturer": "BQ",
|
||||||
"author": "BQ",
|
"author": "BQ",
|
||||||
"file_formats": "text/x-code",
|
"file_formats": "text/x-gcode",
|
||||||
"platform": "bq_hephestos_platform.stl",
|
"platform": "bq_hephestos_platform.stl",
|
||||||
"platform_offset": [ 0, -82, 0]
|
"platform_offset": [ 0, -82, 0]
|
||||||
},
|
},
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"machine_nozzle_size": { "default_value": 0.5 },
|
"machine_nozzle_size": { "default_value": 0.5 },
|
||||||
"machine_shape": { "default_value": "elliptic" },
|
"machine_shape": { "default_value": "elliptic" },
|
||||||
"machine_width": { "default_value": 290 },
|
"machine_width": { "default_value": 290 },
|
||||||
|
"material_diameter": { "default_value": 1.75 },
|
||||||
"relative_extrusion": { "default_value": false },
|
"relative_extrusion": { "default_value": false },
|
||||||
"retraction_amount": { "default_value": 3.2 },
|
"retraction_amount": { "default_value": 3.2 },
|
||||||
"retraction_combing": { "default_value": "off" },
|
"retraction_combing": { "default_value": "off" },
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"machine_nozzle_size": { "default_value": 0.5 },
|
"machine_nozzle_size": { "default_value": 0.5 },
|
||||||
"machine_shape": { "default_value": "elliptic" },
|
"machine_shape": { "default_value": "elliptic" },
|
||||||
"machine_width": { "default_value": 265 },
|
"machine_width": { "default_value": 265 },
|
||||||
|
"material_diameter": { "default_value": 1.75 },
|
||||||
"relative_extrusion": { "default_value": false },
|
"relative_extrusion": { "default_value": false },
|
||||||
"retraction_amount": { "default_value": 3.2 },
|
"retraction_amount": { "default_value": 3.2 },
|
||||||
"retraction_combing": { "default_value": "off" },
|
"retraction_combing": { "default_value": "off" },
|
||||||
|
@ -110,9 +110,9 @@
|
|||||||
"material_bed_temperature": { "maximum_value": "115" },
|
"material_bed_temperature": { "maximum_value": "115" },
|
||||||
"material_bed_temperature_layer_0": { "maximum_value": "115" },
|
"material_bed_temperature_layer_0": { "maximum_value": "115" },
|
||||||
"material_standby_temperature": { "value": "100" },
|
"material_standby_temperature": { "value": "100" },
|
||||||
"meshfix_maximum_resolution": { "value": "0.04" },
|
"meshfix_maximum_resolution": { "value": "0.04" },
|
||||||
"multiple_mesh_overlap": { "value": "0" },
|
"multiple_mesh_overlap": { "value": "0" },
|
||||||
"optimize_wall_printing_order": { "value": "True" },
|
"optimize_wall_printing_order": { "value": "True" },
|
||||||
"prime_tower_enable": { "default_value": true },
|
"prime_tower_enable": { "default_value": true },
|
||||||
"raft_airgap": { "value": "0" },
|
"raft_airgap": { "value": "0" },
|
||||||
"raft_base_thickness": { "value": "0.3" },
|
"raft_base_thickness": { "value": "0.3" },
|
||||||
|
@ -217,6 +217,7 @@ UM.MainWindow
|
|||||||
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
|
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
|
||||||
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
|
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
|
||||||
visible: Cura.MachineManager.getExtruder(model.index).isEnabled
|
visible: Cura.MachineManager.getExtruder(model.index).isEnabled
|
||||||
|
enabled: Cura.MachineManager.numberExtrudersEnabled > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,8 @@ ToolButton
|
|||||||
color: UM.Theme.getColor("sidebar_header_text_active")
|
color: UM.Theme.getColor("sidebar_header_text_active")
|
||||||
text: control.text;
|
text: control.text;
|
||||||
elide: Text.ElideRight;
|
elide: Text.ElideRight;
|
||||||
anchors.left: isNetworkPrinter ? printerStatusIcon.right : parent.left;
|
anchors.left: printerStatusIcon.visible ? printerStatusIcon.right : parent.left;
|
||||||
anchors.leftMargin: isNetworkPrinter ? UM.Theme.getSize("sidebar_lining").width : UM.Theme.getSize("sidebar_margin").width
|
anchors.leftMargin: printerStatusIcon.visible ? UM.Theme.getSize("sidebar_lining").width : UM.Theme.getSize("sidebar_margin").width
|
||||||
anchors.right: downArrow.left;
|
anchors.right: downArrow.left;
|
||||||
anchors.rightMargin: control.rightMargin;
|
anchors.rightMargin: control.rightMargin;
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
@ -31,7 +31,7 @@ Menu
|
|||||||
MenuItem {
|
MenuItem {
|
||||||
text: "%1: %2 - %3".arg(model.name).arg(model.material).arg(model.variant)
|
text: "%1: %2 - %3".arg(model.name).arg(model.material).arg(model.variant)
|
||||||
visible: base.shouldShowExtruders
|
visible: base.shouldShowExtruders
|
||||||
enabled: UM.Selection.hasSelection
|
enabled: UM.Selection.hasSelection && model.enabled
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(model.id) != -1
|
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(model.id) != -1
|
||||||
onTriggered: CuraActions.setExtruderForSelection(model.id)
|
onTriggered: CuraActions.setExtruderForSelection(model.id)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.1
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.2 as UM
|
||||||
import Cura 1.0 as Cura
|
import Cura 1.0 as Cura
|
||||||
@ -12,44 +12,26 @@ Menu
|
|||||||
id: menu
|
id: menu
|
||||||
title: catalog.i18nc("@action:inmenu", "Visible Settings")
|
title: catalog.i18nc("@action:inmenu", "Visible Settings")
|
||||||
|
|
||||||
|
property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel()
|
||||||
property bool showingSearchResults
|
property bool showingSearchResults
|
||||||
property bool showingAllSettings
|
property bool showingAllSettings
|
||||||
|
|
||||||
signal showAllSettings()
|
signal showAllSettings()
|
||||||
signal showSettingVisibilityProfile()
|
signal showSettingVisibilityProfile()
|
||||||
|
|
||||||
MenuItem
|
|
||||||
{
|
|
||||||
text: catalog.i18nc("@action:inmenu", "Custom selection")
|
|
||||||
checkable: true
|
|
||||||
checked: !showingSearchResults && !showingAllSettings && Cura.SettingVisibilityPresetsModel.activePreset == "custom"
|
|
||||||
exclusiveGroup: group
|
|
||||||
onTriggered:
|
|
||||||
{
|
|
||||||
Cura.SettingVisibilityPresetsModel.setActivePreset("custom");
|
|
||||||
// Restore custom set from preference
|
|
||||||
UM.Preferences.setValue("general/visible_settings", UM.Preferences.getValue("cura/custom_visible_settings"));
|
|
||||||
showSettingVisibilityProfile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuSeparator { }
|
|
||||||
|
|
||||||
Instantiator
|
Instantiator
|
||||||
{
|
{
|
||||||
model: Cura.SettingVisibilityPresetsModel
|
model: settingVisibilityPresetsModel
|
||||||
|
|
||||||
MenuItem
|
MenuItem
|
||||||
{
|
{
|
||||||
text: model.name
|
text: model.name
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model.id == Cura.SettingVisibilityPresetsModel.activePreset
|
checked: model.id == settingVisibilityPresetsModel.activePreset
|
||||||
exclusiveGroup: group
|
exclusiveGroup: group
|
||||||
onTriggered:
|
onTriggered:
|
||||||
{
|
{
|
||||||
Cura.SettingVisibilityPresetsModel.setActivePreset(model.id);
|
settingVisibilityPresetsModel.setActivePreset(model.id);
|
||||||
|
|
||||||
UM.Preferences.setValue("general/visible_settings", model.settings.join(";"));
|
|
||||||
|
|
||||||
showSettingVisibilityProfile();
|
showSettingVisibilityProfile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,6 +364,7 @@ Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
width: true ? (parent.width * 0.4) | 0 : parent.width
|
width: true ? (parent.width * 0.4) | 0 : parent.width
|
||||||
|
frameVisible: true
|
||||||
|
|
||||||
ListView
|
ListView
|
||||||
{
|
{
|
||||||
|
@ -369,6 +369,7 @@ Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
width: true ? (parent.width * 0.4) | 0 : parent.width
|
width: true ? (parent.width * 0.4) | 0 : parent.width
|
||||||
|
frameVisible: true
|
||||||
|
|
||||||
ListView
|
ListView
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,8 @@ UM.PreferencesPage
|
|||||||
{
|
{
|
||||||
title: catalog.i18nc("@title:tab", "Setting Visibility");
|
title: catalog.i18nc("@title:tab", "Setting Visibility");
|
||||||
|
|
||||||
|
property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel()
|
||||||
|
|
||||||
property int scrollToIndex: 0
|
property int scrollToIndex: 0
|
||||||
|
|
||||||
signal scrollToSection( string key )
|
signal scrollToSection( string key )
|
||||||
@ -27,8 +29,7 @@ UM.PreferencesPage
|
|||||||
|
|
||||||
// After calling this function update Setting visibility preset combobox.
|
// After calling this function update Setting visibility preset combobox.
|
||||||
// Reset should set default setting preset ("Basic")
|
// Reset should set default setting preset ("Basic")
|
||||||
visibilityPreset.setDefaultPreset()
|
visibilityPreset.currentIndex = 1
|
||||||
|
|
||||||
}
|
}
|
||||||
resetEnabled: true;
|
resetEnabled: true;
|
||||||
|
|
||||||
@ -37,8 +38,6 @@ UM.PreferencesPage
|
|||||||
id: base;
|
id: base;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
|
||||||
property bool inhibitSwitchToCustom: false
|
|
||||||
|
|
||||||
CheckBox
|
CheckBox
|
||||||
{
|
{
|
||||||
id: toggleVisibleSettings
|
id: toggleVisibleSettings
|
||||||
@ -112,11 +111,6 @@ UM.PreferencesPage
|
|||||||
|
|
||||||
ComboBox
|
ComboBox
|
||||||
{
|
{
|
||||||
function setDefaultPreset()
|
|
||||||
{
|
|
||||||
visibilityPreset.currentIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
id: visibilityPreset
|
id: visibilityPreset
|
||||||
width: 150 * screenScaleFactor
|
width: 150 * screenScaleFactor
|
||||||
anchors
|
anchors
|
||||||
@ -125,51 +119,25 @@ UM.PreferencesPage
|
|||||||
right: parent.right
|
right: parent.right
|
||||||
}
|
}
|
||||||
|
|
||||||
model: ListModel
|
model: settingVisibilityPresetsModel
|
||||||
{
|
textRole: "name"
|
||||||
id: visibilityPresetsModel
|
|
||||||
Component.onCompleted:
|
|
||||||
{
|
|
||||||
visibilityPresetsModel.append({text: catalog.i18nc("@action:inmenu", "Custom selection"), id: "custom"});
|
|
||||||
|
|
||||||
var presets = Cura.SettingVisibilityPresetsModel;
|
|
||||||
for(var i = 0; i < presets.rowCount(); i++)
|
|
||||||
{
|
|
||||||
visibilityPresetsModel.append({text: presets.getItem(i)["name"], id: presets.getItem(i)["id"]});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentIndex:
|
currentIndex:
|
||||||
{
|
{
|
||||||
// Load previously selected preset.
|
// Load previously selected preset.
|
||||||
var index = Cura.SettingVisibilityPresetsModel.find("id", Cura.SettingVisibilityPresetsModel.activePreset);
|
var index = settingVisibilityPresetsModel.find("id", settingVisibilityPresetsModel.activePreset)
|
||||||
if(index == -1)
|
if (index == -1)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return index + 1; // "Custom selection" entry is added in front, so index is off by 1
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
onActivated:
|
onActivated:
|
||||||
{
|
{
|
||||||
base.inhibitSwitchToCustom = true;
|
var preset_id = settingVisibilityPresetsModel.getItem(index).id;
|
||||||
var preset_id = visibilityPresetsModel.get(index).id;
|
settingVisibilityPresetsModel.setActivePreset(preset_id);
|
||||||
Cura.SettingVisibilityPresetsModel.setActivePreset(preset_id);
|
|
||||||
|
|
||||||
UM.Preferences.setValue("cura/active_setting_visibility_preset", preset_id);
|
|
||||||
if (preset_id != "custom")
|
|
||||||
{
|
|
||||||
UM.Preferences.setValue("general/visible_settings", Cura.SettingVisibilityPresetsModel.getItem(index - 1).settings.join(";"));
|
|
||||||
// "Custom selection" entry is added in front, so index is off by 1
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Restore custom set from preference
|
|
||||||
UM.Preferences.setValue("general/visible_settings", UM.Preferences.getValue("cura/custom_visible_settings"));
|
|
||||||
}
|
|
||||||
base.inhibitSwitchToCustom = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,16 +167,7 @@ UM.PreferencesPage
|
|||||||
exclude: ["machine_settings", "command_line_settings"]
|
exclude: ["machine_settings", "command_line_settings"]
|
||||||
showAncestors: true
|
showAncestors: true
|
||||||
expanded: ["*"]
|
expanded: ["*"]
|
||||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler
|
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||||
{
|
|
||||||
onVisibilityChanged:
|
|
||||||
{
|
|
||||||
if(Cura.SettingVisibilityPresetsModel.activePreset != "" && !base.inhibitSwitchToCustom)
|
|
||||||
{
|
|
||||||
Cura.SettingVisibilityPresetsModel.setActivePreset("custom");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Loader
|
delegate: Loader
|
||||||
|
@ -12,9 +12,20 @@ Item
|
|||||||
property alias color: background.color
|
property alias color: background.color
|
||||||
property var extruderModel
|
property var extruderModel
|
||||||
property var position: index
|
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
|
implicitWidth: parent.width
|
||||||
implicitHeight: UM.Theme.getSize("sidebar_extruder_box").height
|
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
|
Rectangle
|
||||||
{
|
{
|
||||||
id: background
|
id: background
|
||||||
@ -34,12 +45,11 @@ Item
|
|||||||
{
|
{
|
||||||
id: extruderTargetTemperature
|
id: extruderTargetTemperature
|
||||||
text: Math.round(extruderModel.targetHotendTemperature) + "°C"
|
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")
|
font: UM.Theme.getFont("small")
|
||||||
color: UM.Theme.getColor("text_inactive")
|
color: UM.Theme.getColor("text_inactive")
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
anchors.bottom: extruderTemperature.bottom
|
anchors.bottom: extruderCurrentTemperature.bottom
|
||||||
|
|
||||||
MouseArea //For tooltip.
|
MouseArea //For tooltip.
|
||||||
{
|
{
|
||||||
@ -52,7 +62,7 @@ Item
|
|||||||
{
|
{
|
||||||
base.showTooltip(
|
base.showTooltip(
|
||||||
base,
|
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.")
|
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.
|
Label //Temperature indication.
|
||||||
{
|
{
|
||||||
id: extruderTemperature
|
id: extruderCurrentTemperature
|
||||||
text: Math.round(extruderModel.hotendTemperature) + "°C"
|
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")
|
color: UM.Theme.getColor("text")
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
anchors.right: extruderTargetTemperature.left
|
anchors.right: extruderTargetTemperature.left
|
||||||
@ -76,7 +85,7 @@ Item
|
|||||||
|
|
||||||
MouseArea //For tooltip.
|
MouseArea //For tooltip.
|
||||||
{
|
{
|
||||||
id: extruderTemperatureTooltipArea
|
id: extruderCurrentTemperatureTooltipArea
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onHoveredChanged:
|
onHoveredChanged:
|
||||||
@ -85,8 +94,8 @@ Item
|
|||||||
{
|
{
|
||||||
base.showTooltip(
|
base.showTooltip(
|
||||||
base,
|
base,
|
||||||
{x: 0, y: parent.mapToItem(base, 0, -parent.height / 4).y},
|
{x: 0, y: parent.mapToItem(base, 0, Math.floor(-parent.height / 4)).y},
|
||||||
catalog.i18nc("@tooltip", "The current temperature of this extruder.")
|
catalog.i18nc("@tooltip", "The current temperature of this hotend.")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
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.
|
Rectangle //Material colour indication.
|
||||||
{
|
{
|
||||||
id: materialColor
|
id: materialColor
|
||||||
|
@ -114,21 +114,24 @@ Item
|
|||||||
{
|
{
|
||||||
return false; //Not allowed to do anything.
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
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")
|
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.right: preheatButton.left
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||||
width: UM.Theme.getSize("setting_control").width
|
width: UM.Theme.getSize("monitor_preheat_temperature_control").width
|
||||||
height: UM.Theme.getSize("setting_control").height
|
height: UM.Theme.getSize("monitor_preheat_temperature_control").height
|
||||||
visible: printerModel != null ? printerModel.canPreHeatBed: true
|
visible: printerModel != null ? enabled && printerModel.canPreHeatBed && !printerModel.isPreheating : true
|
||||||
Rectangle //Highlight of input field.
|
Rectangle //Highlight of input field.
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
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
|
TextInput
|
||||||
{
|
{
|
||||||
id: preheatTemperatureInput
|
id: preheatTemperatureInput
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
|
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
maximumLength: 10
|
maximumLength: 5
|
||||||
enabled: parent.enabled
|
enabled: parent.enabled
|
||||||
validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex.
|
validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex.
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
|
anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||||
anchors.right: parent.right
|
anchors.right: unit.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
|
|
||||||
|
@ -215,7 +215,8 @@ SettingItem
|
|||||||
{
|
{
|
||||||
text: model.name
|
text: model.name
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
color: {
|
color:
|
||||||
|
{
|
||||||
if (model.enabled) {
|
if (model.enabled) {
|
||||||
UM.Theme.getColor("setting_control_text")
|
UM.Theme.getColor("setting_control_text")
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,8 +27,19 @@ SettingItem
|
|||||||
|
|
||||||
onActivated:
|
onActivated:
|
||||||
{
|
{
|
||||||
forceActiveFocus();
|
if (model.getItem(index).enabled)
|
||||||
propertyProvider.setPropertyValue("value", model.getItem(index).index);
|
{
|
||||||
|
forceActiveFocus();
|
||||||
|
propertyProvider.setPropertyValue("value", model.getItem(index).index);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (propertyProvider.properties.value == -1)
|
||||||
|
{
|
||||||
|
control.currentIndex = model.rowCount() - 1; // we know the last item is "Not overriden"
|
||||||
|
} else {
|
||||||
|
control.currentIndex = propertyProvider.properties.value; // revert to the old value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveFocusChanged:
|
onActiveFocusChanged:
|
||||||
@ -192,7 +203,14 @@ SettingItem
|
|||||||
{
|
{
|
||||||
text: model.name
|
text: model.name
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
color: UM.Theme.getColor("setting_control_text")
|
color:
|
||||||
|
{
|
||||||
|
if (model.enabled) {
|
||||||
|
UM.Theme.getColor("setting_control_text")
|
||||||
|
} else {
|
||||||
|
UM.Theme.getColor("action_button_disabled_text");
|
||||||
|
}
|
||||||
|
}
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
@ -15,6 +15,7 @@ Item
|
|||||||
{
|
{
|
||||||
id: base;
|
id: base;
|
||||||
|
|
||||||
|
property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel()
|
||||||
property Action configureSettings
|
property Action configureSettings
|
||||||
property bool findingSettings
|
property bool findingSettings
|
||||||
property bool showingAllSettings
|
property bool showingAllSettings
|
||||||
@ -439,6 +440,7 @@ Item
|
|||||||
key: model.key ? model.key : ""
|
key: model.key ? model.key : ""
|
||||||
watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ]
|
watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ]
|
||||||
storeIndex: 0
|
storeIndex: 0
|
||||||
|
removeUnusedValue: model.resolve == undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections
|
Connections
|
||||||
@ -562,9 +564,9 @@ Item
|
|||||||
{
|
{
|
||||||
definitionsModel.hide(contextMenu.key);
|
definitionsModel.hide(contextMenu.key);
|
||||||
// visible settings have changed, so we're no longer showing a preset
|
// visible settings have changed, so we're no longer showing a preset
|
||||||
if (Cura.SettingVisibilityPresetsModel.activePreset != "" && !showingAllSettings)
|
if (settingVisibilityPresetsModel.activePreset != "" && !showingAllSettings)
|
||||||
{
|
{
|
||||||
Cura.SettingVisibilityPresetsModel.setActivePreset("custom");
|
settingVisibilityPresetsModel.setActivePreset("custom");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,16 +596,16 @@ Item
|
|||||||
definitionsModel.show(contextMenu.key);
|
definitionsModel.show(contextMenu.key);
|
||||||
}
|
}
|
||||||
// visible settings have changed, so we're no longer showing a preset
|
// visible settings have changed, so we're no longer showing a preset
|
||||||
if (Cura.SettingVisibilityPresetsModel.activePreset != "" && !showingAllSettings)
|
if (settingVisibilityPresetsModel.activePreset != "" && !showingAllSettings)
|
||||||
{
|
{
|
||||||
Cura.SettingVisibilityPresetsModel.setActivePreset("custom");
|
settingVisibilityPresetsModel.setActivePreset("custom");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuItem
|
MenuItem
|
||||||
{
|
{
|
||||||
//: Settings context menu action
|
//: Settings context menu action
|
||||||
text: catalog.i18nc("@action:menu", "Configure setting visiblity...");
|
text: catalog.i18nc("@action:menu", "Configure setting visibility...");
|
||||||
|
|
||||||
onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu);
|
onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu);
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,7 @@ Column
|
|||||||
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
|
text: catalog.i18nc("@action:inmenu", "Disable Extruder")
|
||||||
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
|
onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
|
||||||
visible: extruder_enabled
|
visible: extruder_enabled
|
||||||
|
enabled: Cura.MachineManager.numberExtrudersEnabled > 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,22 +186,34 @@ Column
|
|||||||
{
|
{
|
||||||
background: Item
|
background: Item
|
||||||
{
|
{
|
||||||
Rectangle
|
function buttonBackgroundColor(index)
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
var extruder = Cura.MachineManager.getExtruder(index)
|
||||||
border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width
|
if (extruder.isEnabled) {
|
||||||
border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") :
|
return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") :
|
||||||
control.hovered ? UM.Theme.getColor("action_button_hovered_border") :
|
control.hovered ? UM.Theme.getColor("action_button_hovered") :
|
||||||
UM.Theme.getColor("action_button_border")
|
UM.Theme.getColor("action_button")
|
||||||
color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") :
|
} else {
|
||||||
control.hovered ? UM.Theme.getColor("action_button_hovered") :
|
return UM.Theme.getColor("action_button_disabled")
|
||||||
UM.Theme.getColor("action_button")
|
}
|
||||||
Behavior on color { ColorAnimation { duration: 50; } }
|
}
|
||||||
|
|
||||||
|
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) {
|
function buttonColor(index) {
|
||||||
var extruder = Cura.MachineManager.getExtruder(index);
|
var extruder = Cura.MachineManager.getExtruder(index);
|
||||||
if (extruder.isEnabled) {
|
if (extruder.isEnabled)
|
||||||
|
{
|
||||||
return (
|
return (
|
||||||
control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
|
control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
|
||||||
control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
|
control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
|
||||||
@ -210,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
|
Item
|
||||||
{
|
{
|
||||||
id: extruderButtonFace
|
id: extruderButtonFace
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
width: {
|
width: {
|
||||||
var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0;
|
var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0;
|
||||||
var iconWidth = extruderIconItem.width;
|
var iconWidth = extruderIconItem.width;
|
||||||
|
@ -19,7 +19,7 @@ Item
|
|||||||
property Action configureSettings;
|
property Action configureSettings;
|
||||||
property variant minimumPrintTime: PrintInformation.minimumPrintTime;
|
property variant minimumPrintTime: PrintInformation.minimumPrintTime;
|
||||||
property variant maximumPrintTime: PrintInformation.maximumPrintTime;
|
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.onCompleted: PrintInformation.enabled = true
|
||||||
Component.onDestruction: PrintInformation.enabled = false
|
Component.onDestruction: PrintInformation.enabled = false
|
||||||
@ -111,7 +111,6 @@ Item
|
|||||||
|
|
||||||
// Set selected value
|
// Set selected value
|
||||||
if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) {
|
if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) {
|
||||||
|
|
||||||
// set to -1 when switching to user created profile so all ticks are clickable
|
// set to -1 when switching to user created profile so all ticks are clickable
|
||||||
if (Cura.SimpleModeSettingsManager.isProfileUserCreated) {
|
if (Cura.SimpleModeSettingsManager.isProfileUserCreated) {
|
||||||
qualityModel.qualitySliderActiveIndex = -1
|
qualityModel.qualitySliderActiveIndex = -1
|
||||||
@ -474,18 +473,7 @@ Item
|
|||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
// if the current profile is user-created, switch to a built-in quality
|
// if the current profile is user-created, switch to a built-in quality
|
||||||
if (Cura.SimpleModeSettingsManager.isProfileUserCreated)
|
Cura.MachineManager.resetToUseDefaultQuality()
|
||||||
{
|
|
||||||
if (Cura.QualityProfilesDropDownMenuModel.rowCount() > 0)
|
|
||||||
{
|
|
||||||
var item = Cura.QualityProfilesDropDownMenuModel.getItem(0);
|
|
||||||
Cura.MachineManager.activeQualityGroup = item.quality_group;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Cura.SimpleModeSettingsManager.isProfileCustomized)
|
|
||||||
{
|
|
||||||
discardOrKeepProfileChangesDialog.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onEntered:
|
onEntered:
|
||||||
{
|
{
|
||||||
@ -594,7 +582,9 @@ Item
|
|||||||
// Update value only if the Recomended mode is Active,
|
// 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
|
// Otherwise if I change the value in the Custom mode the Recomended view will try to repeat
|
||||||
// same operation
|
// 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)
|
Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,16 +84,16 @@
|
|||||||
"tab_background": [39, 44, 48, 255],
|
"tab_background": [39, 44, 48, 255],
|
||||||
|
|
||||||
"action_button": [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_border": [255, 255, 255, 30],
|
||||||
"action_button_hovered": [39, 44, 48, 255],
|
"action_button_hovered": [39, 44, 48, 255],
|
||||||
"action_button_hovered_text": [255, 255, 255, 255],
|
"action_button_hovered_text": [255, 255, 255, 255],
|
||||||
"action_button_hovered_border": [255, 255, 255, 30],
|
"action_button_hovered_border": [255, 255, 255, 30],
|
||||||
"action_button_active": [39, 44, 48, 30],
|
"action_button_active": [39, 44, 48, 30],
|
||||||
"action_button_active_text": [255, 255, 255, 255],
|
"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": [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],
|
"action_button_disabled_border": [255, 255, 255, 30],
|
||||||
|
|
||||||
"scrollbar_background": [39, 44, 48, 0],
|
"scrollbar_background": [39, 44, 48, 0],
|
||||||
|
@ -411,6 +411,8 @@
|
|||||||
"save_button_save_to_button": [0.3, 2.7],
|
"save_button_save_to_button": [0.3, 2.7],
|
||||||
"save_button_specs_icons": [1.4, 1.4],
|
"save_button_specs_icons": [1.4, 1.4],
|
||||||
|
|
||||||
|
"monitor_preheat_temperature_control": [4.5, 2.0],
|
||||||
|
|
||||||
"modal_window_minimum": [60.0, 45],
|
"modal_window_minimum": [60.0, 45],
|
||||||
"license_window_minimum": [45, 45],
|
"license_window_minimum": [45, 45],
|
||||||
"wizard_progress": [10.0, 0.0],
|
"wizard_progress": [10.0, 0.0],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user