Borealis-Legacy/borealis.py

147 lines
5.4 KiB
Python

# -*- coding: utf-8 -*-
#!/usr/bin/env python3
from Qt import QtWidgets, QtCore, QtGui
import sys
import pkgutil
import importlib
import inspect
# --- BEGIN MONKEY PATCH FOR PIPE COLOR (Optional) ---
# If you want custom pipe colors, uncomment this patch:
"""
try:
from OdenGraphQt.qgraphics.pipe import PipeItem
_orig_pipeitem_init = PipeItem.__init__
def _new_pipeitem_init(self, *args, **kwargs):
_orig_pipeitem_init(self, *args, **kwargs)
new_color = QtGui.QColor(29, 202, 151)
self._pen = QtGui.QPen(new_color, 2.0)
self._pen_dragging = QtGui.QPen(new_color, 2.0)
PipeItem.__init__ = _new_pipeitem_init
except ImportError:
print("WARNING: Could not patch PipeItem color - OdenGraphQt.qgraphics.pipe not found.")
"""
# --- END MONKEY PATCH FOR PIPE COLOR ---
# --- BEGIN ROBUST PATCH FOR QGraphicsScene.setSelectionArea ---
_original_setSelectionArea = QtWidgets.QGraphicsScene.setSelectionArea
def _patched_setSelectionArea(self, *args, **kwargs):
"""
A robust patch that handles various call signatures for QGraphicsScene.setSelectionArea().
We try calling the original method with whatever arguments are provided.
If a TypeError occurs, we assume it was missing some arguments and re-call with defaults.
"""
try:
# First, try the original call with the given arguments.
return _original_setSelectionArea(self, *args, **kwargs)
except TypeError:
# If a TypeError occurs, the caller likely used a minimal signature.
# We'll fallback to a known signature with default arguments.
if not args:
raise # If no args at all, we cannot fix it.
painterPath = args[0] # QPainterPath
selection_op = QtCore.Qt.ReplaceSelection
selection_mode = QtCore.Qt.IntersectsItemShape
transform = QtGui.QTransform()
return _original_setSelectionArea(self, painterPath, selection_op, selection_mode, transform)
QtWidgets.QGraphicsScene.setSelectionArea = _patched_setSelectionArea
# --- END ROBUST PATCH FOR QGraphicsScene.setSelectionArea ---
from OdenGraphQt import NodeGraph, BaseNode
def import_nodes_from_folder(package_name):
"""
Dynamically import all modules from the given package
and return a list of classes that subclass BaseNode.
"""
imported_nodes = []
package = importlib.import_module(package_name)
for loader, module_name, is_pkg in pkgutil.walk_packages(package.__path__, package.__name__ + "."):
module = importlib.import_module(module_name)
for name, obj in inspect.getmembers(module, inspect.isclass):
if issubclass(obj, BaseNode) and obj.__module__ == module.__name__:
imported_nodes.append(obj)
return imported_nodes
def make_node_command(graph, node_type_str):
"""
Return a function that creates a node of the given type at the current cursor position.
"""
def command():
try:
pos = graph.cursor_pos()
graph.create_node(node_type_str, pos=pos)
except Exception as e:
print(f"Error creating node of type {node_type_str}: {e}")
return command
if __name__ == "__main__":
app = QtWidgets.QApplication([])
# Create the NodeGraph controller.
graph = NodeGraph()
graph.widget.setWindowTitle("Project Borealis - Flyff Information Overlay")
# Dynamically import custom node classes from the 'Nodes' package.
custom_nodes = import_nodes_from_folder("Nodes")
for node_class in custom_nodes:
graph.register_node(node_class)
# Add context menu commands for dynamic node creation.
graph_context_menu = graph.get_context_menu("graph")
for node_class in custom_nodes:
node_type = f"{node_class.__identifier__}.{node_class.__name__}"
node_name = node_class.NODE_NAME
graph_context_menu.add_command(
f"Add {node_name}",
make_node_command(graph, node_type)
)
# Add a "Remove Selected Node" command to the graph context menu.
graph_context_menu.add_command(
"Remove Selected Node",
lambda: [graph.remove_node(node) for node in graph.selected_nodes()] if graph.selected_nodes() else None
)
# Grid styling changes
# 1) Dark background color
graph.set_background_color(20, 20, 20) # Dark gray
# 2) Subdued grid color
graph.set_grid_color(60, 60, 60) # Gray grid lines
# Optionally, create a subtle gradient in the scene:
scene = graph.scene()
gradient = QtGui.QLinearGradient(0, 0, 0, 1)
gradient.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
gradient.setColorAt(0.0, QtGui.QColor(9, 44, 68)) # Very Top Gradient
gradient.setColorAt(0.3, QtGui.QColor(30, 30, 30)) # Middle Gradient
gradient.setColorAt(0.7, QtGui.QColor(30, 30, 30)) # Middle Gradient
gradient.setColorAt(1.0, QtGui.QColor(9, 44, 68)) # Very Bottom Gradient
scene.setBackgroundBrush(QtGui.QBrush(gradient))
# Resize and show the graph widget.
graph.widget.resize(1600, 900)
graph.widget.show()
def global_update():
for node in graph.all_nodes():
if hasattr(node, "process_input"):
try:
node.process_input()
except Exception as e:
print("Error updating node", node, e)
timer = QtCore.QTimer()
timer.timeout.connect(global_update)
timer.start(500)
sys.exit(app.exec_())