[core] add enabled property on attributes

The new property "enabled" allows to define a lambda to dynamically enable/disable parameters.
Disabled parameters are not used in the uid, not exported to the command line and not visible in the interface.
This commit is contained in:
Julien-Haudegond 2020-07-24 17:36:17 +02:00
parent f7b6b27a5a
commit 2d953d7319
4 changed files with 53 additions and 28 deletions

View file

@ -58,6 +58,7 @@ class Attribute(BaseObject):
self._isOutput = isOutput
self._value = copy.copy(attributeDesc.value)
self._label = attributeDesc.label
self._enabled = True
# invalidation value for output attributes
self._invalidationValue = ""
@ -95,6 +96,15 @@ class Attribute(BaseObject):
def getLabel(self):
return self._label
def getEnabled(self):
return self._enabled
def setEnabled(self, v):
if self._enabled == v:
return
self._enabled = v
self.enabledChanged.emit()
def _get_value(self):
return self.getLinkParam().value if self.isLink else self._value
@ -224,6 +234,12 @@ class Attribute(BaseObject):
def getPrimitiveValue(self, exportDefault=True):
return self._value
def updateInternals(self):
if isinstance(self.desc.enabled, types.FunctionType):
self.setEnabled(self.desc.enabled(self.node))
else:
self.setEnabled(self.attributeDesc.enabled)
name = Property(str, getName, constant=True)
fullName = Property(str, getFullName, constant=True)
label = Property(str, getLabel, constant=True)
@ -237,6 +253,8 @@ class Attribute(BaseObject):
isDefault = Property(bool, _isDefault, notify=valueChanged)
linkParam = Property(BaseObject, getLinkParam, notify=isLinkChanged)
node = Property(BaseObject, node.fget, constant=True)
enabledChanged = Signal()
enabled = Property(bool, getEnabled, setEnabled, notify=enabledChanged)
def raiseIfLink(func):

40
meshroom/core/desc.py Executable file → Normal file
View file

@ -10,7 +10,7 @@ class Attribute(BaseObject):
"""
"""
def __init__(self, name, label, description, value, advanced, uid, group):
def __init__(self, name, label, description, value, advanced, uid, group, enabled):
super(Attribute, self).__init__()
self._name = name
self._label = label
@ -19,6 +19,7 @@ class Attribute(BaseObject):
self._uid = uid
self._group = group
self._advanced = advanced
self._enabled = enabled
name = Property(str, lambda self: self._name, constant=True)
label = Property(str, lambda self: self._label, constant=True)
@ -27,6 +28,7 @@ class Attribute(BaseObject):
uid = Property(Variant, lambda self: self._uid, constant=True)
group = Property(str, lambda self: self._group, constant=True)
advanced = Property(bool, lambda self: self._advanced, constant=True)
enabled = Property(Variant, lambda self: self._enabled, constant=True)
type = Property(str, lambda self: self.__class__.__name__, constant=True)
def validateValue(self, value):
@ -53,13 +55,13 @@ class Attribute(BaseObject):
class ListAttribute(Attribute):
""" A list of Attributes """
def __init__(self, elementDesc, name, label, description, group='allParams', advanced=False, joinChar=' '):
def __init__(self, elementDesc, name, label, description, group='allParams', advanced=False, enabled=True, joinChar=' '):
"""
:param elementDesc: the Attribute description of elements to store in that list
"""
self._elementDesc = elementDesc
self._joinChar = joinChar
super(ListAttribute, self).__init__(name=name, label=label, description=description, value=[], uid=(), group=group, advanced=advanced)
super(ListAttribute, self).__init__(name=name, label=label, description=description, value=[], uid=(), group=group, advanced=advanced, enabled=enabled)
elementDesc = Property(Attribute, lambda self: self._elementDesc, constant=True)
uid = Property(Variant, lambda self: self.elementDesc.uid, constant=True)
@ -82,13 +84,13 @@ class ListAttribute(Attribute):
class GroupAttribute(Attribute):
""" A macro Attribute composed of several Attributes """
def __init__(self, groupDesc, name, label, description, group='allParams', advanced=False, joinChar=' '):
def __init__(self, groupDesc, name, label, description, group='allParams', advanced=False, enabled=True, joinChar=' '):
"""
:param groupDesc: the description of the Attributes composing this group
"""
self._groupDesc = groupDesc
self._joinChar = joinChar
super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, uid=(), group=group, advanced=advanced)
super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, uid=(), group=group, advanced=advanced, enabled=enabled)
groupDesc = Property(Variant, lambda self: self._groupDesc, constant=True)
@ -143,15 +145,15 @@ class GroupAttribute(Attribute):
class Param(Attribute):
"""
"""
def __init__(self, name, label, description, value, uid, group, advanced):
super(Param, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group, advanced, enabled):
super(Param, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
class File(Attribute):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False):
super(File, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, enabled=True):
super(File, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
def validateValue(self, value):
if not isinstance(value, pyCompatibility.basestring):
@ -162,8 +164,8 @@ class File(Attribute):
class BoolParam(Param):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False):
super(BoolParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, enabled=True):
super(BoolParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
def validateValue(self, value):
try:
@ -175,9 +177,9 @@ class BoolParam(Param):
class IntParam(Param):
"""
"""
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False):
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False, enabled=True):
self._range = range
super(IntParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
super(IntParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
def validateValue(self, value):
# handle unsigned int values that are translated to int by shiboken and may overflow
@ -194,9 +196,9 @@ class IntParam(Param):
class FloatParam(Param):
"""
"""
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False):
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False, enabled=True):
self._range = range
super(FloatParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
super(FloatParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
def validateValue(self, value):
try:
@ -210,13 +212,13 @@ class FloatParam(Param):
class ChoiceParam(Param):
"""
"""
def __init__(self, name, label, description, value, values, exclusive, uid, group='allParams', joinChar=' ', advanced=False):
def __init__(self, name, label, description, value, values, exclusive, uid, group='allParams', joinChar=' ', advanced=False, enabled=True):
assert values
self._values = values
self._exclusive = exclusive
self._joinChar = joinChar
self._valueType = type(self._values[0]) # cast to value type
super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
def conformValue(self, val):
""" Conform 'val' to the correct type and check for its validity """
@ -241,8 +243,8 @@ class ChoiceParam(Param):
class StringParam(Param):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, enabled=True):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)
def validateValue(self, value):
if not isinstance(value, pyCompatibility.basestring):

View file

@ -541,21 +541,22 @@ class BaseNode(BaseObject):
""" Compute node uids by combining associated attributes' uids. """
for uidIndex, associatedAttributes in self.attributesPerUid.items():
# uid is computed by hashing the sorted list of tuple (name, value) of all attributes impacting this uid
uidAttributes = [(a.getName(), a.uid(uidIndex)) for a in associatedAttributes]
uidAttributes = [(a.getName(), a.uid(uidIndex)) for a in associatedAttributes if a.enabled]
uidAttributes.sort()
self._uids[uidIndex] = hashValue(uidAttributes)
def _buildCmdVars(self):
def _buildAttributeCmdVars(cmdVars, name, attr):
if attr.attributeDesc.group is not None:
# if there is a valid command line "group"
v = attr.getValueStr()
cmdVars[name] = '--{name} {value}'.format(name=name, value=v)
cmdVars[name + 'Value'] = str(v)
if attr.enabled:
# if there is a valid command line "group"
v = attr.getValueStr()
cmdVars[name] = '--{name} {value}'.format(name=name, value=v)
cmdVars[name + 'Value'] = str(v)
if v:
cmdVars[attr.attributeDesc.group] = cmdVars.get(attr.attributeDesc.group, '') + \
' ' + cmdVars[name]
if v:
cmdVars[attr.attributeDesc.group] = cmdVars.get(attr.attributeDesc.group, '') + \
' ' + cmdVars[name]
elif isinstance(attr, GroupAttribute):
assert isinstance(attr.value, DictModel)
# if the GroupAttribute is not set in a single command line argument,
@ -678,6 +679,10 @@ class BaseNode(BaseObject):
"""
if self.nodeDesc:
self.nodeDesc.update(self)
for attr in self._attributes:
attr.updateInternals()
# Update chunks splitting
self._updateChunks()
# Retrieve current internal folder (if possible)

View file

@ -26,7 +26,7 @@ ListView {
model: attributes
delegate: Loader {
active: !object.desc.advanced || GraphEditorSettings.showAdvancedAttributes
active: object.enabled && (!object.desc.advanced || GraphEditorSettings.showAdvancedAttributes)
visible: active
height: item ? item.implicitHeight : -spacing // compensate for spacing if item is hidden