Menu Milestone
This commit is contained in:
parent
01070966a7
commit
d66dcfefd5
105
borealis.py
105
borealis.py
@ -16,48 +16,44 @@ from Qt import QtWidgets, QtCore, QtGui
|
|||||||
# PATCH: Override the color of interconnection pipes between nodes
|
# PATCH: Override the color of interconnection pipes between nodes
|
||||||
try:
|
try:
|
||||||
from OdenGraphQt.qgraphics.pipe import PipeItem
|
from OdenGraphQt.qgraphics.pipe import PipeItem
|
||||||
|
from OdenGraphQt.qgraphics.node_base import NodeItem
|
||||||
from qtpy.QtGui import QPen, QColor
|
from qtpy.QtGui import QPen, QColor
|
||||||
from qtpy import QtCore
|
from qtpy import QtCore
|
||||||
|
|
||||||
# If you want the original paint logic, capture it first:
|
# If you want the original paint logic, capture it first:
|
||||||
_orig_paint = PipeItem.paint
|
_orig_paint_pipe = PipeItem.paint
|
||||||
|
_orig_paint_node = NodeItem.paint
|
||||||
|
|
||||||
def _custom_paint(self, painter, option, widget=None):
|
# Custom pipe painting function
|
||||||
"""
|
def _custom_paint_pipe(self, painter, option, widget=None):
|
||||||
Force the pen color after (or before) the original drawing code
|
|
||||||
so it can't revert to orange.
|
|
||||||
"""
|
|
||||||
painter.save()
|
painter.save()
|
||||||
|
my_pen = QPen(QColor(0, 161, 115, 255)) # Match desired RGBA
|
||||||
# Option A: override the pen BEFORE the original paint.
|
|
||||||
# This might work if OdenGraphQt doesn't re-set the pen later.
|
|
||||||
my_pen = QPen(QColor(60, 120, 180, 255)) # RGBA
|
|
||||||
my_pen.setWidthF(2.0)
|
my_pen.setWidthF(2.0)
|
||||||
painter.setPen(my_pen)
|
painter.setPen(my_pen)
|
||||||
|
_orig_paint_pipe(self, painter, option, widget)
|
||||||
# Call original method (which might set color to orange again)
|
|
||||||
_orig_paint(self, painter, option, widget)
|
|
||||||
|
|
||||||
# Option B: forcibly override color AFTER the original paint
|
|
||||||
# in case the library sets orange near the end.
|
|
||||||
pen = painter.pen()
|
|
||||||
pen.setColor(QColor(60,120,180,255))
|
|
||||||
pen.setWidthF(2.0)
|
|
||||||
painter.setPen(pen)
|
|
||||||
|
|
||||||
# The library may have already drawn the path in orange, so
|
|
||||||
# re-draw if needed:
|
|
||||||
if hasattr(self, "path"):
|
|
||||||
painter.drawPath(self.path())
|
|
||||||
|
|
||||||
painter.restore()
|
painter.restore()
|
||||||
|
|
||||||
PipeItem.paint = _custom_paint
|
# Custom node painting function
|
||||||
print("Patched PipeItem.paint to forcibly override pipe color.")
|
def _custom_paint_node(self, painter, option, widget=None):
|
||||||
except ImportError:
|
painter.save()
|
||||||
print("WARNING: Could not patch PipeItem paint method.")
|
_orig_paint_node(self, painter, option, widget) # Call original method
|
||||||
|
if self.isSelected():
|
||||||
|
pen = QPen(QColor(0, 161, 115, 255)) # Set selected border color
|
||||||
|
pen.setWidth(3)
|
||||||
|
painter.setPen(pen)
|
||||||
|
painter.drawRect(self.boundingRect())
|
||||||
|
painter.restore()
|
||||||
|
|
||||||
|
# Apply the patches
|
||||||
|
PipeItem.paint = _custom_paint_pipe
|
||||||
|
NodeItem.paint = _custom_paint_node
|
||||||
|
|
||||||
|
print("Patched PipeItem.paint and NodeItem.paint to override colors.")
|
||||||
|
|
||||||
|
except ImportError as e:
|
||||||
|
print(f"WARNING: Could not patch PipeItem or NodeItem: {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Patch for PipeItem.paint override failed: {e}")
|
print(f"Patch for PipeItem or NodeItem override failed: {e}")
|
||||||
|
|
||||||
# PATCH: Fix "module 'qtpy.QtGui' has no attribute 'QUndoStack'"
|
# PATCH: Fix "module 'qtpy.QtGui' has no attribute 'QUndoStack'"
|
||||||
try:
|
try:
|
||||||
@ -95,7 +91,9 @@ def _patched_setSelectionArea(self, *args, **kwargs):
|
|||||||
|
|
||||||
QtWidgets.QGraphicsScene.setSelectionArea = _patched_setSelectionArea
|
QtWidgets.QGraphicsScene.setSelectionArea = _patched_setSelectionArea
|
||||||
|
|
||||||
# Import your data_manager so we can start the Flask server
|
# ----------------------------------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
# Import data_manager so we can start the Flask server
|
||||||
from Modules import data_manager
|
from Modules import data_manager
|
||||||
|
|
||||||
from OdenGraphQt import NodeGraph, BaseNode
|
from OdenGraphQt import NodeGraph, BaseNode
|
||||||
@ -130,6 +128,7 @@ def import_nodes_from_folder(package_name):
|
|||||||
|
|
||||||
return nodes_by_category
|
return nodes_by_category
|
||||||
|
|
||||||
|
|
||||||
def make_node_command(graph, node_type_str):
|
def make_node_command(graph, node_type_str):
|
||||||
"""
|
"""
|
||||||
Return a function that creates a node of the given type at the current cursor position.
|
Return a function that creates a node of the given type at the current cursor position.
|
||||||
@ -195,7 +194,8 @@ def save_workflow(graph: NodeGraph):
|
|||||||
|
|
||||||
def load_workflow(graph: NodeGraph):
|
def load_workflow(graph: NodeGraph):
|
||||||
"""
|
"""
|
||||||
Loads a workflow (including node values, connections, positions, etc.) from a specified JSON file.
|
Loads a workflow (including node values, connections, positions, etc.) from a specified JSON file
|
||||||
|
and centers it within the graph.
|
||||||
"""
|
"""
|
||||||
ensure_workflows_folder()
|
ensure_workflows_folder()
|
||||||
file_filter = "JSON Files (*.json);;All Files (*.*)"
|
file_filter = "JSON Files (*.json);;All Files (*.*)"
|
||||||
@ -207,6 +207,14 @@ def load_workflow(graph: NodeGraph):
|
|||||||
try:
|
try:
|
||||||
graph.load_session(file_path)
|
graph.load_session(file_path)
|
||||||
print(f"Workflow loaded from {file_path}")
|
print(f"Workflow loaded from {file_path}")
|
||||||
|
|
||||||
|
# Center the workflow within the graph
|
||||||
|
nodes = graph.all_nodes()
|
||||||
|
if nodes:
|
||||||
|
graph.center_on(nodes)
|
||||||
|
else:
|
||||||
|
print("No nodes found in the loaded workflow.")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
QtWidgets.QMessageBox.critical(None, "Error Loading Workflow", str(e))
|
QtWidgets.QMessageBox.critical(None, "Error Loading Workflow", str(e))
|
||||||
|
|
||||||
@ -218,7 +226,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Create the NodeGraph
|
# Create the NodeGraph
|
||||||
graph = NodeGraph()
|
graph = NodeGraph()
|
||||||
graph.widget.setWindowTitle("Project Borealis - Workflow Automation System")
|
graph.widget.setWindowTitle("Borealis - Workflow Automation Tool")
|
||||||
|
|
||||||
# Dynamically import custom node classes from the 'Nodes' package.
|
# Dynamically import custom node classes from the 'Nodes' package.
|
||||||
custom_nodes_by_category = import_nodes_from_folder("Nodes")
|
custom_nodes_by_category = import_nodes_from_folder("Nodes")
|
||||||
@ -247,18 +255,12 @@ if __name__ == "__main__":
|
|||||||
lambda: [graph.remove_node(node) for node in graph.selected_nodes()] if graph.selected_nodes() else None
|
lambda: [graph.remove_node(node) for node in graph.selected_nodes()] if graph.selected_nodes() else None
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add workflow menu commands
|
|
||||||
workflow_menu = graph_context_menu.add_menu("Workflow")
|
|
||||||
workflow_menu.add_command("Load Workflow", lambda: load_workflow(graph))
|
|
||||||
workflow_menu.add_command("Save Workflow", lambda: save_workflow(graph))
|
|
||||||
workflow_menu.add_command("Close Workflow", lambda: close_workflow(graph))
|
|
||||||
|
|
||||||
# ------------------------------#
|
# ------------------------------#
|
||||||
# WRAPPER: QMainWindow Integration with Additional UI Elements
|
# WRAPPER: QMainWindow Integration with Additional UI Elements
|
||||||
# ------------------------------#
|
# ------------------------------#
|
||||||
# SECTION: Enhanced Graph Wrapper for QMainWindow
|
# SECTION: Enhanced Graph Wrapper for QMainWindow
|
||||||
# This section wraps the NodeGraph widget in a QMainWindow with:
|
# This section wraps the NodeGraph widget in a QMainWindow with:
|
||||||
# - A menu bar at the top (with a minimal "File" menu so it shows up)
|
# - A menu bar at the top (named "Workflows" menu)
|
||||||
# - A blank status bar at the bottom
|
# - A blank status bar at the bottom
|
||||||
# - A central QSplitter dividing the window horizontally:
|
# - A central QSplitter dividing the window horizontally:
|
||||||
# * Left side (2/3): the NodeGraph widget
|
# * Left side (2/3): the NodeGraph widget
|
||||||
@ -267,15 +269,30 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
def _wrapped_show():
|
def _wrapped_show():
|
||||||
"""
|
"""
|
||||||
Wrap the NodeGraph widget inside a QMainWindow with a minimal "File" menu,
|
Wrap the NodeGraph widget inside a QMainWindow with a "Workflows" menu,
|
||||||
a status bar, and a central splitter for layout.
|
a status bar, and a central splitter for layout.
|
||||||
"""
|
"""
|
||||||
# Create a new QMainWindow instance
|
# Create a new QMainWindow instance
|
||||||
main_window = QtWidgets.QMainWindow()
|
main_window = QtWidgets.QMainWindow()
|
||||||
|
|
||||||
# Create a menu bar and add a "File" menu so it appears at the top on Windows.
|
# Create a menu bar and add a "Workflows" menu
|
||||||
menu_bar = main_window.menuBar()
|
menu_bar = main_window.menuBar()
|
||||||
menu_bar.addMenu("File") # Minimal named menu
|
workflows_menu = menu_bar.addMenu("Workflows")
|
||||||
|
|
||||||
|
# Add "Open" action
|
||||||
|
open_action = QtWidgets.QAction("Open", main_window)
|
||||||
|
open_action.triggered.connect(lambda: load_workflow(graph))
|
||||||
|
workflows_menu.addAction(open_action)
|
||||||
|
|
||||||
|
# Add "Save" action
|
||||||
|
save_action = QtWidgets.QAction("Save", main_window)
|
||||||
|
save_action.triggered.connect(lambda: save_workflow(graph))
|
||||||
|
workflows_menu.addAction(save_action)
|
||||||
|
|
||||||
|
# Add "Close" action
|
||||||
|
close_action = QtWidgets.QAction("Close", main_window)
|
||||||
|
close_action.triggered.connect(lambda: close_workflow(graph))
|
||||||
|
workflows_menu.addAction(close_action)
|
||||||
|
|
||||||
# Create and set a blank status bar at the bottom.
|
# Create and set a blank status bar at the bottom.
|
||||||
main_window.setStatusBar(QtWidgets.QStatusBar())
|
main_window.setStatusBar(QtWidgets.QStatusBar())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user