mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-09-26 23:09:28 +08:00
Refactor settings into base settings, fixup modules
TODO: reset
This commit is contained in:
parent
ff5974ec8d
commit
aa3be78f54
@ -2,61 +2,20 @@ import PySimpleGUI as sg
|
||||
|
||||
from config import EyeTrackConfig
|
||||
from osc import EyeId
|
||||
from queue import Queue
|
||||
from threading import Event
|
||||
|
||||
from settings.BaseSettings import BaseSettingsWidget
|
||||
from settings.modules.AdvancedTrackingAlgoSettingsModule import (
|
||||
AdvancedTrackingAlgoSettingsModule,
|
||||
)
|
||||
from settings.modules.BlinkAlgoModule import BlinkAlgoSettingsModule
|
||||
from settings.modules.TrackingAlgorithmModule import TrackingAlgorithmModule
|
||||
|
||||
|
||||
class AlgoSettingsWidget:
|
||||
def __init__(
|
||||
self, widget_id: EyeId, main_config: EyeTrackConfig
|
||||
):
|
||||
self.gui_general_settings_layout = f"-GENERALSETTINGSLAYOUT{widget_id}-"
|
||||
self.main_config = main_config
|
||||
self.config = main_config.settings
|
||||
|
||||
# Define the window's contents
|
||||
self.general_settings_layout = [
|
||||
class AlgoSettingsWidget(BaseSettingsWidget):
|
||||
def __init__(self, widget_id: EyeId, main_config: EyeTrackConfig):
|
||||
settings_modules = [
|
||||
TrackingAlgorithmModule,
|
||||
BlinkAlgoSettingsModule,
|
||||
AdvancedTrackingAlgoSettingsModule,
|
||||
]
|
||||
|
||||
self.widget_layout = [
|
||||
[
|
||||
sg.Text(
|
||||
"Tracking Algorithm Order Settings:", background_color="#242224"
|
||||
),
|
||||
],
|
||||
[
|
||||
sg.Column(
|
||||
self.general_settings_layout,
|
||||
key=self.gui_general_settings_layout,
|
||||
background_color="#424042",
|
||||
),
|
||||
],
|
||||
]
|
||||
|
||||
self.cancellation_event = (
|
||||
Event()
|
||||
) # Set the event until start is called, otherwise we can block if shutdown is called.
|
||||
self.cancellation_event.set()
|
||||
self.image_queue = Queue()
|
||||
|
||||
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()
|
||||
|
||||
def render(self, window, event, values):
|
||||
# If anything has changed in our configuration settings, change/update those.
|
||||
changed = False
|
||||
|
||||
if changed:
|
||||
self.main_config.save()
|
||||
super().__init__(widget_id, main_config, settings_modules)
|
||||
|
@ -148,14 +148,14 @@ def main():
|
||||
background_color="#424042",
|
||||
),
|
||||
sg.Column(
|
||||
settings[0].widget_layout,
|
||||
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].widget_layout,
|
||||
settings[1].get_layout(),
|
||||
vertical_alignment="top",
|
||||
key=ALGO_SETTINGS_NAME,
|
||||
visible=(config.eye_display_id in [EyeId.ALGOSETTINGS]),
|
||||
|
@ -1,102 +1,18 @@
|
||||
import PySimpleGUI as sg
|
||||
|
||||
from config import EyeTrackConfig, EyeTrackSettingsConfig
|
||||
from config import EyeTrackConfig
|
||||
from osc import EyeId
|
||||
from threading import Event
|
||||
|
||||
from settings.BaseSettings import BaseSettingsWidget
|
||||
from settings.modules.GeneralSettingsModule import GeneralSettingsModule
|
||||
from settings.modules.OneEuroSettingsModule import OneEuroSettingsModule
|
||||
from settings.modules.OSCSettingsModule import OSCSettingsModule
|
||||
|
||||
|
||||
class SettingsWidget:
|
||||
class SettingsWidget(BaseSettingsWidget):
|
||||
def __init__(self, widget_id: EyeId, main_config: EyeTrackConfig):
|
||||
self.is_saving = False
|
||||
self.main_config = main_config
|
||||
self.config = main_config.settings
|
||||
|
||||
settings_modules = [
|
||||
GeneralSettingsModule,
|
||||
OneEuroSettingsModule,
|
||||
OSCSettingsModule,
|
||||
]
|
||||
super().__init__(widget_id, main_config, settings_modules)
|
||||
|
||||
self.initialized_modules = self._initialize_modules(
|
||||
settings_modules=settings_modules, widget_id=widget_id
|
||||
)
|
||||
self.gui_general_settings_layout = f"-GENERALSETTINGSLAYOUT{widget_id}-"
|
||||
|
||||
# Define the window's contents
|
||||
self.general_settings_layout = []
|
||||
|
||||
for module in self.initialized_modules:
|
||||
self.general_settings_layout.extend(module.get_layout())
|
||||
|
||||
self.widget_layout = [
|
||||
[
|
||||
sg.Text("General Settings:", background_color="#242224"),
|
||||
],
|
||||
[
|
||||
sg.Column(
|
||||
self.general_settings_layout,
|
||||
key=self.gui_general_settings_layout,
|
||||
background_color="#424042",
|
||||
),
|
||||
],
|
||||
]
|
||||
|
||||
self.cancellation_event = (
|
||||
Event()
|
||||
) # Set the event until start is called, otherwise we can block if shutdown is called.
|
||||
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()
|
||||
|
||||
def _update_and_save_config(self, validated_data: dict):
|
||||
self.main_config.update(validated_data, save=True)
|
||||
self.is_saving = False
|
||||
|
||||
def _handle_errors(self, errors):
|
||||
print(errors)
|
||||
|
||||
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)
|
||||
|
||||
def _initialize_modules(self, settings_modules, widget_id):
|
||||
return [
|
||||
module(
|
||||
config=self.config,
|
||||
settings=self.main_config,
|
||||
settings_base_class=EyeTrackSettingsConfig,
|
||||
widget_id=widget_id,
|
||||
)
|
||||
for module in settings_modules
|
||||
]
|
||||
|
@ -2,19 +2,21 @@
|
||||
from pythonosc import udp_client
|
||||
from pythonosc import osc_server
|
||||
from pythonosc import dispatcher
|
||||
from config import EyeTrackConfig
|
||||
from utils.misc_utils import PlaySound,SND_FILENAME,SND_ASYNC
|
||||
import queue
|
||||
import threading
|
||||
from enum import IntEnum
|
||||
import time
|
||||
|
||||
|
||||
class EyeId(IntEnum):
|
||||
RIGHT = 0
|
||||
LEFT = 1
|
||||
BOTH = 2
|
||||
SETTINGS = 3
|
||||
ALGOSETTINGS = 4
|
||||
from config import EyeTrackConfig
|
||||
|
||||
|
||||
def eyelid_transformer(self,eye_blink):
|
||||
if self.config.osc_invert_eye_close:
|
||||
|
97
EyeTrackApp/settings/BaseSettings.py
Normal file
97
EyeTrackApp/settings/BaseSettings.py
Normal file
@ -0,0 +1,97 @@
|
||||
from typing import Iterable, Optional
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
from config import EyeTrackConfig, EyeTrackSettingsConfig
|
||||
from threading import Event
|
||||
from osc import EyeId # TODO this is bad, fix this
|
||||
|
||||
|
||||
class BaseSettingsWidget:
|
||||
def __init__(
|
||||
self,
|
||||
widget_id: EyeId,
|
||||
main_config: EyeTrackConfig,
|
||||
settings_modules: Iterable,
|
||||
):
|
||||
self.gui_general_settings_layout = f"-GENERALSETTINGSLAYOUT{widget_id}-"
|
||||
self.is_saving = False
|
||||
self.main_config = main_config
|
||||
self.config = main_config.settings
|
||||
|
||||
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",
|
||||
),
|
||||
],
|
||||
]
|
||||
|
||||
self.cancellation_event = (
|
||||
Event()
|
||||
) # Set the event until start is called, otherwise we can block if shutdown is called.
|
||||
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()
|
||||
|
||||
def _update_and_save_config(self, validated_data: dict):
|
||||
self.main_config.update(validated_data, save=True)
|
||||
self.is_saving = False
|
||||
|
||||
def _handle_errors(self, errors):
|
||||
print(errors)
|
||||
|
||||
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)
|
||||
|
||||
def _initialize_modules(self, settings_modules, widget_id):
|
||||
return [
|
||||
module(
|
||||
config=self.config,
|
||||
settings=self.main_config,
|
||||
settings_base_class=EyeTrackSettingsConfig,
|
||||
widget_id=widget_id,
|
||||
)
|
||||
for module in settings_modules
|
||||
]
|
||||
|
||||
def get_layout(self) -> Iterable:
|
||||
return self.widget_layout
|
@ -3,7 +3,6 @@ import PySimpleGUI as sg
|
||||
|
||||
|
||||
class AdvancedTrackingAlgoSettingsValidationModel(BaseValidationModel):
|
||||
gui_HSF_radius: int
|
||||
gui_HSF_radius_left: int
|
||||
gui_HSF_radius_right: int
|
||||
gui_blob_maxsize: int
|
||||
@ -12,22 +11,19 @@ class AdvancedTrackingAlgoSettingsValidationModel(BaseValidationModel):
|
||||
gui_legacy_ransac_thresh_right: int
|
||||
gui_skip_autoradius: bool
|
||||
gui_thresh_add: int
|
||||
gui_threshold_slider: int
|
||||
gui_update_check: int
|
||||
gui_threshold: int
|
||||
|
||||
|
||||
class GeneralSettingsModule(BaseSettingsModule):
|
||||
class AdvancedTrackingAlgoSettingsModule(BaseSettingsModule):
|
||||
def __init__(self, config, widget_id, settings_base_class, **kwargs):
|
||||
super().__init__(config, widget_id, settings_base_class, **kwargs)
|
||||
self.validation_model = AdvancedTrackingAlgoSettingsValidationModel
|
||||
|
||||
self.gui_HSF_radius = f"-HSFRADIUS{widget_id}-"
|
||||
self.gui_blob_maxsize = f"-BLOBMAXSIZE{widget_id}-"
|
||||
self.gui_blob_minsize = f"-BLOBMINSIZE{widget_id}-"
|
||||
self.gui_skip_autoradius = f"-SKIPAUTORADIUS{widget_id}-"
|
||||
self.gui_thresh_add = f"-THRESHADD{widget_id}-"
|
||||
self.gui_update_check = f"-UPDATECHECK{widget_id}-"
|
||||
self.gui_threshold_slider = f"-BLOBTHRESHOLD{widget_id}-"
|
||||
self.gui_threshold = f"-BLOBTHRESHOLD{widget_id}-"
|
||||
self.gui_HSF_radius_left = f"-HSFRADIUSLEFT{widget_id}-"
|
||||
self.gui_HSF_radius_right = f"-HSFRADIUSRIGHT{widget_id}-"
|
||||
|
||||
@ -36,6 +32,7 @@ class GeneralSettingsModule(BaseSettingsModule):
|
||||
|
||||
def get_layout(self):
|
||||
return [
|
||||
[sg.Text("Advanced Tracking Algorithm Settings:", background_color="#242224")],
|
||||
[
|
||||
sg.Checkbox(
|
||||
"HSF: Skip Auto Radius",
|
||||
@ -81,7 +78,7 @@ class GeneralSettingsModule(BaseSettingsModule):
|
||||
range=(0, 110),
|
||||
default_value=self.config.gui_threshold,
|
||||
orientation="h",
|
||||
key=self.gui_threshold_slider,
|
||||
key=self.gui_threshold,
|
||||
background_color="#424042",
|
||||
tooltip="Adjusts the threshold for blob tracking.",
|
||||
),
|
||||
|
@ -14,7 +14,7 @@ class BlinkAlgoSettingsValidationModel(BaseValidationModel):
|
||||
gui_circular_crop_right: bool
|
||||
|
||||
|
||||
class GeneralSettingsModule(BaseSettingsModule):
|
||||
class BlinkAlgoSettingsModule(BaseSettingsModule):
|
||||
def __init__(self, config, widget_id, settings_base_class, **kwargs):
|
||||
super().__init__(config, widget_id, settings_base_class, **kwargs)
|
||||
self.validation_model = BlinkAlgoSettingsValidationModel
|
||||
@ -31,12 +31,6 @@ class GeneralSettingsModule(BaseSettingsModule):
|
||||
|
||||
def get_layout(self):
|
||||
return [
|
||||
[
|
||||
sg.Text(
|
||||
"Blink Algo Settings:",
|
||||
background_color="#242224",
|
||||
)
|
||||
],
|
||||
[sg.Text("Blink Algo Settings:", background_color="#242224")],
|
||||
[
|
||||
sg.Checkbox(
|
||||
|
@ -25,6 +25,9 @@ class GeneralSettingsModule(BaseSettingsModule):
|
||||
|
||||
def get_layout(self):
|
||||
return [
|
||||
[
|
||||
sg.Text("General Settings:", background_color="#242224"),
|
||||
],
|
||||
[
|
||||
sg.Checkbox(
|
||||
"Flip Left Eye X Axis",
|
||||
|
@ -19,7 +19,7 @@ class TrackingAlgorithmValidationModel(BaseValidationModel):
|
||||
gui_RANSAC3DP: int
|
||||
|
||||
|
||||
class GeneralSettingsModule(BaseSettingsModule):
|
||||
class TrackingAlgorithmModule(BaseSettingsModule):
|
||||
def __init__(self, config, widget_id, settings_base_class, **kwargs):
|
||||
super().__init__(config, widget_id, settings_base_class, **kwargs)
|
||||
self.algo_count = ["1", "2", "3", "4", "5", "6"]
|
||||
|
Loading…
Reference in New Issue
Block a user