Added Status Bar with Flask API Server Link Exposing Variables captured in Borealis for use by other applications / systems

Added a menubar for workflow management (Save/Load/Close), as well as an About section for credits, updating, and finding the Gitea project on the Bunny Lab Gitea repository.
Added automatic workflow centering when you load a workflow, so it spawns the loaded JSON nodes in the center instead of off-screen somewhere at the exact original coordinates.
Changed the context menu and hyperlink colors to a more muted blue color
This commit is contained in:
Nicole Rappe 2025-02-25 17:39:01 -07:00
parent 9d3ef80f57
commit db848211fd

View File

@ -97,7 +97,7 @@ def save_workflow(graph: NodeGraph):
def load_workflow(graph: NodeGraph):
"""
Loads a workflow (including node values, connections, positions, etc.)
from a specified JSON file, and then centers the view on all loaded nodes.
from a specified JSON file, then centers the view on all loaded nodes.
"""
ensure_workflows_folder()
file_filter = "JSON Files (*.json);;All Files (*.*)"
@ -108,16 +108,15 @@ def load_workflow(graph: NodeGraph):
try:
graph.load_session(file_path)
# After loading, center the viewer on all nodes.
all_nodes = graph.all_nodes()
if all_nodes:
graph.viewer().zoom_to_nodes([node.view for node in all_nodes])
print(f"Workflow loaded from {file_path}")
except Exception as e:
QtWidgets.QMessageBox.critical(None, "Error Loading Workflow", str(e))
def import_nodes_from_folder(package_name):
"""
Recursively import all modules from the given package.
@ -219,21 +218,30 @@ class BorealisWindow(QtWidgets.QMainWindow):
# Create a status bar
self.setStatusBar(QtWidgets.QStatusBar(self))
# Default status message
self.update_status_bar("Flask Server: http://0.0.0.0:5000/data")
# Remove the resize handle from the status bar:
self.statusBar().setSizeGripEnabled(False)
# Add a permanent clickable link to the right side of the status bar:
self.link_label = QtWidgets.QLabel()
self.link_label.setTextFormat(QtCore.Qt.RichText)
self.link_label.setOpenExternalLinks(True)
# Add a couple spaces after the URL using  
# Also color style to match your "blue-ish" highlight:
self.link_label.setText(
"<a href='http://127.0.0.1:5000/data' "
"style='color: rgb(60,120,180); text-decoration: none;'>"
"Flask API Server: http://127.0.0.1:5000/data&nbsp;&nbsp;</a>"
)
self.statusBar().addPermanentWidget(self.link_label)
# Resize
self.resize(1200, 800)
def _build_graph_context_menu(self, custom_nodes_by_category):
"""
Build context menu and re-apply the custom stylesheet for a
'blue-ish' highlight, removing the pink/purple highlight.
Build context menu and apply custom stylesheet for the 'blue-ish' highlight.
"""
# Grab the node graph's context menu
graph_context_menu = self.graph.get_context_menu("graph")
# We can define a custom style for the QMenu objects:
menu_stylesheet = """
QMenu {
background-color: rgb(30, 30, 30);
@ -253,22 +261,15 @@ class BorealisWindow(QtWidgets.QMainWindow):
margin: 4px 8px;
}
"""
# Apply the custom style
if graph_context_menu and graph_context_menu.qmenu:
graph_context_menu.qmenu.setStyleSheet(menu_stylesheet)
# Top-level "Add Nodes" folder in the context menu
add_nodes_menu = graph_context_menu.add_menu("Add Nodes")
# If you want the same style for "Add Nodes" submenus:
if add_nodes_menu and add_nodes_menu.qmenu:
add_nodes_menu.qmenu.setStyleSheet(menu_stylesheet)
# For each category, build a submenu under "Add Nodes"
for category, node_classes in custom_nodes_by_category.items():
category_menu = add_nodes_menu.add_menu(category)
# Also reapply style for each new sub-menu:
if category_menu and category_menu.qmenu:
category_menu.qmenu.setStyleSheet(menu_stylesheet)
@ -280,7 +281,6 @@ class BorealisWindow(QtWidgets.QMainWindow):
make_node_command(self.graph, node_type)
)
# Provide a way to remove selected nodes
graph_context_menu.add_command(
"Remove Selected Node",
lambda: [self.graph.remove_node(node)
@ -288,12 +288,10 @@ class BorealisWindow(QtWidgets.QMainWindow):
if self.graph.selected_nodes() else None
)
# No 'Workflows' portion here because we moved it into the top menubar.
def _build_menubar(self):
menubar = self.menuBar()
# 1) Workflows menu in menubar
# Workflows menu
workflows_menu = menubar.addMenu("Workflows")
load_action = QtWidgets.QAction("Load Workflow", self)
@ -308,20 +306,17 @@ class BorealisWindow(QtWidgets.QMainWindow):
close_action.triggered.connect(lambda: close_workflow(self.graph))
workflows_menu.addAction(close_action)
# 2) About menu
# About menu
about_menu = menubar.addMenu("About")
# "Gitea Project" option
gitea_action = QtWidgets.QAction("Gitea Project", self)
gitea_action.triggered.connect(self._open_gitea_project)
about_menu.addAction(gitea_action)
# "Credits" option
credits_action = QtWidgets.QAction("Credits", self)
credits_action.triggered.connect(self._show_credits_popup)
about_menu.addAction(credits_action)
# "Check for Updates" option
updates_action = QtWidgets.QAction("Check for Updates", self)
updates_action.triggered.connect(self._show_updates_popup)
about_menu.addAction(updates_action)
@ -344,15 +339,6 @@ class BorealisWindow(QtWidgets.QMainWindow):
"Built-in update functionality has not been built yet, but it's on the roadmap. Stay tuned."
)
def update_status_bar(self, data: str):
"""
Flattens multi-line data into a single line
(using ' | ' to replace newlines)
and shows it in the status bar.
"""
flattened = data.replace("\n", " | ")
self.statusBar().showMessage(flattened)
def main():
app = QtWidgets.QApplication(sys.argv)