Menu Milestone
This commit is contained in:
		
							
								
								
									
										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 | ||||
| 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()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user