From ff9aa657d3ab7023dab554205b44f53e57a5f889 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 12 Jun 2025 14:44:01 -0700 Subject: [PATCH] generic visibility --- selfdrive/ui/layouts/home.py | 1 + system/ui/lib/widget.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/selfdrive/ui/layouts/home.py b/selfdrive/ui/layouts/home.py index f255d2403c..955619655e 100644 --- a/selfdrive/ui/layouts/home.py +++ b/selfdrive/ui/layouts/home.py @@ -51,6 +51,7 @@ class HomeLayout(Widget): self.alert_notif_rect = rl.Rectangle(0, 0, 220, HEADER_HEIGHT - 10) self._prime_widget = PrimeWidget() + self._prime_widget.set_visible(lambda: round(time.time()) % 2 == 0) # Show prime widget every other second self._setup_widget = SetupWidget() self._exp_mode_button = ExperimentalModeButton() diff --git a/system/ui/lib/widget.py b/system/ui/lib/widget.py index 1823241d02..a34e45e210 100644 --- a/system/ui/lib/widget.py +++ b/system/ui/lib/widget.py @@ -1,6 +1,7 @@ import abc import pyray as rl from enum import IntEnum +from typing import Callable, TypeVar class DialogResult(IntEnum): @@ -9,10 +10,28 @@ class DialogResult(IntEnum): NO_ACTION = -1 +T = TypeVar("T") + + +def _resolve_value(value: T | Callable[[], T], default: T = ""): + if callable(value): + return value() + return value if value is not None else default + + class Widget(abc.ABC): def __init__(self): self._rect: rl.Rectangle = rl.Rectangle(0, 0, 0, 0) self._is_pressed = False + self._is_visible: bool | Callable[[], bool] = True + + @property + def is_visible(self) -> bool: + print('Widget.is_visible called') + return _resolve_value(self._is_visible, True) + + def set_visible(self, visible: bool | Callable[[], bool]) -> None: + self._is_visible = visible def set_rect(self, rect: rl.Rectangle) -> None: self._rect = rect @@ -21,6 +40,9 @@ class Widget(abc.ABC): if rect is not None: self.set_rect(rect) + if not self.is_visible: + return None + ret = self._render(self._rect) # Keep track of whether mouse down started within the widget's rectangle