From a499f4712b53528e87372dcc43121931a651a414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Tue, 17 Sep 2024 17:44:39 +0200 Subject: [PATCH 1/7] [core] Attribute: Add notion of depth for attributes with parents For attributes in `GroupAttribute` and `ListAttribute`, the notion of parent attribute exists through the `root` property. As a parent can itself have a parent, the `depth` property describes how many levels there are between the attribute and the root level. A value of 0 means that the attribute is at the root level, and it increases as it gets deeper. --- meshroom/core/attribute.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index 0dd9e079f4..f6b46f3782 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -61,6 +61,13 @@ def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): self._description = attributeDesc.description self._invalidate = False if self._isOutput else attributeDesc.invalidate + self._depth = 0 + if root is not None: + current = self + while current.root is not None: + self._depth += 1 + current = current.root + # invalidation value for output attributes self._invalidationValue = "" @@ -77,6 +84,9 @@ def node(self): def root(self): return self._root() if self._root else None + def getDepth(self): + return self._depth + def getName(self): """ Attribute name """ return self._name @@ -454,6 +464,7 @@ def updateInternals(self): validValueChanged = Signal() validValue = Property(bool, getValidValue, setValidValue, notify=validValueChanged) root = Property(BaseObject, root.fget, constant=True) + depth = Property(int, getDepth, constant=True) def raiseIfLink(func): From e67e7898fa7b29a928aa68d3d753f41ba37b3b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Thu, 19 Sep 2024 12:00:39 +0200 Subject: [PATCH 2/7] [core] Attribute: Add a `flattenedChildren` property `flattenedChildren` returns the list of all the attributes that refer to this attribute as their parent (either direct or indirect) through the `root` property. The search for the children attributes is recursive and alllows to retrieve at once all the nested attributes, independently from their level. At the moment, only `ListAttribute` and `GroupAttribute` will return a non-empty list of flattened children attributes. --- meshroom/core/attribute.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index f6b46f3782..a1e4eaa81d 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -423,6 +423,33 @@ def updateInternals(self): # Emit if the enable status has changed self.setEnabled(self.getEnabled()) + def getFlattenedChildren(self): + """ Return a list of all the attributes that refer to this instance as their parent through + the 'root' property. If no such attribute exist, return an empty list. The depth difference is not + taken into account in the list, which is thus always flat. """ + attributes = ListModel(parent=self) + if isinstance(self._value, str): + # String/File attributes are iterable but cannot have children: immediately rule that case out + return attributes + + try: + # If self._value is not iterable, then it is not an attribute that can have children + iter(self._value) + except TypeError: + return attributes + + for attribute in self._value: + if not isinstance(attribute, Attribute): + # Handle ChoiceParam values, which contained in a list hence iterable, but are string + continue + attributes.add(attribute) + if isinstance(attribute, ListAttribute) or isinstance(attribute, GroupAttribute): + # Handle nested ListAttributes and GroupAttributes + flattened = attribute.getFlattenedChildren() + for i in flattened: + attributes.add(i) + return attributes + name = Property(str, getName, constant=True) fullName = Property(str, getFullName, constant=True) fullNameToNode = Property(str, getFullNameToNode, constant=True) @@ -465,6 +492,7 @@ def updateInternals(self): validValue = Property(bool, getValidValue, setValidValue, notify=validValueChanged) root = Property(BaseObject, root.fget, constant=True) depth = Property(int, getDepth, constant=True) + flattenedChildren = Property(BaseObject, getFlattenedChildren, constant=True) def raiseIfLink(func): From a5958a65941b732ad55c6807ad89a158a12f0fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 23 Sep 2024 18:54:14 +0200 Subject: [PATCH 3/7] [core] Correctly match descriptions for connected attributes within groups --- meshroom/core/attribute.py | 2 +- meshroom/core/node.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index a1e4eaa81d..c970c4d926 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -356,7 +356,7 @@ def _applyExpr(self): elif self.isInput and Attribute.isLinkExpression(v): # value is a link to another attribute link = v[1:-1] - linkNode, linkAttr = link.split('.') + linkNode, linkAttr = link.split('.', 1) try: g.addEdge(g.node(linkNode).attribute(linkAttr), self) except KeyError as err: diff --git a/meshroom/core/node.py b/meshroom/core/node.py index 2c9466b879..785642a20f 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -1678,9 +1678,18 @@ def attributeDescFromName(refAttributes, name, value, strict=True): attrDesc = next((d for d in refAttributes if d.name == name), None) if attrDesc is None: return None + # We have found a description, and we still need to # check if the value matches the attribute description. - # + + # If it is a GroupAttribute, all attributes within the group should be matched individually + # so that links that can be correctly evaluated + if isinstance(attrDesc, desc.GroupAttribute): + for k, v in value.items(): + if CompatibilityNode.attributeDescFromName(attrDesc.groupDesc, k, v, strict=True) is None: + return None + return attrDesc + # If it is a serialized link expression (no proper value to set/evaluate) if Attribute.isLinkExpression(value): return attrDesc From 257e91e06724c0f3309f3ffb04d200c30e56a9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Fri, 20 Sep 2024 15:04:07 +0200 Subject: [PATCH 4/7] [core] Attribute: Parent's `exposed` property takes precedence over description's The `exposed` property, which determines whether the attribute is displayed on the upper part of the node in the Graph Editor, is set for each attribute individually in their node's description. If an attribute has a parent (meaning it depends on a `GroupAttribute` or a `ListAttribute`) whose `exposed` property value differs, it does not make sense to display it separately from it. The attribute's `exposed` should align with its parent's. --- meshroom/core/attribute.py | 7 +++++++ meshroom/ui/qml/GraphEditor/Node.qml | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index c970c4d926..ff353a3de1 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -61,11 +61,14 @@ def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): self._description = attributeDesc.description self._invalidate = False if self._isOutput else attributeDesc.invalidate + self._exposed = attributeDesc.exposed self._depth = 0 if root is not None: current = self while current.root is not None: self._depth += 1 + if current.root.exposed != self._exposed: + self._exposed = current.root.exposed current = current.root # invalidation value for output attributes @@ -87,6 +90,9 @@ def root(self): def getDepth(self): return self._depth + def getExposed(self): + return self._exposed + def getName(self): """ Attribute name """ return self._name @@ -462,6 +468,7 @@ def getFlattenedChildren(self): type = Property(str, getType, constant=True) baseType = Property(str, getType, constant=True) isReadOnly = Property(bool, _isReadOnly, constant=True) + exposed = Property(bool, getExposed, constant=True) # Description of the attribute descriptionChanged = Signal() diff --git a/meshroom/ui/qml/GraphEditor/Node.qml b/meshroom/ui/qml/GraphEditor/Node.qml index 9a8bb05a17..b5a206873e 100755 --- a/meshroom/ui/qml/GraphEditor/Node.qml +++ b/meshroom/ui/qml/GraphEditor/Node.qml @@ -434,7 +434,7 @@ Item { delegate: Loader { id: inputLoader - active: !object.isOutput && object.desc.exposed && object.desc.visible + active: !object.isOutput && object.exposed && object.desc.visible visible: Boolean(object.enabled) width: inputs.width @@ -494,7 +494,7 @@ Item { model: node ? node.attributes : undefined delegate: Loader { id: paramLoader - active: !object.isOutput && !object.desc.exposed && object.desc.visible + active: !object.isOutput && !object.exposed && object.desc.visible visible: Boolean(object.enabled || object.isLink || object.hasOutputConnections) property bool isFullyActive: Boolean(m.displayParams || object.isLink || object.hasOutputConnections) width: parent.width From 1c7482a5da9030643f235710feb4df577e1e9c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 23 Sep 2024 12:21:58 +0200 Subject: [PATCH 5/7] [GraphEditor] Allow to display and connect attributes within `GroupAttribute` --- meshroom/ui/qml/GraphEditor/AttributePin.qml | 61 +++++-- meshroom/ui/qml/GraphEditor/Node.qml | 167 +++++++++++++++++-- 2 files changed, 194 insertions(+), 34 deletions(-) diff --git a/meshroom/ui/qml/GraphEditor/AttributePin.qml b/meshroom/ui/qml/GraphEditor/AttributePin.qml index a4e710822f..6e160f48f0 100755 --- a/meshroom/ui/qml/GraphEditor/AttributePin.qml +++ b/meshroom/ui/qml/GraphEditor/AttributePin.qml @@ -12,6 +12,7 @@ RowLayout { property var nodeItem property var attribute + property bool expanded: false property bool readOnly: false /// Whether to display an output pin for input attribute property bool displayOutputPinForInput: true @@ -24,6 +25,8 @@ RowLayout { outputAnchor.y + outputAnchor.height / 2) readonly property bool isList: attribute && attribute.type === "ListAttribute" + readonly property bool isGroup: attribute && attribute.type === "GroupAttribute" + readonly property bool isChild: attribute && attribute.root signal childPinCreated(var childAttribute, var pin) signal childPinDeleted(var childAttribute, var pin) @@ -31,6 +34,8 @@ RowLayout { signal pressed(var mouse) signal edgeAboutToBeRemoved(var input) + signal clicked() + objectName: attribute ? attribute.name + "." : "" layoutDirection: Qt.LeftToRight spacing: 3 @@ -43,14 +48,30 @@ RowLayout { x: nameLabel.x } - function updatePin(isSrc, isVisible) - { + function updatePin(isSrc, isVisible) { if (isSrc) { innerOutputAnchor.linkEnabled = isVisible } else { innerInputAnchor.linkEnabled = isVisible } + } + + function updateLabel() { + var label = "" + var expandedGroup = expanded ? "-" : "+" + if (attribute && attribute.label !== undefined) { + label = attribute.label + if (isGroup && attribute.isOutput) { + label = label + " " + expandedGroup + } else if (isGroup && !attribute.isOutput) { + label = expandedGroup + " " + label + } + } + return label + } + onExpandedChanged: { + nameLabel.text = updateLabel() } // Instantiate empty Items for each child attribute @@ -160,17 +181,16 @@ RowLayout { drag.smoothed: false enabled: !root.readOnly anchors.fill: parent - // use the same negative margins as DropArea to ease pin selection + // Use the same negative margins as DropArea to ease pin selection anchors.margins: inputDropArea.anchors.margins anchors.leftMargin: inputDropArea.anchors.leftMargin anchors.rightMargin: inputDropArea.anchors.rightMargin - onPressed: { - root.pressed(mouse) - } - onReleased: { - inputDragTarget.Drag.drop() - } - hoverEnabled: true + + onPressed: root.pressed(mouse) + onReleased: inputDragTarget.Drag.drop() + onClicked: root.clicked() + + hoverEnabled: root.visible } Edge { @@ -186,7 +206,6 @@ RowLayout { } - // Attribute name Item { id: nameContainer @@ -199,17 +218,22 @@ RowLayout { id: nameLabel enabled: !root.readOnly + visible: true property bool hovered: (inputConnectMA.containsMouse || inputConnectMA.drag.active || inputDropArea.containsDrag || outputConnectMA.containsMouse || outputConnectMA.drag.active || outputDropArea.containsDrag) - text: (attribute && attribute.label) !== undefined ? attribute.label : "" + text: root.updateLabel() elide: hovered ? Text.ElideNone : Text.ElideMiddle width: hovered ? contentWidth : parent.width font.pointSize: 7 + font.italic: isChild ? true : false horizontalAlignment: attribute && attribute.isOutput ? Text.AlignRight : Text.AlignLeft anchors.right: attribute && attribute.isOutput ? parent.right : undefined rightPadding: 0 color: { - if ((object.hasOutputConnections || object.isLink) && !object.enabled) return Colors.lightgrey - return hovered ? palette.highlight : palette.text + if ((object.hasOutputConnections || object.isLink) && !object.enabled) + return Colors.lightgrey + else if (hovered) + return palette.highlight + return palette.text } } } @@ -236,8 +260,8 @@ RowLayout { anchors.fill: parent anchors.margins: 2 color: { - if (object.enabled && (outputConnectMA.containsMouse || outputConnectMA.drag.active || - (outputDropArea.containsDrag && outputDropArea.acceptableDrop))) + if (modelData.enabled && (outputConnectMA.containsMouse || outputConnectMA.drag.active || + (outputDropArea.containsDrag && outputDropArea.acceptableDrop))) return Colors.sysPalette.highlight return Colors.sysPalette.text } @@ -309,15 +333,16 @@ RowLayout { // Move the edge's tip straight to the the current mouse position instead of waiting after the drag operation has started drag.smoothed: false anchors.fill: parent - // use the same negative margins as DropArea to ease pin selection + // Use the same negative margins as DropArea to ease pin selection anchors.margins: outputDropArea.anchors.margins anchors.leftMargin: outputDropArea.anchors.leftMargin anchors.rightMargin: outputDropArea.anchors.rightMargin onPressed: root.pressed(mouse) onReleased: outputDragTarget.Drag.drop() + onClicked: root.clicked() - hoverEnabled: true + hoverEnabled: root.visible } Edge { diff --git a/meshroom/ui/qml/GraphEditor/Node.qml b/meshroom/ui/qml/GraphEditor/Node.qml index b5a206873e..f5cd7ca198 100755 --- a/meshroom/ui/qml/GraphEditor/Node.qml +++ b/meshroom/ui/qml/GraphEditor/Node.qml @@ -115,6 +115,54 @@ Item { return str } + function updateChildPin(attribute, parentPins, pin) { + /* + * Update the pin of a child attribute: if the attribute is enabled and its parent is a GroupAttribute, + * the visibility is determined based on the parent pin's "expanded" state, using the "parentPins" map to + * access the status. + * If the current pin is also a GroupAttribute and is expanded while its newly "visible" state is false, + * it is reset. + */ + if (Boolean(attribute.enabled)) { + // If the parent's a GroupAttribute, use status of the parent's pin to determine visibility + if (attribute.root && attribute.root.type === "GroupAttribute") { + var visible = Boolean(parentPins.get(attribute.root.name)) + if (!visible && parentPins.has(attribute.name) && parentPins.get(attribute.name) === true) { + parentPins.set(attribute.name, false) + pin.expanded = false + } + return visible + } + return true + } + return false + } + + function generateAttributesModel(isOutput, parentPins) { + if (!node) + return undefined + + const attributes = [] + for (let i = 0; i < node.attributes.count; ++i) { + let attr = node.attributes.at(i) + if (attr.isOutput == isOutput) { + attributes.push(attr) + if (attr.type === "GroupAttribute") { + parentPins.set(attr.name, false) + } + + for (let j = 0; j < attr.flattenedChildren.count; ++j) { + attributes.push(attr.flattenedChildren.at(j)) + if (attr.flattenedChildren.at(j).type === "GroupAttribute") { + parentPins.set(attr.flattenedChildren.at(j).name, false) + } + } + } + } + + return attributes + } + // Main Layout MouseArea { id: mouseArea @@ -394,25 +442,52 @@ Item { width: parent.width spacing: 3 + property var parentPins: new Map() + signal parentPinsUpdated() + Repeater { - model: node ? node.attributes : undefined + model: generateAttributesModel(true, outputs.parentPins) // isOutput = true delegate: Loader { id: outputLoader - active: Boolean(object.isOutput && object.desc.visible) - visible: Boolean(object.enabled || object.hasOutputConnections) + active: Boolean(modelData.isOutput && modelData.desc.visible) + + visible: { + if (Boolean(modelData.enabled || modelData.hasOutputConnections)) { + if (modelData.root && modelData.root.type === "GroupAttribute") { + return Boolean(outputs.parentPins.get(modelData.root.name)) + } + return true + } + return false + } anchors.right: parent.right width: outputs.width + Connections { + target: outputs + + function onParentPinsUpdated() { + visible = updateChildPin(modelData, outputs.parentPins, outputLoader.item) + } + } + sourceComponent: AttributePin { id: outPin nodeItem: root - attribute: object + attribute: modelData property real globalX: root.x + nodeAttributes.x + outputs.x + outputLoader.x + outPin.x property real globalY: root.y + nodeAttributes.y + outputs.y + outputLoader.y + outPin.y onPressed: root.pressed(mouse) + onClicked: { + expanded = !expanded + if (outputs.parentPins.has(modelData.name)) { + outputs.parentPins.set(modelData.name, expanded) + outputs.parentPinsUpdated() + } + } onEdgeAboutToBeRemoved: root.edgeAboutToBeRemoved(input) Component.onCompleted: attributePinCreated(attribute, outPin) @@ -429,27 +504,55 @@ Item { width: parent.width spacing: 3 + property var parentPins: new Map() + signal parentPinsUpdated() + Repeater { - model: node ? node.attributes : undefined + model: generateAttributesModel(false, inputs.parentPins) // isOutput = false delegate: Loader { id: inputLoader - active: !object.isOutput && object.exposed && object.desc.visible - visible: Boolean(object.enabled) + active: !modelData.isOutput && modelData.exposed && modelData.desc.visible + visible: { + if (Boolean(modelData.enabled)) { + if (modelData.root && modelData.root.type === "GroupAttribute") { + return Boolean(inputs.parentPins.get(modelData.root.name)) + } + return true + } + return false + } width: inputs.width + Connections { + target: inputs + + function onParentPinsUpdated() { + visible = updateChildPin(modelData, inputs.parentPins, inputLoader.item) + } + } + sourceComponent: AttributePin { id: inPin nodeItem: root - attribute: object + attribute: modelData property real globalX: root.x + nodeAttributes.x + inputs.x + inputLoader.x + inPin.x property real globalY: root.y + nodeAttributes.y + inputs.y + inputLoader.y + inPin.y - readOnly: root.readOnly || object.isReadOnly + readOnly: Boolean(root.readOnly || modelData.isReadOnly) Component.onCompleted: attributePinCreated(attribute, inPin) Component.onDestruction: attributePinDeleted(attribute, inPin) + onPressed: root.pressed(mouse) + onClicked: { + expanded = !expanded + if (inputs.parentPins.has(modelData.name)) { + inputs.parentPins.set(modelData.name, expanded) + inputs.parentPinsUpdated() + } + } + onEdgeAboutToBeRemoved: root.edgeAboutToBeRemoved(input) onChildPinCreated: attributePinCreated(childAttribute, inPin) onChildPinDeleted: attributePinDeleted(childAttribute, inPin) @@ -489,30 +592,62 @@ Item { id: inputParams width: parent.width spacing: 3 + + property var parentPins: new Map() + signal parentPinsUpdated() + Repeater { - id: inputParamsRepeater - model: node ? node.attributes : undefined + model: generateAttributesModel(false, inputParams.parentPins) // isOutput = false + delegate: Loader { id: paramLoader - active: !object.isOutput && !object.exposed && object.desc.visible - visible: Boolean(object.enabled || object.isLink || object.hasOutputConnections) - property bool isFullyActive: Boolean(m.displayParams || object.isLink || object.hasOutputConnections) + active: !modelData.isOutput && !modelData.exposed && modelData.desc.visible + visible: { + if (Boolean(modelData.enabled || modelData.isLink || modelData.hasOutputConnections)) { + if (modelData.root && modelData.root.type === "GroupAttribute") { + return Boolean(inputParams.parentPins.get(modelData.root.name)) + active: !modelData.isOutput && modelData.desc.exposed && modelData.desc.visible } + return true + } + return false + } + property bool isFullyActive: Boolean(m.displayParams || modelData.isLink || modelData.hasOutputConnections) width: parent.width + Connections { + target: inputParams + + function onParentPinsUpdated() { + visible = updateChildPin(modelData, inputParams.parentPins, paramLoader.item) + } + } + sourceComponent: AttributePin { id: inParamsPin nodeItem: root + attribute: modelData + property real globalX: root.x + nodeAttributes.x + inputParamsRect.x + paramLoader.x + inParamsPin.x property real globalY: root.y + nodeAttributes.y + inputParamsRect.y + paramLoader.y + inParamsPin.y height: isFullyActive ? childrenRect.height : 0 Behavior on height { PropertyAnimation {easing.type: Easing.Linear} } visible: (height == childrenRect.height) - attribute: object - readOnly: Boolean(root.readOnly || object.isReadOnly) + + readOnly: Boolean(root.readOnly || modelData.isReadOnly) Component.onCompleted: attributePinCreated(attribute, inParamsPin) Component.onDestruction: attributePinDeleted(attribute, inParamsPin) + onPressed: root.pressed(mouse) + + onClicked: { + expanded = !expanded + if (inputParams.parentPins.has(modelData.name)) { + inputParams.parentPins.set(modelData.name, expanded) + inputParams.parentPinsUpdated() + } + } + onEdgeAboutToBeRemoved: root.edgeAboutToBeRemoved(input) onChildPinCreated: attributePinCreated(childAttribute, inParamsPin) onChildPinDeleted: attributePinDeleted(childAttribute, inParamsPin) From ed4dc3fea9a517498b9a27a159c0763f249a52f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 23 Sep 2024 19:02:34 +0200 Subject: [PATCH 6/7] [ui] Graph: `canExpandForLoop`: Ensure all checks are performed on a `ListAttribute` --- meshroom/ui/graph.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meshroom/ui/graph.py b/meshroom/ui/graph.py index 448f25484a..b55079bc28 100644 --- a/meshroom/ui/graph.py +++ b/meshroom/ui/graph.py @@ -753,7 +753,8 @@ def duplicateNodesFrom(self, nodes): def canExpandForLoop(self, currentEdge): """ Check if the list attribute can be expanded by looking at all the edges connected to it. """ listAttribute = currentEdge.src.root - if not listAttribute: + # Check that the parent is indeed a ListAttribute (it could be a GroupAttribute, for instance) + if not listAttribute or not isinstance(listAttribute, ListAttribute): return False srcIndex = listAttribute.index(currentEdge.src) allSrc = [e.src for e in self._graph.edges.values()] From 0cdfd8b640dc58a4cb3b89b47ecfdb0cd4e7864b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Candice=20Bent=C3=A9jac?= Date: Mon, 23 Sep 2024 19:19:36 +0200 Subject: [PATCH 7/7] [GraphEditor] Refer to an attribute's parent in its tooltip If an attribute belongs to a `GroupAttribute` or a `ListAttribute`, it has a parent, and its full name is "parentName.attributeName". Instead of displaying only "attributeName" in the tooltip, this commit now displays "parentName.attributeName" to ensure that the link is obvious. --- meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml | 6 ++++-- meshroom/ui/qml/GraphEditor/AttributePin.qml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml index d0942e2c6e..8d426326ed 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml @@ -29,12 +29,14 @@ RowLayout { function updateAttributeLabel() { background.color = attribute.validValue ? Qt.darker(palette.window, 1.1) : Qt.darker(Colors.red, 1.5) + console.warn("about to enter if") if (attribute.desc) { var tooltip = "" if (!attribute.validValue && attribute.desc.errorMessage !== "") tooltip += "Error: " + Format.plainToHtml(attribute.desc.errorMessage) + "

" - tooltip += " " + attribute.desc.name + ": " + attribute.type + "
" + Format.plainToHtml(attribute.desc.description) + tooltip += " " + attribute.fullName + ": " + attribute.type + "
" + Format.plainToHtml(attribute.desc.description) + console.warn(attribute.fullName) parameterTooltip.text = tooltip } } @@ -81,7 +83,7 @@ RowLayout { var tooltip = "" if (!object.validValue && object.desc.errorMessage !== "") tooltip += "Error: " + Format.plainToHtml(object.desc.errorMessage) + "

" - tooltip += "" + object.desc.name + ": " + attribute.type + "
" + Format.plainToHtml(object.description) + tooltip += "" + object.fullName + ": " + attribute.type + "
" + Format.plainToHtml(object.description) return tooltip } visible: parameterMA.containsMouse diff --git a/meshroom/ui/qml/GraphEditor/AttributePin.qml b/meshroom/ui/qml/GraphEditor/AttributePin.qml index 6e160f48f0..a02f49b19c 100755 --- a/meshroom/ui/qml/GraphEditor/AttributePin.qml +++ b/meshroom/ui/qml/GraphEditor/AttributePin.qml @@ -41,7 +41,7 @@ RowLayout { spacing: 3 ToolTip { - text: attribute.name + ": " + attribute.type + text: attribute.fullName + ": " + attribute.type visible: nameLabel.hovered y: nameLabel.y + nameLabel.height