From 6888b55612dd9eb8443e298dc4d9c219612246f3 Mon Sep 17 00:00:00 2001
From: Nicole Rappe <nicole.rappe@bunny-lab.io>
Date: Sun, 16 Feb 2025 21:07:26 -0700
Subject: [PATCH] Fixed On-Screen OCR region Overlay

---
 .../data_collector.cpython-312.pyc            | Bin 11112 -> 10299 bytes
 Modules/data_collector.py                     | 186 ++++++++----------
 .../Flyff/Resources/bars_template.png         | Bin
 ...lyff_character_status_node.cpython-312.pyc | Bin 5005 -> 5251 bytes
 Nodes/Flyff/flyff_character_status_node.py    |  53 +++--
 5 files changed, 108 insertions(+), 131 deletions(-)
 rename bars_template.png => Nodes/Flyff/Resources/bars_template.png (100%)

diff --git a/Modules/__pycache__/data_collector.cpython-312.pyc b/Modules/__pycache__/data_collector.cpython-312.pyc
index bb082f31f103164178cd6209590e8da85690ec89..2cfb3154669bcf66305291adf2b72ceea8d6040a 100644
GIT binary patch
literal 10299
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
L@Sg;#@$UZ@-k24E

literal 11112
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
E57<SoU;qFB

diff --git a/Modules/data_collector.py b/Modules/data_collector.py
index 2144aa8..bc2e29e 100644
--- a/Modules/data_collector.py
+++ b/Modules/data_collector.py
@@ -3,12 +3,13 @@
 import threading
 import time
 import re
+import sys
 import numpy as np
 import cv2
 import pytesseract
 from PIL import Image, ImageGrab, ImageFilter
 
-from PyQt5.QtWidgets import QWidget, QApplication
+from PyQt5.QtWidgets import QApplication, QWidget
 from PyQt5.QtCore import QRect, QPoint, Qt, QMutex, QTimer
 from PyQt5.QtGui import QPainter, QPen, QColor, QFont
 
@@ -21,19 +22,37 @@ LABEL_HEIGHT = 20
 
 collector_mutex = QMutex()
 regions = {}
-overlay_window = None
+
+app_instance = None
+
+def _ensure_qapplication():
+    """
+    Ensures that QApplication is initialized before creating widgets.
+    """
+    global app_instance
+    if QApplication.instance() is None:
+        print("Starting QApplication in a separate thread.")
+        app_instance = QApplication(sys.argv)
+        threading.Thread(target=app_instance.exec_, daemon=True).start()
 
 def create_ocr_region(region_id, x=250, y=50, w=DEFAULT_WIDTH, h=DEFAULT_HEIGHT):
+    """
+    Creates an OCR region with a visible, resizable box on the screen.
+    """
+    print(f"Creating OCR Region: {region_id} at ({x}, {y}, {w}, {h})")
+    
+    _ensure_qapplication()  # Ensure QApplication is running first
+
     collector_mutex.lock()
     if region_id in regions:
         collector_mutex.unlock()
         return
     regions[region_id] = {
         'bbox': [x, y, w, h],
-        'raw_text': ""
+        'raw_text': "",
+        'widget': OCRRegionWidget(x, y, w, h, region_id)
     }
     collector_mutex.unlock()
-    _ensure_overlay()
 
 def get_raw_text(region_id):
     collector_mutex.lock()
@@ -69,6 +88,8 @@ def _update_ocr_loop():
                 regions[rid]['raw_text'] = raw_text
             collector_mutex.unlock()
 
+            print(f"OCR Text for {rid}: {raw_text}")
+
         time.sleep(0.7)
 
 def _preprocess_image(image):
@@ -77,130 +98,87 @@ def _preprocess_image(image):
     thresh = scaled.point(lambda p: 255 if p > 200 else 0)
     return thresh.filter(ImageFilter.MedianFilter(3))
 
-def _ensure_overlay():
-    """
-    Creates the overlay window if none exists.
-    If no QApplication instance is running yet, schedule the creation after
-    the main application event loop starts (to avoid "Must construct a QApplication first" errors).
-    """
-    global overlay_window
-    if overlay_window is not None:
-        return
+class OCRRegionWidget(QWidget):
+    def __init__(self, x, y, w, h, region_id):
+        super().__init__()
 
-    # If there's already a running QApplication, create overlay immediately.
-    if QApplication.instance() is not None:
-        overlay_window = OverlayCanvas()
-        overlay_window.show()
-    else:
-        # Schedule creation for when the app event loop is up.
-        def delayed_create():
-            global overlay_window
-            if overlay_window is None:
-                overlay_window = OverlayCanvas()
-                overlay_window.show()
-
-        QTimer.singleShot(0, delayed_create)
-
-class OverlayCanvas(QWidget):
-    def __init__(self, parent=None):
-        super().__init__(parent)
-        screen_geo = QApplication.primaryScreen().geometry()
-        self.setGeometry(screen_geo)
-        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
+        self.setGeometry(x, y, w, h)
+        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
         self.setAttribute(Qt.WA_TranslucentBackground, True)
+        self.setAttribute(Qt.WA_TransparentForMouseEvents, False)
 
         self.drag_offset = None
         self.selected_handle = None
-        self.selected_region_id = None
+        self.region_id = region_id
+
+        print(f"OCR Region Widget Created at {x}, {y}, {w}, {h}")
+
+        self.show()
 
     def paintEvent(self, event):
         painter = QPainter(self)
         pen = QPen(QColor(0, 0, 255))
-        pen.setWidth(5)
+        pen.setWidth(3)
         painter.setPen(pen)
 
-        collector_mutex.lock()
-        region_copy = {rid: data['bbox'][:] for rid, data in regions.items()}
-        collector_mutex.unlock()
+        # Draw main rectangle
+        painter.drawRect(0, 0, self.width(), self.height())
 
-        for rid, bbox in region_copy.items():
-            x, y, w, h = bbox
-            painter.drawRect(x, y, w, h)
-            painter.setFont(QFont("Arial", 12, QFont.Bold))
-            painter.setPen(QColor(0, 0, 255))
-            painter.drawText(x, y - 5, f"OCR Region: {rid}")
+        # Draw resize handles
+        painter.setBrush(QColor(0, 0, 255))
+        for handle in self._resize_handles():
+            painter.drawRect(handle)
+
+    def _resize_handles(self):
+        w, h = self.width(), self.height()
+        return [
+            QRect(0, 0, HANDLE_SIZE, HANDLE_SIZE),  # Top-left
+            QRect(w - HANDLE_SIZE, h - HANDLE_SIZE, HANDLE_SIZE, HANDLE_SIZE)  # Bottom-right
+        ]
 
     def mousePressEvent(self, event):
         if event.button() == Qt.LeftButton:
-            collector_mutex.lock()
-            all_items = list(regions.items())
-            collector_mutex.unlock()
-
-            for rid, data in all_items:
-                x, y, w, h = data['bbox']
-                handles = self._resize_handles(x, y, w, h)
-                for i, handle_rect in enumerate(handles):
-                    if handle_rect.contains(event.pos()):
-                        self.selected_handle = i
-                        self.selected_region_id = rid
-                        return
-                if QRect(x, y, w, h).contains(event.pos()):
-                    self.drag_offset = event.pos() - QPoint(x, y)
-                    self.selected_region_id = rid
+            for i, handle in enumerate(self._resize_handles()):
+                if handle.contains(event.pos()):
+                    self.selected_handle = i
                     return
 
-    def mouseMoveEvent(self, event):
-        if not self.selected_region_id:
-            return
-        collector_mutex.lock()
-        if self.selected_region_id not in regions:
-            collector_mutex.unlock()
-            return
-        bbox = regions[self.selected_region_id]['bbox']
-        collector_mutex.unlock()
+            self.drag_offset = event.pos()
 
-        x, y, w, h = bbox
+    def mouseMoveEvent(self, event):
         if self.selected_handle is not None:
-            # resizing
-            if self.selected_handle == 0:  # top-left
-                new_w = w + (x - event.x())
-                new_h = h + (y - event.y())
-                new_x = event.x()
-                new_y = event.y()
-                if new_w < 10: new_w = 10
-                if new_h < 10: new_h = 10
-                collector_mutex.lock()
-                if self.selected_region_id in regions:
-                    regions[self.selected_region_id]['bbox'] = [new_x, new_y, new_w, new_h]
-                collector_mutex.unlock()
-            elif self.selected_handle == 1:  # bottom-right
-                new_w = event.x() - x
-                new_h = event.y() - y
-                if new_w < 10: new_w = 10
-                if new_h < 10: new_h = 10
-                collector_mutex.lock()
-                if self.selected_region_id in regions:
-                    regions[self.selected_region_id]['bbox'] = [x, y, new_w, new_h]
-                collector_mutex.unlock()
+            w, h = self.width(), self.height()
+            if self.selected_handle == 0:  # Top-left
+                new_w = w + (self.x() - event.globalX())
+                new_h = h + (self.y() - event.globalY())
+                new_x = event.globalX()
+                new_y = event.globalY()
+                if new_w < 20: new_w = 20
+                if new_h < 20: new_h = 20
+                self.setGeometry(new_x, new_y, new_w, new_h)
+            elif self.selected_handle == 1:  # Bottom-right
+                new_w = event.globalX() - self.x()
+                new_h = event.globalY() - self.y()
+                if new_w < 20: new_w = 20
+                if new_h < 20: new_h = 20
+                self.setGeometry(self.x(), self.y(), new_w, new_h)
+
+            collector_mutex.lock()
+            if self.region_id in regions:
+                regions[self.region_id]['bbox'] = [self.x(), self.y(), self.width(), self.height()]
+            collector_mutex.unlock()
+
             self.update()
         elif self.drag_offset:
-            # dragging
-            new_x = event.x() - self.drag_offset.x()
-            new_y = event.y() - self.drag_offset.y()
+            new_x = event.globalX() - self.drag_offset.x()
+            new_y = event.globalY() - self.drag_offset.y()
+            self.move(new_x, new_y)
+
             collector_mutex.lock()
-            if self.selected_region_id in regions:
-                regions[self.selected_region_id]['bbox'][0] = new_x
-                regions[self.selected_region_id]['bbox'][1] = new_y
+            if self.region_id in regions:
+                regions[self.region_id]['bbox'] = [new_x, new_y, self.width(), self.height()]
             collector_mutex.unlock()
-            self.update()
 
     def mouseReleaseEvent(self, event):
         self.selected_handle = None
         self.drag_offset = None
-        self.selected_region_id = None
-
-    def _resize_handles(self, x, y, w, h):
-        return [
-            QRect(x - HANDLE_SIZE//2, y - HANDLE_SIZE//2, HANDLE_SIZE, HANDLE_SIZE),  # top-left
-            QRect(x + w - HANDLE_SIZE//2, y + h - HANDLE_SIZE//2, HANDLE_SIZE, HANDLE_SIZE)  # bottom-right
-        ]
diff --git a/bars_template.png b/Nodes/Flyff/Resources/bars_template.png
similarity index 100%
rename from bars_template.png
rename to Nodes/Flyff/Resources/bars_template.png
diff --git a/Nodes/Flyff/__pycache__/flyff_character_status_node.cpython-312.pyc b/Nodes/Flyff/__pycache__/flyff_character_status_node.cpython-312.pyc
index fa3bce4df7419ac6a8d5d8ad797194cd1380c04e..3192abdb659b64b895a81563a4a6881051ecb2b6 100644
GIT binary patch
delta 1852
zcmZuxTSy#N7(QoqE@x+Fc6Gg=M$O>08_lYywb;})ST7AttKvh@gk{;8+BNI$_RNSE
z##nj*11Ta0T1#8nJXH}IXbL4SKDG~q5Q(j2h*U}-p--vWzVxN%%sN>G2j;*3|2OlW
z|NNgcei%`IQB@hxr{st4C%#)z%i-8cV|x?=9qM8VP5H<CQ}UP$0S5+vE`0=aWcW6G
zECYbCz#JFx&)-^EtmL}om7khc_M>4fp4PSLtRA-vQ!}l&HBIiodOvi;;nC!jfyqPo
zC-*6L_ebtAT(qikl>pc{5^N9)c{UqNR(o=uPilGDlO}6DDbHzkU0(B~4VaT4p#HAY
z$~StUd9Ih|)8;^=f_%;YRm<9zd`eppDRu;NI%{C;rzQu*V###Uip8)<z7?)QiSS}u
z2Nsx5uviNmiLuPI<w%K4I&CB@N6q3)!Z1ymnx%GuHV#{)QyhmHSrHqgFwHh)NH)b@
zxJRN=HR+N{=&Skm%A3else1e|D&0X1Tc}|hz3@9ymerf;gVNS*)OIL>(n@k=iN7T?
zyL?mLK^0r5Vh7c1p_*?xc4|AfYCE^li_g7fTc~Wc_*YbYKv6-0Be%I?d4&GyXTXM&
zkX+*{$Zyi;<vo_f0@$PTwr_*W$q<ky!RiKGuzk8%PHmoJAz%k^ho$Di0I&m-A@UT}
zck(A~o<GlZ<Q;&=7lb^BbOJ=Nl@lP!5r}vUgxd1OJ?Rt>DG!29fT*^50z^FmLB~L-
z%`2Vfr-1l#Ab#2|`2<MN4&rlGp_gn2b0B9zc1Rbm({5u<7Z;coxc<7U1;~B57Aj<4
zPL!4m<wh!*p3vUz9ns!QrVX>3j0So%zayL3RMJW@6B{<1%sRf5k#>YEPNprg5vYMt
zazC&JTgi-aNjyit!CWRkEAfIyO5uZWWUX^sVUtx>akoi51DgjRC>(?)yA!0Ozm8uI
zQ<6BkYwiy)7uy>L9}pbutvoh5(1zZGxVO?z?gd*2=c^(@D0H6tQu5B+^`6#KA00pL
z3!n?+VyFm)$TNR2(j}XBP49(@s!mHny5APvh})r}#nU2WJzygmp?r00w&&DHaQ>34
z9X-AARLambdi#?ZJ(-}|oMvT?7NC}RH;&^8%fPu!Xln1^%oIC~=<@>e>PUP>TVy9R
zYRp>Q5ed_?1h|ipentiu8D!)QMv56>cW9m;9O~8_*n$gO?K0IcTNLwrKNDHtywG>W
z4XS@Df-t+Tjxu3bF&v+XSriV}Qxkp}(9MO1m?)CXf?6@k#Eaxf!7Kh&CN@(-x(d%n
zcB$|_I7FbhW~V5+RTN#b?%Y_v@vx|82|YsUQf76Q?w`Gmm&nJ3_h1`&HQX1_SOvFu
zGg%IoRJ2gtWTWvKc8jyE>8{Qo*$kK0o!xJ36vpAdBd|<p$8DZ7qBv44re_j#v0fnm
zg_~_<Xl~f*j1F798EoYCt8_V|Pp1qMi!6=(u3LB=<mxau2VIzQgL?2JRoQo#5lWu<
lAcTMOJme1)0Oehv?SjT#aP|+-ddOdcuzhv*AHcX<>VL>%e3<|M

delta 1657
zcma)6TTEO<7@pZZw>@VM%d$n>wzPwk%fdowu`v>XRxDy8$dek{WOLYafJ2u(o0+rH
zC5PfIUJ@@M<AX`9>60npp{b1zCi?E>r9>MNOk+&?)Te6E_~3*89J(o+Xv!q#oB3zH
z`M<fH@2$*-9p;awsUs*~z4PVlKdWXMPpo$Iw=ZZ@8b%THJhGLyk*zw>^{8MWG!?5v
zGMd$o5z_fhscH3!)J-}koJI1oLz(LpGXpy5A!8OJMUS|}QrTxmy|ORrUY)Fd(T&OK
zM(;|Nlq|{|MqHoFIn)6v@#h?vWII`%5MmW=!W^Fw+w!g4f>pF;9ooUj*kqQB!#4`w
z=~pL-mCt+Bc8jxx3gqu0rwYs?<r2&alQZHiLT2ZJPi9=FU^BAl`g5dSXoV}V$!k`j
z?C>OR<0tWNkvsTCD}Yo%nKb`ax_c-FyUx^Y$*f#*DAgd^(sDVs==!-FmH7|yIjryw
z<rx1!IjbCo;iVRyY)B`noPE&6HW6=BN9217ikZBm0$C*@+Mngu)I-hN(BHJFwQp$c
zKWm*K>tpkM^X6lHx3putMLU28_@MSp^ti9`mm&wJY$=G^avCzPM*yHK8-YQe^o^Ye
zp}?3otL=xit*pbviBheXrP?{X&uELvyJeIbnRpPdk%{k7M%g6;b3z$)w~SgNV+Ll8
zjJZb{ZI=wp31wnCGBdUYhZd`msSE08m!H@<5;(NFJ<244ge{+kqo)yDUKWvl{<$#H
zdC6$S2LHs!^SbyT*7%F@G%v(ka3}vLeie7|r_3`-78Kc={9V(E-f2qT_}e^yvm+QK
z$1oFrBX1miTv}@Y$UnHQaD`$>{D$}E`EX)H3eddD--xF8^~6DbJ=V<cCK4<7GqrlP
z7y;wI9zn#829ZlhJfchJvQ&LS|I3$cC6GeC{3t#jGL$oL&`L;GA4M12vSYR$Xuvlv
zM;|Vw63>`R7XPlkd1bm1I>T(io3;wXcNZKg+@j)@DOs?fWtB<=H*fjiKBRNnqmET@
zS#PP50Yi9DGAbPeEjlD%SingErvyAJASECUuq2I54v;N;l!|AuB#jS4NRwfER5S&1
zNe1f?thNcrtU%9JeAe-E)LP65uc1evi@qR0=2w!fN~dTJ@b8m@sV>1bOVrCdjDe4U
zGx9`3Ps=Une;sY>Xx|f?sosrL?^XZW#kGq+rH0<qz!6S7&7Fp?aW_AlI&BD>*-8Hj
z_fn1fGY~WJR8CTnK6I%N>iOrX^pWF#^tH)n@m~`-E%(#zDkGzBskxl(<-y2K@Ly8d
z8Fk#V%LRu~S#ZR@!YpfOXHvLy?U{v;G(__-E<{;7z`ZEO_;*Rg()|X6_1lQtMjgMR
SzHR9o#{HjO_!Egb%=0gxJXzuZ

diff --git a/Nodes/Flyff/flyff_character_status_node.py b/Nodes/Flyff/flyff_character_status_node.py
index afd9701..3a2b5ef 100644
--- a/Nodes/Flyff/flyff_character_status_node.py
+++ b/Nodes/Flyff/flyff_character_status_node.py
@@ -1,46 +1,44 @@
 #!/usr/bin/env python3
 """
-Flyff Character Status Node (New Version):
- - Has no inputs/outputs.
- - Creates an OCR region in data_collector.
- - Periodically grabs raw text from that region, parses it here in the node,
-   and sets data_manager's HP, MP, FP, EXP accordingly.
- - Also updates its own text fields with the parsed values.
+Flyff Character Status Node:
+- Creates an OCR region in data_collector.
+- Periodically grabs raw text from that region and updates status.
 """
 
 import re
 from OdenGraphQt import BaseNode
 from PyQt5.QtWidgets import QMessageBox
+from PyQt5.QtCore import QTimer  # Corrected import
 from Modules import data_manager, data_collector
 
 class FlyffCharacterStatusNode(BaseNode):
-    __identifier__ = 'bunny-lab.io.flyff_character_status_node'
-    NODE_NAME = 'Flyff - Character Status'
+    __identifier__ = "bunny-lab.io.flyff_character_status_node"
+    NODE_NAME = "Flyff - Character Status"
 
     def __init__(self):
         super(FlyffCharacterStatusNode, self).__init__()
-        # Prevent duplicates
+
         if data_manager.character_status_collector_exists:
             QMessageBox.critical(None, "Error", "Only one Flyff Character Status Collector node is allowed.")
             raise Exception("Duplicate Character Status Node.")
         data_manager.character_status_collector_exists = True
 
-        # Add text fields for display
-        self.add_text_input('hp', 'HP', text="HP: 0/0")
-        self.add_text_input('mp', 'MP', text="MP: 0/0")
-        self.add_text_input('fp', 'FP', text="FP: 0/0")
-        self.add_text_input('exp', 'EXP', text="EXP: 0%")
+        self.add_text_input("hp", "HP", text="HP: 0/0")
+        self.add_text_input("mp", "MP", text="MP: 0/0")
+        self.add_text_input("fp", "FP", text="FP: 0/0")
+        self.add_text_input("exp", "EXP", text="EXP: 0%")
 
-        # Create a unique region id for this node (or just "character_status")
         self.region_id = "character_status"
         data_collector.create_ocr_region(self.region_id, x=250, y=50, w=180, h=130)
 
-        # Start the data_collector background thread (if not already started)
         data_collector.start_collector()
-
-        # Set the node name
         self.set_name("Flyff - Character Status")
 
+        # Set up a timer to periodically update character stats
+        self.timer = QTimer()
+        self.timer.timeout.connect(self.process_input)
+        self.timer.start(1000)  # Update every second
+
     def parse_character_stats(self, raw_text):
         """
         Extract HP, MP, FP, EXP from the raw OCR text lines.
@@ -52,6 +50,8 @@ class FlyffCharacterStatusNode(BaseNode):
         exp_value = 0.0
 
         if len(lines) >= 4:
+            print("Processing OCR Lines:", lines)  # Debugging output
+
             # line 1: HP
             hp_match = re.search(r"(\d+)\s*/\s*(\d+)", lines[0])
             if hp_match:
@@ -82,15 +82,14 @@ class FlyffCharacterStatusNode(BaseNode):
 
     def process_input(self):
         """
-        Called periodically by the global timer in your main application (borealis.py).
+        Called periodically to update character status from OCR.
         """
-        # Grab raw text from data_collector
         raw_text = data_collector.get_raw_text(self.region_id)
+        print("Raw OCR Text:", raw_text)  # Debugging OCR text reading
 
-        # Parse it
         hp_c, hp_t, mp_c, mp_t, fp_c, fp_t, exp_v = self.parse_character_stats(raw_text)
 
-        # Update data_manager
+        # Update the data manager with the parsed values
         data_manager.set_data_bulk({
             "hp_current": hp_c,
             "hp_total": hp_t,
@@ -101,8 +100,8 @@ class FlyffCharacterStatusNode(BaseNode):
             "exp": exp_v
         })
 
-        # Update the node's text fields
-        self.set_property('hp', f"HP: {hp_c}/{hp_t}")
-        self.set_property('mp', f"MP: {mp_c}/{mp_t}")
-        self.set_property('fp', f"FP: {fp_c}/{fp_t}")
-        self.set_property('exp', f"EXP: {exp_v}%")
+        # Update the node's UI text fields
+        self.set_property("hp", f"HP: {hp_c}/{hp_t}")
+        self.set_property("mp", f"MP: {mp_c}/{mp_t}")
+        self.set_property("fp", f"FP: {fp_c}/{fp_t}")
+        self.set_property("exp", f"EXP: {exp_v}%")