[ui] Node: improve node UI

* unify colors and spacing
* simplify status icon display
* remove duplicated code
This commit is contained in:
Yann Lanthony 2020-01-24 11:41:58 +01:00
parent e2ef6520d7
commit 61866708ac

View file

@ -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 {
} }
} }
} }
}
} }