feat: no gui mode working

This commit is contained in:
Prohurtz 2024-07-22 18:07:27 -05:00
parent e6ab12e30e
commit 4ae620eece
3 changed files with 448 additions and 417 deletions

View File

@ -115,20 +115,104 @@ class CameraWidget:
self.capture_queue,
)
self.hover = None
# cartesian co-ordinates in widget space are used during selection
self.xy0 = None
self.xy1 = None
self.cartesian_needs_update = False
# polar co-ordinates from the image center are the canonical representation
self.cr, self.ca = None, None
self.roi_size = None
self.clip_size = None
self.clip_pos = None
self.padded_size = None
self.img_pos = None
self.roi_image_center = None
self.is_mouse_up = True
self.hover_pos = None
self.in_roi_mode = False
self.movavg_fps_queue = deque(maxlen=120)
self.movavg_bps_queue = deque(maxlen=120)
def get_widget_layout(self):
self.widget_layout = [
[
sg.Text("Camera Address", background_color="#424042"),
sg.InputText(
self.config.capture_source,
key=self.gui_camera_addr,
tooltip="Enter the IP address or UVC port of your camera. (Include the 'http://')",
),
],
[
sg.Button(
"Save and Restart Tracking",
key=self.gui_save_tracking_button,
button_color="#6f4ca1",
),
],
[
sg.Button(
"Tracking Mode",
key=self.gui_tracking_button,
button_color="#6f4ca1",
tooltip="Go here to track your eye.",
),
sg.Button(
"Cropping Mode",
key=self.gui_roi_button,
button_color="#6f4ca1",
tooltip="Go here to crop out your eye.",
),
],
[
sg.Text("Rotation", background_color="#424042"),
sg.Slider(
range=(0, 360),
default_value=self.config.rotation_angle,
orientation="h",
key=self.gui_rotation_slider,
background_color="#424042",
tooltip="Adjust the rotation of your cameras, make them level.",
),
],
[
sg.Column(
self.tracking_layout,
key=self.gui_tracking_layout,
background_color="#424042",
),
sg.Column(
self.roi_layout,
key=self.gui_roi_layout,
background_color="#424042",
visible=False,
),
],
]
def get_roi_layout(self):
self.roi_layout = [
[
# sg.Button(
# sg.Button(
# "Mark Out",
# key=self.gui_mask_markup,
# button_color="#6f4ca1",
# tooltip="Mark out stuff that is not your eye.",
# ),
# sg.Button(
# "Lighten",
# key=self.gui_mask_lighten,
# button_color="#6f4ca1",
# tooltip="Lighten shadowed areas.",
# ),
# key=self.gui_mask_markup,
# button_color="#6f4ca1",
# tooltip="Mark out stuff that is not your eye.",
# ),
# sg.Button(
# "Lighten",
# key=self.gui_mask_lighten,
# button_color="#6f4ca1",
# tooltip="Lighten shadowed areas.",
# ),
sg.Checkbox(
"Camera Widget Padding",
default=self.config.gui_rotation_ui_padding,
@ -151,6 +235,7 @@ class CameraWidget:
],
]
def get_tracking_layout(self):
# Define the window's contents
self.tracking_layout = [
[
@ -208,82 +293,11 @@ class CameraWidget:
],
]
self.widget_layout = [
[
sg.Text("Camera Address", background_color="#424042"),
sg.InputText(
self.config.capture_source,
key=self.gui_camera_addr,
tooltip="Enter the IP address or UVC port of your camera. (Include the 'http://')",
),
],
[
sg.Button(
"Save and Restart Tracking",
key=self.gui_save_tracking_button,
button_color="#6f4ca1",
),
],
[
sg.Button(
"Tracking Mode",
key=self.gui_tracking_button,
button_color="#6f4ca1",
tooltip="Go here to track your eye.",
),
sg.Button(
"Cropping Mode",
key=self.gui_roi_button,
button_color="#6f4ca1",
tooltip="Go here to crop out your eye.",
),
],
[
sg.Text("Rotation", background_color="#424042"),
sg.Slider(
range=(0, 360),
default_value=self.config.rotation_angle,
orientation="h",
key=self.gui_rotation_slider,
background_color="#424042",
tooltip="Adjust the rotation of your cameras, make them level.",
),
],
[
sg.Column(
self.tracking_layout,
key=self.gui_tracking_layout,
background_color="#424042",
),
sg.Column(
self.roi_layout,
key=self.gui_roi_layout,
background_color="#424042",
visible=False,
),
],
]
self.hover = None
# cartesian co-ordinates in widget space are used during selection
self.xy0 = None
self.xy1 = None
self.cartesian_needs_update = False
# polar co-ordinates from the image center are the canonical representation
self.cr, self.ca = None, None
self.roi_size = None
self.clip_size = None
self.clip_pos = None
self.padded_size = None
self.img_pos = None
self.roi_image_center = None
self.is_mouse_up = True
self.hover_pos = None
self.in_roi_mode = False
self.movavg_fps_queue = deque(maxlen=120)
self.movavg_bps_queue = deque(maxlen=120)
def update_layouts(self):
self.get_roi_layout()
self.get_tracking_layout()
self.get_widget_layout()
def _movavg_fps(self, next_fps):
self.movavg_fps_queue.append(next_fps)
@ -417,6 +431,7 @@ class CameraWidget:
self.main_config.save()
if event == self.gui_tracking_button:
self.get_tracking_layout()
print("\033[94m[INFO] Moving to tracking mode\033[0m")
self.in_roi_mode = False
self.camera.set_output_queue(self.capture_queue)
@ -424,6 +439,7 @@ class CameraWidget:
window[self.gui_tracking_layout].update(visible=True)
if event == self.gui_roi_button:
self.get_roi_layout()
print("\033[94m[INFO] Move to roi mode\033[0m")
self.in_roi_mode = True
self.camera.set_output_queue(self.roi_queue)

View File

@ -41,6 +41,8 @@ from utils.misc_utils import is_nt, resource_path
import time
import cv2
import numpy as np
import uuid
if is_nt:
from winotify import Notification
@ -50,23 +52,159 @@ os.system("color") # init ANSI color
# https://github.com/opencv/opencv/issues/17687
os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0"
WINDOW_NAME = "EyeTrackApp"
RIGHT_EYE_NAME = "-RIGHTEYEWIDGET-"
LEFT_EYE_NAME = "-LEFTEYEWIDGET-"
SETTINGS_NAME = "-SETTINGSWIDGET-"
ALGO_SETTINGS_NAME = "-ALGOSETTINGSWIDGET-"
VRCFT_MODULE_SETTINGS_NAME = "-VRCFTSETTINGSWIDGET-"
LEFT_EYE_RADIO_NAME = "-LEFTEYERADIO-"
RIGHT_EYE_RADIO_NAME = "-RIGHTEYERADIO-"
BOTH_EYE_RADIO_NAME = "-BOTHEYERADIO-"
SETTINGS_RADIO_NAME = "-SETTINGSRADIO-"
ALGO_SETTINGS_RADIO_NAME = "-ALGOSETTINGSRADIO-"
VRCFT_MODULE_SETTINGS_RADIO_NAME = "-VRCFTSETTINGSRADIO-"
GUIOFF_RADIO_NAME = "-GUIOFF-"
page_url = "https://github.com/RedHawk989/EyeTrackVR/releases/latest"
appversion = "EyeTrackApp 0.2.0 BETA 13"
class KeyManager:
def __init__(self):
self.update_keys()
def update_keys(self):
unique_id = str(uuid.uuid4())
self.RIGHT_EYE_NAME = f"-RIGHTEYEWIDGET{unique_id}-"
self.LEFT_EYE_NAME = f"-LEFTEYEWIDGET{unique_id}-"
self.SETTINGS_NAME = f"-SETTINGSWIDGET{unique_id}-"
self.ALGO_SETTINGS_NAME = f"-ALGOSETTINGSWIDGET{unique_id}-"
self.VRCFT_MODULE_SETTINGS_NAME = f"-VRCFTSETTINGSWIDGET{unique_id}-"
self.LEFT_EYE_RADIO_NAME = f"-LEFTEYERADIO{unique_id}-"
self.RIGHT_EYE_RADIO_NAME = f"-RIGHTEYERADIO{unique_id}-"
self.BOTH_EYE_RADIO_NAME = f"-BOTHEYERADIO{unique_id}-"
self.SETTINGS_RADIO_NAME = f"-SETTINGSRADIO{unique_id}-"
self.ALGO_SETTINGS_RADIO_NAME = f"-ALGOSETTINGSRADIO{unique_id}-"
self.VRCFT_MODULE_SETTINGS_RADIO_NAME = f"-VRCFTSETTINGSRADIO{unique_id}-"
self.GUIOFF_RADIO_NAME = f"-GUIOFF{unique_id}-"
# Create an instance of the KeyManager
key_manager = KeyManager()
def create_window(config, settings, eyes):
key_manager.update_keys()
for eye in eyes:
eye.update_layouts()
layout = [
[
sg.Radio(
"Left Eye",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.LEFT),
key=key_manager.LEFT_EYE_RADIO_NAME,
),
sg.Radio(
"Right Eye",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.RIGHT),
key=key_manager.RIGHT_EYE_RADIO_NAME,
),
sg.Radio(
"Both Eyes",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.BOTH),
key=key_manager.BOTH_EYE_RADIO_NAME,
),
sg.Radio(
"Settings",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.SETTINGS),
key=key_manager.SETTINGS_RADIO_NAME,
),
sg.Radio(
"Algo Settings",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.ALGOSETTINGS),
key=key_manager.ALGO_SETTINGS_RADIO_NAME,
),
],
[
sg.Radio(
"VRCFT Module Settings",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.VRCFTMODULESETTINGS),
key=key_manager.VRCFT_MODULE_SETTINGS_RADIO_NAME,
),
sg.Radio(
"GUI OFF",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.GUIOFF),
key=key_manager.GUIOFF_RADIO_NAME,
),
],
[
sg.Column(
eyes[1].widget_layout,
vertical_alignment="top",
key=key_manager.LEFT_EYE_NAME,
visible=(config.eye_display_id in [EyeId.LEFT, EyeId.BOTH]),
background_color="#424042",
),
sg.Column(
eyes[0].widget_layout,
vertical_alignment="top",
key=key_manager.RIGHT_EYE_NAME,
visible=(config.eye_display_id in [EyeId.RIGHT, EyeId.BOTH]),
background_color="#424042",
),
sg.Column(
settings[0].get_layout(),
vertical_alignment="top",
key=key_manager.SETTINGS_NAME,
visible=(config.eye_display_id in [EyeId.SETTINGS]),
background_color="#424042",
),
sg.Column(
settings[1].get_layout(),
vertical_alignment="top",
key=key_manager.ALGO_SETTINGS_NAME,
visible=(config.eye_display_id in [EyeId.ALGOSETTINGS]),
background_color="#424042",
),
sg.Column(
settings[2].get_layout(),
vertical_alignment="top",
key=key_manager.VRCFT_MODULE_SETTINGS_NAME,
visible=(config.eye_display_id in [EyeId.VRCFTMODULESETTINGS]),
background_color="#424042",
),
],
]
if config.eye_display_id in [EyeId.LEFT, EyeId.BOTH]:
eyes[1].start()
if config.eye_display_id in [EyeId.RIGHT, EyeId.BOTH]:
eyes[0].start()
if config.eye_display_id in [EyeId.SETTINGS]:
settings[0].start()
if config.eye_display_id in [EyeId.ALGOSETTINGS]:
settings[1].start()
if config.eye_display_id in [EyeId.VRCFTMODULESETTINGS]:
settings[2].start()
# the eye's needs to be running before it is passed to the OSC
# Create the window
return sg.Window(
f"{appversion}",
layout,
icon=resource_path("Images/logo.ico"),
background_color="#292929")
def main():
# Get Configuration
config: EyeTrackConfig = EyeTrackConfig.load()
@ -147,279 +285,206 @@ def main():
osc_manager.start()
layout = [
[
sg.Radio(
"Left Eye",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.LEFT),
key=LEFT_EYE_RADIO_NAME,
),
sg.Radio(
"Right Eye",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.RIGHT),
key=RIGHT_EYE_RADIO_NAME,
),
sg.Radio(
"Both Eyes",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.BOTH),
key=BOTH_EYE_RADIO_NAME,
),
sg.Radio(
"Settings",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.SETTINGS),
key=SETTINGS_RADIO_NAME,
),
sg.Radio(
"Algo Settings",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.ALGOSETTINGS),
key=ALGO_SETTINGS_RADIO_NAME,
),
],
[
sg.Radio(
"VRCFT Module Settings",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.VRCFTMODULESETTINGS),
key=VRCFT_MODULE_SETTINGS_RADIO_NAME,
),
sg.Radio(
"GUI OFF",
"EYESELECTRADIO",
background_color="#292929",
default=(config.eye_display_id == EyeId.GUIOFF),
key=GUIOFF_RADIO_NAME,
),
],
[
sg.Column(
eyes[1].widget_layout,
vertical_alignment="top",
key=LEFT_EYE_NAME,
visible=(config.eye_display_id in [EyeId.LEFT, EyeId.BOTH]),
background_color="#424042",
),
sg.Column(
eyes[0].widget_layout,
vertical_alignment="top",
key=RIGHT_EYE_NAME,
visible=(config.eye_display_id in [EyeId.RIGHT, EyeId.BOTH]),
background_color="#424042",
),
sg.Column(
settings[0].get_layout(),
vertical_alignment="top",
key=SETTINGS_NAME,
visible=(config.eye_display_id in [EyeId.SETTINGS]),
background_color="#424042",
),
sg.Column(
settings[1].get_layout(),
vertical_alignment="top",
key=ALGO_SETTINGS_NAME,
visible=(config.eye_display_id in [EyeId.ALGOSETTINGS]),
background_color="#424042",
),
sg.Column(
settings[2].get_layout(),
vertical_alignment="top",
key=VRCFT_MODULE_SETTINGS_NAME,
visible=(config.eye_display_id in [EyeId.VRCFTMODULESETTINGS]),
background_color="#424042",
),
],
]
if config.eye_display_id in [EyeId.LEFT, EyeId.BOTH]:
eyes[1].start()
if config.eye_display_id in [EyeId.RIGHT, EyeId.BOTH]:
eyes[0].start()
if config.eye_display_id in [EyeId.SETTINGS]:
settings[0].start()
if config.eye_display_id in [EyeId.ALGOSETTINGS]:
settings[1].start()
if config.eye_display_id in [EyeId.VRCFTMODULESETTINGS]:
settings[2].start()
# the eye's needs to be running before it is passed to the OSC
# Create the window
window = sg.Window(
f"{appversion}",
layout,
icon=resource_path("Images/logo.ico"),
background_color="#292929",
)
# window = create_window(config, settings, eyes)
while True:
print('main loop')
if config.settings.gui_disable_gui:
timeout = 10 #TODO: test this on windows, on mac im not seeing a negitive side effect
layout = [[sg.Button("Enable GUI")]]
print('ee')
layoutg = [
[sg.Button('Enable GUI')]
]
# Create the window
window = sg.Window("Simple Button", layout)
windowg = sg.Window('Simple Window', layoutg)
# Event loop to process events and get the values of the inputs
# Event loop
while True:
event, values = window.read()
# If user closes window or clicks the button, break the loop
if event == sg.WINDOW_CLOSED:
eventg, valuesg = windowg.read()
if eventg == sg.WINDOW_CLOSED:
break
elif event == "Enable GUI":
print("Button clicked!")
elif eventg == 'Enable GUI':
config.settings.gui_disable_gui = False
config.save()
print('GUI Enabled')
break
# Close the window
window.close()
windowg.close()
print('close')
else:
timeout = 1
# GUI Render loop
while True:
# First off, check for any events from the GUI
event, values = window.read(timeout=timeout) # this higher timeout saves some cpu usage
# First off, check for any events from the GUI
window = create_window(config, settings, eyes)
print('new window')
while True:
event, values = window.read(timeout=1) # this higher timeout saves some cpu usage
# If we're in either mode and someone hits q, quit immediately
if event == "Exit" or event == sg.WIN_CLOSED:
for eye in eyes:
eye.stop()
cancellation_event.set()
osc_manager.shutdown()
print("\033[94m[INFO] Exiting EyeTrackApp\033[0m")
os._exit(0) # I do not like this, but for now this fixes app hang on close
return
# If we're in either mode and someone hits q, quit immediately
if event == "Exit" or event == sg.WIN_CLOSED and not config.settings.gui_disable_gui:
print(event == "Exit", event == sg.WIN_CLOSED, config.settings.gui_disable_gui)
for eye in eyes:
eye.stop()
cancellation_event.set()
osc_manager.shutdown()
print("\033[94m[INFO] Exiting EyeTrackApp\033[0m")
window.close()
os._exit(0) # I do not like this, but for now this fixes app hang on close
return
if values[RIGHT_EYE_RADIO_NAME] and config.eye_display_id != EyeId.RIGHT:
config.settings.gui_disable_gui = False
eyes[0].start()
eyes[1].stop()
settings[0].stop()
settings[1].stop()
settings[2].stop()
window[RIGHT_EYE_NAME].update(visible=True)
window[LEFT_EYE_NAME].update(visible=False)
window[SETTINGS_NAME].update(visible=False)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.RIGHT
config.settings.tracker_single_eye = 2
config.save()
if values[key_manager.RIGHT_EYE_RADIO_NAME] and config.eye_display_id != EyeId.RIGHT:
config.settings.gui_disable_gui = False
eyes[0].start()
eyes[1].stop()
settings[0].stop()
settings[1].stop()
settings[2].stop()
window[key_manager.RIGHT_EYE_NAME].update(visible=True)
window[key_manager.LEFT_EYE_NAME].update(visible=False)
window[key_manager.SETTINGS_NAME].update(visible=False)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.RIGHT
config.settings.tracker_single_eye = 2
config.save()
elif values[LEFT_EYE_RADIO_NAME] and config.eye_display_id != EyeId.LEFT:
config.settings.gui_disable_gui = False
settings[0].stop()
settings[1].stop()
settings[2].stop()
eyes[0].stop()
eyes[1].start()
window[RIGHT_EYE_NAME].update(visible=False)
window[LEFT_EYE_NAME].update(visible=True)
window[SETTINGS_NAME].update(visible=False)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.LEFT
config.settings.tracker_single_eye = 1
config.save()
elif values[key_manager.LEFT_EYE_RADIO_NAME] and config.eye_display_id != EyeId.LEFT:
config.settings.gui_disable_gui = False
settings[0].stop()
settings[1].stop()
settings[2].stop()
eyes[0].stop()
eyes[1].start()
window[key_manager.RIGHT_EYE_NAME].update(visible=False)
window[key_manager.LEFT_EYE_NAME].update(visible=True)
window[key_manager.SETTINGS_NAME].update(visible=False)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.LEFT
config.settings.tracker_single_eye = 1
config.save()
elif values[BOTH_EYE_RADIO_NAME] and config.eye_display_id != EyeId.BOTH:
config.settings.gui_disable_gui = False
settings[0].stop()
settings[1].stop()
settings[2].stop()
eyes[1].start()
eyes[0].start()
window[LEFT_EYE_NAME].update(visible=True)
window[RIGHT_EYE_NAME].update(visible=True)
window[SETTINGS_NAME].update(visible=False)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.BOTH
config.settings.tracker_single_eye = 0
config.save()
elif values[key_manager.BOTH_EYE_RADIO_NAME] and config.eye_display_id != EyeId.BOTH:
config.settings.gui_disable_gui = False
settings[0].stop()
settings[1].stop()
settings[2].stop()
eyes[1].start()
eyes[0].start()
window[key_manager.LEFT_EYE_NAME].update(visible=True)
window[key_manager.RIGHT_EYE_NAME].update(visible=True)
window[key_manager.SETTINGS_NAME].update(visible=False)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.BOTH
config.settings.tracker_single_eye = 0
config.save()
elif values[SETTINGS_RADIO_NAME] and config.eye_display_id != EyeId.SETTINGS:
config.settings.gui_disable_gui = False
eyes[0].stop()
eyes[1].stop()
settings[1].stop()
settings[0].start()
settings[2].stop()
window[RIGHT_EYE_NAME].update(visible=False)
window[LEFT_EYE_NAME].update(visible=False)
window[SETTINGS_NAME].update(visible=True)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.SETTINGS
config.save()
elif values[key_manager.SETTINGS_RADIO_NAME] and config.eye_display_id != EyeId.SETTINGS:
config.settings.gui_disable_gui = False
eyes[0].stop()
eyes[1].stop()
settings[1].stop()
settings[0].start()
settings[2].stop()
window[key_manager.RIGHT_EYE_NAME].update(visible=False)
window[key_manager.LEFT_EYE_NAME].update(visible=False)
window[key_manager.SETTINGS_NAME].update(visible=True)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.SETTINGS
config.save()
elif values[ALGO_SETTINGS_RADIO_NAME] and config.eye_display_id != EyeId.ALGOSETTINGS:
config.settings.gui_disable_gui = False
eyes[0].stop()
eyes[1].stop()
settings[0].stop()
settings[1].start()
settings[2].stop()
window[RIGHT_EYE_NAME].update(visible=False)
window[LEFT_EYE_NAME].update(visible=False)
window[SETTINGS_NAME].update(visible=False)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[ALGO_SETTINGS_NAME].update(visible=True)
config.eye_display_id = EyeId.ALGOSETTINGS
config.save()
elif values[key_manager.ALGO_SETTINGS_RADIO_NAME] and config.eye_display_id != EyeId.ALGOSETTINGS:
config.settings.gui_disable_gui = False
eyes[0].stop()
eyes[1].stop()
settings[0].stop()
settings[1].start()
settings[2].stop()
window[key_manager.RIGHT_EYE_NAME].update(visible=False)
window[key_manager.LEFT_EYE_NAME].update(visible=False)
window[key_manager.SETTINGS_NAME].update(visible=False)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=True)
config.eye_display_id = EyeId.ALGOSETTINGS
config.save()
elif values[VRCFT_MODULE_SETTINGS_RADIO_NAME] and config.eye_display_id != EyeId.VRCFTMODULESETTINGS:
config.settings.gui_disable_gui = False
eyes[0].stop()
eyes[1].stop()
settings[0].stop()
settings[1].stop()
settings[2].start()
window[RIGHT_EYE_NAME].update(visible=False)
window[LEFT_EYE_NAME].update(visible=False)
window[SETTINGS_NAME].update(visible=False)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=True)
window[ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.VRCFTMODULESETTINGS
config.save()
elif values[GUIOFF_RADIO_NAME] and config.eye_display_id != EyeId.GUIOFF:
config.settings.gui_disable_gui = True
# eyes[0].stop()
# eyes[1].stop()
settings[0].stop()
settings[1].stop()
settings[2].stop()
window[RIGHT_EYE_NAME].update(visible=False)
window[LEFT_EYE_NAME].update(visible=False)
window[SETTINGS_NAME].update(visible=False)
window[VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.GUIOFF
config.save()
break
elif values[key_manager.VRCFT_MODULE_SETTINGS_RADIO_NAME] and config.eye_display_id != EyeId.VRCFTMODULESETTINGS:
config.settings.gui_disable_gui = False
eyes[0].stop()
eyes[1].stop()
settings[0].stop()
settings[1].stop()
settings[2].start()
window[key_manager.RIGHT_EYE_NAME].update(visible=False)
window[key_manager.LEFT_EYE_NAME].update(visible=False)
window[key_manager.SETTINGS_NAME].update(visible=False)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=True)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.VRCFTMODULESETTINGS
config.save()
elif values[key_manager.GUIOFF_RADIO_NAME] and config.eye_display_id != EyeId.GUIOFF:
config.settings.gui_disable_gui = True
# eyes[0].stop()
# eyes[1].stop()
settings[0].stop()
settings[1].stop()
settings[2].stop()
window[key_manager.RIGHT_EYE_NAME].update(visible=False)
window[key_manager.LEFT_EYE_NAME].update(visible=False)
window[key_manager.SETTINGS_NAME].update(visible=False)
window[key_manager.VRCFT_MODULE_SETTINGS_NAME].update(visible=False)
window[key_manager.ALGO_SETTINGS_NAME].update(visible=False)
config.eye_display_id = EyeId.GUIOFF
config.save()
window.close()
break
else:
# Otherwise, render all
for eye in eyes:
if eye.started():
eye.render(window, event, values)
for setting in settings:
if setting.started():
setting.render(window, event, values)
# while True:
# print('main loop')
# if config.settings.gui_disable_gui:
# layoutg = [[sg.Button("Enable GUI")]]
# Create the window
# windowc = sg.Window("Simple Button", layoutg)
# Event loop to process events and get the values of the inputs
# while True:
# eventg, valuesg = windowc.read()
#
# If user closes window or clicks the button, break the loop
# if eventg == sg.WINDOW_CLOSED:
# break
# elif eventg == "Enable GUI":
# config.settings.gui_disable_gui = False
# config.save()
# break
# Close the window
# windowc.close()
# else:
# print('main loop')
# run_window(config, settings, eyes)
else:
# Otherwise, render all
for eye in eyes:
if eye.started():
eye.render(window, event, values)
for setting in settings:
if setting.started():
setting.render(window, event, values)
if __name__ == "__main__":

View File

@ -3,70 +3,32 @@ from typing import Iterable
import PySimpleGUI as sg
from colorama import Fore
from config import EyeTrackConfig, EyeTrackSettingsConfig
from threading import Event
from eye import EyeId
from config import EyeTrackConfig, EyeTrackSettingsConfig
class BaseSettingsWidget:
def __init__(
self,
widget_id: EyeId,
main_config: EyeTrackConfig,
settings_modules: Iterable,
):
# we put the last time an error was printed in the past so whenever a newone appears
self.last_error_printout = datetime.now() - timedelta(seconds=20)
self.error_printout_timeout = 2
self.gui_general_settings_layout = f"-GENERALSETTINGSLAYOUT{widget_id}-"
self.reset_button_key = f"RESET_SETTINGS{widget_id}"
self.is_saving = False
def __init__(self, widget_id: EyeId, main_config: EyeTrackConfig, settings_modules: Iterable):
self.widget_id = widget_id
self.main_config = main_config
self.config = main_config.settings
self.last_error_printout = datetime.now() - timedelta(seconds=20)
self.error_printout_timeout = 2
self.reset_button_key = f"RESET_SETTINGS{widget_id}"
self.is_saving = False
self.initialized_modules = self._initialize_modules(settings_modules=settings_modules, widget_id=widget_id)
self.general_settings_layout = []
for module in self.initialized_modules:
self.general_settings_layout.extend(module.get_layout())
self.widget_layout = [
[
sg.Column(
self.general_settings_layout,
key=self.gui_general_settings_layout,
background_color="#424042",
),
],
[
sg.Text("", background_color="#424042"),
],
[
sg.Button(
"Reset settings to default",
key=self.reset_button_key,
button_color="#c40e23",
)
],
]
self.cancellation_event = (
Event()
) # Set the event until start is called, otherwise we can block if shutdown is called.
self.cancellation_event = Event()
self.cancellation_event.set()
def started(self):
return not self.cancellation_event.is_set()
def start(self):
# If we're already running, bail
if not self.cancellation_event.is_set():
return
self.cancellation_event.clear()
def stop(self):
# If we're not running yet, bail
if self.cancellation_event.is_set():
return
self.cancellation_event.set()
@ -80,58 +42,47 @@ class BaseSettingsWidget:
elapsed_seconds = (datetime.now() - self.last_error_printout).seconds
if elapsed_seconds > self.error_printout_timeout:
self.last_error_printout = now
messages = []
for module_errors in errors:
for error in module_errors:
messages.append(f"{Fore.RED}[ERROR]{Fore.RESET} {error['msg']} \n")
messages = [f"{Fore.RED}[ERROR]{Fore.RESET} {error['msg']} \n" for module_errors in errors for error in module_errors]
print("".join(messages))
def render(self, window, event, values):
validated_data, errors = {}, []
# we might want to think about event driven architecture here eventually, validate only
# if anything changes instead of checking for changes
for module in self.initialized_modules:
module_validated_data = module.validate(values)
if module_validated_data.changes:
validated_data.update(module_validated_data.changes)
if module_validated_data.errors:
errors.append(module_validated_data.errors)
if not errors and validated_data and not self.is_saving:
self.is_saving = True
self._update_and_save_config(validated_data)
if errors:
self._handle_errors(errors)
self.handle_events(event, window)
def _initialize_modules(self, settings_modules, widget_id):
return [
module(
config=self.config,
settings=self.main_config,
widget_id=widget_id,
)
for module in settings_modules
]
return [module(config=self.config, settings=self.main_config, widget_id=widget_id) for module in settings_modules]
def get_layout(self) -> Iterable:
return self.widget_layout
general_settings_layout = []
for module in self.initialized_modules:
general_settings_layout.extend(module.get_layout())
widget_layout = [
[sg.Column(general_settings_layout, key=f"-GENERALSETTINGSLAYOUT{self.widget_id}-", background_color="#424042")],
[sg.Text("", background_color="#424042")],
[sg.Button("Reset settings to default", key=self.reset_button_key, button_color="#c40e23")]
]
return widget_layout
def handle_events(self, event, window):
if event == "__TIMEOUT__":
return
if event == self.reset_button_key:
self.reset_config(window)
def reset_config(self, window):
default_values = {}
base_settings = EyeTrackSettingsConfig()
print(f"\033[92m[INFO] Resetting config to defaults\033[0m")
for module in self.initialized_modules:
for key in module.get_key_for_panel_defaults():
@ -140,5 +91,4 @@ class BaseSettingsWidget:
default_values[key] = default_val
window[widget_key].update(default_val)
print(f"\033[92m[INFO] Config reset, saving\033[0m")
self._update_and_save_config(default_values)