WIP: Make MachineSetting panel work

This commit is contained in:
Lipu Fei 2019-03-19 08:28:45 +01:00
parent 8242a3801c
commit 987ebba33b
8 changed files with 168 additions and 51 deletions

View file

@ -60,6 +60,7 @@ from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Scene.CuraSceneController import CuraSceneController from cura.Scene.CuraSceneController import CuraSceneController
from cura.UI.WelcomePagesModel import WelcomePagesModel from cura.UI.WelcomePagesModel import WelcomePagesModel
from cura.UI.MachineSettingsManager import MachineSettingsManager
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
@ -212,8 +213,9 @@ class CuraApplication(QtApplication):
self._cura_scene_controller = None self._cura_scene_controller = None
self._machine_error_checker = None self._machine_error_checker = None
self._discovered_printer_model = DiscoveredPrintersModel(self) self._machine_settings_manager = MachineSettingsManager(self)
self._discovered_printer_model = DiscoveredPrintersModel(self)
self._welcome_pages_model = WelcomePagesModel(self) self._welcome_pages_model = WelcomePagesModel(self)
self._quality_profile_drop_down_menu_model = None self._quality_profile_drop_down_menu_model = None
@ -862,6 +864,10 @@ class CuraApplication(QtApplication):
def getWelcomePagesModel(self, *args) -> "WelcomePagesModel": def getWelcomePagesModel(self, *args) -> "WelcomePagesModel":
return self._welcome_pages_model return self._welcome_pages_model
@pyqtSlot(result = QObject)
def getMachineSettingsManager(self, *args) -> "MachineSettingsManager":
return self._machine_settings_manager
def getCuraFormulaFunctions(self, *args) -> "CuraFormulaFunctions": def getCuraFormulaFunctions(self, *args) -> "CuraFormulaFunctions":
if self._cura_formula_functions is None: if self._cura_formula_functions is None:
self._cura_formula_functions = CuraFormulaFunctions(self) self._cura_formula_functions = CuraFormulaFunctions(self)

View file

@ -0,0 +1,66 @@
from typing import Any, Dict, Optional, TYPE_CHECKING
from PyQt5.QtCore import Qt, QObject, pyqtSlot
from UM.i18n import i18nCatalog
class MachineSettingsManager(QObject):
def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent)
self._i18n_catalog = i18nCatalog("cura")
from cura.CuraApplication import CuraApplication
self._application = CuraApplication.getInstance()
# Force rebuilding the build volume by reloading the global container stack. This is a bit of a hack, but it seems
# quite enough.
@pyqtSlot()
def forceUpdate(self) -> None:
self._application.getMachineManager().globalContainerChanged.emit()
# Function for the Machine Settings panel (QML) to update the compatible material diameter after a user has changed
# an extruder's compatible material diameter. This ensures that after the modification, changes can be notified
# and updated right away.
@pyqtSlot(int)
def updateMaterialForDiameter(self, extruder_position: int):
# Updates the material container to a material that matches the material diameter set for the printer
self._application.getMachineManager().updateMaterialWithVariant(str(extruder_position))
# FIXME(Lipu): Better document what this function does, especially the fuzzy gcode flavor and has_materials logic
# regarding UM2 and UM2+
# Function for the Machine Settings panel (QML) to update after the usre changes "Number of Extruders".
@pyqtSlot()
def updateHasMaterialsMetadata(self):
machine_manager = self._application.getMachineManager()
material_manager = self._application.getMaterialManager()
global_stack = material_manager.activeMachine
definition = global_stack.definition
if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or definition.getMetaDataEntry(
"has_materials", False):
# In other words: only continue for the UM2 (extended), but not for the UM2+
return
extruder_positions = list(global_stack.extruders.keys())
has_materials = global_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
material_node = None
if has_materials:
global_stack.setMetaDataEntry("has_materials", True)
else:
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
if "has_materials" in global_stack.getMetaData():
global_stack.removeMetaDataEntry("has_materials")
# set materials
for position in extruder_positions:
if has_materials:
material_node = material_manager.getDefaultMaterial(global_stack, position, None)
machine_manager.setMaterial(position, material_node)
self.forceUpdate()

View file

@ -39,8 +39,8 @@ UM.TooltipArea
property string tooltipText: propertyProvider.properties.description property string tooltipText: propertyProvider.properties.description
// callback functions // callback functions
property var afterOnActivateFunction: dummy_func
property var forceUpdateOnChangeFunction: dummy_func property var forceUpdateOnChangeFunction: dummy_func
property var afterOnEditingFinishedFunction: dummy_func
// a dummy function for default property values // a dummy function for default property values
function dummy_func() {} function dummy_func() {}
@ -64,8 +64,10 @@ UM.TooltipArea
ListModel ListModel
{ {
id: defaultOptionsModel id: defaultOptionsModel
Component.onCompleted:
function updateModel()
{ {
clear()
// Options come in as a string-representation of an OrderedDict // Options come in as a string-representation of an OrderedDict
var options = propertyProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/) var options = propertyProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/)
if (options) if (options)
@ -74,10 +76,19 @@ UM.TooltipArea
for (var i = 0; i < options.length; i++) for (var i = 0; i < options.length; i++)
{ {
var option = options[i].substring(1, options[i].length - 1).split("', '") var option = options[i].substring(1, options[i].length - 1).split("', '")
defaultOptionsModel.append({text: option[1], value: option[0]}) append({text: option[1], value: option[0]})
} }
} }
} }
Component.onCompleted: updateModel()
}
// Remake the model when the model is bound to a different container stack
Connections
{
target: propertyProvider
onContainerStackChanged: defaultOptionsModel.updateModel()
} }
CuraComboBox CuraComboBox
@ -107,11 +118,11 @@ UM.TooltipArea
onActivated: onActivated:
{ {
if(propertyProvider.properties.value != model.get(index).value) if (propertyProvider.properties.value != model.get(index).value)
{ {
propertyProvider.setPropertyValue("value", model.get(index).value) propertyProvider.setPropertyValue("value", model.get(index).value)
forceUpdateOnChangeFunction() forceUpdateOnChangeFunction()
afterOnActivateFunction() afterOnEditingFinishedFunction()
} }
} }
} }

View file

@ -181,7 +181,7 @@ UM.TooltipArea
propertyProvider.setPropertyValue("value", text) propertyProvider.setPropertyValue("value", text)
} }
forceUpdateOnChangeFunction() forceUpdateOnChangeFunction()
afterOnEditingFinished() afterOnEditingFinishedFunction()
} }
} }

View file

@ -23,8 +23,6 @@ Item
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
property string extruderStackId: ""
property int labelWidth: 180 property int labelWidth: 180
property int controlWidth: UM.Theme.getSize("setting_control").width * 3 / 4 property int controlWidth: UM.Theme.getSize("setting_control").width * 3 / 4
property var labelFont: UM.Theme.getFont("medium") property var labelFont: UM.Theme.getFont("medium")
@ -33,6 +31,15 @@ Item
property int columnSpacing: 3 property int columnSpacing: 3
property int propertyStoreIndex: 5 // definition_changes property int propertyStoreIndex: 5 // definition_changes
property string extruderStackId: ""
property int extruderPosition: 0
property var forceUpdateFunction: CuraApplication.getMachineSettingsManager().forceUpdate
function updateMaterialDiameter()
{
CuraApplication.getMachineSettingsManager().updateMaterialForDiameter(extruderPosition)
}
Item Item
{ {
id: upperBlock id: upperBlock
@ -73,7 +80,7 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
NumericTextFieldWithUnit // "Compatible material diameter" NumericTextFieldWithUnit // "Compatible material diameter"
@ -87,7 +94,9 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
// Other modules won't automatically respond after the user changes the value, so we need to force it.
afterOnEditingFinishedFunction: updateMaterialDiameter
} }
NumericTextFieldWithUnit // "Nozzle offset X" NumericTextFieldWithUnit // "Nozzle offset X"
@ -101,7 +110,7 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
NumericTextFieldWithUnit // "Nozzle offset Y" NumericTextFieldWithUnit // "Nozzle offset Y"
@ -115,7 +124,7 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
NumericTextFieldWithUnit // "Cooling Fan Number" NumericTextFieldWithUnit // "Cooling Fan Number"
@ -129,7 +138,7 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: "" unitText: ""
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
} }
} }

View file

@ -30,6 +30,10 @@ Item
property int columnSpacing: 3 property int columnSpacing: 3
property int propertyStoreIndex: 5 // definition_changes property int propertyStoreIndex: 5 // definition_changes
property string machineStackId: Cura.MachineManager.activeMachineId
property var forceUpdateFunction: CuraApplication.getMachineSettingsManager().forceUpdate
Item Item
{ {
id: upperBlock id: upperBlock
@ -61,7 +65,7 @@ Item
NumericTextFieldWithUnit // "X (Width)" NumericTextFieldWithUnit // "X (Width)"
{ {
id: machineXWidthField id: machineXWidthField
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_width" settingKey: "machine_width"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "X (Width)") labelText: catalog.i18nc("@label", "X (Width)")
@ -69,13 +73,13 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
NumericTextFieldWithUnit // "Y (Depth)" NumericTextFieldWithUnit // "Y (Depth)"
{ {
id: machineYDepthField id: machineYDepthField
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_depth" settingKey: "machine_depth"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Y (Depth)") labelText: catalog.i18nc("@label", "Y (Depth)")
@ -83,13 +87,13 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
NumericTextFieldWithUnit // "Z (Height)" NumericTextFieldWithUnit // "Z (Height)"
{ {
id: machineZHeightField id: machineZHeightField
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_height" settingKey: "machine_height"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Z (Height)") labelText: catalog.i18nc("@label", "Z (Height)")
@ -97,58 +101,61 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
ComboBoxWithOptions // "Build plate shape" ComboBoxWithOptions // "Build plate shape"
{ {
id: buildPlateShapeComboBox id: buildPlateShapeComboBox
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_shape" settingKey: "machine_shape"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Build plate shape") labelText: catalog.i18nc("@label", "Build plate shape")
labelFont: base.labelFont labelFont: base.labelFont
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
SimpleCheckBox // "Origin at center" SimpleCheckBox // "Origin at center"
{ {
id: originAtCenterCheckBox id: originAtCenterCheckBox
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_center_is_zero" settingKey: "machine_center_is_zero"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Origin at center") labelText: catalog.i18nc("@label", "Origin at center")
labelFont: base.labelFont labelFont: base.labelFont
labelWidth: base.labelWidth labelWidth: base.labelWidth
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
SimpleCheckBox // "Heated bed" SimpleCheckBox // "Heated bed"
{ {
id: heatedBedCheckBox id: heatedBedCheckBox
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_heated_bed" settingKey: "machine_heated_bed"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Heated bed") labelText: catalog.i18nc("@label", "Heated bed")
labelFont: base.labelFont labelFont: base.labelFont
labelWidth: base.labelWidth labelWidth: base.labelWidth
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
ComboBoxWithOptions // "G-code flavor" ComboBoxWithOptions // "G-code flavor"
{ {
id: gcodeFlavorComboBox id: gcodeFlavorComboBox
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_gcode_flavor" settingKey: "machine_gcode_flavor"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "G-code flavor") labelText: catalog.i18nc("@label", "G-code flavor")
labelFont: base.labelFont labelFont: base.labelFont
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
// TODO: add afterOnActivate: manager.updateHasMaterialsMetadata // FIXME(Lipu): better document this.
// This has something to do with UM2 and UM2+ regarding "has_material" and the gcode flavor settings.
// I don't remember exactly what.
afterOnEditingFinishedFunction: CuraApplication.getMachineSettingsManager().updateHasMaterialsMetadata
} }
} }
@ -185,7 +192,7 @@ Item
axisName: "x" axisName: "x"
axisMinOrMax: "min" axisMinOrMax: "min"
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
PrintHeadMinMaxTextField // "Y min" PrintHeadMinMaxTextField // "Y min"
@ -203,7 +210,7 @@ Item
axisName: "y" axisName: "y"
axisMinOrMax: "min" axisMinOrMax: "min"
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
PrintHeadMinMaxTextField // "X max" PrintHeadMinMaxTextField // "X max"
@ -221,14 +228,14 @@ Item
axisName: "x" axisName: "x"
axisMinOrMax: "max" axisMinOrMax: "max"
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
PrintHeadMinMaxTextField // "Y max" PrintHeadMinMaxTextField // "Y max"
{ {
id: machineYMaxField id: machineYMaxField
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_head_with_fans_polygon" settingKey: "machine_head_with_fans_polygon"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
@ -241,13 +248,13 @@ Item
axisName: "y" axisName: "y"
axisMinOrMax: "max" axisMinOrMax: "max"
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
NumericTextFieldWithUnit // "Gantry Height" NumericTextFieldWithUnit // "Gantry Height"
{ {
id: machineGantryHeightField id: machineGantryHeightField
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "gantry_height" settingKey: "gantry_height"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Gantry Height") labelText: catalog.i18nc("@label", "Gantry Height")
@ -255,21 +262,24 @@ Item
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm") unitText: catalog.i18nc("@label", "mm")
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
} }
ComboBoxWithOptions // "Number of Extruders" ComboBoxWithOptions // "Number of Extruders"
{ {
id: numberOfExtrudersComboBox id: numberOfExtrudersComboBox
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_extruder_count" settingKey: "machine_extruder_count"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
labelText: catalog.i18nc("@label", "Number of Extruders") labelText: catalog.i18nc("@label", "Number of Extruders")
labelFont: base.labelFont labelFont: base.labelFont
labelWidth: base.labelWidth labelWidth: base.labelWidth
controlWidth: base.controlWidth controlWidth: base.controlWidth
// TODO: add forceUpdateOnChangeFunction: forceUpdateOnChangeFunction: forceUpdateFunction
// TODO: add afterOnActivate: manager.updateHasMaterialsMetadata // FIXME(Lipu): better document this.
// This has something to do with UM2 and UM2+ regarding "has_material" and the gcode flavor settings.
// I don't remember exactly what.
afterOnEditingFinishedFunction: CuraApplication.getMachineSettingsManager().updateHasMaterialsMetadata
optionModel: ListModel optionModel: ListModel
{ {
@ -305,7 +315,7 @@ Item
width: base.columnWidth - UM.Theme.getSize("default_margin").width width: base.columnWidth - UM.Theme.getSize("default_margin").width
labelText: catalog.i18nc("@title:label", "Start G-code") labelText: catalog.i18nc("@title:label", "Start G-code")
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_start_gcode" settingKey: "machine_start_gcode"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
} }
@ -319,7 +329,7 @@ Item
width: base.columnWidth - UM.Theme.getSize("default_margin").width width: base.columnWidth - UM.Theme.getSize("default_margin").width
labelText: catalog.i18nc("@title:label", "End G-code") labelText: catalog.i18nc("@title:label", "End G-code")
containerStackId: Cura.MachineManager.activeMachineId containerStackId: machineStackId
settingKey: "machine_end_gcode" settingKey: "machine_end_gcode"
settingStoreIndex: propertyStoreIndex settingStoreIndex: propertyStoreIndex
} }

View file

@ -26,11 +26,31 @@ Item
property var extrudersModel: Cura.ExtrudersModel {} property var extrudersModel: Cura.ExtrudersModel {}
onVisibleChanged: // If we create a CuraTabButton for "Printer" and use Repeater for extruders, for some reason, once the component
// finishes it will automatically change "currentIndex = 1", and it is VERY difficult to change "currentIndex = 0"
// after that. Using a model and a Repeater to create both "Printer" and extruder CuraTabButtons seem to solve this
// problem.
Connections
{ {
if (visible) target: extrudersModel
onItemsChanged: tabNameModel.update()
}
ListModel
{
id: tabNameModel
Component.onCompleted: update()
function update()
{ {
tabBar.currentIndex = 0 clear()
append({ name: catalog.i18nc("@title:tab", "Printer") })
for (var i = 0; i < extrudersModel.count; i++)
{
const m = extrudersModel.getItem(i)
append({ name: m.name })
}
} }
} }
@ -46,14 +66,9 @@ Item
id: tabBar id: tabBar
width: parent.width width: parent.width
CuraTabButton
{
text: catalog.i18nc("@title:tab", "Printer")
}
Repeater Repeater
{ {
model: extrudersModel model: tabNameModel
delegate: CuraTabButton delegate: CuraTabButton
{ {
text: model.name text: model.name
@ -83,6 +98,7 @@ Item
delegate: MachineSettingsExtruderTab delegate: MachineSettingsExtruderTab
{ {
id: discoverTab id: discoverTab
extruderPosition: model.index
extruderStackId: model.id extruderStackId: model.id
} }
} }

View file

@ -3,7 +3,6 @@
import QtQuick 2.10 import QtQuick 2.10
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import UM 1.3 as UM import UM 1.3 as UM
import Cura 1.1 as Cura import Cura 1.1 as Cura