Skip to content

Commit

Permalink
[ui] GraphEditor: only connect compatible attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiencastan committed Dec 28, 2020
1 parent 85044e5 commit 73902e4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 10 deletions.
8 changes: 8 additions & 0 deletions meshroom/core/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ def getName(self):
def getType(self):
return self.attributeDesc.__class__.__name__

def getBaseType(self):
return self.getType()

def getLabel(self):
return self._label

Expand Down Expand Up @@ -258,6 +261,7 @@ def updateInternals(self):
fullName = Property(str, getFullName, constant=True)
label = Property(str, getLabel, constant=True)
type = Property(str, getType, constant=True)
baseType = Property(str, getType, constant=True)
desc = Property(desc.Attribute, lambda self: self.attributeDesc, constant=True)
valueChanged = Signal()
value = Property(Variant, _get_value, _set_value, notify=valueChanged)
Expand Down Expand Up @@ -292,6 +296,9 @@ def __init__(self, node, attributeDesc, isOutput, root=None, parent=None):
def __len__(self):
return len(self._value)

def getBaseType(self):
return self.attributeDesc.elementDesc.__class__.__name__

def at(self, idx):
""" Returns child attribute at index 'idx' """
# implement 'at' rather than '__getitem__'
Expand Down Expand Up @@ -396,6 +403,7 @@ def updateInternals(self):
# Override value property setter
value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged)
isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged)
baseType = Property(str, getBaseType, constant=True)


class GroupAttribute(Attribute):
Expand Down
3 changes: 3 additions & 0 deletions meshroom/ui/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ def __init__(self, graph, src, dst, parent=None):
self.dstAttr = dst.getFullName()
self.setText("Connect '{}'->'{}'".format(self.srcAttr, self.dstAttr))

if src.baseType != dst.baseType:
raise ValueError("Attribute types are not compatible and cannot be connected: '{}'({})->'{}'({})".format(self.srcAttr, src.baseType, self.dstAttr, dst.baseType))

def redoImpl(self):
self.graph.addEdge(self.graph.attribute(self.srcAttr), self.graph.attribute(self.dstAttr))
return True
Expand Down
24 changes: 14 additions & 10 deletions meshroom/ui/qml/GraphEditor/AttributePin.qml
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,18 @@ RowLayout {

keys: [inputDragTarget.objectName]
onEntered: {
// Filter drops:
if( root.readOnly
|| drag.source.objectName != inputDragTarget.objectName // not an edge connector
|| drag.source.nodeItem == inputDragTarget.nodeItem // connection between attributes of the same node
|| inputDragTarget.attribute.isLink // already connected attribute
|| (drag.source.isList && !inputDragTarget.isList) // connection between a list and a simple attribute
|| (drag.source.isList && childrenRepeater.count) // source/target are lists but target already has children
|| drag.source.connectorType == "input"
)
// Check if attributes are compatible to create a valid connection
if( root.readOnly // cannot connect on a read-only attribute
|| drag.source.objectName != inputDragTarget.objectName // not an edge connector
|| drag.source.baseType != inputDragTarget.baseType // not the same base type
|| drag.source.nodeItem == inputDragTarget.nodeItem // connection between attributes of the same node
|| inputDragTarget.attribute.isLink // already connected attribute
|| (drag.source.isList && !inputDragTarget.isList) // connection between a list and a simple attribute
|| (drag.source.isList && childrenRepeater.count) // source/target are lists but target already has children
|| drag.source.connectorType == "input" // refuse to connect an "input pin" on another one (input attr can be connected to input attr, but not the graphical pin)
)
{
// Refuse attributes connection
drag.accepted = false
}
inputDropArea.acceptableDrop = drag.accepted
Expand All @@ -112,7 +114,8 @@ RowLayout {
readonly property string connectorType: "input"
readonly property alias attribute: root.attribute
readonly property alias nodeItem: root.nodeItem
readonly property bool isOutput: attribute && attribute.isOutput
readonly property bool isOutput: attribute.isOutput
readonly property string baseType: attribute.baseType
readonly property alias isList: root.isList
property bool dragAccepted: false
anchors.verticalCenter: parent.verticalCenter
Expand Down Expand Up @@ -249,6 +252,7 @@ RowLayout {
readonly property alias nodeItem: root.nodeItem
readonly property bool isOutput: attribute.isOutput
readonly property alias isList: root.isList
readonly property string baseType: attribute.baseType
property bool dropAccepted: false
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Expand Down

0 comments on commit 73902e4

Please sign in to comment.