From bd76c3e30f68560fc8d1bc821e6f488a9978f61d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 9 Jun 2016 15:46:22 +0200 Subject: [PATCH] Add drop-down in per-object settings to select extruder Actually selecting an extruder has no effect because there are dragons in that area and I need better armour with bonus damage against bugs before I venture in there. Contributes to issues CURA-340 and CURA-1278. --- cura/SettingOverrideDecorator.py | 38 ++++++-- .../PerObjectSettingsPanel.qml | 94 ++++++++++++++++++- .../PerObjectSettingsTool.py | 19 +++- 3 files changed, 142 insertions(+), 9 deletions(-) diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index f9878e436c..06dbc2cb31 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -1,5 +1,9 @@ # Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. + +from PyQt5.QtCore import pyqtSignal +import copy + from UM.Scene.SceneNodeDecorator import SceneNodeDecorator from UM.Settings.ContainerStack import ContainerStack @@ -7,24 +11,29 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Application import Application -import copy + ## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding # the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by # this stack still resolve. class SettingOverrideDecorator(SceneNodeDecorator): + ## Event indicating that the user selected a different extruder. + activeExtruderChanged = pyqtSignal() + def __init__(self): super().__init__() self._stack = ContainerStack(stack_id = id(self)) self._stack.setDirty(False) # This stack does not need to be saved. self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) + self._extruder_stack = None #Stack upon which our stack is based. self._stack.propertyChanged.connect(self._onSettingChanged) ContainerRegistry.getInstance().addContainer(self._stack) - Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) - self._onGlobalContainerStackChanged() + Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack) + self.activeExtruderChanged.connect(self._updateNextStack) + self._updateNextStack() def __deepcopy__(self, memo): ## Create a fresh decorator object @@ -35,13 +44,30 @@ class SettingOverrideDecorator(SceneNodeDecorator): deep_copy._stack.replaceContainer(0, deep_copy._instance) return deep_copy + ## Gets the currently active extruder to print this object with. + # + # \return An extruder's container stack. + def getActiveExtruder(self): + return self._extruder_stack + def _onSettingChanged(self, instance, property): if property == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() - def _onGlobalContainerStackChanged(self): - ## Ensure that the next stack is always the global stack. - self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) + ## Makes sure that the stack upon which the container stack is placed is + # kept up to date. + def _updateNextStack(self): + if self._extruder_stack: + self._stack.setNextStack(ContainerRegistry.getInstance().findContainerStack(id = self._extruder_stack)) + else: + self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) + + ## Changes the extruder with which to print this node. + # + # \param extruder_stack_id The new extruder stack to print with. + def setActiveExtruder(self, extruder_stack_id): + self._extruder_stack = extruder_stack_id + self.activeExtruderChanged.emit() def getStack(self): return self._stack \ No newline at end of file diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index d07db2e212..4610083674 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Ultimaker B.V. +// Copyright (c) 2016 Ultimaker B.V. // Uranium is released under the terms of the AGPLv3 or higher. import QtQuick 2.2 @@ -26,6 +26,98 @@ Item { spacing: UM.Theme.getSize("default_margin").height; + Row + { + ComboBox + { + id: extruderSelector + + model: Cura.ExtrudersModel + { + id: extruders_model + } + textRole: "name" + width: items.width + height: UM.Theme.getSize("section").height + MouseArea + { + anchors.fill: parent + acceptedButtons: Qt.NoButton + onWheel: wheel.accepted = true; + } + + style: ComboBoxStyle + { + background: Rectangle + { + color: + { + if(extruderSelector.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight"); + } + else + { + return extruders_model.getItem(extruderSelector.currentIndex).colour; + } + } + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("setting_control_border") + } + label: Item + { + Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_lining").width + anchors.right: downArrow.left + anchors.rightMargin: UM.Theme.getSize("default_lining").width + anchors.verticalCenter: parent.verticalCenter + + text: extruderSelector.currentText + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("setting_control_disabled_text") + + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + UM.RecolorImage + { + id: downArrow + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 + 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") + } + } + } + + onActivated: UM.ActiveTool.properties.setValue("SelectedActiveExtruder", extruders_model.getItem(index).id); + onModelChanged: updateCurrentIndex(); + + function updateCurrentIndex() + { + for(var i = 0; i < extruders_model.rowCount(); ++i) + { + if(extruders_model.getItem(i).id == UM.ActiveTool.properties.getValue("SelectedActiveExtruder")) + { + extruderSelector.currentIndex = i; + return; + } + } + extruderSelector.currentIndex = -1; + } + } + } + Repeater { id: contents diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index 6ae44c2671..255277c3af 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Uranium is released under the terms of the AGPLv3 or higher. from UM.Tool import Tool @@ -14,7 +14,7 @@ class PerObjectSettingsTool(Tool): super().__init__() self._model = None - self.setExposedProperties("SelectedObjectId", "ContainerID") + self.setExposedProperties("SelectedObjectId", "ContainerID", "SelectedActiveExtruder") Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged) Selection.selectionChanged.connect(self.propertyChanged) @@ -42,6 +42,21 @@ class PerObjectSettingsTool(Tool): except AttributeError: return "" + ## Gets the active extruder of the currently selected object. + # + # \return The active extruder of the currently selected object. + def getSelectedActiveExtruder(self): + selected_object = Selection.getSelectedObject(0) + selected_object.callDecoration("getActiveExtruder") + + ## Changes the active extruder of the currently selected object. + # + # \param extruder_stack_id The ID of the extruder to print the currently + # selected object with. + def setSelectedActiveExtruder(self, extruder_stack_id): + selected_object = Selection.getSelectedObject(0) + selected_object.callDecoration("setActiveExtruder", extruder_stack_id) + def _onPreferenceChanged(self, preference): if preference == "cura/active_mode": enabled = Preferences.getInstance().getValue(preference)==1