From ab8bcc4ae38564c16b45bf40cd06983e5fa31cbf Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 09:51:59 +0200 Subject: [PATCH 01/14] small code fixes --- cura/Settings/ProfilesModel.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index e39ed949b0..c1f41c58d2 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -110,12 +110,11 @@ class ProfilesModel(InstanceContainersModel): # active machine and material, and later yield the right ones. tmp_all_quality_items = OrderedDict() for item in super()._recomputeItems(): - profile = container_registry.findContainers(id = item["id"]) + profile = container_registry.findContainers(id=item["id"]) quality_type = profile[0].getMetaDataEntry("quality_type") if profile else "" if quality_type not in tmp_all_quality_items: - tmp_all_quality_items[quality_type] = {"suitable_container": None, - "all_containers": []} + tmp_all_quality_items[quality_type] = {"suitable_container": None, "all_containers": []} tmp_all_quality_items[quality_type]["all_containers"].append(item) if tmp_all_quality_items[quality_type]["suitable_container"] is None and profile[0] in qualities: @@ -142,9 +141,9 @@ class ProfilesModel(InstanceContainersModel): # Now all the containers are set for item in containers: - profile = container_registry.findContainers(id = item["id"]) + profile = container_registry.findContainers(id=item["id"]) if not profile: - item["layer_height"] = "" #Can't update a profile that is unknown. + item["layer_height"] = "" # Can't update a profile that is unknown. item["available"] = False yield item continue @@ -152,13 +151,13 @@ class ProfilesModel(InstanceContainersModel): profile = profile[0] item["available"] = profile in qualities - #Easy case: This profile defines its own layer height. + # Easy case: This profile defines its own layer height. if profile.hasProperty("layer_height", "value"): self._setItemLayerHeight(item, profile.getProperty("layer_height", "value"), unit) yield item continue - #Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile. + # Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile. quality_type = profile.getMetaDataEntry("quality_type", None) if quality_type: quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(quality_type) From 7f909df84a7fa3014046a3336a37f897461a5678 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 11:04:46 +0200 Subject: [PATCH 02/14] CURA-4182 refactor quality slider to use model for updating --- resources/qml/SidebarSimple.qml | 246 +++++++++++++++----------------- 1 file changed, 119 insertions(+), 127 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index c91c1fcb93..3347f56f43 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -40,110 +40,111 @@ Item // // Quality profile // - Rectangle + Item { - - Timer { - id: qualitySliderChangeTimer - interval: 50 - running: false - repeat: false - onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualityRowSlider.value).id) - } - - Component.onCompleted: - { - qualityRow.updateQualitySliderProperties() - } - - Connections - { - target: Cura.MachineManager - onActiveQualityChanged: - { - qualityRow.updateQualitySliderProperties() - } - } - - id: qualityRow - property var totalTicks: 0 - property var availableTotalTicks: 0 - property var qualitySliderStep: qualityRow.totalTicks != 0 ? (base.width * 0.55) / (qualityRow.totalTicks) : 0 - property var qualitySliderSelectedValue: 0 - - property var sliderAvailableMin : 0 - property var sliderAvailableMax : 0 - property var sliderMarginRight : 0 - - function updateQualitySliderProperties() - { - qualityRow.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0 - - var availableMin = -1 - var availableMax = -1 - - for (var i = 0; i <= Cura.ProfilesModel.rowCount(); i++) - { - //Find slider range, min and max value - if (availableMin == -1 && Cura.ProfilesModel.getItem(i).available) - { - availableMin = i - availableMax = i - } - else if(Cura.ProfilesModel.getItem(i).available) - { - availableMax = i - } - - //Find selected value - if(Cura.MachineManager.activeQualityId == Cura.ProfilesModel.getItem(i).id) - { - qualitySliderSelectedValue = i - } - } - - if(availableMin !=-1) - { - availableTotalTicks = availableMax - availableMin - } - else - { - availableTotalTicks = -1 - } - - qualitySliderStep = qualityRow.totalTicks != 0 ? (base.width * 0.55) / (qualityRow.totalTicks) : 0 - - if(availableMin == -1) - { - sliderMarginRight = base.width * 0.55 - } - else if (availableMin == 0 && availableMax == 0) - { - sliderMarginRight = base.width * 0.55 - } - else if(availableMin == availableMax) - { - sliderMarginRight = (qualityRow.totalTicks - availableMin) * qualitySliderStep - } - else if(availableMin != availableMax) - { - sliderMarginRight = (qualityRow.totalTicks - availableMax) * qualitySliderStep - } - - - qualityRow.sliderAvailableMin = availableMin - qualityRow.sliderAvailableMax = availableMax - } - height: UM.Theme.getSize("sidebar_margin").height - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.right: parent.right + Timer + { + id: qualitySliderChangeTimer + interval: 50 + running: false + repeat: false + onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualitySlider.value).id) + } + + Component.onCompleted: qualityModel.update() + + Connections + { + target: Cura.MachineManager + onActiveQualityChanged: qualityModel.update() + } + + ListModel + { + id: qualityModel + + property var totalTicks: 0 + property var availableTotalTicks: 0 + property var qualitySliderStepWidth: qualityModel.totalTicks != 0 ? (base.width * 0.55) / (qualityModel.totalTicks) : 0 + property var activeQualityId: 0 + + property var sliderAvailableMin : 0 + property var sliderAvailableMax : 0 + property var sliderMarginRight : 0 + + function update () { + qualityModel.clear() + + qualityModel.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0 + + var availableMin = -1 + var availableMax = -1 + + for (var i = 0; i <= Cura.ProfilesModel.rowCount(); i++) { + var qualityItem = Cura.ProfilesModel.getItem(i) + + // Add each quality item to the UI quality model + qualityModel.append(qualityItem) + + // Find slider range, min and max value + if (qualityItem.available && availableMin == -1) { + availableMin = i + availableMax = i + } else if (qualityItem.available) { + availableMax = i + } + + // Find selected value + if(Cura.MachineManager.activeQualityId == qualityItem.id) { + qualityModel.activeQualityId = i + } + } + + if (availableMin != -1) { + qualityModel.availableTotalTicks = availableMax - availableMin + } else { + qualityModel.availableTotalTicks = -1 + } + + calculateSliderStepWidth(qualityModel.totalTicks) + calculateSliderMargins(availableMin, availableMax) + + qualityModel.sliderAvailableMin = availableMin + qualityModel.sliderAvailableMax = availableMax + } + + function calculateSliderStepWidth (totalTicks) { + qualityModel.qualitySliderStepWidth = totalTicks != 0 ? (base.width * 0.55) / (totalTicks) : 0 + } + + function calculateSliderMargins (availableMin, availableMax) { + if(availableMin == -1) + { + qualityModel.sliderMarginRight = base.width * 0.55 + } + else if (availableMin == 0 && availableMax == 0) + { + qualityModel.sliderMarginRight = base.width * 0.55 + } + else if(availableMin == availableMax) + { + qualityModel.sliderMarginRight = (qualityModel.totalTicks - availableMin) * qualitySliderStepWidth + } + else if(availableMin != availableMax) + { + qualityModel.sliderMarginRight = (qualityModel.totalTicks - availableMax) * qualitySliderStepWidth + } + } + } + Text { id: qualityRowTitle @@ -159,7 +160,8 @@ Item anchors.left: speedSlider.left Repeater { - model: qualityRow.totalTicks + 1 + model: qualityModel + Text { anchors.verticalCenter: parent.verticalCenter @@ -167,15 +169,8 @@ Item anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 color: UM.Theme.getColor("text") text: Cura.ProfilesModel.getItem(index).layer_height_without_unit - width: 1 - x: - { - if(index != qualityRow.totalTicks) - return (base.width * 0.55 / qualityRow.totalTicks) * index; - else - return (base.width * 0.55 / qualityRow.totalTicks) * index - 15; - } + x: (index != qualityModel.totalTicks) ? (base.width * 0.55 / qualityModel.totalTicks) * index : (base.width * 0.55 / qualityModel.totalTicks) * index - 15 } } } @@ -197,8 +192,7 @@ Item width: base.width * 0.55 height: 2 color: UM.Theme.getColor("quality_slider_unavailable") - //radius: parent.radius - anchors.verticalCenter: qualityRowSlider.verticalCenter + anchors.verticalCenter: qualitySlider.verticalCenter x: 0 } @@ -206,51 +200,52 @@ Item Repeater { id: qualityRepeater - model: qualityRow.totalTicks + 1 - Rectangle { + model: qualityModel + + Rectangle + { anchors.verticalCenter: parent.verticalCenter - color: qualityRow.availableTotalTicks != 0 ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: qualityModel.count > 1 ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") width: 1 height: 6 y: 0 - x: qualityRow.qualitySliderStep * index + x: qualityModel.qualitySliderStepWidth * index } } Slider { - - id: qualityRowSlider + id: qualitySlider height: UM.Theme.getSize("sidebar_margin").height anchors.bottom: speedSlider.bottom - enabled: qualityRow.availableTotalTicks != 0 + enabled: qualityModel.availableTotalTicks > 0 updateValueWhileDragging : false - minimumValue: qualityRow.sliderAvailableMin - maximumValue: qualityRow.sliderAvailableMax + minimumValue: qualityModel.sliderAvailableMin + maximumValue: qualityModel.sliderAvailableMax stepSize: 1 - value: qualityRow.qualitySliderSelectedValue + value: qualityModel.activeQualityId - width: qualityRow.qualitySliderStep * (qualityRow.availableTotalTicks) + width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks anchors.right: parent.right - anchors.rightMargin: qualityRow.sliderMarginRight + anchors.rightMargin: qualityModel.sliderMarginRight style: SliderStyle { //Draw Available line groove: Rectangle { implicitHeight: 2 - anchors.verticalCenter: qualityRowSlider.verticalCenter + anchors.verticalCenter: qualitySlider.verticalCenter color: UM.Theme.getColor("quality_slider_available") radius: 1 } handle: Item { Rectangle { id: qualityhandleButton - anchors.verticalCenter: qualityRowSlider.verticalCenter + anchors.verticalCenter: qualitySlider.verticalCenter anchors.centerIn: parent color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") implicitWidth: 10 @@ -261,12 +256,9 @@ Item } onValueChanged: { - - //Prevent updating during view initializing. Trigger only if the value changed by user - if(qualityRowSlider.value != qualityRow.qualitySliderSelectedValue) - { - //start updating with short delay - qualitySliderChangeTimer.start(); + // Prevent updating during view initializing. Trigger only if the value changed by user + if (qualitySlider.value != qualityModel.activeQualityId) { + qualitySliderChangeTimer.start() } } } @@ -519,7 +511,7 @@ Item Text { id: gradualInfillLabel anchors.left: enableGradualInfillCheckBox.right - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2 // FIXME better margin value + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2 text: catalog.i18nc("@label", "Enable gradual") font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") From 88155d35e8987a61fefeb3cb4f94e18d3f1ca101 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 22 Sep 2017 11:11:34 +0200 Subject: [PATCH 03/14] Correct signature of activeMachine Because there isn't always a global container stack. Contributes to issue CURA-4357. --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e807e49200..a2d32a35ea 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -475,7 +475,7 @@ class MachineManager(QObject): return "" @pyqtProperty(QObject, notify = globalContainerChanged) - def activeMachine(self) -> "GlobalStack": + def activeMachine(self) -> Optional["GlobalStack"]: return self._global_container_stack @pyqtProperty(str, notify = activeStackChanged) From ae6b1a9f156626ae8efeaf26bb292582b657aa7d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 11:14:13 +0200 Subject: [PATCH 04/14] CURA-4182 better variable names --- resources/qml/SidebarSimple.qml | 36 ++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 3347f56f43..1b042d8748 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -73,17 +73,15 @@ Item property var totalTicks: 0 property var availableTotalTicks: 0 - property var qualitySliderStepWidth: qualityModel.totalTicks != 0 ? (base.width * 0.55) / (qualityModel.totalTicks) : 0 property var activeQualityId: 0 - property var sliderAvailableMin : 0 - property var sliderAvailableMax : 0 - property var sliderMarginRight : 0 + property var qualitySliderStepWidth: qualityModel.totalTicks != 0 ? (base.width * 0.55) / (qualityModel.totalTicks) : 0 + property var qualitySliderAvailableMin : 0 + property var qualitySliderAvailableMax : 0 + property var qualitySliderMarginRight : 0 function update () { - qualityModel.clear() - - qualityModel.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0 + reset() var availableMin = -1 var availableMax = -1 @@ -117,8 +115,8 @@ Item calculateSliderStepWidth(qualityModel.totalTicks) calculateSliderMargins(availableMin, availableMax) - qualityModel.sliderAvailableMin = availableMin - qualityModel.sliderAvailableMax = availableMax + qualityModel.qualitySliderAvailableMin = availableMin + qualityModel.qualitySliderAvailableMax = availableMax } function calculateSliderStepWidth (totalTicks) { @@ -128,21 +126,27 @@ Item function calculateSliderMargins (availableMin, availableMax) { if(availableMin == -1) { - qualityModel.sliderMarginRight = base.width * 0.55 + qualityModel.qualitySliderMarginRight = base.width * 0.55 } else if (availableMin == 0 && availableMax == 0) { - qualityModel.sliderMarginRight = base.width * 0.55 + qualityModel.qualitySliderMarginRight = base.width * 0.55 } else if(availableMin == availableMax) { - qualityModel.sliderMarginRight = (qualityModel.totalTicks - availableMin) * qualitySliderStepWidth + qualityModel.qualitySliderMarginRight = (qualityModel.totalTicks - availableMin) * qualitySliderStepWidth } else if(availableMin != availableMax) { - qualityModel.sliderMarginRight = (qualityModel.totalTicks - availableMax) * qualitySliderStepWidth + qualityModel.qualitySliderMarginRight = (qualityModel.totalTicks - availableMax) * qualitySliderStepWidth } } + + function reset () { + qualityModel.clear() + qualityModel.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0 + qualityModel.availableTotalTicks = -1 + } } Text @@ -222,8 +226,8 @@ Item enabled: qualityModel.availableTotalTicks > 0 updateValueWhileDragging : false - minimumValue: qualityModel.sliderAvailableMin - maximumValue: qualityModel.sliderAvailableMax + minimumValue: qualityModel.qualitySliderAvailableMin + maximumValue: qualityModel.qualitySliderAvailableMax stepSize: 1 value: qualityModel.activeQualityId @@ -231,7 +235,7 @@ Item width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks anchors.right: parent.right - anchors.rightMargin: qualityModel.sliderMarginRight + anchors.rightMargin: qualityModel.qualitySliderMarginRight style: SliderStyle { From 1596437bbdbcfc22875aa18db78428a9e1e70acc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 22 Sep 2017 11:17:42 +0200 Subject: [PATCH 05/14] getActiveGlobalAndContainerStacks may return None Change the code to reflect on this. Mostly this is to fix up the type warnings, because we were already checking for there being no global container stack but that was not thread-safe. Contributes to issue CURA-4357. --- cura/Settings/MachineManager.py | 42 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a2d32a35ea..26deaa6987 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -497,8 +497,9 @@ class MachineManager(QObject): @pyqtProperty("QVariantList", notify=activeVariantChanged) def activeVariantNames(self): result = [] - if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None: - for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() + if active_stacks is not None: + for stack in active_stacks: variant_container = stack.variant if variant_container and variant_container != self._empty_variant_container: result.append(variant_container.getName()) @@ -508,8 +509,9 @@ class MachineManager(QObject): @pyqtProperty("QVariantList", notify = activeMaterialChanged) def activeMaterialNames(self): result = [] - if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None: - for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() + if active_stacks is not None: + for stack in active_stacks: material_container = stack.material if material_container and material_container != self._empty_material_container: result.append(material_container.getName()) @@ -526,33 +528,29 @@ class MachineManager(QObject): @pyqtProperty("QVariantMap", notify = activeVariantChanged) def allActiveVariantIds(self): - if not self._global_container_stack: - return {} - result = {} + active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() + if active_stacks is not None: #If we have a global stack. + for stack in active_stacks: + variant_container = stack.variant + if not variant_container: + continue - for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): - variant_container = stack.variant - if not variant_container: - continue - - result[stack.getId()] = variant_container.getId() + result[stack.getId()] = variant_container.getId() return result @pyqtProperty("QVariantMap", notify = activeMaterialChanged) def allActiveMaterialIds(self): - if not self._global_container_stack: - return {} - result = {} + active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() + if active_stacks is not None: #If we have a global stack. + for stack in active_stacks: + material_container = stack.material + if not material_container: + continue - for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): - material_container = stack.material - if not material_container: - continue - - result[stack.getId()] = material_container.getId() + result[stack.getId()] = material_container.getId() return result From 37da9f654bde6cf92548a6b18b9b4f5be3d0206c Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 22 Sep 2017 11:20:57 +0200 Subject: [PATCH 06/14] Reverted changes done that makes sliders fail - CURA-4327 --- cura/Settings/ProfilesModel.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index e39ed949b0..b6ef1fdcef 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -126,25 +126,14 @@ class ProfilesModel(InstanceContainersModel): for key in reversed(tmp_all_quality_items.keys()): all_quality_items[key] = tmp_all_quality_items[key] - # First the suitable containers are set in the model - containers = [] for data_item in all_quality_items.values(): - suitable_item = data_item["suitable_container"] - if suitable_item is None: - suitable_item = data_item["all_containers"][0] - containers.append(suitable_item) + item = data_item["suitable_container"] + if item is None: + item = data_item["all_containers"][0] - # Once the suitable containers are collected, the rest of the containers are appended - for data_item in all_quality_items.values(): - for item in data_item["all_containers"]: - if item not in containers: - containers.append(item) - - # Now all the containers are set - for item in containers: profile = container_registry.findContainers(id = item["id"]) if not profile: - item["layer_height"] = "" #Can't update a profile that is unknown. + item["layer_height"] = "" # Can't update a profile that is unknown. item["available"] = False yield item continue From f016e5346a7bfbf641400b45834ee1926246343e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 11:29:18 +0200 Subject: [PATCH 07/14] CURA-4182 code improvements for slider property calcs --- resources/qml/SidebarSimple.qml | 51 +++++++++++++++------------------ 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 1b042d8748..8f30c24d42 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -75,7 +75,7 @@ Item property var availableTotalTicks: 0 property var activeQualityId: 0 - property var qualitySliderStepWidth: qualityModel.totalTicks != 0 ? (base.width * 0.55) / (qualityModel.totalTicks) : 0 + property var qualitySliderStepWidth: 0 property var qualitySliderAvailableMin : 0 property var qualitySliderAvailableMax : 0 property var qualitySliderMarginRight : 0 @@ -92,28 +92,30 @@ Item // Add each quality item to the UI quality model qualityModel.append(qualityItem) - // Find slider range, min and max value - if (qualityItem.available && availableMin == -1) { - availableMin = i - availableMax = i - } else if (qualityItem.available) { - availableMax = i - } - - // Find selected value - if(Cura.MachineManager.activeQualityId == qualityItem.id) { + // Set selected value + if (Cura.MachineManager.activeQualityId == qualityItem.id) { qualityModel.activeQualityId = i } + + // Set min available + if (qualityItem.available && availableMin == -1) { + availableMin = i + } + + // Set max available + if (qualityItem.available) { + availableMax = i + } } + // Set total available ticks for active slider part if (availableMin != -1) { qualityModel.availableTotalTicks = availableMax - availableMin - } else { - qualityModel.availableTotalTicks = -1 } + // Calculate slider values calculateSliderStepWidth(qualityModel.totalTicks) - calculateSliderMargins(availableMin, availableMax) + calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks) qualityModel.qualitySliderAvailableMin = availableMin qualityModel.qualitySliderAvailableMax = availableMax @@ -123,22 +125,15 @@ Item qualityModel.qualitySliderStepWidth = totalTicks != 0 ? (base.width * 0.55) / (totalTicks) : 0 } - function calculateSliderMargins (availableMin, availableMax) { - if(availableMin == -1) - { + function calculateSliderMargins (availableMin, availableMax, totalTicks) { + if (availableMin == -1) { qualityModel.qualitySliderMarginRight = base.width * 0.55 - } - else if (availableMin == 0 && availableMax == 0) - { + } else if (availableMin == 0 && availableMax == 0) { qualityModel.qualitySliderMarginRight = base.width * 0.55 - } - else if(availableMin == availableMax) - { - qualityModel.qualitySliderMarginRight = (qualityModel.totalTicks - availableMin) * qualitySliderStepWidth - } - else if(availableMin != availableMax) - { - qualityModel.qualitySliderMarginRight = (qualityModel.totalTicks - availableMax) * qualitySliderStepWidth + } else if (availableMin == availableMax) { + qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth + } else if (availableMin != availableMax) { + qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth } } From 3d921c1b4e7c1c9c7f5c447556ac41bee050459a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 22 Sep 2017 11:30:35 +0200 Subject: [PATCH 08/14] Add type hinting of return values I thought this might help find some bugs there. Contributes to issue CURA-4357. --- cura/Settings/MachineManager.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 26deaa6987..6712bef92d 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1,6 +1,9 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. -from typing import Union + +#Type hinting. +from typing import Union, List, Dict +from UM.Signal import Signal from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer from UM.FlameProfiler import pyqtSlot @@ -366,7 +369,7 @@ class MachineManager(QObject): def _createUniqueName(self, container_type: str, current_name: str, new_name: str, fallback_name: str) -> str: return ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name) - def _checkStacksHaveErrors(self): + def _checkStacksHaveErrors(self) -> bool: if self._global_container_stack is None: #No active machine. return False @@ -390,7 +393,7 @@ class MachineManager(QObject): ## Check if the global_container has instances in the user container @pyqtProperty(bool, notify = activeStackValueChanged) - def hasUserSettings(self): + def hasUserSettings(self) -> bool: if not self._global_container_stack: return False @@ -405,7 +408,7 @@ class MachineManager(QObject): return False @pyqtProperty(int, notify = activeStackValueChanged) - def numUserSettings(self): + def numUserSettings(self) -> int: if not self._global_container_stack: return 0 num_user_settings = 0 @@ -450,7 +453,7 @@ class MachineManager(QObject): # Note that the _stacks_have_errors is cached due to performance issues # Calling _checkStack(s)ForErrors on every change is simply too expensive @pyqtProperty(bool, notify = stacksValidationChanged) - def stacksHaveErrors(self): + def stacksHaveErrors(self) -> bool: return bool(self._stacks_have_errors) @pyqtProperty(str, notify = activeStackChanged) @@ -495,7 +498,7 @@ class MachineManager(QObject): return "" @pyqtProperty("QVariantList", notify=activeVariantChanged) - def activeVariantNames(self): + def activeVariantNames(self) -> List[str]: result = [] active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() if active_stacks is not None: @@ -507,7 +510,7 @@ class MachineManager(QObject): return result @pyqtProperty("QVariantList", notify = activeMaterialChanged) - def activeMaterialNames(self): + def activeMaterialNames(self) -> List[str]: result = [] active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() if active_stacks is not None: @@ -527,7 +530,7 @@ class MachineManager(QObject): return "" @pyqtProperty("QVariantMap", notify = activeVariantChanged) - def allActiveVariantIds(self): + def allActiveVariantIds(self) -> Dict[str, str]: result = {} active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() if active_stacks is not None: #If we have a global stack. @@ -541,7 +544,7 @@ class MachineManager(QObject): return result @pyqtProperty("QVariantMap", notify = activeMaterialChanged) - def allActiveMaterialIds(self): + def allActiveMaterialIds(self) -> Dict[str, str]: result = {} active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() if active_stacks is not None: #If we have a global stack. @@ -860,7 +863,7 @@ class MachineManager(QObject): # \param quality_name \type{str} the name of the quality. # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes". @UM.FlameProfiler.profile - def determineQualityAndQualityChangesForQualityType(self, quality_type: str): + def determineQualityAndQualityChangesForQualityType(self, quality_type: str) -> List[Dict[str, Union[CuraContainerStack, InstanceContainer]]]: quality_manager = QualityManager.getInstance() result = [] empty_quality_changes = self._empty_quality_changes_container @@ -897,7 +900,7 @@ class MachineManager(QObject): # # \param quality_changes_name \type{str} the name of the quality changes. # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes". - def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str): + def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str) -> Optional[List[Dict[str, Union[CuraContainerStack, InstanceContainer]]]]: result = [] quality_manager = QualityManager.getInstance() @@ -1134,7 +1137,7 @@ class MachineManager(QObject): return MachineManager() @deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7") - def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None): + def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None) -> InstanceContainer: if not definition.getMetaDataEntry("has_materials"): return self._empty_material_container @@ -1180,7 +1183,7 @@ class MachineManager(QObject): def _onQualityNameChanged(self): self.activeQualityChanged.emit() - def _getContainerChangedSignals(self): + def _getContainerChangedSignals(self) -> List[Signal]: stacks = ExtruderManager.getInstance().getActiveExtruderStacks() stacks.append(self._global_container_stack) return [ s.containersChanged for s in stacks ] From 781f2d56c81981bf14a4825db022e3ed10466d38 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 11:31:24 +0200 Subject: [PATCH 09/14] CURA-4182 code improvements for slider property calcs 2 --- resources/qml/SidebarSimple.qml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 8f30c24d42..1528ed26a7 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -126,13 +126,11 @@ Item } function calculateSliderMargins (availableMin, availableMax, totalTicks) { - if (availableMin == -1) { - qualityModel.qualitySliderMarginRight = base.width * 0.55 - } else if (availableMin == 0 && availableMax == 0) { + if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) { qualityModel.qualitySliderMarginRight = base.width * 0.55 } else if (availableMin == availableMax) { qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth - } else if (availableMin != availableMax) { + } else { qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth } } From 261089eed3a9b8f3f2ce48c00f9c6b8cae258533 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 22 Sep 2017 11:53:10 +0200 Subject: [PATCH 10/14] Fix type hinting imports Because circular imports. I hate our current import technique... Contributes to issue CURA-4357. --- cura/Settings/MachineManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6712bef92d..69f672ab0f 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -863,7 +863,7 @@ class MachineManager(QObject): # \param quality_name \type{str} the name of the quality. # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes". @UM.FlameProfiler.profile - def determineQualityAndQualityChangesForQualityType(self, quality_type: str) -> List[Dict[str, Union[CuraContainerStack, InstanceContainer]]]: + def determineQualityAndQualityChangesForQualityType(self, quality_type: str) -> List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]: quality_manager = QualityManager.getInstance() result = [] empty_quality_changes = self._empty_quality_changes_container @@ -900,7 +900,7 @@ class MachineManager(QObject): # # \param quality_changes_name \type{str} the name of the quality changes. # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes". - def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str) -> Optional[List[Dict[str, Union[CuraContainerStack, InstanceContainer]]]]: + def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str) -> Optional[List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]]: result = [] quality_manager = QualityManager.getInstance() From fe5910dd9619bd0ad89a7a0bb4bcd6de73e7f67d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 11:54:59 +0200 Subject: [PATCH 11/14] CURA-4182 final tweaks to quality slider color and position --- resources/qml/SidebarSimple.qml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 1528ed26a7..3cc65f47d3 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -150,7 +150,7 @@ Item color: UM.Theme.getColor("text") } - //Show titles for the each quality slider ticks + // Show titles for the each quality slider ticks Item { y: -5; @@ -164,10 +164,20 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.top: parent.top anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 - color: UM.Theme.getColor("text") + + color: UM.Theme.getColor("quality_slider_unavailable") ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: Cura.ProfilesModel.getItem(index).layer_height_without_unit - width: 1 - x: (index != qualityModel.totalTicks) ? (base.width * 0.55 / qualityModel.totalTicks) * index : (base.width * 0.55 / qualityModel.totalTicks) * index - 15 + + x: { + // Make sure the text aligns correctly with each tick + if (index == 0) { + return (base.width * 0.55 / qualityModel.totalTicks) * index + } else if (index == qualityModel.totalTicks) { + return (base.width * 0.55 / qualityModel.totalTicks) * index - width + } else { + return (base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2) + } + } } } } @@ -202,7 +212,7 @@ Item Rectangle { anchors.verticalCenter: parent.verticalCenter - color: qualityModel.count > 1 ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") width: 1 height: 6 y: 0 From 0fa3bdd68b868a45690b86c07666ae8a4486d9a6 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 11:57:05 +0200 Subject: [PATCH 12/14] CURA-4182 text color for unavailable quality to disabled --- resources/qml/SidebarSimple.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 3cc65f47d3..500cf115fe 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -165,7 +165,7 @@ Item anchors.top: parent.top anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 - color: UM.Theme.getColor("quality_slider_unavailable") ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: Cura.ProfilesModel.getItem(index).layer_height_without_unit x: { From 0183616b8f1af34da765dced9e0d313798284e3d Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 22 Sep 2017 12:48:05 +0200 Subject: [PATCH 13/14] Only switch profiles with slider if there is an added machine Otherwise we crash and burn. Contributes to issue CURA-4357. --- resources/qml/SidebarSimple.qml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index c91c1fcb93..cb6a0f2643 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -261,12 +261,14 @@ Item } onValueChanged: { - - //Prevent updating during view initializing. Trigger only if the value changed by user - if(qualityRowSlider.value != qualityRow.qualitySliderSelectedValue) + if(Cura.MachineManager.activeMachine != null) { - //start updating with short delay - qualitySliderChangeTimer.start(); + //Prevent updating during view initializing. Trigger only if the value changed by user + if(qualityRowSlider.value != qualityRow.qualitySliderSelectedValue) + { + //start updating with short delay + qualitySliderChangeTimer.start(); + } } } } From bf6c6891c4cf91ebf87ff9046fd6fc4037cc86bd Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 22 Sep 2017 12:52:22 +0200 Subject: [PATCH 14/14] Don't display layer height before a printer is added Contributes to issue CURA-4357, somewhat. --- resources/qml/SidebarSimple.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index cb6a0f2643..194c43bc55 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -166,7 +166,7 @@ Item anchors.top: parent.top anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 color: UM.Theme.getColor("text") - text: Cura.ProfilesModel.getItem(index).layer_height_without_unit + text: Cura.MachineManager.activeMachine != null ? Cura.ProfilesModel.getItem(index).layer_height_without_unit : "" width: 1 x: