import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import Utils 1.0 Item { id: root property variant node property bool readOnly: false property color baseColor: defaultColor property color shadowColor: "black" readonly property bool isCompatibilityNode: node.hasOwnProperty("compatibilityIssue") readonly property color defaultColor: isCompatibilityNode ? "#444" : "#607D8B" property bool selected: false signal pressed(var mouse) signal doubleClicked(var mouse) signal moved(var position) signal attributePinCreated(var attribute, var pin) signal attributePinDeleted(var attribute, var pin) implicitHeight: body.height objectName: node.name SystemPalette { id: activePalette } // initialize position with node coordinates x: root.node.x y: root.node.y Connections { target: root.node // update x,y when node position changes onPositionChanged: { root.x = root.node.x root.y = root.node.y } } MouseArea { anchors.fill: parent drag.target: parent // small drag threshold to avoid moving the node by mistake drag.threshold: 2 hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: root.pressed(mouse) onDoubleClicked: root.doubleClicked(mouse) drag.onActiveChanged: { if(!drag.active) root.moved(Qt.point(root.x, root.y)) } } // Selection border Rectangle { anchors.fill: parent anchors.margins: -border.width visible: root.selected border.width: 2.5 border.color: activePalette.highlight opacity: 0.9 color: "transparent" } Rectangle { id: background anchors.fill: parent color: activePalette.base layer.enabled: true layer.effect: DropShadow { radius: 2; color: shadowColor } } Column { id: body width: parent.width Label { width: parent.width horizontalAlignment: Text.AlignHCenter padding: 4 text: node.label color: "#EEE" font.pointSize: 8 background: Rectangle { color: root.baseColor } } // Node Chunks NodeChunks { defaultColor: Qt.darker(baseColor, 1.3) implicitHeight: 3 width: parent.width model: node.chunks } Item { width: 1; height: 2} Item { width: parent.width + 6 height: childrenRect.height anchors.horizontalCenter: parent.horizontalCenter Column { id: inputs width: parent.width / 2 spacing: 1 Repeater { model: node.attributes delegate: Loader { active: !object.isOutput && object.type == "File" || (object.type == "ListAttribute" && object.desc.elementDesc.type == "File") // TODO: review this width: inputs.width sourceComponent: AttributePin { id: inPin nodeItem: root attribute: object readOnly: root.readOnly Component.onCompleted: attributePinCreated(attribute, inPin) Component.onDestruction: attributePinDeleted(attribute, inPin) onPressed: root.pressed(mouse) onChildPinCreated: attributePinCreated(childAttribute, inPin) onChildPinDeleted: attributePinDeleted(childAttribute, inPin) } } } } Column { id: outputs width: parent.width / 2 anchors.right: parent.right spacing: 1 Repeater { model: node.attributes delegate: Loader { active: object.isOutput anchors.right: parent.right width: outputs.width sourceComponent: AttributePin { id: outPin nodeItem: root attribute: object readOnly: root.readOnly onPressed: root.pressed(mouse) Component.onCompleted: attributePinCreated(object, outPin) Component.onDestruction: attributePinDeleted(attribute, outPin) } } } } } Item { width: 1; height: 2} } // CompatibilityBadge icon for CompatibilityNodes Loader { active: root.isCompatibilityNode anchors { right: parent.right top: parent.top margins: -4 } sourceComponent: CompatibilityBadge { sourceComponent: iconDelegate canUpgrade: root.node.canUpgrade issueDetails: root.node.issueDetails } } }