mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-15 21:55:52 +08:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
184247ced6
@ -101,7 +101,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||||||
if key == "print_sequence" and property_name == "value":
|
if key == "print_sequence" and property_name == "value":
|
||||||
self._onChanged()
|
self._onChanged()
|
||||||
|
|
||||||
def _onChanged(self):
|
def _onChanged(self, *args):
|
||||||
if self._convex_hull_job:
|
if self._convex_hull_job:
|
||||||
self._convex_hull_job.cancel()
|
self._convex_hull_job.cancel()
|
||||||
self.setConvexHull(None)
|
self.setConvexHull(None)
|
||||||
|
@ -18,6 +18,7 @@ from UM.JobQueue import JobQueue
|
|||||||
from UM.SaveFile import SaveFile
|
from UM.SaveFile import SaveFile
|
||||||
from UM.Scene.Selection import Selection
|
from UM.Scene.Selection import Selection
|
||||||
from UM.Scene.GroupDecorator import GroupDecorator
|
from UM.Scene.GroupDecorator import GroupDecorator
|
||||||
|
import UM.Settings.Validator
|
||||||
|
|
||||||
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
||||||
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
||||||
@ -30,7 +31,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
|
|||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
|
|
||||||
from . import ExtruderManager
|
from . import ExtrudersModel
|
||||||
from . import PlatformPhysics
|
from . import PlatformPhysics
|
||||||
from . import BuildVolume
|
from . import BuildVolume
|
||||||
from . import CameraAnimation
|
from . import CameraAnimation
|
||||||
@ -89,6 +90,7 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
# Need to do this before ContainerRegistry tries to load the machines
|
# Need to do this before ContainerRegistry tries to load the machines
|
||||||
SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False)
|
SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False)
|
||||||
|
SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator)
|
||||||
|
|
||||||
super().__init__(name = "cura", version = CuraVersion)
|
super().__init__(name = "cura", version = CuraVersion)
|
||||||
|
|
||||||
@ -327,8 +329,6 @@ class CuraApplication(QtApplication):
|
|||||||
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
|
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
|
||||||
MachineManagerModel.createMachineManagerModel)
|
MachineManagerModel.createMachineManagerModel)
|
||||||
|
|
||||||
self._extruder_manager = ExtruderManager.ExtruderManager()
|
|
||||||
|
|
||||||
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
||||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||||
self.initializeEngine()
|
self.initializeEngine()
|
||||||
@ -368,6 +368,8 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
||||||
|
|
||||||
|
qmlRegisterType(ExtrudersModel.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
||||||
|
|
||||||
qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions")
|
qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions")
|
||||||
|
|
||||||
for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles):
|
for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles):
|
||||||
|
@ -25,8 +25,8 @@ class Extruder:
|
|||||||
self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId())
|
self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId())
|
||||||
|
|
||||||
#Create a container stack for this extruder.
|
#Create a container stack for this extruder.
|
||||||
name = self._uniqueName(self._definition.getId())
|
self._name = self._uniqueName(self._definition.getId())
|
||||||
self._container_stack = UM.Settings.ContainerStack(name)
|
self._container_stack = UM.Settings.ContainerStack(self._name)
|
||||||
self._container_stack.addMetaDataEntry("type", "extruder_train")
|
self._container_stack.addMetaDataEntry("type", "extruder_train")
|
||||||
self._container_stack.addContainer(self._definition)
|
self._container_stack.addContainer(self._definition)
|
||||||
|
|
||||||
@ -73,15 +73,38 @@ class Extruder:
|
|||||||
self._container_stack.addContainer(self._quality)
|
self._container_stack.addContainer(self._quality)
|
||||||
|
|
||||||
#Add an empty user profile.
|
#Add an empty user profile.
|
||||||
self._user_profile = UM.Settings.InstanceContainer(name + "_current_settings")
|
self._user_profile = UM.Settings.InstanceContainer(self._name + "_current_settings")
|
||||||
self._user_profile.addMetaDataEntry("type", "user")
|
self._user_profile.addMetaDataEntry("type", "user")
|
||||||
self._container_stack.addContainer(self._user_profile)
|
self._container_stack.addContainer(self._user_profile)
|
||||||
|
|
||||||
self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
||||||
|
|
||||||
nozzle_changed = UM.Signal.Signal()
|
definition_changed = UM.Signal()
|
||||||
material_changed = UM.Signal.Signal()
|
material_changed = UM.Signal()
|
||||||
quality_changed = UM.Signal.Signal()
|
name_changed = UM.Signal()
|
||||||
|
nozzle_changed = UM.Signal()
|
||||||
|
quality_changed = UM.Signal()
|
||||||
|
|
||||||
|
## Gets the definition container of this extruder.
|
||||||
|
#
|
||||||
|
# \return The definition container of this extruder.
|
||||||
|
@property
|
||||||
|
def definition(self):
|
||||||
|
return self._definition
|
||||||
|
|
||||||
|
## Changes the definition container of this extruder.
|
||||||
|
#
|
||||||
|
# \param value The new definition for this extruder.
|
||||||
|
@definition.setter
|
||||||
|
def definition(self, value):
|
||||||
|
try:
|
||||||
|
position = self._container_stack.index(self._definition)
|
||||||
|
except ValueError: #Definition is not in the list. Big trouble!
|
||||||
|
UM.Logger.log("e", "I've lost my old extruder definition, so I can't find where to insert the new definition.")
|
||||||
|
return
|
||||||
|
self._container_stack.replaceContainer(position, value)
|
||||||
|
self._definition = value
|
||||||
|
self.definition_changed.emit()
|
||||||
|
|
||||||
## Gets the currently active material on this extruder.
|
## Gets the currently active material on this extruder.
|
||||||
#
|
#
|
||||||
@ -104,6 +127,22 @@ class Extruder:
|
|||||||
self._material = value
|
self._material = value
|
||||||
self.material_changed.emit()
|
self.material_changed.emit()
|
||||||
|
|
||||||
|
## Gets the name of this extruder.
|
||||||
|
#
|
||||||
|
# \return The name of this extruder.
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
## Changes the name of this extruder.
|
||||||
|
#
|
||||||
|
# \param value The new name for this extruder.
|
||||||
|
@name.setter
|
||||||
|
def name(self, value):
|
||||||
|
self._name = value
|
||||||
|
self._container_stack.setName(value) #Also update in container stack, being defensive.
|
||||||
|
self.name_changed.emit()
|
||||||
|
|
||||||
## Gets the currently active nozzle on this extruder.
|
## Gets the currently active nozzle on this extruder.
|
||||||
#
|
#
|
||||||
# \return The currently active nozzle on this extruder.
|
# \return The currently active nozzle on this extruder.
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2016 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from cura.Extruder import Extruder #The individual extruders managed by this manager.
|
from cura.Extruder import Extruder #The individual extruders managed by this manager.
|
||||||
from UM.Application import Application #To get the global container stack to find the current machine.
|
import UM.Application #To get the global container stack to find the current machine.
|
||||||
from UM.Logger import Logger
|
import UM.Logger
|
||||||
from UM.Settings.ContainerStack import ContainerStack #To create container stacks for each extruder.
|
import UM.Settings.ContainerRegistry #Finding containers by ID.
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID.
|
import UM.Signal #To notify other components of changes in the extruders.
|
||||||
|
|
||||||
|
|
||||||
## Class that handles the current extruder stack.
|
## Class that handles the current extruder stack.
|
||||||
@ -16,19 +14,42 @@ from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers
|
|||||||
# and makes sure that whenever the machine is swapped, this list is kept up to
|
# and makes sure that whenever the machine is swapped, this list is kept up to
|
||||||
# date. It also contains and updates the setting stacks for the extruders.
|
# date. It also contains and updates the setting stacks for the extruders.
|
||||||
class ExtruderManager:
|
class ExtruderManager:
|
||||||
|
## The singleton instance of this manager.
|
||||||
|
__instance = None
|
||||||
|
|
||||||
|
## Signal to notify other components when the list of extruders changes.
|
||||||
|
extrudersChanged = UM.Signal()
|
||||||
|
|
||||||
## Registers listeners and such to listen to changes to the extruders.
|
## Registers listeners and such to listen to changes to the extruders.
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._extruders = [] #Extruders for the current machine.
|
self._extruders = [] #Extruders for the current machine.
|
||||||
self._global_container_stack = None
|
self._global_container_stack = None
|
||||||
|
self._next_item = 0 #For when you use this class as iterator.
|
||||||
|
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine.
|
UM.Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine.
|
||||||
|
|
||||||
|
## Gets an instance of this extruder manager.
|
||||||
|
#
|
||||||
|
# If an instance was already created, the old instance is returned. This
|
||||||
|
# implements the singleton pattern.
|
||||||
|
@classmethod
|
||||||
|
def getInstance(cls):
|
||||||
|
if not cls.__instance:
|
||||||
|
cls.__instance = ExtruderManager()
|
||||||
|
return cls.__instance
|
||||||
|
|
||||||
|
## Creates an iterator over the extruders in this manager.
|
||||||
|
#
|
||||||
|
# \return An iterator over the extruders in this manager.
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._extruders)
|
||||||
|
|
||||||
## When the global container stack changes, this reconnects to the new
|
## When the global container stack changes, this reconnects to the new
|
||||||
# signal for containers changing.
|
# signal for containers changing.
|
||||||
def _reconnectExtruderReload(self):
|
def _reconnectExtruderReload(self):
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack.
|
self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack.
|
||||||
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
self._global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||||
self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine.
|
self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine.
|
||||||
|
|
||||||
## (Re)loads all extruders of the currently active machine.
|
## (Re)loads all extruders of the currently active machine.
|
||||||
@ -36,18 +57,20 @@ class ExtruderManager:
|
|||||||
# This looks at the global container stack to see which machine is active.
|
# This looks at the global container stack to see which machine is active.
|
||||||
# Then it loads the extruders for that machine and loads each of them in a
|
# Then it loads the extruders for that machine and loads each of them in a
|
||||||
# list of extruders.
|
# list of extruders.
|
||||||
def _reloadExtruders(self):
|
def _reloadExtruders(self, *args):
|
||||||
self._extruders = []
|
self._extruders = []
|
||||||
if not self._global_container_stack: #No machine has been added yet.
|
if not self._global_container_stack: #No machine has been added yet.
|
||||||
|
self.extrudersChanged.emit() #Yes, we just cleared the _extruders list!
|
||||||
return #Then leave them empty!
|
return #Then leave them empty!
|
||||||
|
|
||||||
#Get the extruder definitions belonging to the current machine.
|
#Get the extruder definitions belonging to the current machine.
|
||||||
machine = self._global_container_stack.getBottom()
|
machine = self._global_container_stack.getBottom()
|
||||||
extruder_train_ids = machine.getMetaData("machine_extruder_trains")
|
extruder_train_ids = machine.getMetaDataEntry("machine_extruder_trains")
|
||||||
for extruder_train_id in extruder_train_ids:
|
for extruder_train_id in extruder_train_ids:
|
||||||
extruder_definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway.
|
extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway.
|
||||||
if not extruder_definitions: #Empty list or error.
|
if not extruder_definitions: #Empty list or error.
|
||||||
Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id)
|
UM.Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id)
|
||||||
continue
|
continue
|
||||||
for extruder_definition in extruder_definitions:
|
for extruder_definition in extruder_definitions:
|
||||||
self._extruders.append(Extruder(extruder_definition))
|
self._extruders.append(Extruder(extruder_definition))
|
||||||
|
self.extrudersChanged.emit()
|
56
cura/ExtrudersModel.py
Normal file
56
cura/ExtrudersModel.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Copyright (c) 2016 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
|
|
||||||
|
import cura.ExtruderManager
|
||||||
|
import UM.Qt.ListModel
|
||||||
|
|
||||||
|
## Model that holds extruders.
|
||||||
|
#
|
||||||
|
# This model is designed for use by any list of extruders, but specifically
|
||||||
|
# intended for drop-down lists of extruders in place of settings.
|
||||||
|
class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
|
## Human-readable name of the extruder.
|
||||||
|
NameRole = Qt.UserRole + 1
|
||||||
|
|
||||||
|
## Colour of the material loaded in the extruder.
|
||||||
|
ColourRole = Qt.UserRole + 2
|
||||||
|
|
||||||
|
## Index of the extruder, which is also the value of the setting itself.
|
||||||
|
#
|
||||||
|
# An index of 0 indicates the first extruder, an index of 1 the second
|
||||||
|
# one, and so on. This is the value that will be saved in instance
|
||||||
|
# containers.
|
||||||
|
IndexRole = Qt.UserRole + 3
|
||||||
|
|
||||||
|
## Initialises the extruders model, defining the roles and listening for
|
||||||
|
# changes in the data.
|
||||||
|
#
|
||||||
|
# \param parent Parent QtObject of this list.
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.addRoleName(self.NameRole, "name")
|
||||||
|
self.addRoleName(self.ColourRole, "colour")
|
||||||
|
self.addRoleName(self.IndexRole, "index")
|
||||||
|
|
||||||
|
#Listen to changes.
|
||||||
|
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
||||||
|
manager.extrudersChanged.connect(self._updateExtruders)
|
||||||
|
self._updateExtruders()
|
||||||
|
|
||||||
|
## Update the list of extruders.
|
||||||
|
#
|
||||||
|
# This should be called whenever the list of extruders changes.
|
||||||
|
def _updateExtruders(self):
|
||||||
|
self.clear()
|
||||||
|
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
||||||
|
for index, extruder in enumerate(manager):
|
||||||
|
item = { #Construct an item with only the relevant information.
|
||||||
|
"name": extruder.name,
|
||||||
|
"colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"),
|
||||||
|
"index": index
|
||||||
|
}
|
||||||
|
self.appendItem(item)
|
||||||
|
self.sort(lambda item: item["index"])
|
@ -18,11 +18,17 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||||||
self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
||||||
self._stack.addContainer(self._instance)
|
self._stack.addContainer(self._instance)
|
||||||
|
|
||||||
|
self._stack.propertyChanged.connect(self._onSettingChanged)
|
||||||
|
|
||||||
ContainerRegistry.getInstance().addContainer(self._stack)
|
ContainerRegistry.getInstance().addContainer(self._stack)
|
||||||
|
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
|
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
|
||||||
self._onGlobalContainerStackChanged()
|
self._onGlobalContainerStackChanged()
|
||||||
|
|
||||||
|
def _onSettingChanged(self, instance, property):
|
||||||
|
if property == "value": # Only reslice if the value has changed.
|
||||||
|
Application.getInstance().getBackend().forceSlice()
|
||||||
|
|
||||||
def _onGlobalContainerStackChanged(self):
|
def _onGlobalContainerStackChanged(self):
|
||||||
## Ensure that the next stack is always the global stack.
|
## Ensure that the next stack is always the global stack.
|
||||||
self._stack.setNextStack(Application.getInstance().getGlobalContainerStack())
|
self._stack.setNextStack(Application.getInstance().getGlobalContainerStack())
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
from string import Formatter
|
from string import Formatter
|
||||||
import traceback
|
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
from UM.Job import Job
|
from UM.Job import Job
|
||||||
@ -59,7 +58,7 @@ class StartSliceJob(Job):
|
|||||||
self.setResult(StartJobResult.Error)
|
self.setResult(StartJobResult.Error)
|
||||||
return
|
return
|
||||||
|
|
||||||
#Don't slice if there is a setting with an error value.
|
# Don't slice if there is a setting with an error value.
|
||||||
for key in stack.getAllKeys():
|
for key in stack.getAllKeys():
|
||||||
validation_state = stack.getProperty(key, "validationState")
|
validation_state = stack.getProperty(key, "validationState")
|
||||||
if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
|
if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
|
||||||
@ -69,6 +68,22 @@ class StartSliceJob(Job):
|
|||||||
|
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
|
# Don't slice if there is a per object setting with an error value.
|
||||||
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
if type(node) is not SceneNode or not node.isSelectable():
|
||||||
|
continue
|
||||||
|
|
||||||
|
node_stack = node.callDecoration("getStack")
|
||||||
|
if node_stack:
|
||||||
|
for key in node_stack.getAllKeys():
|
||||||
|
validation_state = node_stack.getProperty(key, "validationState")
|
||||||
|
if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
|
||||||
|
Logger.log("w", "Per object setting %s is not valid, but %s. Aborting slicing.", key, validation_state)
|
||||||
|
self.setResult(StartJobResult.SettingError)
|
||||||
|
return
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
with self._scene.getSceneLock():
|
with self._scene.getSceneLock():
|
||||||
# Remove old layer data.
|
# Remove old layer data.
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
@ -5,7 +5,8 @@ from UM.Logger import Logger
|
|||||||
|
|
||||||
from cura.SettingOverrideDecorator import SettingOverrideDecorator
|
from cura.SettingOverrideDecorator import SettingOverrideDecorator
|
||||||
|
|
||||||
|
## The per object setting visibility handler ensures that only setting defintions that have a matching instance Container
|
||||||
|
# are returned as visible.
|
||||||
class PerObjectSettingVisibilityHandler(QObject):
|
class PerObjectSettingVisibilityHandler(QObject):
|
||||||
def __init__(self, parent = None, *args, **kwargs):
|
def __init__(self, parent = None, *args, **kwargs):
|
||||||
super().__init__(parent = parent, *args, **kwargs)
|
super().__init__(parent = parent, *args, **kwargs)
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
# Copyright (c) 2015 Ultimaker B.V.
|
|
||||||
# Uranium is released under the terms of the AGPLv3 or higher.
|
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, pyqtSlot, QUrl
|
|
||||||
|
|
||||||
from UM.Application import Application
|
|
||||||
from UM.Qt.ListModel import ListModel
|
|
||||||
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
|
||||||
from UM.Scene.SceneNode import SceneNode
|
|
||||||
#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator
|
|
||||||
#from UM.Settings.ProfileOverrideDecorator import ProfileOverrideDecorator
|
|
||||||
|
|
||||||
from . import SettingOverrideModel
|
|
||||||
|
|
||||||
class PerObjectSettingsModel(ListModel):
|
|
||||||
IdRole = Qt.UserRole + 1 # ID of the node
|
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self._scene = Application.getInstance().getController().getScene()
|
|
||||||
self._root = self._scene.getRoot()
|
|
||||||
self.addRoleName(self.IdRole,"id")
|
|
||||||
|
|
||||||
self._updateModel()
|
|
||||||
|
|
||||||
@pyqtSlot("quint64", str)
|
|
||||||
def setObjectProfile(self, object_id, profile_name):
|
|
||||||
self.setProperty(self.find("id", object_id), "profile", profile_name)
|
|
||||||
|
|
||||||
profile = None
|
|
||||||
'''if profile_name != "global":
|
|
||||||
profile = Application.getInstance().getMachineManager().findProfile(profile_name)
|
|
||||||
|
|
||||||
node = self._scene.findObject(object_id)
|
|
||||||
if profile:
|
|
||||||
if not node.getDecorator(ProfileOverrideDecorator):
|
|
||||||
node.addDecorator(ProfileOverrideDecorator())
|
|
||||||
node.callDecoration("setProfile", profile)
|
|
||||||
else:
|
|
||||||
if node.getDecorator(ProfileOverrideDecorator):
|
|
||||||
node.removeDecorator(ProfileOverrideDecorator)'''
|
|
||||||
|
|
||||||
@pyqtSlot("quint64", str)
|
|
||||||
def addOverride(self, object_id, key):
|
|
||||||
machine = Application.getInstance().getMachineManager().getActiveMachineInstance()
|
|
||||||
if not machine:
|
|
||||||
return
|
|
||||||
|
|
||||||
node = self._scene.findObject(object_id)
|
|
||||||
#if not node.getDecorator(SettingOverrideDecorator):
|
|
||||||
# node.addDecorator(SettingOverrideDecorator())
|
|
||||||
|
|
||||||
node.callDecoration("addSetting", key)
|
|
||||||
|
|
||||||
@pyqtSlot("quint64", str)
|
|
||||||
def removerOverride(self, object_id, key):
|
|
||||||
node = self._scene.findObject(object_id)
|
|
||||||
node.callDecoration("removeSetting", key)
|
|
||||||
|
|
||||||
#if len(node.callDecoration("getAllSettings")) == 0:
|
|
||||||
# node.removeDecorator(SettingOverrideDecorator)
|
|
||||||
|
|
||||||
def _updateModel(self):
|
|
||||||
self.clear()
|
|
||||||
|
|
||||||
for node in BreadthFirstIterator(self._root):
|
|
||||||
if type(node) is not SceneNode or not node.isSelectable():
|
|
||||||
continue
|
|
||||||
|
|
||||||
node_stack = node.callDecoration("getStack")
|
|
||||||
|
|
||||||
if not node_stack:
|
|
||||||
self.appendItem({
|
|
||||||
"id": id(node)
|
|
||||||
})
|
|
@ -45,6 +45,7 @@ Item {
|
|||||||
{
|
{
|
||||||
Loader
|
Loader
|
||||||
{
|
{
|
||||||
|
id: settingLoader
|
||||||
width: UM.Theme.getSize("setting").width;
|
width: UM.Theme.getSize("setting").width;
|
||||||
height: UM.Theme.getSize("section").height;
|
height: UM.Theme.getSize("section").height;
|
||||||
|
|
||||||
@ -57,6 +58,12 @@ Item {
|
|||||||
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
|
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
|
||||||
asynchronous: model.type != "enum"
|
asynchronous: model.type != "enum"
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
settingLoader.item.showRevertButton = false
|
||||||
|
settingLoader.item.showInheritButton = false
|
||||||
|
settingLoader.item.doDepthIdentation = false
|
||||||
|
}
|
||||||
|
|
||||||
source:
|
source:
|
||||||
{
|
{
|
||||||
switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job!
|
switch(model.type) // TODO: This needs to be fixed properly. Got frustrated with it not working, so this is the patch job!
|
||||||
|
@ -6,14 +6,15 @@ from UM.Scene.Selection import Selection
|
|||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
|
|
||||||
from . import PerObjectSettingsModel
|
|
||||||
|
|
||||||
|
## This tool allows the user to add & change settings per node in the scene.
|
||||||
|
# The settings per object are kept in a ContainerStack, which is linked to a node by decorator.
|
||||||
class PerObjectSettingsTool(Tool):
|
class PerObjectSettingsTool(Tool):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._model = None
|
self._model = None
|
||||||
|
|
||||||
self.setExposedProperties("SelectedObjectId","ContainerID")
|
self.setExposedProperties("SelectedObjectId", "ContainerID")
|
||||||
|
|
||||||
Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged)
|
Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged)
|
||||||
Selection.selectionChanged.connect(self.propertyChanged)
|
Selection.selectionChanged.connect(self.propertyChanged)
|
||||||
@ -33,21 +34,13 @@ class PerObjectSettingsTool(Tool):
|
|||||||
return selected_object_id
|
return selected_object_id
|
||||||
|
|
||||||
def getContainerID(self):
|
def getContainerID(self):
|
||||||
|
selected_object = Selection.getSelectedObject(0)
|
||||||
|
if selected_object.getParent().callDecoration("isGroup"):
|
||||||
|
selected_object = selected_object.getParent()
|
||||||
try:
|
try:
|
||||||
selected_object = Selection.getSelectedObject(0)
|
return selected_object.callDecoration("getStack").getId()
|
||||||
if selected_object.getParent().callDecoration("isGroup"):
|
except AttributeError:
|
||||||
selected_object = selected_object.getParent()
|
return ""
|
||||||
try:
|
|
||||||
return selected_object.callDecoration("getStack").getId()
|
|
||||||
except:
|
|
||||||
print(":(")
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
print(":((")
|
|
||||||
return
|
|
||||||
|
|
||||||
def setContainerID(self, value):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _onPreferenceChanged(self, preference):
|
def _onPreferenceChanged(self, preference):
|
||||||
if preference == "cura/active_mode":
|
if preference == "cura/active_mode":
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
# Copyright (c) 2015 Ultimaker B.V.
|
|
||||||
# Uranium is released under the terms of the AGPLv3 or higher.
|
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, pyqtSlot, QUrl
|
|
||||||
|
|
||||||
from UM.Application import Application
|
|
||||||
from UM.Qt.ListModel import ListModel
|
|
||||||
#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator
|
|
||||||
|
|
||||||
class SettingOverrideModel(ListModel):
|
|
||||||
KeyRole = Qt.UserRole + 1
|
|
||||||
LabelRole = Qt.UserRole + 2
|
|
||||||
DescriptionRole = Qt.UserRole + 3
|
|
||||||
ValueRole = Qt.UserRole + 4
|
|
||||||
TypeRole = Qt.UserRole + 5
|
|
||||||
UnitRole = Qt.UserRole + 6
|
|
||||||
ValidRole = Qt.UserRole + 7
|
|
||||||
OptionsRole = Qt.UserRole + 8
|
|
||||||
WarningDescriptionRole = Qt.UserRole + 9
|
|
||||||
ErrorDescriptionRole = Qt.UserRole + 10
|
|
||||||
GlobalOnlyRole = Qt.UserRole + 11
|
|
||||||
|
|
||||||
def __init__(self, node, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
self._ignore_setting_change = None
|
|
||||||
|
|
||||||
self._node = node
|
|
||||||
self._node.decoratorsChanged.connect(self._onDecoratorsChanged)
|
|
||||||
self._onDecoratorsChanged(None)
|
|
||||||
|
|
||||||
#self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes.
|
|
||||||
#self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged)
|
|
||||||
#Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged)
|
|
||||||
|
|
||||||
self.addRoleName(self.KeyRole, "key")
|
|
||||||
self.addRoleName(self.LabelRole, "label")
|
|
||||||
self.addRoleName(self.DescriptionRole, "description")
|
|
||||||
self.addRoleName(self.ValueRole,"value")
|
|
||||||
self.addRoleName(self.TypeRole, "type")
|
|
||||||
self.addRoleName(self.UnitRole, "unit")
|
|
||||||
self.addRoleName(self.ValidRole, "valid")
|
|
||||||
self.addRoleName(self.OptionsRole, "options")
|
|
||||||
self.addRoleName(self.WarningDescriptionRole, "warning_description")
|
|
||||||
self.addRoleName(self.ErrorDescriptionRole, "error_description")
|
|
||||||
self.addRoleName(self.GlobalOnlyRole, "global_only")
|
|
||||||
|
|
||||||
@pyqtSlot(str, "QVariant")
|
|
||||||
def setSettingValue(self, key, value):
|
|
||||||
if not self._decorator:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._decorator.setSettingValue(key, value)
|
|
||||||
|
|
||||||
def _onDecoratorsChanged(self, node):
|
|
||||||
return
|
|
||||||
'''if not self._node.getDecorator(SettingOverrideDecorator):
|
|
||||||
self.clear()
|
|
||||||
return
|
|
||||||
|
|
||||||
self._decorator = self._node.getDecorator(SettingOverrideDecorator)
|
|
||||||
self._decorator.settingAdded.connect(self._onSettingsChanged)
|
|
||||||
self._decorator.settingRemoved.connect(self._onSettingsChanged)
|
|
||||||
self._decorator.settingValueChanged.connect(self._onSettingValueChanged)
|
|
||||||
self._onSettingsChanged()'''
|
|
||||||
|
|
||||||
def _createOptionsModel(self, options):
|
|
||||||
if not options:
|
|
||||||
return None
|
|
||||||
|
|
||||||
model = ListModel()
|
|
||||||
model.addRoleName(Qt.UserRole + 1, "value")
|
|
||||||
model.addRoleName(Qt.UserRole + 2, "name")
|
|
||||||
for value, name in options.items():
|
|
||||||
model.appendItem({"value": str(value), "name": str(name)})
|
|
||||||
return model
|
|
||||||
|
|
||||||
## Updates the active profile in this model if the active profile is
|
|
||||||
# changed.
|
|
||||||
#
|
|
||||||
# This links the settingValueChanged of the new profile to this model's
|
|
||||||
# _onSettingValueChanged function, so that it properly listens to those
|
|
||||||
# events again.
|
|
||||||
def _onProfileChanged(self):
|
|
||||||
if self._activeProfile: #Unlink from the old profile.
|
|
||||||
self._activeProfile.settingValueChanged.disconnect(self._onProfileSettingValueChanged)
|
|
||||||
old_profile = self._activeProfile
|
|
||||||
self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile()
|
|
||||||
self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) #Re-link to the new profile.
|
|
||||||
for setting_name in old_profile.getChangedSettings().keys(): #Update all changed settings in the old and new profiles.
|
|
||||||
self._onProfileSettingValueChanged(setting_name)
|
|
||||||
for setting_name in self._activeProfile.getChangedSettings().keys():
|
|
||||||
self._onProfileSettingValueChanged(setting_name)
|
|
||||||
|
|
||||||
## Updates the global_only property of a setting once a setting value
|
|
||||||
# changes.
|
|
||||||
#
|
|
||||||
# This method should only get called on settings that are dependent on the
|
|
||||||
# changed setting.
|
|
||||||
#
|
|
||||||
# \param setting_name The setting that needs to be updated.
|
|
||||||
def _onProfileSettingValueChanged(self, setting_name):
|
|
||||||
index = self.find("key", setting_name)
|
|
||||||
if index != -1:
|
|
||||||
self.setProperty(index, "global_only", Application.getInstance().getMachineManager().getActiveMachineInstance().getMachineDefinition().getSetting(setting_name).getGlobalOnly())
|
|
||||||
|
|
||||||
def _onSettingsChanged(self):
|
|
||||||
self.clear()
|
|
||||||
|
|
||||||
items = []
|
|
||||||
for key, setting in self._decorator.getAllSettings().items():
|
|
||||||
value = self._decorator.getSettingValue(key)
|
|
||||||
items.append({
|
|
||||||
"key": key,
|
|
||||||
"label": setting.getLabel(),
|
|
||||||
"description": setting.getDescription(),
|
|
||||||
"value": str(value),
|
|
||||||
"type": setting.getType(),
|
|
||||||
"unit": setting.getUnit(),
|
|
||||||
"valid": setting.validate(value),
|
|
||||||
"options": self._createOptionsModel(setting.getOptions()),
|
|
||||||
"warning_description": setting.getWarningDescription(),
|
|
||||||
"error_description": setting.getErrorDescription(),
|
|
||||||
"global_only": setting.getGlobalOnly()
|
|
||||||
})
|
|
||||||
|
|
||||||
items.sort(key = lambda i: i["key"])
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
self.appendItem(item)
|
|
||||||
|
|
||||||
def _onSettingValueChanged(self, setting):
|
|
||||||
index = self.find("key", setting.getKey())
|
|
||||||
value = self._decorator.getSettingValue(setting.getKey())
|
|
||||||
if index != -1:
|
|
||||||
self.setProperty(index, "value", str(value))
|
|
||||||
self.setProperty(index, "valid", setting.validate(value))
|
|
||||||
self.setProperty(index, "global_only", setting.getGlobalOnly())
|
|
@ -22,7 +22,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Extruder",
|
"label": "Extruder",
|
||||||
"description": "The extruder train used for printing. This is used in multi-extrusion.",
|
"description": "The extruder train used for printing. This is used in multi-extrusion.",
|
||||||
"type": "int",
|
"type": "extruder",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"minimum_value": "0"
|
"minimum_value": "0"
|
||||||
},
|
},
|
||||||
|
@ -2125,7 +2125,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Platform Adhesion Extruder",
|
"label": "Platform Adhesion Extruder",
|
||||||
"description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.",
|
"description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.",
|
||||||
"type": "int",
|
"type": "extruder",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "machine_extruder_count - 1",
|
"maximum_value": "machine_extruder_count - 1",
|
||||||
@ -2135,7 +2135,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Support Extruder",
|
"label": "Support Extruder",
|
||||||
"description": "The extruder train to use for printing the support. This is used in multi-extrusion.",
|
"description": "The extruder train to use for printing the support. This is used in multi-extrusion.",
|
||||||
"type": "int",
|
"type": "extruder",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "machine_extruder_count - 1",
|
"maximum_value": "machine_extruder_count - 1",
|
||||||
@ -2145,7 +2145,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Support Infill Extruder",
|
"label": "Support Infill Extruder",
|
||||||
"description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.",
|
"description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.",
|
||||||
"type": "int",
|
"type": "extruder",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"value": "support_extruder_nr",
|
"value": "support_extruder_nr",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
@ -2156,7 +2156,7 @@
|
|||||||
{
|
{
|
||||||
"label": "First Layer Support Extruder",
|
"label": "First Layer Support Extruder",
|
||||||
"description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.",
|
"description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.",
|
||||||
"type": "int",
|
"type": "extruder",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"value": "support_extruder_nr",
|
"value": "support_extruder_nr",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
@ -2167,7 +2167,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Support Roof Extruder",
|
"label": "Support Roof Extruder",
|
||||||
"description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.",
|
"description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.",
|
||||||
"type": "int",
|
"type": "extruder",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"value": "support_extruder_nr",
|
"value": "support_extruder_nr",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
|
112
resources/qml/Settings/SettingExtruder.qml
Normal file
112
resources/qml/Settings/SettingExtruder.qml
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright (c) 2016 Ultimaker B.V.
|
||||||
|
// Uranium is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
|
||||||
|
import UM 1.1 as UM
|
||||||
|
import Cura 1.0 as Cura
|
||||||
|
|
||||||
|
SettingItem
|
||||||
|
{
|
||||||
|
id: base
|
||||||
|
|
||||||
|
contents: ComboBox
|
||||||
|
{
|
||||||
|
id: control
|
||||||
|
|
||||||
|
model: Cura.ExtrudersModel {
|
||||||
|
id: extruders_model
|
||||||
|
}
|
||||||
|
textRole: "name";
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill: parent;
|
||||||
|
acceptedButtons: Qt.NoButton;
|
||||||
|
onWheel: wheel.accepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
style: ComboBoxStyle
|
||||||
|
{
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
color:
|
||||||
|
{
|
||||||
|
if (!enabled)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("setting_control_disabled")
|
||||||
|
}
|
||||||
|
if(control.hovered || base.activeFocus)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("setting_control_highlight")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("setting_control")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
border.width: UM.Theme.getSize("default_lining").width;
|
||||||
|
border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border");
|
||||||
|
}
|
||||||
|
label: Item
|
||||||
|
{
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: UM.Theme.getSize("default_lining").width
|
||||||
|
anchors.right: downArrow.left;
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_lining").width;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
|
||||||
|
text: control.currentText;
|
||||||
|
font: UM.Theme.getFont("default");
|
||||||
|
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text");
|
||||||
|
|
||||||
|
elide: Text.ElideRight;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
id: downArrow
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
|
||||||
|
source: UM.Theme.getIcon("arrow_bottom")
|
||||||
|
width: UM.Theme.getSize("standard_arrow").width
|
||||||
|
height: UM.Theme.getSize("standard_arrow").height
|
||||||
|
sourceSize.width: width + 5
|
||||||
|
sourceSize.height: width + 5
|
||||||
|
|
||||||
|
color: UM.Theme.getColor("setting_control_text");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onActivated: provider.setPropertyValue("value", extruders_model.getItem(index).index)
|
||||||
|
onModelChanged: updateCurrentIndex();
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: provider
|
||||||
|
onPropertiesChanged: control.updateCurrentIndex()
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCurrentIndex() {
|
||||||
|
for(var i = 0; i < extruders_model.rowCount(); ++i) {
|
||||||
|
if(extruders_model.getItem(i).index == provider.properties.value) {
|
||||||
|
currentIndex = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,10 @@ Item {
|
|||||||
property alias contents: controlContainer.children;
|
property alias contents: controlContainer.children;
|
||||||
property alias hovered: mouse.containsMouse
|
property alias hovered: mouse.containsMouse
|
||||||
|
|
||||||
|
property var showRevertButton: true
|
||||||
|
property var showInheritButton: true
|
||||||
|
property var doDepthIdentation: true
|
||||||
|
|
||||||
signal contextMenuRequested()
|
signal contextMenuRequested()
|
||||||
signal showTooltip(string text);
|
signal showTooltip(string text);
|
||||||
signal hideTooltip();
|
signal hideTooltip();
|
||||||
@ -93,7 +97,7 @@ Item {
|
|||||||
id: label;
|
id: label;
|
||||||
|
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)
|
anchors.leftMargin: doDepthIdentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0
|
||||||
anchors.right: settingControls.left;
|
anchors.right: settingControls.left;
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
@ -124,7 +128,7 @@ Item {
|
|||||||
{
|
{
|
||||||
id: revertButton;
|
id: revertButton;
|
||||||
|
|
||||||
visible: propertyProvider.stackLevel == 0
|
visible: propertyProvider.stackLevel == 0 && base.showRevertButton
|
||||||
|
|
||||||
height: parent.height;
|
height: parent.height;
|
||||||
width: height;
|
width: height;
|
||||||
@ -151,7 +155,7 @@ Item {
|
|||||||
id: inheritButton;
|
id: inheritButton;
|
||||||
|
|
||||||
//visible: has_profile_value && base.has_inherit_function && base.is_enabled
|
//visible: has_profile_value && base.has_inherit_function && base.is_enabled
|
||||||
visible: propertyProvider.properties.state == "InstanceState.User" && propertyProvider.stackLevel > 0
|
visible: propertyProvider.properties.state == "InstanceState.User" && propertyProvider.stackLevel > 0 && base.showInheritButton
|
||||||
|
|
||||||
height: parent.height;
|
height: parent.height;
|
||||||
width: height;
|
width: height;
|
||||||
|
@ -48,7 +48,7 @@ ScrollView
|
|||||||
|
|
||||||
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
|
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
|
||||||
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
|
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
|
||||||
//causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely.
|
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
|
||||||
asynchronous: model.type != "enum"
|
asynchronous: model.type != "enum"
|
||||||
active: model.type != undefined
|
active: model.type != undefined
|
||||||
|
|
||||||
@ -62,6 +62,8 @@ ScrollView
|
|||||||
return "SettingTextField.qml"
|
return "SettingTextField.qml"
|
||||||
case "enum":
|
case "enum":
|
||||||
return "SettingComboBox.qml"
|
return "SettingComboBox.qml"
|
||||||
|
case "extruder":
|
||||||
|
return "SettingExtruder.qml"
|
||||||
case "bool":
|
case "bool":
|
||||||
return "SettingCheckBox.qml"
|
return "SettingCheckBox.qml"
|
||||||
case "str":
|
case "str":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user