diff --git a/selfdrive/ui/layouts/main.py b/selfdrive/ui/layouts/main.py index 099444b9af..a1adf667f9 100644 --- a/selfdrive/ui/layouts/main.py +++ b/selfdrive/ui/layouts/main.py @@ -18,7 +18,6 @@ class MainLayout(Widget): def __init__(self): super().__init__() self._sidebar = Sidebar() - self._sidebar_visible = True self._current_mode = MainState.HOME self._prev_onroad = False @@ -46,7 +45,7 @@ class MainLayout(Widget): def _update_layout_rects(self, rect): self._sidebar_rect = rl.Rectangle(rect.x, rect.y, SIDEBAR_WIDTH, rect.height) - x_offset = SIDEBAR_WIDTH if self._sidebar_visible else 0 + x_offset = SIDEBAR_WIDTH if self._sidebar.is_visible else 0 self._content_rect = rl.Rectangle(rect.y + x_offset, rect.y, rect.width - x_offset, rect.height) def _handle_onroad_transition(self): @@ -58,30 +57,30 @@ class MainLayout(Widget): def _set_mode_for_state(self): if ui_state.started: self._current_mode = MainState.ONROAD - self._sidebar_visible = False + self._sidebar.set_visible(False) else: self._current_mode = MainState.HOME - self._sidebar_visible = True + self._sidebar.set_visible(True) def open_settings(self, panel_type: PanelType): self._layouts[MainState.SETTINGS].set_current_panel(panel_type) self._current_mode = MainState.SETTINGS - self._sidebar_visible = False + self._sidebar.set_visible(False) def _on_settings_clicked(self): self._current_mode = MainState.SETTINGS - self._sidebar_visible = False + self._sidebar.set_visible(False) def _on_flag_clicked(self): pass def _on_onroad_clicked(self): - self._sidebar_visible = not self._sidebar_visible + self._sidebar.set_visible(not self._sidebar.is_visible) def _render_main_content(self): # Render sidebar - if self._sidebar_visible: + if self._sidebar.is_visible: self._sidebar.render(self._sidebar_rect) - content_rect = self._content_rect if self._sidebar_visible else self._rect + content_rect = self._content_rect if self._sidebar.is_visible else self._rect self._layouts[self._current_mode].render(content_rect) diff --git a/selfdrive/ui/onroad/driver_state.py b/selfdrive/ui/onroad/driver_state.py index 0f55fb4532..20248d7e6e 100644 --- a/selfdrive/ui/onroad/driver_state.py +++ b/selfdrive/ui/onroad/driver_state.py @@ -76,10 +76,10 @@ class DriverStateRenderer(Widget): self.engaged_color = rl.Color(26, 242, 66, 255) self.disengaged_color = rl.Color(139, 139, 139, 255) - def _render(self, rect): - if not self._is_visible(ui_state.sm): - return + self.set_visible(lambda: (ui_state.sm.recv_frame['driverStateV2'] > ui_state.started_frame and + ui_state.sm.seen['driverMonitoringState'])) + def _render(self, rect): self._update_state(ui_state.sm, rect) if not self.state_updated: return @@ -108,11 +108,6 @@ class DriverStateRenderer(Widget): if self.v_arc_data: rl.draw_spline_linear(self.v_arc_lines, len(self.v_arc_lines), self.v_arc_data.thickness, self.arc_color) - def _is_visible(self, sm): - """Check if the visualization should be rendered.""" - return (sm.recv_frame['driverStateV2'] > ui_state.started_frame and - sm.seen['driverMonitoringState']) - def _update_state(self, sm, rect): """Update the driver monitoring state based on model data""" if not sm.updated["driverMonitoringState"]: diff --git a/system/ui/lib/widget.py b/system/ui/lib/widget.py index 1823241d02..d31f961e26 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 collections.abc import Callable class DialogResult(IntEnum): @@ -13,6 +14,14 @@ 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: + return self._is_visible() if callable(self._is_visible) else self._is_visible + + 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 +30,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