diff --git a/borealis.py b/borealis.py index f0f864e..dad5fc1 100644 --- a/borealis.py +++ b/borealis.py @@ -16,48 +16,44 @@ from Qt import QtWidgets, QtCore, QtGui # PATCH: Override the color of interconnection pipes between nodes try: from OdenGraphQt.qgraphics.pipe import PipeItem + from OdenGraphQt.qgraphics.node_base import NodeItem from qtpy.QtGui import QPen, QColor from qtpy import QtCore # 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): - """ - Force the pen color after (or before) the original drawing code - so it can't revert to orange. - """ + # Custom pipe painting function + def _custom_paint_pipe(self, painter, option, widget=None): painter.save() - - # 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 = QPen(QColor(0, 161, 115, 255)) # Match desired RGBA my_pen.setWidthF(2.0) painter.setPen(my_pen) - - # 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()) - + _orig_paint_pipe(self, painter, option, widget) painter.restore() - PipeItem.paint = _custom_paint - print("Patched PipeItem.paint to forcibly override pipe color.") -except ImportError: - print("WARNING: Could not patch PipeItem paint method.") + # Custom node painting function + def _custom_paint_node(self, painter, option, widget=None): + painter.save() + _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: - 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'" try: @@ -95,7 +91,9 @@ def _patched_setSelectionArea(self, *args, **kwargs): 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 OdenGraphQt import NodeGraph, BaseNode @@ -130,6 +128,7 @@ def import_nodes_from_folder(package_name): return nodes_by_category + def make_node_command(graph, node_type_str): """ 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): """ - 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() file_filter = "JSON Files (*.json);;All Files (*.*)" @@ -207,6 +207,14 @@ def load_workflow(graph: NodeGraph): try: graph.load_session(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: QtWidgets.QMessageBox.critical(None, "Error Loading Workflow", str(e)) @@ -218,7 +226,7 @@ if __name__ == "__main__": # Create the 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. 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 ) - # 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 # ------------------------------# # SECTION: Enhanced Graph Wrapper for QMainWindow # 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 central QSplitter dividing the window horizontally: # * Left side (2/3): the NodeGraph widget @@ -267,15 +269,30 @@ if __name__ == "__main__": 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. """ # Create a new QMainWindow instance 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.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. main_window.setStatusBar(QtWidgets.QStatusBar())