Added loading window and window group switching

This commit is contained in:
2026-07-08 21:14:52 +01:00
parent 05bc8bdf25
commit 614c597d65
11 changed files with 472 additions and 43 deletions

View File

@@ -11,11 +11,19 @@ import traceback
import dearpygui.dearpygui as dpg
import sys
from dynalab.config import ConfigLoadError, load_config
from dynalab.data.json import json_thread_main
from dynalab.state import AppState
from dynalab.tags import MENU_WINDOW_DATA_INPUT
from dynalab.tags import WINDOW_DATA_INPUT_GAUGE_GRID
from dynalab.ui.error import build_error_modal, show_error_modal
import dynalab.ui.windows
from dynalab.ui.windows import build_loading, build_windows
from dynalab.ui.windows import (
LOADING_WINDOW_HEIGHT,
LOADING_WINDOW_WIDTH,
build_loading,
build_windows,
center_loading_content,
)
import dpg_gauges as dpgg
from dpg_gauges.exceptions import GaugeNotFoundError
@@ -56,24 +64,52 @@ def _asset_path(relative_path: str) -> str:
def _init_worker(
state: AppState, stop_event: threading.Event, message_queue: Queue[str]
) -> None:
time.sleep(1.0)
try:
time.sleep(1.0)
message_queue.put("Fetching DynaLab config")
time.sleep(0.5)
state.app_config = load_config()
message_queue.put("Fetched DynaLab config")
time.sleep(0.5)
message_queue.put("Starting JSON data server")
# Init and start json connector thread
state.data_json_thread = Thread(
target=json_thread_main,
name="json-connector-network",
daemon=True,
args=(state,),
)
state.data_json_thread.start()
time.sleep(0.5)
message_queue.put("JSON data server started")
time.sleep(0.5)
message_queue.put("DynaLab Ready")
time.sleep(1.0)
message_queue.put("Starting JSON data server")
# Init and start json connector thread
state.data_json_thread = Thread(
target=json_thread_main,
name="json-connector-network",
daemon=True,
args=(state,),
)
state.data_json_thread.start()
time.sleep(0.5)
message_queue.put("JSON data server started")
time.sleep(0.5)
message_queue.put("DynaLab Ready")
time.sleep(1.0)
stop_event.set()
stop_event.set()
except ConfigLoadError as exc:
state.init_error = str(exc)
state.stop_init.set()
except Exception as exc:
state.init_error = f"Unexpected startup error: {exc}"
state.stop_init.set()
def _load_image(path: Path, tag: str) -> None:
width, height, channels, data = dpg.load_image(f"{path}")
with dpg.texture_registry():
dpg.add_static_texture(width=width, height=height, default_value=data, tag=tag)
def _maximize_viewport() -> None:
maximize_viewport = getattr(dpg, "maximize_viewport", None)
if callable(maximize_viewport):
maximize_viewport()
return
dpg.set_viewport_height(720)
dpg.set_viewport_width(1280)
def run() -> None:
@@ -87,7 +123,9 @@ def run() -> None:
# Switch callback management to manual
dpg.configure_app(manual_callback_management=True)
# Initialize viewport
dpg.create_viewport(title="DynaLab", width=600, height=400)
dpg.create_viewport(
title="DynaLab", width=LOADING_WINDOW_WIDTH, height=LOADING_WINDOW_HEIGHT
)
# Load fonts at 2x size for HiDPI scaling
with dpg.font_registry():
@@ -101,17 +139,21 @@ def run() -> None:
)
dpg.bind_font(app_font)
_load_image(_asset_path("assets/images/logo@300.png"), "logo")
build_loading()
build_error_modal()
# Open viewport
dpg.setup_dearpygui()
dpg.show_viewport()
# Config main window size
vp_w = dpg.get_viewport_client_width()
vp_h = dpg.get_viewport_client_height()
dpg.configure_item("loading_window", pos=(0, 0), width=vp_w, height=vp_h)
dpg.set_primary_window("loading_window", True)
dpg.configure_item(
"loading_window",
pos=(0, 0),
width=LOADING_WINDOW_WIDTH,
height=LOADING_WINDOW_HEIGHT,
)
# Init global app state
state: AppState = AppState()
@@ -128,12 +170,17 @@ def run() -> None:
while not loading_stop.is_set():
# Fetch and execute callbacks
if state.stop_init.is_set():
show_error_modal(
state.init_error if state.init_error is not None else "Fatal error"
)
jobs = dpg.get_callback_queue()
try:
dpg.run_callbacks(jobs)
except Exception:
traceback.print_exc()
center_loading_content()
try:
msg = loading_msg_queue.get_nowait()
except Empty:
@@ -145,9 +192,8 @@ def run() -> None:
dpg.delete_item("loading_window")
# Call ui building function
dpg.set_viewport_height(720)
dpg.set_viewport_width(1280)
build_windows()
_maximize_viewport()
build_windows(state)
# Config main window size
vp_w = dpg.get_viewport_client_width()
@@ -172,7 +218,7 @@ def run() -> None:
dpgg.digital_gauge(
tag=f"{new_signal.id}",
label=f"{new_signal.name}",
parent=MENU_WINDOW_DATA_INPUT,
parent=WINDOW_DATA_INPUT_GAUGE_GRID,
unit=new_signal.unit if new_signal.unit is not None else "",
value=0,
precision=1,