mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
Added new intent selection buttons and resolution drop down to replace the matrix.
We are now selecting intents first and then quality, however the container hierarchy quality -> intents. This is the reason for the new functions inside machine manager. CURA-8849
This commit is contained in:
parent
6f88adab8e
commit
a87695cd8d
9 changed files with 454 additions and 178 deletions
|
@ -115,6 +115,8 @@ from . import CuraActions
|
||||||
from . import PlatformPhysics
|
from . import PlatformPhysics
|
||||||
from . import PrintJobPreviewImageProvider
|
from . import PrintJobPreviewImageProvider
|
||||||
from .AutoSave import AutoSave
|
from .AutoSave import AutoSave
|
||||||
|
from .Machines.Models.ActiveIntentQualitiesModel import ActiveIntentQualitiesModel
|
||||||
|
from .Machines.Models.IntentSelectionModel import IntentSelectionModel
|
||||||
from .SingleInstance import SingleInstance
|
from .SingleInstance import SingleInstance
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -1192,6 +1194,8 @@ class CuraApplication(QtApplication):
|
||||||
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
|
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
|
||||||
qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel")
|
qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel")
|
||||||
qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel")
|
qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel")
|
||||||
|
qmlRegisterType(IntentSelectionModel, "Cura", 1, 7, "IntentSelectionModel")
|
||||||
|
qmlRegisterType(ActiveIntentQualitiesModel, "Cura", 1, 7, "ActiveIntentQualitiesModel")
|
||||||
|
|
||||||
self.processEvents()
|
self.processEvents()
|
||||||
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
||||||
|
|
121
cura/Machines/Models/ActiveIntentQualitiesModel.py
Normal file
121
cura/Machines/Models/ActiveIntentQualitiesModel.py
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
# Copyright (c) 2022 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
from typing import Optional, Set, Dict, List, Any
|
||||||
|
|
||||||
|
from PyQt6.QtCore import Qt, QObject, QTimer
|
||||||
|
|
||||||
|
import cura.CuraApplication
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.Qt.ListModel import ListModel
|
||||||
|
from cura.Machines.ContainerTree import ContainerTree
|
||||||
|
from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
|
||||||
|
from cura.Machines.MaterialNode import MaterialNode
|
||||||
|
from cura.Machines.QualityGroup import QualityGroup
|
||||||
|
from cura.Settings.IntentManager import IntentManager
|
||||||
|
|
||||||
|
|
||||||
|
class ActiveIntentQualitiesModel(ListModel):
|
||||||
|
NameRole = Qt.ItemDataRole.UserRole + 1
|
||||||
|
DisplayTextRole = Qt.ItemDataRole.UserRole + 2
|
||||||
|
QualityTypeRole = Qt.ItemDataRole.UserRole + 3
|
||||||
|
LayerHeightRole = Qt.ItemDataRole.UserRole + 4
|
||||||
|
IntentCategeoryRole = Qt.ItemDataRole.UserRole + 5
|
||||||
|
|
||||||
|
def __init__(self, parent: Optional[QObject] = None) -> None:
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.addRoleName(self.NameRole, "name")
|
||||||
|
self.addRoleName(self.QualityTypeRole, "quality_type")
|
||||||
|
self.addRoleName(self.LayerHeightRole, "layer_height")
|
||||||
|
self.addRoleName(self.DisplayTextRole, "display_text")
|
||||||
|
self.addRoleName(self.IntentCategeoryRole, "intent_category")
|
||||||
|
|
||||||
|
self._intent_category = ""
|
||||||
|
|
||||||
|
IntentManager.intentCategoryChangedSignal.connect(self._update)
|
||||||
|
|
||||||
|
self._update_timer = QTimer()
|
||||||
|
self._update_timer.setInterval(100)
|
||||||
|
self._update_timer.setSingleShot(True)
|
||||||
|
self._update_timer.timeout.connect(self._update)
|
||||||
|
|
||||||
|
self._update()
|
||||||
|
|
||||||
|
def _updateDelayed(self):
|
||||||
|
self._update_timer.start()
|
||||||
|
|
||||||
|
def _onChanged(self, container):
|
||||||
|
if container.getMetaDataEntry("type") == "intent":
|
||||||
|
self._updateDelayed()
|
||||||
|
|
||||||
|
def _update(self):
|
||||||
|
active_extruder_stack = cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeStack
|
||||||
|
if active_extruder_stack:
|
||||||
|
self._intent_category = active_extruder_stack.intent.getMetaDataEntry("intent_category", "")
|
||||||
|
|
||||||
|
new_items = [] # type: List[Dict[str, Any]]
|
||||||
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
|
if not global_stack:
|
||||||
|
self.setItems(new_items)
|
||||||
|
return
|
||||||
|
quality_groups = ContainerTree.getInstance().getCurrentQualityGroups()
|
||||||
|
|
||||||
|
material_nodes = self._getActiveMaterials()
|
||||||
|
|
||||||
|
added_quality_type_set = set() # type: Set[str]
|
||||||
|
for material_node in material_nodes:
|
||||||
|
intents = self._getIntentsForMaterial(material_node, quality_groups)
|
||||||
|
for intent in intents:
|
||||||
|
if intent["quality_type"] not in added_quality_type_set:
|
||||||
|
new_items.append(intent)
|
||||||
|
added_quality_type_set.add(intent["quality_type"])
|
||||||
|
|
||||||
|
new_items = sorted(new_items, key=lambda x: x["layer_height"])
|
||||||
|
self.setItems(new_items)
|
||||||
|
|
||||||
|
def _getActiveMaterials(self) -> Set["MaterialNode"]:
|
||||||
|
"""Get the active materials for all extruders. No duplicates will be returned"""
|
||||||
|
|
||||||
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
|
if global_stack is None:
|
||||||
|
return set()
|
||||||
|
|
||||||
|
container_tree = ContainerTree.getInstance()
|
||||||
|
machine_node = container_tree.machines[global_stack.definition.getId()]
|
||||||
|
nodes = set() # type: Set[MaterialNode]
|
||||||
|
|
||||||
|
for extruder in global_stack.extruderList:
|
||||||
|
active_variant_name = extruder.variant.getMetaDataEntry("name")
|
||||||
|
if active_variant_name not in machine_node.variants:
|
||||||
|
Logger.log("w", "Could not find the variant %s", active_variant_name)
|
||||||
|
continue
|
||||||
|
active_variant_node = machine_node.variants[active_variant_name]
|
||||||
|
active_material_node = active_variant_node.materials.get(extruder.material.getMetaDataEntry("base_file"))
|
||||||
|
if active_material_node is None:
|
||||||
|
Logger.log("w", "Could not find the material %s", extruder.material.getMetaDataEntry("base_file"))
|
||||||
|
continue
|
||||||
|
nodes.add(active_material_node)
|
||||||
|
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
def _getIntentsForMaterial(self, active_material_node: "MaterialNode", quality_groups: Dict[str, "QualityGroup"]) -> List[Dict[str, Any]]:
|
||||||
|
extruder_intents = [] # type: List[Dict[str, Any]]
|
||||||
|
|
||||||
|
for quality_id, quality_node in active_material_node.qualities.items():
|
||||||
|
if quality_node.quality_type not in quality_groups: # Don't add the empty quality type (or anything else that would crash, defensively).
|
||||||
|
continue
|
||||||
|
quality_group = quality_groups[quality_node.quality_type]
|
||||||
|
layer_height = fetchLayerHeight(quality_group)
|
||||||
|
|
||||||
|
for intent_id, intent_node in quality_node.intents.items():
|
||||||
|
if intent_node.intent_category != self._intent_category:
|
||||||
|
continue
|
||||||
|
extruder_intents.append({"name": quality_group.name,
|
||||||
|
"display_text": f"{quality_group.name} - {layer_height}mm",
|
||||||
|
"quality_type": quality_group.quality_type,
|
||||||
|
"layer_height": layer_height,
|
||||||
|
"intent_category": self._intent_category
|
||||||
|
})
|
||||||
|
return extruder_intents
|
||||||
|
|
||||||
|
|
129
cura/Machines/Models/IntentSelectionModel.py
Normal file
129
cura/Machines/Models/IntentSelectionModel.py
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
# Copyright (c) 2022 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
import collections
|
||||||
|
from typing import OrderedDict
|
||||||
|
|
||||||
|
from PyQt6.QtCore import Qt, QTimer
|
||||||
|
|
||||||
|
import cura
|
||||||
|
from UM import i18nCatalog
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.Qt.ListModel import ListModel
|
||||||
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
from UM.Settings.Interfaces import ContainerInterface
|
||||||
|
from cura.Settings.IntentManager import IntentManager
|
||||||
|
|
||||||
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
|
class IntentSelectionModel(ListModel):
|
||||||
|
|
||||||
|
NameRole = Qt.ItemDataRole.UserRole + 1
|
||||||
|
IntentCategoryRole = Qt.ItemDataRole.UserRole + 2
|
||||||
|
WeightRole = Qt.ItemDataRole.UserRole + 3
|
||||||
|
DescriptionRole = Qt.ItemDataRole.UserRole + 4
|
||||||
|
IconRole = Qt.ItemDataRole.UserRole + 5
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.addRoleName(self.NameRole, "name")
|
||||||
|
self.addRoleName(self.IntentCategoryRole, "intent_category")
|
||||||
|
self.addRoleName(self.WeightRole, "weight")
|
||||||
|
self.addRoleName(self.DescriptionRole, "description")
|
||||||
|
self.addRoleName(self.IconRole, "icon")
|
||||||
|
|
||||||
|
application = cura.CuraApplication.CuraApplication.getInstance()
|
||||||
|
|
||||||
|
ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange)
|
||||||
|
ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange)
|
||||||
|
machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
|
||||||
|
machine_manager.activeMaterialChanged.connect(self._update)
|
||||||
|
machine_manager.activeVariantChanged.connect(self._update)
|
||||||
|
machine_manager.extruderChanged.connect(self._update)
|
||||||
|
|
||||||
|
extruder_manager = application.getExtruderManager()
|
||||||
|
extruder_manager.extrudersChanged.connect(self._update)
|
||||||
|
|
||||||
|
self._update_timer = QTimer() # type: QTimer
|
||||||
|
self._update_timer.setInterval(100)
|
||||||
|
self._update_timer.setSingleShot(True)
|
||||||
|
self._update_timer.timeout.connect(self._update)
|
||||||
|
|
||||||
|
self._onChange()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _getDefaultProfileInformation() -> OrderedDict[str, dict]:
|
||||||
|
""" Default information user-visible string. Ordered by weight. """
|
||||||
|
default_profile_information = collections.OrderedDict()
|
||||||
|
default_profile_information["default"] = {
|
||||||
|
"name": catalog.i18nc("@label", "Default"),
|
||||||
|
"icon": "GearCheck"
|
||||||
|
}
|
||||||
|
default_profile_information["visual"] = {
|
||||||
|
"name": catalog.i18nc("@label", "Visual"),
|
||||||
|
"description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."),
|
||||||
|
"icon" : "Visual"
|
||||||
|
}
|
||||||
|
default_profile_information["engineering"] = {
|
||||||
|
"name": catalog.i18nc("@label", "Engineering"),
|
||||||
|
"description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."),
|
||||||
|
"icon": "Nut"
|
||||||
|
}
|
||||||
|
default_profile_information["quick"] = {
|
||||||
|
"name": catalog.i18nc("@label", "Draft"),
|
||||||
|
"description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."),
|
||||||
|
"icon": "SpeedOMeter"
|
||||||
|
}
|
||||||
|
return default_profile_information
|
||||||
|
|
||||||
|
def _onContainerChange(self, container: ContainerInterface) -> None:
|
||||||
|
"""Updates the list of intents if an intent profile was added or removed."""
|
||||||
|
|
||||||
|
if container.getMetaDataEntry("type") == "intent":
|
||||||
|
self._update()
|
||||||
|
|
||||||
|
def _onChange(self) -> None:
|
||||||
|
self._update_timer.start()
|
||||||
|
|
||||||
|
def _update(self):
|
||||||
|
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
|
||||||
|
|
||||||
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
|
if global_stack is None:
|
||||||
|
self.setItems([])
|
||||||
|
Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check for material compatibility
|
||||||
|
if not cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMaterialsCompatible():
|
||||||
|
Logger.log("d", "No active material compatibility, set quality profile model as empty.")
|
||||||
|
self.setItems([])
|
||||||
|
return
|
||||||
|
|
||||||
|
default_profile_info = self._getDefaultProfileInformation()
|
||||||
|
|
||||||
|
available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
|
||||||
|
result = []
|
||||||
|
for i, category in enumerate(available_categories):
|
||||||
|
profile_info = default_profile_info.get(category, {})
|
||||||
|
|
||||||
|
try:
|
||||||
|
weight = list(default_profile_info.keys()).index(category)
|
||||||
|
except ValueError:
|
||||||
|
weight = len(available_categories) + i
|
||||||
|
|
||||||
|
result.append({
|
||||||
|
"name": profile_info.get("name", category.title()),
|
||||||
|
"description": profile_info.get("description", None),
|
||||||
|
"icon" : profile_info.get("icon", ""),
|
||||||
|
"intent_category": category,
|
||||||
|
"weight": weight,
|
||||||
|
})
|
||||||
|
|
||||||
|
result.sort(key=lambda k: k["weight"])
|
||||||
|
|
||||||
|
self.setItems(result)
|
||||||
|
|
||||||
|
|
|
@ -1778,3 +1778,31 @@ class MachineManager(QObject):
|
||||||
abbr_machine += stripped_word
|
abbr_machine += stripped_word
|
||||||
|
|
||||||
return abbr_machine
|
return abbr_machine
|
||||||
|
|
||||||
|
@pyqtSlot(str, str, result = bool)
|
||||||
|
def intentCategoryHasQuality(self, intent_category: str, quality_type: str) -> bool:
|
||||||
|
""" Checks if there are any quality groups for active extruders that have an intent category """
|
||||||
|
quality_groups = ContainerTree.getInstance().getCurrentQualityGroups()
|
||||||
|
|
||||||
|
if quality_type in quality_groups:
|
||||||
|
quality_group = quality_groups[quality_type]
|
||||||
|
for node in quality_group.nodes_for_extruders.values():
|
||||||
|
if any(intent.intent_category == intent_category for intent in node.intents.values()):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@pyqtSlot(str, result = str)
|
||||||
|
def getDefaultQualityTypeForIntent(self, intent_category) -> str:
|
||||||
|
""" If there is an intent category for the default machine quality return it, otherwise return the first quality for this intent category """
|
||||||
|
machine = ContainerTree.getInstance().machines.get(self._global_container_stack.definition.getId())
|
||||||
|
|
||||||
|
if self.intentCategoryHasQuality(intent_category, machine.preferred_quality_type):
|
||||||
|
return machine.preferred_quality_type
|
||||||
|
|
||||||
|
for quality_type, quality_group in ContainerTree.getInstance().getCurrentQualityGroups().items():
|
||||||
|
for node in quality_group.nodes_for_extruders.values():
|
||||||
|
if any(intent.intent_category == intent_category for intent in node.intents.values()):
|
||||||
|
return quality_type
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.6 as UM
|
||||||
import Cura 1.0 as Cura
|
import Cura 1.6 as Cura
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
|
@ -13,11 +13,11 @@ Item
|
||||||
height: childrenRect.height + 2 * padding
|
height: childrenRect.height + 2 * padding
|
||||||
|
|
||||||
property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1
|
property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1
|
||||||
property real padding: UM.Theme.getSize("thick_margin").width
|
property real padding: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
spacing: UM.Theme.getSize("wide_margin").height
|
spacing: UM.Theme.getSize("default_margin").height
|
||||||
|
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
|
@ -30,11 +30,26 @@ Item
|
||||||
// TODO
|
// TODO
|
||||||
property real firstColumnWidth: Math.round(width / 3)
|
property real firstColumnWidth: Math.round(width / 3)
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
text: catalog.i18nc("@label", "Profiles")
|
||||||
|
font: UM.Theme.getFont("medium")
|
||||||
|
}
|
||||||
|
|
||||||
RecommendedQualityProfileSelector
|
RecommendedQualityProfileSelector
|
||||||
{
|
{
|
||||||
width: parent.width
|
width: parent.width
|
||||||
// TODO Create a reusable component with these properties to not define them separately for each component
|
}
|
||||||
labelColumnWidth: parent.firstColumnWidth
|
|
||||||
|
RecommendedResolutionSelector
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
text: catalog.i18nc("@label", "Print settings")
|
||||||
|
font: UM.Theme.getFont("medium")
|
||||||
}
|
}
|
||||||
|
|
||||||
RecommendedInfillDensitySelector
|
RecommendedInfillDensitySelector
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
|
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
import QtQuick.Controls 2.3
|
import QtQuick.Controls 2.3
|
||||||
|
import QtQuick.Layouts 2.10
|
||||||
|
|
||||||
import UM 1.5 as UM
|
import UM 1.5 as UM
|
||||||
import Cura 1.6 as Cura
|
import Cura 1.7 as Cura
|
||||||
import ".."
|
import ".."
|
||||||
|
|
||||||
Item
|
Item
|
||||||
|
@ -13,187 +14,35 @@ Item
|
||||||
id: qualityRow
|
id: qualityRow
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
||||||
property real labelColumnWidth: Math.round(width / 3)
|
RowLayout
|
||||||
property real settingsColumnWidth: width - labelColumnWidth
|
|
||||||
|
|
||||||
// Here are the elements that are shown in the left column
|
|
||||||
|
|
||||||
Column
|
|
||||||
{
|
{
|
||||||
anchors
|
id: intentRow
|
||||||
{
|
width: parent.width
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
|
|
||||||
spacing: UM.Theme.getSize("default_margin").height
|
|
||||||
|
|
||||||
ButtonGroup
|
|
||||||
{
|
|
||||||
id: activeProfileButtonGroup
|
|
||||||
exclusive: true
|
|
||||||
onClicked: Cura.IntentManager.selectIntent(button.modelData.intent_category, button.modelData.quality_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
height: childrenRect.height
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
Cura.IconWithText
|
|
||||||
{
|
|
||||||
id: profileLabel
|
|
||||||
source: UM.Theme.getIcon("PrintQuality")
|
|
||||||
text: catalog.i18nc("@label", "Profiles")
|
|
||||||
font: UM.Theme.getFont("medium")
|
|
||||||
width: labelColumnWidth
|
|
||||||
iconSize: UM.Theme.getSize("medium_button_icon").width
|
|
||||||
}
|
|
||||||
UM.SimpleButton
|
|
||||||
{
|
|
||||||
id: resetToDefaultQualityButton
|
|
||||||
|
|
||||||
visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.MachineManager.hasCustomQuality
|
|
||||||
height: visible ? UM.Theme.getSize("print_setup_icon").height : 0
|
|
||||||
width: height
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
right: profileLabel.right
|
|
||||||
rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
|
|
||||||
iconSource: UM.Theme.getIcon("ArrowReset")
|
|
||||||
|
|
||||||
onClicked:
|
|
||||||
{
|
|
||||||
// if the current profile is user-created, switch to a built-in quality
|
|
||||||
Cura.MachineManager.resetToUseDefaultQuality()
|
|
||||||
}
|
|
||||||
onEntered:
|
|
||||||
{
|
|
||||||
var tooltipContent = catalog.i18nc("@tooltip","You have modified some profile settings. If you want to change these go to custom mode.")
|
|
||||||
base.showTooltip(qualityRow, Qt.point(-UM.Theme.getSize("thick_margin").width, 0), tooltipContent)
|
|
||||||
}
|
|
||||||
onExited: base.hideTooltip()
|
|
||||||
}
|
|
||||||
|
|
||||||
Cura.LabelBar
|
|
||||||
{
|
|
||||||
id: labelbar
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
left: profileLabel.right
|
|
||||||
right: parent.right
|
|
||||||
verticalCenter: profileLabel.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
model: Cura.QualityProfilesDropDownMenuModel
|
|
||||||
modelKey: "layer_height"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Repeater
|
Repeater
|
||||||
{
|
{
|
||||||
model: Cura.IntentCategoryModel {}
|
model: Cura.IntentSelectionModel {}
|
||||||
Item
|
|
||||||
|
RecommendedQualityProfileSelectorButton
|
||||||
{
|
{
|
||||||
anchors
|
text: model.name
|
||||||
{
|
iconSource: UM.Theme.getIcon(model.icon)
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: intentCategoryLabel.height
|
|
||||||
|
|
||||||
UM.Label
|
|
||||||
{
|
|
||||||
id: intentCategoryLabel
|
|
||||||
text: model.name
|
|
||||||
width: labelColumnWidth - UM.Theme.getSize("section_icon").width
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("section_icon").width + UM.Theme.getSize("narrow_margin").width
|
|
||||||
font: UM.Theme.getFont("medium")
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
Cura.RadioCheckbar
|
selected: Cura.MachineManager.activeIntentCategory == model.intent_category
|
||||||
{
|
|
||||||
anchors
|
onClicked: {
|
||||||
|
var qualityType
|
||||||
|
if (Cura.MachineManager.intentCategoryHasQuality(model.intent_category, Cura.MachineManager.activeQualityType))
|
||||||
{
|
{
|
||||||
left: intentCategoryLabel.right
|
qualityType = Cura.MachineManager.activeQualityType
|
||||||
right: parent.right
|
} else {
|
||||||
|
qualityType = Cura.MachineManager.getDefaultQualityTypeForIntent(model.intent_category)
|
||||||
|
print(Cura.MachineManager.getDefaultQualityTypeForIntent(model.intent_category))
|
||||||
}
|
}
|
||||||
dataModel: model["qualities"]
|
Cura.IntentManager.selectIntent(model.intent_category, qualityType)
|
||||||
buttonGroup: activeProfileButtonGroup
|
|
||||||
|
|
||||||
function checkedFunction(modelItem)
|
|
||||||
{
|
|
||||||
if(Cura.MachineManager.hasCustomQuality)
|
|
||||||
{
|
|
||||||
// When user created profile is active, no quality tickbox should be active.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if(modelItem === null)
|
|
||||||
{
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return Cura.MachineManager.activeQualityType == modelItem.quality_type && Cura.MachineManager.activeIntentCategory == modelItem.intent_category
|
|
||||||
}
|
|
||||||
|
|
||||||
isCheckedFunction: checkedFunction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea // Intent description tooltip hover area
|
|
||||||
{
|
|
||||||
id: intentDescriptionHoverArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
enabled: model.description !== undefined
|
|
||||||
acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks
|
|
||||||
|
|
||||||
Timer
|
|
||||||
{
|
|
||||||
id: intentTooltipTimer
|
|
||||||
interval: 500
|
|
||||||
running: false
|
|
||||||
repeat: false
|
|
||||||
onTriggered: base.showTooltip(
|
|
||||||
intentCategoryLabel,
|
|
||||||
Qt.point(-(intentCategoryLabel.x - qualityRow.x) - UM.Theme.getSize("thick_margin").width, 0),
|
|
||||||
model.description
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
onEntered: intentTooltipTimer.start()
|
|
||||||
onExited:
|
|
||||||
{
|
|
||||||
base.hideTooltip()
|
|
||||||
intentTooltipTimer.stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NoIntentIcon // This icon has hover priority over intentDescriptionHoverArea, so draw it above it.
|
|
||||||
{
|
|
||||||
affected_extruders: Cura.MachineManager.extruderPositionsWithNonActiveIntent
|
|
||||||
intent_type: model.name
|
|
||||||
anchors.right: intentCategoryLabel.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("narrow_margin").width
|
|
||||||
width: intentCategoryLabel.height * 0.75
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
height: width
|
|
||||||
visible: Cura.MachineManager.activeIntentCategory == model.intent_category && affected_extruders.length
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) 2022 Ultimaker B.V.
|
||||||
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Controls 2.3
|
||||||
|
import QtQuick.Layouts 2.10
|
||||||
|
|
||||||
|
import UM 1.5 as UM
|
||||||
|
import Cura 1.7 as Cura
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: base
|
||||||
|
height: 60
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: mouseArea.containsMouse || selected ? UM.Theme.getColor("um_blue_1") : UM.Theme.getColor("background_1")
|
||||||
|
|
||||||
|
property alias iconSource: intentIcon.source
|
||||||
|
property alias text: qualityLabel.text
|
||||||
|
property bool selected: false
|
||||||
|
|
||||||
|
signal clicked()
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: base.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
width: intentIcon.width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
bottom: qualityLabel.top
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.ColorImage
|
||||||
|
{
|
||||||
|
id: intentIcon
|
||||||
|
width: UM.Theme.getSize("recommended_button_icon").width
|
||||||
|
height: width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: UM.Theme.getColor("icon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
id: qualityLabel
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
bottom: parent.bottom
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottomMargin: UM.Theme.getSize("narrow_margin").height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright (c) 2022 Ultimaker B.V.
|
||||||
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
|
||||||
|
import UM 1.6 as UM
|
||||||
|
import Cura 1.7 as Cura
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
property real labelColumnWidth: Math.round(width / 3)
|
||||||
|
|
||||||
|
Cura.IconWithText
|
||||||
|
{
|
||||||
|
id: resolutionTitle
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
source: UM.Theme.getIcon("PrintQuality")
|
||||||
|
text: catalog.i18nc("@label", "Resolution")
|
||||||
|
width: labelColumnWidth
|
||||||
|
height: parent.height
|
||||||
|
spacing: UM.Theme.getSize("thick_margin").width
|
||||||
|
iconSize: UM.Theme.getSize("medium_button_icon").width
|
||||||
|
}
|
||||||
|
|
||||||
|
Cura.ComboBox
|
||||||
|
{
|
||||||
|
id: visibilityPreset
|
||||||
|
implicitHeight: UM.Theme.getSize("combobox").height
|
||||||
|
implicitWidth: UM.Theme.getSize("combobox").width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
textRole: "display_text"
|
||||||
|
|
||||||
|
model: Cura.ActiveIntentQualitiesModel{}
|
||||||
|
|
||||||
|
currentIndex:
|
||||||
|
{
|
||||||
|
var current_quality_type = Cura.MachineManager.activeQualityType
|
||||||
|
|
||||||
|
var index = 0
|
||||||
|
for (var i = 0; i < model.count; i++)
|
||||||
|
{
|
||||||
|
if (model.getItem(i).quality_type == current_quality_type)
|
||||||
|
{
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
onActivated:
|
||||||
|
{
|
||||||
|
var selected_item = model.getItem(currentIndex)
|
||||||
|
Cura.IntentManager.selectIntent(selected_item.intent_category, selected_item.quality_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -638,6 +638,8 @@
|
||||||
|
|
||||||
"marketplace_large_icon": [4.0, 4.0],
|
"marketplace_large_icon": [4.0, 4.0],
|
||||||
|
|
||||||
"preferences_page_list_item": [8.0, 2.0]
|
"preferences_page_list_item": [8.0, 2.0],
|
||||||
|
|
||||||
|
"recommended_button_icon": [1.7, 1.7]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue