From 2c2ea67775666c39ee4bd5d4ae60e21e21cb799b Mon Sep 17 00:00:00 2001
From: Nicole Rappe <nicole.rappe@bunny-lab.io>
Date: Sun, 16 Feb 2025 01:01:58 -0700
Subject: [PATCH] Added Custom Blueprint Background

---
 .../graph_gradient_style.cpython-312.pyc      | Bin 0 -> 1395 bytes
 .../borealis_graph_style.cpython-312.pyc      | Bin 0 -> 1793 bytes
 __pycache__/myscene.cpython-312.pyc           | Bin 0 -> 1326 bytes
 borealis.py                                   |  94 ++++++++++--------
 4 files changed, 55 insertions(+), 39 deletions(-)
 create mode 100644 Modules/__pycache__/graph_gradient_style.cpython-312.pyc
 create mode 100644 __pycache__/borealis_graph_style.cpython-312.pyc
 create mode 100644 __pycache__/myscene.cpython-312.pyc

diff --git a/Modules/__pycache__/graph_gradient_style.cpython-312.pyc b/Modules/__pycache__/graph_gradient_style.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a04d47a516b459332f85215ea361cce9f560b7fd
GIT binary patch
literal 1395
zcmZux&u<e)6n?Y6vQBJ6iHdNWRtrLv_TnNyQH79&sG6LJ2<d4RX|(K464Uh$X2uGR
zER=(#rih3W3P*ZEC>Q!4aOZ>+M6@abwWr=t0|Ig4y<OWatw-|no0&K7z3=n){G?Qx
z1YG9b-&X%H0RE)SaM=UrU>2Pnh#_VPG+4kG`9@+i%)o3|fyKapd5FzE#Fk*YX8ta)
zySDHAMH`=`g@slumLky<zL7eM`umm?slBM@JM}1!&+Xtb9Gt@a&sbJKz+woD*xG^>
z7PEdKFk_<+LB2QpZeVZ04Hh^{;M?huc^S6X(8P7o)JwXXhzNm=7UieU!8tT{*$(K@
zl^(_QV0#Ln$97qMNq~F6hrK};9<l}BN^R9?3n?csDs?%pH|v`7w7^#f<$W`?lt@-m
zryWXc2d{XPgi3L)D4FMNemFCCZuzooT@#V!7m<`OsjKBnt+<m2wTy|{Yol~r5u9qf
zE3rG+`11cytHUPfw^LuBdA|w2yQRIdcmL#5_tc}Kd+vApm9Ms}?eYQM!YAAi{*0T`
z=<FbV#7sfi>cO=U{^1$G?!aZxWxla7yCk&oLNDql-D-G49=xlvqt?8Ymh|+R@D$0w
zyBbD6t;$xX8CMs4Ll!Yp>U7$1s8J%aL|b>5Kv8R+ClAx<v=W-<6-Lx-d^3iOF>wV<
zppKx~gjbd0Th{IJzFWLA^~=<DNq&aM(Z4ZTc#!dN6CKhDa)91{mz?RbaoqHb@$tI@
zoiWf<AzRuRdZ@i=(q7N_C$0;U8u#s-C3mHsBv(){l7=^zUpbcH`o$5YzLhgL(GKfP
zEo5p*ia&($ii&zDy^KwH40jvH$FTQl!ZN)iU7(;|O&z*ZyH(pSPCqZsJT1=L`|<wS
z2en^od&Sdl94M3rYMXtu{@8lv{*V!y1DK#OX@(7fV=~EkBa=D$Mb58x!X&@R)Ga^9
zT3K^xX)rXAND|I{mZPB2ypThn`O8=!WU7MZeIMQ$hW+*5u4x~AH|f}O>@|?hd!Yvl
zzLQqyPbq`GsH^Mscoo%K&D1IBcTbH)Eh(p@amp$@ggiqgME86Spe9e?JvEdSe{C|x
WUck36Vdjl>n9Z?!mA63O+0&1i9YD1J

literal 0
HcmV?d00001

diff --git a/__pycache__/borealis_graph_style.cpython-312.pyc b/__pycache__/borealis_graph_style.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..19eece1b5c379afcc6a3ab2dc53e478f142485d0
GIT binary patch
literal 1793
zcmZuy&2Jk;6rWk|I-A5cg_Mf4X*GNZSOHd5RTYX*1Sur92op}LN~6v0B;K;#H8W$S
zi7b>uqy|LP6QmNCaza%uMf?NYIaLZGS|M@hiCZ9zs5tT7tk+3PM)LTL-^a}F{oZ^2
zrCuK+u)h2D#}#E0@(2&*at6ZTH4t`4L?W7y4)rNT*-ETV#jkX1-=@SO^CYTllE@Zx
zw^I1|&YI&@|HOkw^U;MY5{scog=gi}mcE`zkvlCt-;2Y-zSsxO<nSt-Z^N~M_%tHE
z6;ZzuIa_3zM%L!2Z{u}-ake*Izq&<kQGaBSc-8!cSqL5^v6`1bx4o#>60v@3jKR9z
zQ#$J~h3{Zt5-7!%Gs#MOrrUvLkqlN93)qSbqFAJwEd}9cD>Cb)kqNRSz(+6yWG-mw
zHxygy#fg3=PQfdVSQ4i~HH~#>oq&hv@N+l~+c$KF=%G>%?fPVUoRB`<rG*mH-6y=v
z3|S-h>4InHj_P%Vlp|o3yPU^qtU1p|dHHUylG{oo%XzgMNWcLqZZLDMFc@PS|GqUh
zedA-9-4vnbWfpEM4bq2^x^1p7fz9rkgjbRE3#FOCZj#$9FGmA)9=0bN<af8e*I@Tv
zd+1(%aBk0icYpHYmc89L1TA?gCy3kR<O&EofE%!)ky(9mbBMeAjgZ}eNXZ)Yto5Hv
zqLJT4p^>?;pt(#0TarE1Hcacb7_fg#YIAJp|AAal)58-+9L9LFHEW_kxwHVfsSIx#
zDn=aJfUdYoXRI5<SURE|r_sPFj*61NxC@>oYXBp!_PSA^p(|t^k8XLP!n`mh&)}~U
zN@!l78q&M|`YBADV)q;bP-kJ=AO{U{{*^8J>&CuYyEFdf_;y`B4~p<)ieU;AbbJ8<
zmMBmF(z8oW_33HU^sUqFcL(K7iN+hu($!LelApkm?_0-qhT7XhGCnk2nf2uV*j<jL
z(r;sqQx*nEqD;C?bFjG6O+*KZKhSZO4ub(d*yYdk@Nw(1EM+?Do}|ku=yI3iB>4o|
zMdIKrny-PeW`{$<vkNLmObG~?+Y;>!4~QMu-!Qbwm*BMi@+mYv9dHuN6wX6vtAiS;
zow+mf)y#fv;<wt=!`jr{Pw!p*Vdndpz1o$>RWjNbbltTFt3TVnx*r*a<tTW2E{=&b
z=m;1SW1M%gsF$Ez<NWhpkPI{<oJU#6xoLO#A~>3N=Jmn!2t|@`?$H7e&ZzebG&qP%
zLXcK<3AQJj<S(n@xJRz#T>9H}opb-39dqXB0l~d^8G0?i(4IUoPn)Z8v;wW%G=o}V
zdFED2OU$0cza?|ceNsd)9pb)Mz?qS+f*xO`F2HtBp_Cp~3BCLWnR;wrq;vG{<PpJd
G<NO~XcD!2v

literal 0
HcmV?d00001

diff --git a/__pycache__/myscene.cpython-312.pyc b/__pycache__/myscene.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..afa64ae97c2faa402dc848010a004361dbd9b0c7
GIT binary patch
literal 1326
zcmZux&1)M+6o0c{UfGi4)-<h&8@7cWmQp1RAqS_3l0bc`spFiMz_8g}$(yb|GBYBP
z5yb~V)e@6lf_qF(Y49ceJ9;RAgqkIgKu)=ZI;NqgzPF=Qo8kdIy*Ka8`}oao_P1JX
z7I2-~{k8SG0q}y1a@iB*;2bKu5JSu|XtRJZ(v8e$n}ON30*iqGs}P$bh^>U}nfhE{
z4{YCgNrunz%33#0Hln1H_(txmtBYNc<o3E+?Wd8B*K%?g4o;)}J(f)%U@-(nY>lDG
zVm7J-W^9Zg(6%{p1A7cNS>SAdZ|5^#4~i-gPBUGUlzs;*DDJRbP*azh#tmU-4q(Xk
zn0C^XL*QjYFn|Ya&9`z}_IrsCGZ>Y-oTr^sah_LrON4Qnbd+!AmQ1o{?({-|HoAC}
zg;H`ZDVgVO|9$eSl`G$f?zJRR`~o5oW~sc=9!SEc-Wv#P1hy6?qtweHR8lUXc(V;p
z-P*0zPwJ8T$=&8-_p|+_569Nd`~f=Qt<h<`V)Qep?BaMh5(O1&2-l|Lm3sht6P3Y$
z`Nr0{jYLT=^rF60-L_Yb>0K3lx#=~#!c&`xSG4Y34Wn;cqTBDp^)=rRRm_w-{azd@
zymnC|(=8K7YR&V+0_`r!L~&hV3gp&_5`ZI|gphm}#Wp-&`e<z3n%{S;x95JC+o_3n
za69_%U>0r^Abf`k-9HYF+W(hW9<rkV85&2&?@hSFKv9KaDW}wsPm9E-q496r07M1-
zzOA8gn`xF^LJ|mig_=_Hu?TNmnBwSL8n&5Un08bma!XMBF^rc~)I&NI5Q-1b+B#lB
z_I4J+SbmNIne%+^*zLxTjs5E4AJyeY)#aZr-#vT3aj)^XdgiqQm3d98Pk&i`c=?ID
zQh=$Oo*}w-!ghjmpXI#Wjr$qtRnD*X!%TY$>WcTURMAjgn~*<BvW#<|>CWkieW}|f
zQWujGaPoZ=Z$@xv81~6OUDH1P*Q{foe+4LXCltQsJNXiQPgX_P+gw-m8)@7^lGY0n
z3cBgsSXYAZ5%d)+@;?Bbq2QbQg>JtgK1M&aQ#`C!CS&Z-0e1QsEWfrE*!gjK2>4eV
F{Rgd#CcOXv

literal 0
HcmV?d00001

diff --git a/borealis.py b/borealis.py
index 01c299b..e1c7c03 100644
--- a/borealis.py
+++ b/borealis.py
@@ -1,36 +1,39 @@
+# -*- coding: utf-8 -*-
 #!/usr/bin/env python3
 
-# --- Patch QGraphicsScene.setSelectionArea to handle selection arguments ---
 from Qt import QtWidgets, QtCore, QtGui
-
-_original_setSelectionArea = QtWidgets.QGraphicsScene.setSelectionArea
-
-def _patched_setSelectionArea(self, *args, **kwargs):
-    try:
-        return _original_setSelectionArea(self, *args, **kwargs)
-    except TypeError as e:
-        # If only a QPainterPath is provided, supply default mode and transform.
-        if len(args) == 1:
-            painterPath = args[0]
-            return _original_setSelectionArea(self, painterPath,
-                                              QtCore.Qt.ReplaceSelection,
-                                              QtGui.QTransform())
-        raise e
-
-# Monkey-patch the setSelectionArea method.
-QtWidgets.QGraphicsScene.setSelectionArea = _patched_setSelectionArea
-
 import sys
 import pkgutil
 import importlib
 import inspect
-from Qt import QtWidgets, QtCore, QtGui
+
+# Patch QGraphicsScene.setSelectionArea to handle selection arguments
+_original_setSelectionArea = QtWidgets.QGraphicsScene.setSelectionArea
+
+def _patched_setSelectionArea(self, painterPath, second_arg, *args, **kwargs):
+    try:
+        # Try calling the original method with the provided arguments.
+        return _original_setSelectionArea(self, painterPath, second_arg, *args, **kwargs)
+    except TypeError:
+        # If a TypeError is raised, assume the call was made with only a QPainterPath
+        # and an ItemSelectionMode, and patch it by supplying defaults.
+        # Default operation: ReplaceSelection, default transform: QTransform()
+        return _original_setSelectionArea(
+            self,
+            painterPath,
+            QtCore.Qt.ReplaceSelection,
+            second_arg,
+            QtGui.QTransform()
+        )
+
+QtWidgets.QGraphicsScene.setSelectionArea = _patched_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.
+    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)
@@ -41,23 +44,19 @@ def import_nodes_from_folder(package_name):
                 imported_nodes.append(obj)
     return imported_nodes
 
-def make_node_command(graph, nt):
+def make_node_command(graph, node_type_str):
     """
-    Given a NodeGraph instance and a node type string nt, return a command
-    function that creates a node of that type at the current mouse location.
+    Return a function that creates a node of the given type at the current cursor position.
     """
     def command():
         try:
-            # Get the current cursor position in scene coordinates
             pos = graph.cursor_pos()
-            # Create the node with the current cursor position.
-            node = graph.create_node(nt, pos=pos)
+            graph.create_node(node_type_str, pos=pos)
         except Exception as e:
-            print(f"Error creating node of type {nt}: {e}")
+            print("Error creating node of type {}: {}".format(node_type_str, e))
     return command
 
-if __name__ == '__main__':
-
+if __name__ == "__main__":
     app = QtWidgets.QApplication([])
 
     # Create the NodeGraph controller.
@@ -65,18 +64,17 @@ if __name__ == '__main__':
     graph.widget.setWindowTitle("Project Borealis - Flyff Information Overlay")
 
     # Dynamically import custom node classes from the 'Nodes' package.
-    custom_nodes = import_nodes_from_folder('Nodes')
+    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')
+    graph_context_menu = graph.get_context_menu("graph")
     for node_class in custom_nodes:
-        # Build the node type string: "<__identifier__>.<ClassName>"
-        node_type = f"{node_class.__identifier__}.{node_class.__name__}"
+        node_type = "{}.{}".format(node_class.__identifier__, node_class.__name__)
         node_name = node_class.NODE_NAME
         graph_context_menu.add_command(
-            f"Add {node_name}",
+            "Add {}".format(node_name),
             make_node_command(graph, node_type)
         )
 
@@ -86,11 +84,28 @@ if __name__ == '__main__':
         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()
+
+    # A QLinearGradient that uses ObjectBoundingMode so it stretches to fill the 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(1920, 1080)
+    graph.widget.resize(1600, 900)
     graph.widget.show()
 
-    # Global update timer:
     def global_update():
         for node in graph.all_nodes():
             if hasattr(node, "process_input"):
@@ -98,8 +113,9 @@ if __name__ == '__main__':
                     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())
+    sys.exit(app.exec_())