mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-29 02:08:08 +02:00
[ui] Coloring a Node: Added ColorSelector to the Graph Editor
The color selector in the Graph Editor provides a quick way to color nodes with predefined palette of colors. Added Command to allow the Coloring to be undone and redone using QUndoStack
This commit is contained in:
parent
58a9b74a72
commit
d77b7a398a
5 changed files with 213 additions and 0 deletions
|
@ -205,6 +205,54 @@ class DuplicateNodesCommand(GraphCommand):
|
|||
self.graph.removeNode(duplicate)
|
||||
|
||||
|
||||
class UpdateNodeColorCommand(GraphCommand):
|
||||
""" Command representing the work for Coloring nodes in the Graph.
|
||||
"""
|
||||
|
||||
def __init__(self, graph, nodes, color, parent=None):
|
||||
""" Command Constructor.
|
||||
|
||||
Args:
|
||||
graph (meshroom.core.Graph): Current Graph instance.
|
||||
nodes (list<Node>): Array of nodes.
|
||||
color (str): Hex code for the color.
|
||||
|
||||
Keyword Args:
|
||||
parent (QObject): Parent QObject instance.
|
||||
"""
|
||||
super(UpdateNodeColorCommand, self).__init__(graph, parent)
|
||||
self._nodes = nodes
|
||||
self._color = color
|
||||
|
||||
# Existing colors
|
||||
# Map <Node: str>
|
||||
# Holds the existing color of the node which can be applied on the node back in case of an undo
|
||||
self._colorMap = {}
|
||||
|
||||
self.setText("Update Selected Node Color")
|
||||
|
||||
def redoImpl(self) -> bool:
|
||||
""" Redo implementation.
|
||||
"""
|
||||
for node in self._nodes:
|
||||
# Update the existing color for the node in the map
|
||||
self._colorMap[node] = node.color
|
||||
|
||||
# Now update the color of the node with the provided one
|
||||
node.color = self._color
|
||||
|
||||
return True
|
||||
|
||||
def undoImpl(self):
|
||||
""" Undo Implementation.
|
||||
"""
|
||||
with GraphModification(self.graph):
|
||||
# Revert the color for the nodes
|
||||
for node in self._nodes:
|
||||
# Get the color which was saved for the node
|
||||
node.color = self._colorMap.get(node)
|
||||
|
||||
|
||||
class PasteNodesCommand(GraphCommand):
|
||||
"""
|
||||
Handle node pasting in a Graph.
|
||||
|
|
|
@ -952,6 +952,17 @@ class UIGraph(QObject):
|
|||
""" Select all the nodes the depend on 'node'. """
|
||||
self.selectNodes(self._graph.dfsOnDiscover(startNodes=[node], reverse=True, dependenciesOnly=True)[0])
|
||||
|
||||
@Slot(str)
|
||||
def updateNodeColor(self, color):
|
||||
""" Sets the Provided color on the selected Nodes.
|
||||
|
||||
Args:
|
||||
color (str): Hex code of the color to be set on the nodes.
|
||||
"""
|
||||
# Update the color attribute of the nodes which are currently selected
|
||||
with self.groupedGraphModification("Update Color for Select Nodes"):
|
||||
self.push(commands.UpdateNodeColorCommand(self._graph, list(self._selectedNodes), color))
|
||||
|
||||
@Slot(QObject, QObject)
|
||||
def boxSelect(self, selection, draggable):
|
||||
"""
|
||||
|
|
133
meshroom/ui/qml/Controls/ColorSelector.qml
Normal file
133
meshroom/ui/qml/Controls/ColorSelector.qml
Normal file
|
@ -0,0 +1,133 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
import Utils 1.0
|
||||
import MaterialIcons 2.2
|
||||
|
||||
/**
|
||||
* ColorSelector is a color picker based on a set of predefined colors.
|
||||
* It takes the form of a ToolButton that pops-up its palette when pressed.
|
||||
*/
|
||||
MaterialToolButton {
|
||||
id: root
|
||||
|
||||
text: MaterialIcons.palette
|
||||
|
||||
// Internal property holding when the popup remains visible and when is it toggled off
|
||||
property var isVisible: false
|
||||
|
||||
property var colors: [
|
||||
"#FF6600",
|
||||
"#FFAD7D",
|
||||
"#FFF82F",
|
||||
"#FFFB8B",
|
||||
"#BDFF07",
|
||||
"#E8FF97",
|
||||
"#0BFFCA",
|
||||
"#8EFFF7",
|
||||
"#1158FF",
|
||||
"#77A7FF",
|
||||
"#9318FF",
|
||||
"#EAACFF",
|
||||
"#B61518",
|
||||
"#FF989A",
|
||||
]
|
||||
|
||||
// When a color gets selected/choosen
|
||||
signal colorSelected(var color)
|
||||
|
||||
// Toggles the visibility of the popup
|
||||
onPressed: toggle()
|
||||
|
||||
function toggle() {
|
||||
/*
|
||||
* Toggles the visibility of the color palette.
|
||||
*/
|
||||
if (!isVisible) {
|
||||
palettePopup.open()
|
||||
isVisible = true
|
||||
}
|
||||
else {
|
||||
palettePopup.close()
|
||||
isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
// Popup for the color palette
|
||||
Popup {
|
||||
id: palettePopup
|
||||
|
||||
// The popup will not get closed unless explicitly closed
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
// Bounds
|
||||
padding: 4
|
||||
width: (root.height * 4) + (padding * 4)
|
||||
|
||||
// center the current color
|
||||
y: -height
|
||||
x: -width + root.width + padding
|
||||
|
||||
// Layout of the Colors
|
||||
Grid {
|
||||
// Allow only 4 columns and all the colors can be adjusted in row multiples of 4
|
||||
columns: 4
|
||||
|
||||
spacing: 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
// Default -- Reset Colour button
|
||||
ToolButton {
|
||||
id: defaultButton
|
||||
padding: 0
|
||||
width: root.height
|
||||
height: root.height
|
||||
|
||||
// Emit no color so the graph sets None as the color of the Node
|
||||
onClicked: {
|
||||
root.colorSelected("")
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "#FFFFFF"
|
||||
// display border of current/selected item
|
||||
border.width: defaultButton.hovered ? 1 : 0
|
||||
border.color: "#000000"
|
||||
|
||||
// Another Rectangle
|
||||
Rectangle {
|
||||
color: "#FF0000"
|
||||
width: parent.width + 8
|
||||
height: 2
|
||||
anchors.centerIn: parent
|
||||
rotation: 135 // Diagonally creating a Red line from bottom left to top right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Colors palette
|
||||
Repeater {
|
||||
model: root.colors
|
||||
// display each color as a ToolButton with a custom background
|
||||
delegate: ToolButton {
|
||||
padding: 0
|
||||
width: root.height
|
||||
height: root.height
|
||||
|
||||
// Emit the model data as the color to update
|
||||
onClicked: {
|
||||
colorSelected(modelData)
|
||||
}
|
||||
|
||||
// Model color as the background of the button
|
||||
background: Rectangle {
|
||||
color: modelData
|
||||
// display border of current/selected item
|
||||
border.width: hovered ? 1 : 0
|
||||
border.color: "#000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
module Controls
|
||||
|
||||
ColorChart 1.0 ColorChart.qml
|
||||
ColorSelector 1.0 ColorSelector.qml
|
||||
ExpandableGroup 1.0 ExpandableGroup.qml
|
||||
FloatingPane 1.0 FloatingPane.qml
|
||||
Group 1.0 Group.qml
|
||||
|
|
|
@ -136,6 +136,8 @@ Item {
|
|||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_F) {
|
||||
fit()
|
||||
} else if (event.key === Qt.Key_C) {
|
||||
colorSelector.toggle()
|
||||
} else if (event.key === Qt.Key_Delete) {
|
||||
if (event.modifiers === Qt.AltModifier) {
|
||||
uigraph.removeNodesFrom(uigraph.selectedNodes)
|
||||
|
@ -1048,6 +1050,24 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Separator
|
||||
Rectangle {
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: 2
|
||||
implicitWidth: 1
|
||||
color: activePalette.window
|
||||
}
|
||||
|
||||
ColorSelector {
|
||||
id: colorSelector
|
||||
Layout.minimumWidth: colorSelector.width
|
||||
|
||||
// When a Color is selected
|
||||
onColorSelected: (color)=> {
|
||||
uigraph.updateNodeColor(color)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue