mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-08-06 10:18:42 +02:00
[ui] Node: improve node UI
* unify colors and spacing * simplify status icon display * remove duplicated code
This commit is contained in:
parent
e2ef6520d7
commit
61866708ac
1 changed files with 72 additions and 116 deletions
|
@ -2,37 +2,54 @@ import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.3
|
import QtQuick.Controls 2.3
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import Utils 1.0
|
import Utils 1.0
|
||||||
import MaterialIcons 2.2
|
import MaterialIcons 2.2
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visual representation of a Graph Node.
|
||||||
|
*/
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
/// The underlying Node object
|
||||||
property variant node
|
property variant node
|
||||||
|
/// Whether the node can be modified
|
||||||
property bool readOnly: false
|
property bool readOnly: false
|
||||||
property color baseColor: defaultColor
|
/// Whether the node is in compatibility mode
|
||||||
property color shadowColor: "#cc000000"
|
|
||||||
readonly property bool isCompatibilityNode: node.hasOwnProperty("compatibilityIssue")
|
readonly property bool isCompatibilityNode: node.hasOwnProperty("compatibilityIssue")
|
||||||
readonly property color defaultColor: isCompatibilityNode ? "#444" : "#34495e" // "#607D8B"
|
/// Mouse related states
|
||||||
property bool selected: false
|
property bool selected: false
|
||||||
property bool hovered: false
|
property bool hovered: false
|
||||||
|
/// Styling
|
||||||
|
property color shadowColor: "#cc000000"
|
||||||
|
readonly property color defaultColor: isCompatibilityNode ? "#444" : activePalette.base
|
||||||
|
property color baseColor: defaultColor
|
||||||
|
|
||||||
|
// Mouse interaction related signals
|
||||||
signal pressed(var mouse)
|
signal pressed(var mouse)
|
||||||
signal doubleClicked(var mouse)
|
signal doubleClicked(var mouse)
|
||||||
signal moved(var position)
|
signal moved(var position)
|
||||||
signal entered()
|
signal entered()
|
||||||
signal exited()
|
signal exited()
|
||||||
|
|
||||||
|
/// Emitted when child attribute pins are created
|
||||||
signal attributePinCreated(var attribute, var pin)
|
signal attributePinCreated(var attribute, var pin)
|
||||||
|
/// Emitted when child attribute pins are deleted
|
||||||
signal attributePinDeleted(var attribute, var pin)
|
signal attributePinDeleted(var attribute, var pin)
|
||||||
|
|
||||||
implicitHeight: childrenRect.height
|
// use node name as object name to simplify debugging
|
||||||
objectName: node.name
|
objectName: node.name
|
||||||
|
|
||||||
SystemPalette { id: activePalette }
|
|
||||||
|
|
||||||
// initialize position with node coordinates
|
// initialize position with node coordinates
|
||||||
x: root.node.x
|
x: root.node.x
|
||||||
y: root.node.y
|
y: root.node.y
|
||||||
|
|
||||||
|
implicitHeight: childrenRect.height
|
||||||
|
|
||||||
|
SystemPalette { id: activePalette }
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.node
|
target: root.node
|
||||||
// update x,y when node position changes
|
// update x,y when node position changes
|
||||||
|
@ -41,9 +58,9 @@ Item {
|
||||||
root.y = root.node.y
|
root.y = root.node.y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
|
|
||||||
|
// Main Layout
|
||||||
MouseArea {
|
MouseArea {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: body.height
|
height: body.height
|
||||||
|
@ -58,9 +75,13 @@ Item {
|
||||||
onExited: root.exited()
|
onExited: root.exited()
|
||||||
drag.onActiveChanged: {
|
drag.onActiveChanged: {
|
||||||
if(!drag.active)
|
if(!drag.active)
|
||||||
root.moved(Qt.point(root.x, root.y))
|
{
|
||||||
|
root.moved(Qt.point(root.x, root.y));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursorShape: drag.active ? Qt.ClosedHandCursor : Qt.ArrowCursor
|
||||||
|
|
||||||
// Selection border
|
// Selection border
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -73,159 +94,93 @@ Item {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Background
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: background
|
id: background
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
color: Qt.lighter(activePalette.base, 1.4)
|
||||||
color: Qt.lighter(activePalette.base, 1.3)
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: DropShadow { radius: 3; color: shadowColor }
|
layer.effect: DropShadow { radius: 3; color: shadowColor }
|
||||||
radius: 3
|
radius: 3
|
||||||
|
opacity: 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data Layout
|
||||||
Column {
|
Column {
|
||||||
id: body
|
id: body
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
// Header
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: stateView
|
id: header
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 20
|
height: headerLayout.height
|
||||||
color: root.baseColor
|
color: root.selected ? activePalette.highlight : root.baseColor
|
||||||
radius: background.radius
|
radius: background.radius
|
||||||
|
|
||||||
|
// Fill header's bottom radius
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.radius
|
height: parent.radius
|
||||||
y: -parent.radius
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
color: parent.color
|
color: parent.color
|
||||||
|
z: -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Header Layout
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
id: headerLayout
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
// Node Name
|
||||||
Label {
|
Label {
|
||||||
width: parent.width
|
Layout.fillWidth: true
|
||||||
padding: 4
|
|
||||||
text: node.label
|
text: node.label
|
||||||
color: "#fff" //Colors.sysPalette.text
|
padding: 4
|
||||||
font.pointSize: 7
|
color: root.selected ? "white" : activePalette.text
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
font.pointSize: 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Node State icons
|
||||||
RowLayout {
|
RowLayout {
|
||||||
width: 50
|
Layout.fillWidth: true
|
||||||
spacing: 0
|
Layout.alignment: Qt.AlignRight
|
||||||
|
Layout.rightMargin: 2
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
MaterialLabel {
|
// Data sharing indicator
|
||||||
id: ghostIcon
|
MaterialToolButton {
|
||||||
visible: node.chunks.count > 0 && node.globalStatus !== "NONE" && node.chunks.at(0).statusNodeName !== node.name
|
visible: node.chunks.count > 0 && node.globalStatus !== "NONE" && node.chunks.at(0).statusNodeName !== node.name
|
||||||
|
text: MaterialIcons.layers
|
||||||
|
font.pointSize: 7
|
||||||
padding: 2
|
padding: 2
|
||||||
text: MaterialIcons.layers //MaterialIcons.all_inclusive
|
palette.text: Colors.sysPalette.text
|
||||||
font.pointSize: 8
|
ToolTip.text: visible ? "Data has been computed by <b>" + node.nameToLabel(node.chunks.at(0).statusNodeName) + "</b>" : ""
|
||||||
color: Colors.sysPalette.text
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
height: parent.height
|
|
||||||
width: parent.width
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
property bool showTooltip: false
|
|
||||||
|
|
||||||
onEntered: {
|
|
||||||
ghostIcon.color = Colors.cyan
|
|
||||||
showTooltip = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
ghostIcon.color = Colors.sysPalette.text
|
|
||||||
showTooltip = false
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip {
|
|
||||||
delay: 800
|
|
||||||
visible: parent.showTooltip
|
|
||||||
text: ""
|
|
||||||
onVisibleChanged: {
|
|
||||||
text = "The data associated to this node has been computed by the other node: <b>" + node.nameToLabel(node.chunks.at(0).statusNodeName) + "</b>."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Submitted externally indicator
|
||||||
MaterialLabel {
|
MaterialLabel {
|
||||||
id: cloudIcon
|
|
||||||
visible: ["SUBMITTED", "RUNNING"].includes(node.globalStatus) && node.chunks.count > 0 && node.chunks.at(0).execModeName === "EXTERN"
|
visible: ["SUBMITTED", "RUNNING"].includes(node.globalStatus) && node.chunks.count > 0 && node.chunks.at(0).execModeName === "EXTERN"
|
||||||
padding: 2
|
|
||||||
text: MaterialIcons.cloud
|
text: MaterialIcons.cloud
|
||||||
font.pointSize: 8
|
padding: 2
|
||||||
|
font.pointSize: 7
|
||||||
MouseArea {
|
palette.text: Colors.sysPalette.text
|
||||||
height: parent.height
|
ToolTip.text: "Computed Externally"
|
||||||
width: parent.width
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
property bool showTooltip: false
|
|
||||||
|
|
||||||
|
|
||||||
onEntered: {
|
|
||||||
cloudIcon.color = Colors.cyan
|
|
||||||
showTooltip = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
cloudIcon.color = Colors.sysPalette.text
|
|
||||||
showTooltip = false
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip {
|
|
||||||
delay: 800
|
|
||||||
visible: parent.showTooltip
|
|
||||||
text: "This nodes is being computed externally"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lock indicator
|
||||||
MaterialLabel {
|
MaterialLabel {
|
||||||
id: lockIcon
|
|
||||||
visible: root.readOnly
|
visible: root.readOnly
|
||||||
padding: 2
|
|
||||||
text: MaterialIcons.lock
|
text: MaterialIcons.lock
|
||||||
font.pointSize: 8
|
padding: 2
|
||||||
|
font.pointSize: 7
|
||||||
MouseArea {
|
palette.text: "red"
|
||||||
height: parent.height
|
ToolTip.text: "Locked"
|
||||||
width: parent.width
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
property bool showTooltip: false
|
|
||||||
|
|
||||||
|
|
||||||
onEntered: {
|
|
||||||
lockIcon.color = Colors.red
|
|
||||||
showTooltip = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
lockIcon.color = Colors.sysPalette.text
|
|
||||||
showTooltip = false
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip {
|
|
||||||
delay: 800
|
|
||||||
visible: parent.showTooltip
|
|
||||||
text: "<b>Locked</b><br/>This node cannot be edited at the moment"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node Chunks
|
// Node Chunks
|
||||||
|
@ -242,7 +197,8 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { width: 1; height: 2}
|
// Vertical Spacer
|
||||||
|
Item { width: parent.width; height: 2 }
|
||||||
|
|
||||||
// Input/Output Attributes
|
// Input/Output Attributes
|
||||||
Item {
|
Item {
|
||||||
|
@ -330,5 +286,5 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue