Skip to content

Commit e800cd4

Browse files
authored
Merge pull request #2604 from alicevision/dev/NodeColoring
[ui] Graph Editor Update: Quick Node Coloring with the Color Selector Tool
2 parents d797692 + 225f4dc commit e800cd4

File tree

4 files changed

+173
-2
lines changed

4 files changed

+173
-2
lines changed

meshroom/ui/graph.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,20 @@ def selectFollowing(self, node):
952952
""" Select all the nodes the depend on 'node'. """
953953
self.selectNodes(self._graph.dfsOnDiscover(startNodes=[node], reverse=True, dependenciesOnly=True)[0])
954954

955+
@Slot(str)
956+
def setSelectedNodesColor(self, color: str):
957+
""" Sets the Provided color on the selected Nodes.
958+
959+
Args:
960+
color (str): Hex code of the color to be set on the nodes.
961+
"""
962+
# Update the color attribute of the nodes which are currently selected
963+
with self.groupedGraphModification("Set Nodes Color"):
964+
# For each of the selected nodes -> Check if the node has a color -> Apply the color if it has
965+
for node in self._selectedNodes:
966+
if node.hasInternalAttribute("color"):
967+
self.setAttribute(node.internalAttribute("color"), color)
968+
955969
@Slot(QObject, QObject)
956970
def boxSelect(self, selection, draggable):
957971
"""
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import QtQuick
2+
import QtQuick.Controls
3+
4+
import Utils 1.0
5+
import MaterialIcons 2.2
6+
7+
/**
8+
* ColorSelector is a color picker based on a set of predefined colors.
9+
* It takes the form of a ToolButton that pops-up its palette when pressed.
10+
*/
11+
MaterialToolButton {
12+
id: root
13+
14+
text: MaterialIcons.palette
15+
16+
// Internal property holding when the popup remains visible and when is it toggled off
17+
property var isVisible: false
18+
19+
property var colors: [
20+
"#E35C03",
21+
"#FFAD7D",
22+
"#D0AE22",
23+
"#C9C770",
24+
"#3D6953",
25+
"#79C62F",
26+
"#02627E",
27+
"#2CB9CC",
28+
"#1453E6",
29+
"#507DD0",
30+
"#4D3E5C",
31+
"#A252BD",
32+
"#B61518",
33+
"#C16162",
34+
]
35+
36+
// When a color gets selected/choosen
37+
signal colorSelected(var color)
38+
39+
// Toggles the visibility of the popup
40+
onPressed: toggle()
41+
42+
function toggle() {
43+
/*
44+
* Toggles the visibility of the color palette.
45+
*/
46+
if (!isVisible) {
47+
palettePopup.open()
48+
isVisible = true
49+
}
50+
else {
51+
palettePopup.close()
52+
isVisible = false
53+
}
54+
}
55+
56+
// Popup for the color palette
57+
Popup {
58+
id: palettePopup
59+
60+
// The popup will not get closed unless explicitly closed
61+
closePolicy: Popup.NoAutoClose
62+
63+
// Bounds
64+
padding: 4
65+
width: (root.height * 4) + (padding * 4)
66+
67+
// center the current color
68+
y: -height
69+
x: -width + root.width + padding
70+
71+
// Layout of the Colors
72+
Grid {
73+
// Allow only 4 columns and all the colors can be adjusted in row multiples of 4
74+
columns: 4
75+
76+
spacing: 2
77+
anchors.centerIn: parent
78+
79+
// Default -- Reset Colour button
80+
ToolButton {
81+
id: defaultButton
82+
padding: 0
83+
width: root.height
84+
height: root.height
85+
86+
// Emit no color so the graph sets None as the color of the Node
87+
onClicked: {
88+
root.colorSelected("")
89+
}
90+
91+
background: Rectangle {
92+
color: "#FFFFFF"
93+
// display border of current/selected item
94+
border.width: defaultButton.hovered ? 1 : 0
95+
border.color: "#000000"
96+
97+
// Another Rectangle
98+
Rectangle {
99+
color: "#FF0000"
100+
width: parent.width + 8
101+
height: 2
102+
anchors.centerIn: parent
103+
rotation: 135 // Diagonally creating a Red line from bottom left to top right
104+
}
105+
}
106+
}
107+
108+
// Colors palette
109+
Repeater {
110+
model: root.colors
111+
// display each color as a ToolButton with a custom background
112+
delegate: ToolButton {
113+
padding: 0
114+
width: root.height
115+
height: root.height
116+
117+
// Emit the model data as the color to update
118+
onClicked: {
119+
colorSelected(modelData)
120+
}
121+
122+
// Model color as the background of the button
123+
background: Rectangle {
124+
color: modelData
125+
// display border of current/selected item
126+
border.width: hovered ? 1 : 0
127+
border.color: "#000000"
128+
}
129+
}
130+
}
131+
}
132+
}
133+
}

meshroom/ui/qml/Controls/qmldir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module Controls
22

33
ColorChart 1.0 ColorChart.qml
4+
ColorSelector 1.0 ColorSelector.qml
45
ExpandableGroup 1.0 ExpandableGroup.qml
56
FloatingPane 1.0 FloatingPane.qml
67
Group 1.0 Group.qml

meshroom/ui/qml/GraphEditor/GraphEditor.qml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,13 @@ Item {
147147
} else if (event.key === Qt.Key_X && event.modifiers === Qt.ControlModifier) {
148148
copyNodes()
149149
uigraph.removeNodes(uigraph.selectedNodes)
150-
} else if (event.key === Qt.Key_C && event.modifiers === Qt.ControlModifier) {
151-
copyNodes()
150+
} else if (event.key === Qt.Key_C) {
151+
if (event.modifiers === Qt.ControlModifier) {
152+
copyNodes()
153+
}
154+
else {
155+
colorSelector.toggle()
156+
}
152157
} else if (event.key === Qt.Key_V && event.modifiers === Qt.ControlModifier) {
153158
pasteNodes()
154159
} else if (event.key === Qt.Key_Tab) {
@@ -1048,6 +1053,24 @@ Item {
10481053
}
10491054
}
10501055
}
1056+
1057+
// Separator
1058+
Rectangle {
1059+
Layout.fillHeight: true
1060+
Layout.margins: 2
1061+
implicitWidth: 1
1062+
color: activePalette.window
1063+
}
1064+
1065+
ColorSelector {
1066+
id: colorSelector
1067+
Layout.minimumWidth: colorSelector.width
1068+
1069+
// When a Color is selected
1070+
onColorSelected: (color)=> {
1071+
uigraph.setSelectedNodesColor(color)
1072+
}
1073+
}
10511074
}
10521075
}
10531076

0 commit comments

Comments
 (0)