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.Controls
CustomPopup {
id: rootItem
property int startNodeId: -1
property int endNodeId: -1
property string selectedNodeFile
property string selectedNodeName
property string selectedNodeDescription
property string selectedNodeRequires
property var selectedNodeProperties: []
property bool selectedNodeCanBeAdded: true
property real showHideAnimationSpeed: 400
// All currently open node groups
property var openGroups: []
function reset() {
startNodeId = -1;
endNodeId = -1;
selectedNodeFile = "";
selectedNodeName = "";
selectedNodeDescription = "";
selectedNodeRequires = "";
selectedNodeProperties = [];
selectedNodeCanBeAdded = true;
}
function addSelectedNode() {
effectManager.addEffectNode(selectedNodeFile, rootItem.startNodeId, rootItem.endNodeId);
rootItem.close();
}
modal: true
width: 700
height: 500
padding: 10
Text {
id: dialogTitle
anchors.horizontalCenter: parent.horizontalCenter
text: "Add Effect Node"
font.pixelSize: 16
color: mainView.foregroundColor2
}
Row {
anchors.top: dialogTitle.bottom
anchors.topMargin: 10
anchors.bottom: buttonBar.top
anchors.bottomMargin: 10
width: parent.width
Component {
id: sectionHeading
Item {
required property string section
readonly property bool show: openGroups.includes(section)
width: effectsListView.width - scrollBar.width - 5
height: 40
Rectangle {
anchors.fill: parent
anchors.margins: 2
color: mainView.backgroundColor2
border.width: 1
border.color: mainView.foregroundColor1
}
Image {
x: 10
source: "images/icon_arrow.png"
anchors.verticalCenter: parent.verticalCenter
rotation: show ? 90 : 0
scale: 0.5
Behavior on rotation {
NumberAnimation {
duration: showHideAnimationSpeed
easing.type: Easing.InOutQuad
}
}
}
Text {
anchors.verticalCenter: parent.verticalCenter
x: 30
color: mainView.foregroundColor2
font.bold: true
font.pixelSize: 12
text: parent.section
font.capitalization: Font.AllUppercase
}
MouseArea {
anchors.fill: parent
onClicked: {
// Show/hide the group
const index = openGroups.indexOf(section);
if (index > -1)
openGroups.splice(index, 1);
else
openGroups.push(section);
// Triggering manually required for array properties
// so 'show' is updated.
openGroupsChanged();
effectManager.showHideAddNodeGroup(parent.section, show);
}
}
}
}
ListView {
id: effectsListView
width: parent.width * 0.35
height: parent.height
model: effectManager.addNodeModel
clip: true
cacheBuffer: 10000
ScrollBar.vertical: ScrollBar {
id: scrollBar
policy: ScrollBar.AlwaysOn
}
section.property: "group"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
delegate: Item {
property real showAnimated: model.show
x: 2
width: effectsListView.width - scrollBar.width - 9
height: showAnimated * 30
visible: opacity
opacity: showAnimated
Behavior on showAnimated {
NumberAnimation {
duration: showHideAnimationSpeed
easing.type: Easing.InOutQuad
}
}
Rectangle {
anchors.fill: parent
color: mainView.backgroundColor1
border.color: (selectedNodeFile === model.file) ? highlightColor : "transparent"
border.width: 2
}
Text {
anchors.verticalCenter: parent.verticalCenter
width: parent.width
horizontalAlignment: Text.AlignHCenter
text: model.name
color: mainView.foregroundColor2
font.pixelSize: 14
elide: Text.ElideRight
}
Image {
anchors.right: parent.right
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
height: parent.height * 0.4
width: height
source: "images/icon_requires.png"
mipmap: true
visible: model.requires !== ""
opacity: 0.2
MouseArea {
id: requiresIconMouseArea
anchors.fill: parent
hoverEnabled: true
}
ToolTip {
parent: parent
visible: requiresIconMouseArea.containsMouse
delay: 1000
text: "Requires: " + model.requires
}
}
MouseArea {
anchors.fill: parent
onClicked: {
selectedNodeName = model.name;
selectedNodeFile = model.file;
selectedNodeDescription = model.description;
selectedNodeRequires = model.requires;
selectedNodeProperties = model.properties;
selectedNodeCanBeAdded = model.canBeAdded;
}
onDoubleClicked: {
if (model.canBeAdded)
addSelectedNode();
}
}
}
BusyIndicator {
id: refreshNodesIndicator
anchors.centerIn: parent
opacity: 0.0
running: opacity > 0
visible: running
function show() {
nodesLoadingIndicatorAnimation.restart();
}
SequentialAnimation {
id: nodesLoadingIndicatorAnimation
NumberAnimation {
target: refreshNodesIndicator
property: "opacity"
to: 1.0
duration: 250
easing.type: Easing.InOutQuad
}
PauseAnimation {
duration: 500
}
NumberAnimation {
target: refreshNodesIndicator
property: "opacity"
to: 0.0
duration: 250
easing.type: Easing.InOutQuad
}
}
}
}
Flickable {
id: nodeInfoFlickable
readonly property int padding: 10
width: parent.width - effectsListView.width
height: parent.height
contentHeight: nodeInfo.height
clip: true
ScrollBar.vertical: ScrollBar {
width: 15
active: true
}
Column {
id: nodeInfo
y: nodeInfoFlickable.padding
x: nodeInfoFlickable.padding
width: parent.width - nodeInfoFlickable.padding * 3
spacing: nodeInfoFlickable.padding
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: selectedNodeName
font.pixelSize: 16
font.bold: true
color: mainView.foregroundColor2
}
Text {
width: parent.width
text: selectedNodeDescription
font.pixelSize: 14
color: mainView.foregroundColor2
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
Text {
width: parent.width
text: "Requires: " + selectedNodeRequires
font.pixelSize: 14
font.bold: true
color: mainView.foregroundColor2
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
visible: selectedNodeRequires !== ""
}
Text {
font.pixelSize: 12
font.bold: true
color: mainView.foregroundColor2
text: "PROPERTIES:"
visible: selectedNodeProperties.length > 0
}
Rectangle {
id: propertiesArea
width: parent.width
height: childrenRect.height + nodeInfoFlickable.padding
color: mainView.backgroundColor2
border.width: 1
border.color: mainView.foregroundColor1
visible: selectedNodeProperties.length > 0
Column {
width: parent.width - nodeInfoFlickable.padding * 2
x: nodeInfoFlickable.padding
y: nodeInfoFlickable.padding * 0.5
Repeater {
model: selectedNodeProperties
Text {
property var nodeProperty: selectedNodeProperties[index]
width: parent.width
elide: Text.ElideRight
font.pixelSize: 14
color: mainView.foregroundColor2
text: "<b>" + nodeProperty.type + "</b> " + nodeProperty.name
}
}
}
}
Item {
width: 1
height: nodeInfoFlickable.padding
}
}
}
}
Item {
id: buttonBar
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: 10
anchors.right: parent.right
anchors.rightMargin: 10
height: 40
Button {
id: cancelButton
anchors.left: parent.left
height: parent.height
text: "Cancel"
onPressed: {
rootItem.close();
}
}
Button {
id: refreshButton
anchors.left: cancelButton.right
anchors.leftMargin: 10
height: parent.height
text: "Refresh"
onPressed: {
refreshNodesIndicator.show();
effectManager.refreshAddNodesList();
}
}
Button {
id: addButton
anchors.right: parent.right
height: parent.height
text: "Add"
enabled: selectedNodeFile != "" && selectedNodeCanBeAdded
onPressed: {
rootItem.addSelectedNode();
}
}
}
}