Merge branch 'feature_extruder_warning_icon' of https://github.com/fieldOfView/Cura into fieldOfView-feature_extruder_warning_icon

This commit is contained in:
Ghostkeeper 2021-11-19 13:48:45 +01:00
commit 6601728741
No known key found for this signature in database
GPG Key ID: D2A8871EE34EC59A
5 changed files with 148 additions and 2 deletions

View File

@ -12,6 +12,7 @@ from UM.Scene.SceneNode import SceneNode
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID. from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
from cura.Machines.ContainerTree import ContainerTree
from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
@ -403,6 +404,32 @@ class ExtruderManager(QObject):
raise IndexError(msg) raise IndexError(msg)
extruder_stack_0.definition = extruder_definition extruder_stack_0.definition = extruder_definition
@pyqtSlot("QVariant", result = bool)
def getExtruderHasQualityForMaterial(self, extruder_stack: "ExtruderStack") -> bool:
"""Checks if quality nodes exist for the variant/material combination."""
application = cura.CuraApplication.CuraApplication.getInstance()
global_stack = application.getGlobalContainerStack()
if not global_stack or not extruder_stack:
return False
if not global_stack.getMetaDataEntry("has_materials"):
return True
machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
active_variant_name = extruder_stack.variant.getMetaDataEntry("name")
if active_variant_name not in machine_node.variants:
Logger.log("w", "Could not find the variant %s", active_variant_name)
return True
active_variant_node = machine_node.variants[active_variant_name]
active_material_node = active_variant_node.materials[extruder_stack.material.getMetaDataEntry("base_file")]
active_material_node_qualities = active_material_node.qualities
if not active_material_node_qualities:
return False
return list(active_material_node_qualities.keys())[0] != "empty_quality"
@pyqtSlot(str, result="QVariant") @pyqtSlot(str, result="QVariant")
def getInstanceExtruderValues(self, key: str) -> List: def getInstanceExtruderValues(self, key: str) -> List:
"""Get all extruder values for a certain setting. """Get all extruder values for a certain setting.

View File

@ -6,7 +6,7 @@ import QtQuick.Controls 2.3
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import UM 1.2 as UM import UM 1.4 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -50,10 +50,16 @@ Cura.ExpandablePopup
model: extrudersModel model: extrudersModel
delegate: Item delegate: Item
{ {
id: extruderItem
Layout.preferredWidth: Math.round(parent.width / extrudersModel.count) Layout.preferredWidth: Math.round(parent.width / extrudersModel.count)
Layout.maximumWidth: Math.round(parent.width / extrudersModel.count) Layout.maximumWidth: Math.round(parent.width / extrudersModel.count)
Layout.fillHeight: true Layout.fillHeight: true
property var extruderStack: Cura.MachineManager.activeMachine.extruders[model.index]
property bool valueWarning: !Cura.ExtruderManager.getExtruderHasQualityForMaterial(extruderStack)
property bool valueError: Cura.ContainerManager.getContainerMetaDataEntry(extruderStack.material.id, "compatible", "") != "True"
// Extruder icon. Shows extruder index and has the same color as the active material. // Extruder icon. Shows extruder index and has the same color as the active material.
Cura.ExtruderIcon Cura.ExtruderIcon
{ {
@ -63,6 +69,109 @@ Cura.ExpandablePopup
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
MouseArea // Connection status tooltip hover area
{
id: tooltipHoverArea
anchors.fill: parent
hoverEnabled: tooltip.text != ""
acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks
onEntered:
{
base.mouseArea.entered() // we want both this and the outer area to be entered
tooltip.show()
}
onExited: { tooltip.hide() }
}
Cura.ToolTip
{
id: tooltip
x: 0
y: parent.height + UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("tooltip").width
targetPoint: Qt.point(Math.round(extruderIcon.width / 2), 0)
text:
{
if (extruderItem.valueError)
{
return catalog.i18nc("@tooltip", "The configuration of this extruder is not allowed, and prohibits slicing.")
}
if (extruderItem.valueWarning)
{
return catalog.i18nc("@tooltip", "There are no profiles matching the configuration of this extruder.")
}
return ""
}
}
// Warning icon that indicates if no qualities are available for the variant/material combination for this extruder
UM.RecolorImage
{
id: badge
anchors
{
top: parent.top
topMargin: - Math.round(height * 1 / 6)
left: parent.left
leftMargin: extruderIcon.width - Math.round(width * 5 / 6)
}
width: UM.Theme.getSize("icon_indicator").width
height: UM.Theme.getSize("icon_indicator").height
visible: extruderItem.valueError || extruderItem.valueWarning
source:
{
if (extruderItem.valueError)
{
return UM.Theme.getIcon("ErrorBadge", "low")
}
if (extruderItem.valueWarning)
{
return UM.Theme.getIcon("WarningBadge", "low")
}
return ""
}
color:
{
if (extruderItem.valueError)
{
return UM.Theme.getColor("error")
}
if (extruderItem.valueWarning)
{
return UM.Theme.getColor("warning")
}
return "transparent"
}
// Make a themable circle in the background so we can change it in other themes
Rectangle
{
id: iconBackground
anchors.centerIn: parent
width: parent.width - 1.5 //1.5 pixels smaller, (at least sqrt(2), regardless of screen pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing.
height: parent.height - 1.5
radius: width / 2
z: parent.z - 1
color:
{
if (extruderItem.valueError)
{
return UM.Theme.getColor("error_badge_background")
}
if (extruderItem.valueWarning)
{
return UM.Theme.getColor("warning_badge_background")
}
return "transparent"
}
}
}
Column Column
{ {
opacity: model.enabled ? 1 : UM.Theme.getColor("extruder_disabled").a opacity: model.enabled ? 1 : UM.Theme.getColor("extruder_disabled").a

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
<path d="M 6 0 A 6 6 0 0 0 0 6 A 6 6 0 0 0 6 12 A 6 6 0 0 0 12 6 A 6 6 0 0 0 6 0 z M 3.8808594 2.4609375 L 6 4.5800781 L 8.1191406 2.4609375 L 9.5390625 3.8808594 L 7.4199219 6 L 9.5390625 8.1191406 L 8.1191406 9.5390625 L 6 7.4199219 L 3.8808594 9.5390625 L 2.4589844 8.1191406 L 4.5800781 6 L 2.4589844 3.8808594 L 3.8808594 2.4609375 z " />
</svg>

After

Width:  |  Height:  |  Size: 480 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
<path d="M 6 0 A 6 6 0 0 0 0 6 A 6 6 0 0 0 6 12 A 6 6 0 0 0 12 6 A 6 6 0 0 0 6 0 z M 5 2 L 7 2 L 7 6 L 5 6 L 5 2 z M 5 8 L 7 8 L 7 10 L 5 10 L 5 8 z " />
</svg>

After

Width:  |  Height:  |  Size: 290 B

View File

@ -472,7 +472,9 @@
"monitor_carousel_dot_current": [119, 119, 119, 255], "monitor_carousel_dot_current": [119, 119, 119, 255],
"cloud_unavailable": [153, 153, 153, 255], "cloud_unavailable": [153, 153, 153, 255],
"connection_badge_background": [255, 255, 255, 255] "connection_badge_background": [255, 255, 255, 255],
"warning_badge_background": [0, 0, 0, 255],
"error_badge_background": [255, 255, 255, 255]
}, },
"sizes": { "sizes": {