Incorporated Save / Load / Close Workflow functionality
This commit is contained in:
		
							
								
								
									
										101
									
								
								Workflows/test.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								Workflows/test.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| { | ||||
|   "graph":{ | ||||
|     "layout_direction":0, | ||||
|     "acyclic":true, | ||||
|     "pipe_collision":false, | ||||
|     "pipe_slicing":true, | ||||
|     "pipe_style":1, | ||||
|     "accept_connection_types":{}, | ||||
|     "reject_connection_types":{} | ||||
|   }, | ||||
|   "nodes":{ | ||||
|     "0x25032ceeae0":{ | ||||
|       "type_":"bunny-lab.io.data_node.DataNode", | ||||
|       "icon":null, | ||||
|       "name":"Data Node", | ||||
|       "color":[ | ||||
|         13, | ||||
|         18, | ||||
|         23, | ||||
|         255 | ||||
|       ], | ||||
|       "border_color":[ | ||||
|         74, | ||||
|         84, | ||||
|         85, | ||||
|         255 | ||||
|       ], | ||||
|       "text_color":[ | ||||
|         255, | ||||
|         255, | ||||
|         255, | ||||
|         180 | ||||
|       ], | ||||
|       "disabled":false, | ||||
|       "selected":false, | ||||
|       "visible":true, | ||||
|       "width":269.0, | ||||
|       "height":74.2, | ||||
|       "pos":[ | ||||
|         -140.9796961059538, | ||||
|         314.0813482866816 | ||||
|       ], | ||||
|       "layout_direction":0, | ||||
|       "port_deletion_allowed":false, | ||||
|       "subgraph_session":{}, | ||||
|       "custom":{ | ||||
|         "value":"56" | ||||
|       } | ||||
|     }, | ||||
|     "0x250626018b0":{ | ||||
|       "type_":"bunny-lab.io.data_node.DataNode", | ||||
|       "icon":null, | ||||
|       "name":"Data Node 1", | ||||
|       "color":[ | ||||
|         13, | ||||
|         18, | ||||
|         23, | ||||
|         255 | ||||
|       ], | ||||
|       "border_color":[ | ||||
|         74, | ||||
|         84, | ||||
|         85, | ||||
|         255 | ||||
|       ], | ||||
|       "text_color":[ | ||||
|         255, | ||||
|         255, | ||||
|         255, | ||||
|         180 | ||||
|       ], | ||||
|       "disabled":false, | ||||
|       "selected":false, | ||||
|       "visible":true, | ||||
|       "width":269.0, | ||||
|       "height":74.2, | ||||
|       "pos":[ | ||||
|         436.3232366823503, | ||||
|         297.12809369166183 | ||||
|       ], | ||||
|       "layout_direction":0, | ||||
|       "port_deletion_allowed":false, | ||||
|       "subgraph_session":{}, | ||||
|       "custom":{ | ||||
|         "value":"56" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "connections":[ | ||||
|     { | ||||
|       "out":[ | ||||
|         "0x25032ceeae0", | ||||
|         "Output" | ||||
|       ], | ||||
|       "in":[ | ||||
|         "0x250626018b0", | ||||
|         "Input" | ||||
|       ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										139
									
								
								Workflows/test2.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								Workflows/test2.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| { | ||||
|   "graph":{ | ||||
|     "layout_direction":0, | ||||
|     "acyclic":true, | ||||
|     "pipe_collision":false, | ||||
|     "pipe_slicing":true, | ||||
|     "pipe_style":1, | ||||
|     "accept_connection_types":{}, | ||||
|     "reject_connection_types":{} | ||||
|   }, | ||||
|   "nodes":{ | ||||
|     "0x25062603f80":{ | ||||
|       "type_":"bunny-lab.io.data_node.DataNode", | ||||
|       "icon":null, | ||||
|       "name":"Data Node", | ||||
|       "color":[ | ||||
|         13, | ||||
|         18, | ||||
|         23, | ||||
|         255 | ||||
|       ], | ||||
|       "border_color":[ | ||||
|         74, | ||||
|         84, | ||||
|         85, | ||||
|         255 | ||||
|       ], | ||||
|       "text_color":[ | ||||
|         255, | ||||
|         255, | ||||
|         255, | ||||
|         180 | ||||
|       ], | ||||
|       "disabled":false, | ||||
|       "selected":false, | ||||
|       "visible":true, | ||||
|       "width":269.0, | ||||
|       "height":74.2, | ||||
|       "pos":[ | ||||
|         -183.12907239097774, | ||||
|         203.3685322819906 | ||||
|       ], | ||||
|       "layout_direction":0, | ||||
|       "port_deletion_allowed":false, | ||||
|       "subgraph_session":{}, | ||||
|       "custom":{ | ||||
|         "value":"25" | ||||
|       } | ||||
|     }, | ||||
|     "0x250626141a0":{ | ||||
|       "type_":"bunny-lab.io.data_node.DataNode", | ||||
|       "icon":null, | ||||
|       "name":"Data Node 1", | ||||
|       "color":[ | ||||
|         13, | ||||
|         18, | ||||
|         23, | ||||
|         255 | ||||
|       ], | ||||
|       "border_color":[ | ||||
|         74, | ||||
|         84, | ||||
|         85, | ||||
|         255 | ||||
|       ], | ||||
|       "text_color":[ | ||||
|         255, | ||||
|         255, | ||||
|         255, | ||||
|         180 | ||||
|       ], | ||||
|       "disabled":false, | ||||
|       "selected":false, | ||||
|       "visible":true, | ||||
|       "width":269.0, | ||||
|       "height":74.2, | ||||
|       "pos":[ | ||||
|         279.96246102035116, | ||||
|         512.9884977805091 | ||||
|       ], | ||||
|       "layout_direction":0, | ||||
|       "port_deletion_allowed":false, | ||||
|       "subgraph_session":{}, | ||||
|       "custom":{ | ||||
|         "value":"25" | ||||
|       } | ||||
|     }, | ||||
|     "0x250626159d0":{ | ||||
|       "type_":"bunny-lab.io.backdrop.BackdropNode", | ||||
|       "icon":null, | ||||
|       "name":"flask", | ||||
|       "color":[ | ||||
|         5, | ||||
|         129, | ||||
|         138, | ||||
|         255 | ||||
|       ], | ||||
|       "border_color":[ | ||||
|         74, | ||||
|         84, | ||||
|         85, | ||||
|         255 | ||||
|       ], | ||||
|       "text_color":[ | ||||
|         255, | ||||
|         255, | ||||
|         255, | ||||
|         180 | ||||
|       ], | ||||
|       "disabled":false, | ||||
|       "selected":false, | ||||
|       "visible":true, | ||||
|       "width":804.65254462634, | ||||
|       "height":483.4329838785975, | ||||
|       "pos":[ | ||||
|         -205.22360825550223, | ||||
|         146.33335545174936 | ||||
|       ], | ||||
|       "layout_direction":0, | ||||
|       "port_deletion_allowed":false, | ||||
|       "subgraph_session":{}, | ||||
|       "custom":{ | ||||
|         "backdrop_text":"" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "connections":[ | ||||
|     { | ||||
|       "out":[ | ||||
|         "0x25062603f80", | ||||
|         "Output" | ||||
|       ], | ||||
|       "in":[ | ||||
|         "0x250626141a0", | ||||
|         "Input" | ||||
|       ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										71
									
								
								borealis.py
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								borealis.py
									
									
									
									
									
								
							| @@ -19,6 +19,17 @@ except ImportError: | ||||
|     print("WARNING: Could not monkey-patch QUndoStack. You may see an error if OdenGraphQt needs it.") | ||||
| # ------------------------------------------------------------------ | ||||
|  | ||||
| # ------------------------------------------------------------------ | ||||
| # MONKEY-PATCH to fix "'BackdropNodeItem' object has no attribute 'widgets'" | ||||
| # by giving BackdropNodeItem a trivial widgets dictionary. | ||||
| try: | ||||
|     from OdenGraphQt.nodes.backdrop_node import BackdropNodeItem | ||||
|     if not hasattr(BackdropNodeItem, "widgets"): | ||||
|         BackdropNodeItem.widgets = {} | ||||
| except ImportError: | ||||
|     print("WARNING: Could not monkey-patch BackdropNodeItem to add `widgets`.") | ||||
| # ------------------------------------------------------------------ | ||||
|  | ||||
| # Import your data_manager so we can start the Flask server | ||||
| from Modules import data_manager | ||||
|  | ||||
| @@ -44,6 +55,7 @@ QtWidgets.QGraphicsScene.setSelectionArea = _patched_setSelectionArea | ||||
| # --- END PATCH --- | ||||
|  | ||||
| from OdenGraphQt import NodeGraph, BaseNode | ||||
| from OdenGraphQt.widgets.dialogs import FileDialog | ||||
|  | ||||
| def import_nodes_from_folder(package_name): | ||||
|     """ | ||||
| @@ -103,6 +115,57 @@ def make_node_command(graph, node_type_str): | ||||
|  | ||||
|     return command | ||||
|  | ||||
| def ensure_workflows_folder(): | ||||
|     """ | ||||
|     Ensures a 'Workflows' subfolder exists. | ||||
|     """ | ||||
|     if not os.path.exists("Workflows"): | ||||
|         os.makedirs("Workflows") | ||||
|  | ||||
| def close_workflow(graph: NodeGraph): | ||||
|     """ | ||||
|     Closes the current workflow (removes all nodes and connections). | ||||
|     """ | ||||
|     graph.clear_session() | ||||
|  | ||||
| def save_workflow(graph: NodeGraph): | ||||
|     """ | ||||
|     Saves the current workflow (including custom names, positions, wires, etc.) into a JSON file | ||||
|     in the 'Workflows' subfolder. | ||||
|     """ | ||||
|     ensure_workflows_folder() | ||||
|     file_filter = "JSON Files (*.json);;All Files (*.*)" | ||||
|     dlg = FileDialog.getSaveFileName(None, "Save Workflow", os.path.join("Workflows", ""), file_filter) | ||||
|     file_path = dlg[0] | ||||
|     if not file_path: | ||||
|         return  # User canceled | ||||
|  | ||||
|     if not file_path.lower().endswith(".json"): | ||||
|         file_path += ".json" | ||||
|  | ||||
|     try: | ||||
|         graph.save_session(file_path) | ||||
|         print(f"Workflow saved to {file_path}") | ||||
|     except Exception as e: | ||||
|         QtWidgets.QMessageBox.critical(None, "Error Saving Workflow", str(e)) | ||||
|  | ||||
| def load_workflow(graph: NodeGraph): | ||||
|     """ | ||||
|     Loads a workflow (including node values, connections, positions, etc.) from a specified JSON file. | ||||
|     """ | ||||
|     ensure_workflows_folder() | ||||
|     file_filter = "JSON Files (*.json);;All Files (*.*)" | ||||
|     dlg = FileDialog.getOpenFileName(None, "Load Workflow", os.path.join("Workflows", ""), file_filter) | ||||
|     file_path = dlg[0] | ||||
|     if not file_path: | ||||
|         return  # User canceled | ||||
|  | ||||
|     try: | ||||
|         graph.load_session(file_path) | ||||
|         print(f"Workflow loaded from {file_path}") | ||||
|     except Exception as e: | ||||
|         QtWidgets.QMessageBox.critical(None, "Error Loading Workflow", str(e)) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     app = QtWidgets.QApplication([]) | ||||
|  | ||||
| @@ -140,6 +203,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)) | ||||
|  | ||||
|     # Grid styling changes | ||||
|     graph.set_background_color(20, 20, 20)  # Dark gray | ||||
|     graph.set_grid_color(60, 60, 60)        # Gray grid lines | ||||
| @@ -151,7 +220,7 @@ if __name__ == "__main__": | ||||
|     gradient.setColorAt(0.0, QtGui.QColor(9, 44, 68))   | ||||
|     gradient.setColorAt(0.3, QtGui.QColor(30, 30, 30)) | ||||
|     gradient.setColorAt(0.7, QtGui.QColor(30, 30, 30)) | ||||
|     gradient.setColorAt(1.0, QtGui.QColor(9, 44, 68))   | ||||
|     gradient.setColorAt(1.0, QtGui.QColor(9, 44, 68)) | ||||
|     scene.setBackgroundBrush(QtGui.QBrush(gradient)) | ||||
|  | ||||
|     # Resize and show the graph widget | ||||
|   | ||||
		Reference in New Issue
	
	Block a user