diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ba42dd2aec..b5aecb9b56 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -145,6 +145,7 @@ class CuraApplication(QtApplication): SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None, depends_on = "value") SettingDefinition.addSettingType("extruder", None, str, Validator) + SettingDefinition.addSettingType("optional_extruder", None, str, None) SettingDefinition.addSettingType("[int]", None, str, None) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 7491f8aa93..fadc259f34 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -67,6 +67,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self._simple_names = False self._active_extruder_stack = None + self._use_optional_extruder = False #Listen to changes. Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders) @@ -89,6 +90,18 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def addGlobal(self): return self._add_global + useOptionalExtruderChanged = pyqtSignal() + + def setUseOptionalExtruder(self, use_optional_extruder): + if use_optional_extruder != self._use_optional_extruder: + self._use_optional_extruder = use_optional_extruder + self.useOptionalExtruderChanged.emit() + self._updateExtruders() + + @pyqtProperty(bool, fset = setUseOptionalExtruder, notify = useOptionalExtruderChanged) + def useOptionalExtruder(self): + return self._use_optional_extruder + ## Set the simpleNames property. def setSimpleNames(self, simple_names): if simple_names != self._simple_names: @@ -184,5 +197,16 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): if changed: items.sort(key = lambda i: i["index"]) + # We need optional extruder to be last, so add it after we do sorting. + # This way we can simply intrepret the -1 of the index as the last item (which it now always is) + if self._use_optional_extruder: + item = { + "id": "zomg", + "name": "Not overridden", + "color": self.defaultColors[0], + "index": -1, + "definition": "" + } + items.append(item) self.setItems(items) self.modelChanged.emit() diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml new file mode 100644 index 0000000000..07b15e404d --- /dev/null +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -0,0 +1,153 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +SettingItem +{ + id: base + + contents: ComboBox + { + id: control + anchors.fill: parent + + model: Cura.ExtrudersModel + { + onModelChanged: control.color = getItem(control.currentIndex).color + useOptionalExtruder: true + } + + textRole: "name" + + onActivated: + { + forceActiveFocus(); + propertyProvider.setPropertyValue("value", model.getItem(index).index); + } + + Binding + { + target: control + property: "currentIndex" + value: + { + if(propertyProvider.properties.value == -1) + { + return control.model.items.length - 1 + } + return propertyProvider.properties.value + } + // Sometimes when the value is already changed, the model is still being built. + // The when clause ensures that the current index is not updated when this happens. + when: control.model.items.length > 0 + } + + MouseArea + { + anchors.fill: parent + acceptedButtons: Qt.NoButton + onWheel: wheel.accepted = true; + } + + property string color: "#fff" + + Binding + { + // We override the color property's value when the ExtruderModel changes. So we need to use an + // explicit binding here otherwise we do not handle value changes after the model changes. + target: control + property: "color" + value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : "" + } + + style: ComboBoxStyle + { + background: Rectangle + { + color: + { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled"); + } + if(control.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight"); + } + else + { + return UM.Theme.getColor("setting_control"); + } + } + border.width: UM.Theme.getSize("default_lining").width + border.color: + { + if(!enabled) + { + return UM.Theme.getColor("setting_control_disabled_border"); + } + if(control.hovered || base.activeFocus) + { + UM.Theme.getColor("setting_control_border_highlight") + } + + return UM.Theme.getColor("setting_control_border") + } + } + label: Item + { + Rectangle + { + id: swatch + height: UM.Theme.getSize("setting_control").height / 2 + width: height + + anchors.verticalCenter: parent.verticalCenter + + border.width: UM.Theme.getSize("default_lining").width + border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") + + color: control.color + } + Label + { + anchors + { + left: swatch.right; + right: arrow.left; + verticalCenter: parent.verticalCenter + margins: UM.Theme.getSize("default_lining").width + } + width: parent.width - swatch.width; + + text: control.currentText + font: UM.Theme.getFont("default") + color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") + + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + UM.RecolorImage + { + id: arrow + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 + sourceSize.height: width + 5 + + color: UM.Theme.getColor("setting_control_text") + } + } + } + } +} diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 85d19b0cf0..7cb45ff75f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -195,7 +195,7 @@ Item //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. - asynchronous: model.type != "enum" && model.type != "extruder" + asynchronous: model.type != "enum" && model.type != "extruder" && model.type != "optional_extruder" active: model.type != undefined source: @@ -218,6 +218,8 @@ Item return "SettingTextField.qml" case "category": return "SettingCategory.qml" + case "optional_extruder": + return "SettingOptionalExtruder.qml" default: return "SettingUnknown.qml" }