Revision control

Copy as Markdown

// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Shapes
import QQEMLib 1.0
NodeViewItem {
id: nodeViewItem
property bool initialized: false
readonly property color borderColor: Qt.lighter(mainView.backgroundColor1, 2.0)
readonly property color connectorColor: "#80d0d040"
function showAddNodeDialog(startNodeId, endNodeId) {
addNodeDialog.reset();
effectManager.updateAddNodeData();
addNodeDialog.startNodeId = startNodeId;
addNodeDialog.endNodeId = endNodeId;
addNodeDialog.open();
}
function showRenameNodeDialog() {
renameNodeDialog.open();
}
focus: true
Component.onCompleted: {
nodeViewItem.updateActiveNodesList();
effectManager.initialize();
}
Timer {
running: true
interval: 1
onTriggered: {
// Do the layout when views have correct sizes
layoutNodes(false);
initialized = true;
}
}
onDoubleClickNode: {
mainToolbar.setDesignMode(false);
}
onOpenDeleteNodeDialog: {
mainWindow.deleteNodeAction();
}
onOpenNodeContextMenu: {
nodeContextMenu.popup();
}
RenameNodeDialog {
id: renameNodeDialog
x: mainWindow.width * 0.5 - width * 0.5
y: mainWindow.height * 0.5 - height * 0.5
}
AddNodeDialog {
id: addNodeDialog
x: mainWindow.width * 0.5 - width * 0.5
y: mainWindow.height * 0.5 - height * 0.5
}
Image {
anchors.fill: parent
source: "images/nodeview_background.jpg"
}
// Render nodes
Repeater {
model: nodeViewItem.nodesModel
delegate: Rectangle {
width: model.width
height: model.height
x: model.x
y: model.y
border.color: model.selected ? highlightColor : borderColor
color: mainView.backgroundColor1
opacity: model.disabled ? 0.4 : 1.0
border.width: 2
radius: model.type > 1 ? 6 : height * 0.5
Text {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
width: model.width - 20
elide: Text.ElideRight
text: model.name
font.pixelSize: 14
opacity: model.disabled ? 0.5 : 1.0
color: mainView.foregroundColor2
}
Image {
id: disableIconButton
anchors.top: parent.top
anchors.topMargin: 2
anchors.left: parent.left
anchors.leftMargin: 6
width: 16
height: 16
mipmap: true
visible: model.type === 2
source: model.disabled ? "images/icon_visibility_off.png" : "images/icon_visibility_on.png"
opacity: model.disabled ? 1.0 : 0.2
MouseArea {
anchors.fill: parent
anchors.margins: -4
onClicked: {
model.disabled = !model.disabled;
nodeViewItem.updateActiveNodesList();
effectManager.bakeShaders(true);
}
}
}
// Connectors
Rectangle {
width: 10
height: 10
x: parent.width * 0.5 - width * 0.5
y: -height * 0.5
radius: width * 0.5
visible: model.type !== 0
border.width: 2
border.color: connectorColor
color: mainView.backgroundColor1
}
Rectangle {
width: 10
height: 10
x: parent.width * 0.5 - width * 0.5
y: parent.height - height * 0.5
radius: width * 0.5
visible: model.type !== 1
border.width: 2
border.color: connectorColor
color: mainView.backgroundColor1
}
}
}
// Render arrows between nodes
Repeater {
model: nodeViewItem.arrowsModel
delegate: Shape {
anchors.fill: parent
ShapePath {
strokeWidth: 2
strokeColor: connectorColor
capStyle: ShapePath.RoundCap
startX: model.startX
startY: model.startY
PathLine {
x: model.endX
y: model.endY
}
}
}
}
// Render '+' into arrows
Repeater {
model: nodeViewItem.arrowsModel
delegate: Rectangle {
property real arrowWidth: Math.sqrt(Math.pow(model.endX - model.startX, 2) + Math.pow(model.endY - model.startY, 2))
x: model.startX + (model.endX - model.startX) * 0.5 - width * 0.5
y: model.startY + (model.endY - model.startY) * 0.5 - height * 0.5
width: 20
height: 20
radius: width * 0.5
border.width: 1
color: mainView.backgroundColor1
border.color: highlightColor
visible: arrowWidth > 50
Rectangle {
width: 8
height: 2
anchors.centerIn: parent
color: mainView.foregroundColor2
}
Rectangle {
width: 2
height: 8
anchors.centerIn: parent
color: mainView.foregroundColor2
}
MouseArea {
anchors.fill: parent
onClicked: {
nodeViewItem.showAddNodeDialog(model.startNodeId, model.endNodeId);
}
}
Text {
anchors.left: parent.right
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 16
color: mainView.foregroundColor1
visible: nodeViewItem.nodeGraphComplete && nodeViewItem.arrowsModel.rowCount === 1
text: "Add Node"
}
}
}
// Add node button
Rectangle {
anchors.left: parent.left
anchors.leftMargin: 20
anchors.top: parent.top
anchors.topMargin: 20
width: 30
height: 30
radius: width * 0.5
border.width: 2
color: mainView.backgroundColor1
border.color: borderColor
Rectangle {
width: 8
height: 2
anchors.centerIn: parent
color: mainView.foregroundColor2
}
Rectangle {
width: 2
height: 8
anchors.centerIn: parent
color: mainView.foregroundColor2
}
MouseArea {
anchors.fill: parent
onClicked: {
nodeViewItem.showAddNodeDialog(-1, -1);
}
}
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.right
anchors.leftMargin: 10
font.pixelSize: 16
color: mainView.foregroundColor1
text: "Add Node"
}
}
// Active arrow user modifies
Shape {
anchors.fill: parent
visible: nodeViewItem.activeArrowEnabled
opacity: 0.4
ShapePath {
strokeWidth: 4
strokeColor: connectorColor
strokeStyle: ShapePath.DashLine
dashPattern: [2, 2]
capStyle: ShapePath.RoundCap
startX: nodeViewItem.activeArrowStartPoint.x
startY: nodeViewItem.activeArrowStartPoint.y
PathLine {
x: nodeViewItem.activeArrowEndPoint.x
y: nodeViewItem.activeArrowEndPoint.y
}
}
}
}