mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-17 04:06:41 +08:00
Merge branch 'Ultimaker:main' into main
This commit is contained in:
commit
25a7c3e263
@ -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")
|
||||||
|
128
cura/Machines/Models/ActiveIntentQualitiesModel.py
Normal file
128
cura/Machines/Models/ActiveIntentQualitiesModel.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# 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)
|
||||||
|
machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
|
||||||
|
machine_manager.activeQualityGroupChanged.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: ContainerStack) -> None:
|
||||||
|
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: 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[str] = set()
|
||||||
|
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[MaterialNode] = set()
|
||||||
|
|
||||||
|
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: 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]
|
||||||
|
|
||||||
|
if not quality_group.is_available:
|
||||||
|
continue
|
||||||
|
|
||||||
|
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"<b>{quality_group.name}</b> - {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, Optional
|
||||||
|
|
||||||
|
from PyQt6.QtCore import Qt, QTimer, QObject
|
||||||
|
|
||||||
|
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: Optional[QObject] = None) -> 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 = 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) -> None:
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2019 Ultimaker B.V.
|
# Copyright (c) 2022 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
||||||
@ -8,6 +8,7 @@ from UM.Logger import Logger
|
|||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
|
|
||||||
import cura.CuraApplication
|
import cura.CuraApplication
|
||||||
|
from UM.Signal import Signal
|
||||||
from cura.Machines.ContainerTree import ContainerTree
|
from cura.Machines.ContainerTree import ContainerTree
|
||||||
from cura.Settings.cura_empty_instance_containers import empty_intent_container
|
from cura.Settings.cura_empty_instance_containers import empty_intent_container
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ class IntentManager(QObject):
|
|||||||
return cls.__instance
|
return cls.__instance
|
||||||
|
|
||||||
intentCategoryChanged = pyqtSignal() #Triggered when we switch categories.
|
intentCategoryChanged = pyqtSignal() #Triggered when we switch categories.
|
||||||
|
intentCategoryChangedSignal = Signal()
|
||||||
|
|
||||||
def intentMetadatas(self, definition_id: str, nozzle_name: str, material_base_file: str) -> List[Dict[str, Any]]:
|
def intentMetadatas(self, definition_id: str, nozzle_name: str, material_base_file: str) -> List[Dict[str, Any]]:
|
||||||
"""Gets the metadata dictionaries of all intent profiles for a given
|
"""Gets the metadata dictionaries of all intent profiles for a given
|
||||||
@ -189,3 +191,4 @@ class IntentManager(QObject):
|
|||||||
application.getMachineManager().setQualityGroupByQualityType(quality_type)
|
application.getMachineManager().setQualityGroupByQualityType(quality_type)
|
||||||
if old_intent_category != intent_category:
|
if old_intent_category != intent_category:
|
||||||
self.intentCategoryChanged.emit()
|
self.intentCategoryChanged.emit()
|
||||||
|
self.intentCategoryChangedSignal.emit()
|
||||||
|
@ -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 ""
|
||||||
|
@ -22,6 +22,7 @@ Item
|
|||||||
property alias elide: label.elide
|
property alias elide: label.elide
|
||||||
property real margin: UM.Theme.getSize("narrow_margin").width
|
property real margin: UM.Theme.getSize("narrow_margin").width
|
||||||
property alias wrapMode: label.wrapMode
|
property alias wrapMode: label.wrapMode
|
||||||
|
property real spacing: UM.Theme.getSize("narrow_margin").width
|
||||||
|
|
||||||
// These properties can be used in combination with layouts.
|
// These properties can be used in combination with layouts.
|
||||||
readonly property real contentWidth: icon.width + margin + label.contentWidth
|
readonly property real contentWidth: icon.width + margin + label.contentWidth
|
||||||
@ -61,6 +62,7 @@ Item
|
|||||||
top: parent.top
|
top: parent.top
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
rightMargin: 0
|
rightMargin: 0
|
||||||
|
leftMargin: spacing
|
||||||
margins: margin
|
margins: margin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
|
||||||
|
import UM 1.6 as UM
|
||||||
|
import Cura 1.6 as Cura
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
height: visible ? UM.Theme.getSize("action_button_icon").height : 0
|
||||||
|
visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.MachineManager.hasCustomQuality
|
||||||
|
anchors.topMargin: UM.Theme.getSize("default_margin")
|
||||||
|
anchors.bottomMargin: UM.Theme.getSize("default_margin")
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: warningIcon
|
||||||
|
color: UM.Theme.getColor("um_yellow_5")
|
||||||
|
height: UM.Theme.getSize("action_button_icon").height
|
||||||
|
width: height
|
||||||
|
radius: width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
UM.ColorImage
|
||||||
|
{
|
||||||
|
height: UM.Theme.getSize("action_button_icon").height
|
||||||
|
width: height
|
||||||
|
source: UM.Theme.getIcon("Warning", "low")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
id: warning
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: warningIcon.right
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
leftMargin: UM.Theme.getSize("thin_margin").width
|
||||||
|
}
|
||||||
|
|
||||||
|
text: ""
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "settings changed and custom quality"
|
||||||
|
when: Cura.SimpleModeSettingsManager.isProfileCustomized && Cura.MachineManager.hasCustomQuality
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: warning
|
||||||
|
text: {
|
||||||
|
var profile_name = Cura.MachineManager.activeQualityChangesGroup.name
|
||||||
|
return "<b>%1</b> %2".arg(profile_name).arg(catalog.i18nc("@info", "custom profile is active and you overwrote some settings."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "custom quality"
|
||||||
|
when: Cura.MachineManager.hasCustomQuality
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: warning
|
||||||
|
text: {
|
||||||
|
var profile_name = Cura.MachineManager.activeQualityChangesGroup.name
|
||||||
|
return "<b>%1</b> %2".arg(profile_name).arg(catalog.i18nc("@info", "custom profile is overriding some settings."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "settings changed"
|
||||||
|
when: Cura.SimpleModeSettingsManager.isProfileCustomized
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: warning
|
||||||
|
text: catalog.i18nc("@info", "Some settings were changed.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.SimpleButton
|
||||||
|
{
|
||||||
|
id: resetToDefaultQualityButton
|
||||||
|
height: UM.Theme.getSize("action_button_icon").height
|
||||||
|
width: height
|
||||||
|
iconSource: UM.Theme.getIcon("ArrowReset")
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
right: parent.right
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
color: UM.Theme.getColor("accent_1")
|
||||||
|
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
Cura.MachineManager.resetToUseDefaultQuality()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
// Copyright (c) 2018 Ultimaker B.V.
|
//Copyright (c) 2022 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
//Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
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 +14,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
|
ColumnLayout
|
||||||
{
|
{
|
||||||
spacing: UM.Theme.getSize("wide_margin").height
|
spacing: UM.Theme.getSize("default_margin").height
|
||||||
|
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
@ -30,11 +31,53 @@ 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
|
visible: recommendedResolutionSelector.visible
|
||||||
labelColumnWidth: parent.firstColumnWidth
|
}
|
||||||
|
|
||||||
|
RecommendedResolutionSelector
|
||||||
|
{
|
||||||
|
id: recommendedResolutionSelector
|
||||||
|
Layout.fillWidth: true
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
UnsupportedProfileIndication
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
visible: !recommendedResolutionSelector.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProfileWarningReset
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
//Line between the sections.
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
height: UM.Theme.getSize("default_lining").height
|
||||||
|
Layout.topMargin: UM.Theme.getSize("narrow_margin").height
|
||||||
|
Layout.bottomMargin: UM.Theme.getSize("narrow_margin").height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: UM.Theme.getColor("lining")
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
text: catalog.i18nc("@label", "Print settings")
|
||||||
|
font: UM.Theme.getFont("medium")
|
||||||
}
|
}
|
||||||
|
|
||||||
RecommendedInfillDensitySelector
|
RecommendedInfillDensitySelector
|
||||||
@ -42,6 +85,9 @@ Item
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
// TODO Create a reusable component with these properties to not define them separately for each component
|
// TODO Create a reusable component with these properties to not define them separately for each component
|
||||||
labelColumnWidth: parent.firstColumnWidth
|
labelColumnWidth: parent.firstColumnWidth
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
Layout.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
}
|
}
|
||||||
|
|
||||||
RecommendedSupportSelector
|
RecommendedSupportSelector
|
||||||
@ -49,6 +95,7 @@ Item
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
// TODO Create a reusable component with these properties to not define them separately for each component
|
// TODO Create a reusable component with these properties to not define them separately for each component
|
||||||
labelColumnWidth: parent.firstColumnWidth
|
labelColumnWidth: parent.firstColumnWidth
|
||||||
|
Layout.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
}
|
}
|
||||||
|
|
||||||
RecommendedAdhesionSelector
|
RecommendedAdhesionSelector
|
||||||
@ -56,6 +103,7 @@ Item
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
// TODO Create a reusable component with these properties to not define them separately for each component
|
// TODO Create a reusable component with these properties to not define them separately for each component
|
||||||
labelColumnWidth: parent.firstColumnWidth
|
labelColumnWidth: parent.firstColumnWidth
|
||||||
|
Layout.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,180 +3,46 @@
|
|||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
id: qualityRow
|
id: qualityRow
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
visible: intentSelectionRepeater.count > 1 //Only show selector if there's more options than just "default".
|
||||||
|
|
||||||
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 {}
|
id: intentSelectionRepeater
|
||||||
Item
|
model: Cura.IntentSelectionModel {}
|
||||||
{
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: intentCategoryLabel.height
|
|
||||||
|
|
||||||
UM.Label
|
RecommendedQualityProfileSelectorButton
|
||||||
{
|
{
|
||||||
id: intentCategoryLabel
|
profileName: model.name
|
||||||
text: model.name
|
icon: model.icon
|
||||||
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
|
|
||||||
{
|
|
||||||
anchors
|
|
||||||
{
|
|
||||||
left: intentCategoryLabel.right
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
dataModel: model["qualities"]
|
|
||||||
buttonGroup: activeProfileButtonGroup
|
|
||||||
|
|
||||||
function checkedFunction(modelItem)
|
selected: Cura.MachineManager.activeIntentCategory == model.intent_category
|
||||||
{
|
|
||||||
if(Cura.MachineManager.hasCustomQuality)
|
|
||||||
{
|
|
||||||
// When user created profile is active, no quality tickbox should be active.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if(modelItem === null)
|
onClicked: {
|
||||||
|
var qualityType
|
||||||
|
if (Cura.MachineManager.intentCategoryHasQuality(model.intent_category, Cura.MachineManager.activeQualityType))
|
||||||
{
|
{
|
||||||
return false
|
qualityType = Cura.MachineManager.activeQualityType
|
||||||
}
|
} else {
|
||||||
return Cura.MachineManager.activeQualityType == modelItem.quality_type && Cura.MachineManager.activeIntentCategory == modelItem.intent_category
|
qualityType = Cura.MachineManager.getDefaultQualityTypeForIntent(model.intent_category)
|
||||||
}
|
print(Cura.MachineManager.getDefaultQualityTypeForIntent(model.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()
|
|
||||||
}
|
}
|
||||||
|
Cura.IntentManager.selectIntent(model.intent_category, qualityType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
// 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("background_3") : UM.Theme.getColor("background_1")
|
||||||
|
|
||||||
|
property bool selected: false
|
||||||
|
property string profileName: ""
|
||||||
|
property string icon: ""
|
||||||
|
|
||||||
|
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
|
||||||
|
topMargin: UM.Theme.getSize("narrow_margin").height
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: intentIcon
|
||||||
|
width: UM.Theme.getSize("recommended_button_icon").width
|
||||||
|
height: UM.Theme.getSize("recommended_button_icon").height
|
||||||
|
UM.ColorImage
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: icon != ""
|
||||||
|
source: UM.Theme.getIcon(icon)
|
||||||
|
color: UM.Theme.getColor("icon")
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: circle
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: width
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: icon == ""
|
||||||
|
border.width: UM.Theme.getSize("thick_lining").width
|
||||||
|
border.color: UM.Theme.getColor("text")
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
id: initialLabel
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: profileName.charAt(0).toUpperCase()
|
||||||
|
font: UM.Theme.getFont("small_bold")
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
id: qualityLabel
|
||||||
|
text: profileName
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
bottom: parent.bottom
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottomMargin: UM.Theme.getSize("narrow_margin").height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
// 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
|
||||||
|
{
|
||||||
|
id: recommendedResolutionSelector
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
property real labelColumnWidth: Math.round(width / 3)
|
||||||
|
property string _previousResolution: "" //Internal variable to detect changes.
|
||||||
|
Component.onCompleted: _previousResolution = Cura.MachineManager.activeQualityType;
|
||||||
|
|
||||||
|
visible: visibilityPreset.count > 0 //Only show if there are quality types to select from.
|
||||||
|
|
||||||
|
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"
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: Cura.IntentManager
|
||||||
|
function onIntentCategoryChanged()
|
||||||
|
{
|
||||||
|
if(recommendedResolutionSelector._previousResolution !== Cura.MachineManager.activeQualityType)
|
||||||
|
{
|
||||||
|
visibilityPreset.pulse();
|
||||||
|
}
|
||||||
|
recommendedResolutionSelector._previousResolution = Cura.MachineManager.activeQualityType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
//Copyright (c) 2022 Ultimaker B.V.
|
||||||
|
//Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
import Cura 1.6 as Cura
|
||||||
|
import UM 1.6 as UM
|
||||||
|
|
||||||
|
//Message showing the user that the configuration they have selected has no profiles.
|
||||||
|
Column
|
||||||
|
{
|
||||||
|
spacing: UM.Theme.getSize("default_margin").height
|
||||||
|
|
||||||
|
Row
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
spacing: UM.Theme.getSize("thin_margin").width
|
||||||
|
|
||||||
|
UM.StatusIcon
|
||||||
|
{
|
||||||
|
width: UM.Theme.getSize("notification_icon").width
|
||||||
|
status: UM.StatusIcon.Status.ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
text: catalog.i18nc("@error", "Configuration not supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.Label
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
text: catalog.i18nc("@message:text %1 is the name the printer uses for 'nozzle'.", "No profiles are available for the selected material/%1 configuration. Please change your configuration."
|
||||||
|
).arg(Cura.MachineManager.activeDefinitionVariantsName)
|
||||||
|
}
|
||||||
|
|
||||||
|
Cura.TertiaryButton
|
||||||
|
{
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
text: catalog.i18nc("@button:label", "Learn more")
|
||||||
|
textFont: UM.Theme.getFont("default")
|
||||||
|
iconSource: UM.Theme.getIcon("LinkExternal")
|
||||||
|
isIconOnRightSide: true
|
||||||
|
|
||||||
|
onClicked: Qt.openUrlExternally("https://support.ultimaker.com/hc/en-us/articles/360012909099")
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,8 @@ ComboBox
|
|||||||
|
|
||||||
property var defaultTextOnEmptyModel: catalog.i18nc("@label", "No items to select from") // Text displayed in the combobox when the model is empty
|
property var defaultTextOnEmptyModel: catalog.i18nc("@label", "No items to select from") // Text displayed in the combobox when the model is empty
|
||||||
property var defaultTextOnEmptyIndex: "" // Text displayed in the combobox when the model has items but no item is selected
|
property var defaultTextOnEmptyIndex: "" // Text displayed in the combobox when the model has items but no item is selected
|
||||||
|
property alias textFormat: contentLabel.textFormat
|
||||||
|
|
||||||
enabled: delegateModel.count > 0
|
enabled: delegateModel.count > 0
|
||||||
|
|
||||||
onVisibleChanged: { popup.close() }
|
onVisibleChanged: { popup.close() }
|
||||||
@ -52,7 +54,34 @@ ComboBox
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
background: UM.UnderlineBackground{}
|
background: UM.UnderlineBackground
|
||||||
|
{
|
||||||
|
//Rectangle for highlighting when this combobox needs to pulse.
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: 0
|
||||||
|
color: UM.Theme.getColor("warning")
|
||||||
|
|
||||||
|
SequentialAnimation on opacity
|
||||||
|
{
|
||||||
|
id: pulseAnimation
|
||||||
|
running: false
|
||||||
|
loops: 1
|
||||||
|
alwaysRunToEnd: true
|
||||||
|
PropertyAnimation
|
||||||
|
{
|
||||||
|
to: 1
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
PropertyAnimation
|
||||||
|
{
|
||||||
|
to: 0
|
||||||
|
duration : 2000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
indicator: UM.ColorImage
|
indicator: UM.ColorImage
|
||||||
{
|
{
|
||||||
@ -146,7 +175,7 @@ ComboBox
|
|||||||
anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
|
anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
|
||||||
|
|
||||||
text: delegateItem.text
|
text: delegateItem.text
|
||||||
textFormat: Text.PlainText
|
textFormat: control.textFormat
|
||||||
color: UM.Theme.getColor("setting_control_text")
|
color: UM.Theme.getColor("setting_control_text")
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
@ -162,4 +191,9 @@ ComboBox
|
|||||||
text: delegateLabel.truncated ? delegateItem.text : ""
|
text: delegateLabel.truncated ? delegateItem.text : ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pulse()
|
||||||
|
{
|
||||||
|
pulseAnimation.restart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
4
resources/themes/cura-light/icons/default/GearCheck.svg
Normal file
4
resources/themes/cura-light/icons/default/GearCheck.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19 12C19 11.895 18.9888 11.7928 18.9843 11.6889L21.2354 9.9966L18.3525 5.0034L15.7525 6.1005C15.5837 5.9927 15.4112 5.8905 15.2325 5.7972L14.8828 3H9.11725L8.76725 5.7972C8.58555 5.8923 8.40965 5.9964 8.23725 6.1066L5.64725 5.0034L2.76465 9.9966L5.01525 11.7C5.01095 11.8 5.00005 11.8988 5.00005 12C5.00005 12.105 5.01125 12.2072 5.01575 12.3111L2.76465 14.0034L5.64755 18.9966L8.24755 17.8994C8.41635 18.0072 8.58885 18.1094 8.76755 18.2028L9.11725 21H14.8828L15.2328 18.2028C15.4145 18.1077 15.5904 18.0036 15.7628 17.8934L18.3528 18.9966L21.2357 14.0034L18.9848 12.3C18.9891 12.2 19 12.1012 19 12ZM18.62 14.5327L17.5028 16.4673L15.4513 15.6018C14.8703 16.1531 14.1649 16.5564 13.3949 16.7773L13.1172 19H10.8828L10.605 16.7773C9.8351 16.5564 9.12973 16.1531 8.54865 15.6018L6.49715 16.4673L5.38005 14.5327L7.15795 13.1865C6.94757 12.4095 6.94757 11.5905 7.15795 10.8135L5.38005 9.4673L6.49715 7.5327L8.54865 8.3982C9.12973 7.84686 9.8351 7.44364 10.605 7.2227L10.8828 5H13.1172L13.395 7.2227C14.165 7.44364 14.8704 7.84686 15.4514 8.3982L17.5029 7.5327L18.62 9.4673L16.8421 10.8135C17.0525 11.5905 17.0525 12.4095 16.8421 13.1865L18.62 14.5327Z"/>
|
||||||
|
<path d="M11 15.414L8.29297 12.707L9.70697 11.293L11 12.586L14.293 9.29297L15.707 10.707L11 15.414Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
8
resources/themes/cura-light/icons/default/Nut.svg
Normal file
8
resources/themes/cura-light/icons/default/Nut.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M17,3.3H7L2,12l5,8.7h10l5-8.7L17,3.3z M15.8,18.7H8.2L4.3,12l3.8-6.7h7.7l3.8,6.7L15.8,18.7z"/>
|
||||||
|
<path d="M12,7c-2.8,0-5,2.2-5,5s2.2,5,5,5s5-2.2,5-5S14.8,7,12,7z M12,15c-1.7,0-3-1.3-3-3s1.3-3,3-3s3,1.3,3,3S13.7,15,12,15z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 498 B |
9
resources/themes/cura-light/icons/default/Visual.svg
Normal file
9
resources/themes/cura-light/icons/default/Visual.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M18,3H6C4.3,3,3,4.3,3,6v12c0,1.7,1.3,3,3,3h12c1.7,0,3-1.3,3-3V6C21,4.3,19.7,3,18,3z M19,19H5v-2.6l4-4l5,5l3-3l2,2V19z
|
||||||
|
M19,13.6l-2-2l-3,3l-5-5l-4,4V5h14V13.6z"/>
|
||||||
|
<circle cx="15.5" cy="8.5" r="1.5"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 478 B |
@ -133,6 +133,11 @@
|
|||||||
"weight": 400,
|
"weight": 400,
|
||||||
"family": "Noto Sans"
|
"family": "Noto Sans"
|
||||||
},
|
},
|
||||||
|
"small_bold": {
|
||||||
|
"size": 0.9,
|
||||||
|
"weight": 700,
|
||||||
|
"family": "Noto Sans"
|
||||||
|
},
|
||||||
"small_ja_JP": {
|
"small_ja_JP": {
|
||||||
"size": 0.9,
|
"size": 0.9,
|
||||||
"weight": 400,
|
"weight": 400,
|
||||||
@ -637,6 +642,10 @@
|
|||||||
|
|
||||||
"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],
|
||||||
|
|
||||||
|
"reset_profile_icon": [1, 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user