diff --git a/selfdrive/ui/layouts/home.py b/selfdrive/ui/layouts/home.py index 53e1968d48..0fa91da552 100644 --- a/selfdrive/ui/layouts/home.py +++ b/selfdrive/ui/layouts/home.py @@ -193,6 +193,7 @@ class HomeLayout(Widget): self._setup_widget.render(setup_rect) def _refresh(self): + # TODO: implement _update_state with a timer self.update_available = self.update_alert.refresh() self.alert_count = self.offroad_alert.refresh() self._update_state_priority(self.update_available, self.alert_count > 0) diff --git a/selfdrive/ui/layouts/sidebar.py b/selfdrive/ui/layouts/sidebar.py index c65f6db736..13f69b79d4 100644 --- a/selfdrive/ui/layouts/sidebar.py +++ b/selfdrive/ui/layouts/sidebar.py @@ -86,8 +86,6 @@ class Sidebar(Widget): self._on_flag_click = on_flag def _render(self, rect: rl.Rectangle): - self.update_state() - # Background rl.draw_rectangle_rec(rect, Colors.SIDEBAR_BG) @@ -95,7 +93,7 @@ class Sidebar(Widget): self._draw_network_indicator(rect) self._draw_metrics(rect) - def update_state(self): + def _update_state(self): sm = ui_state.sm if not sm.updated['deviceState']: return diff --git a/selfdrive/ui/onroad/driver_state.py b/selfdrive/ui/onroad/driver_state.py index 951b39f5cb..9a5da4d298 100644 --- a/selfdrive/ui/onroad/driver_state.py +++ b/selfdrive/ui/onroad/driver_state.py @@ -50,7 +50,6 @@ class DriverStateRenderer(Widget): self.is_active = False self.is_rhd = False self.dm_fade_state = 0.0 - self.state_updated = False self.driver_pose_vals = np.zeros(3, dtype=np.float32) self.driver_pose_diff = np.zeros(3, dtype=np.float32) self.driver_pose_sins = np.zeros(3, dtype=np.float32) @@ -79,10 +78,6 @@ class DriverStateRenderer(Widget): ui_state.sm.seen['driverMonitoringState'])) def _render(self, rect): - self._update_state(ui_state.sm, rect) - if not self.state_updated: - return - # Set opacity based on active state opacity = 0.65 if self.is_active else 0.2 @@ -107,8 +102,9 @@ 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 _update_state(self, sm, rect): + def _update_state(self): """Update the driver monitoring state based on model data""" + sm = ui_state.sm if not sm.updated["driverMonitoringState"]: return @@ -158,16 +154,15 @@ class DriverStateRenderer(Widget): self.face_keypoints_transformed = self.face_kpts_draw[:, :2] * kp_depth[:, None] # Pre-calculate all drawing elements - self._pre_calculate_drawing_elements(rect) - self.state_updated = True + self._pre_calculate_drawing_elements() - def _pre_calculate_drawing_elements(self, rect): + def _pre_calculate_drawing_elements(self): """Pre-calculate all drawing elements based on the current rectangle""" # Calculate icon position (bottom-left or bottom-right) - width, height = rect.width, rect.height + width, height = self._rect.width, self._rect.height offset = UI_BORDER_SIZE + BTN_SIZE // 2 - self.position_x = rect.x + (width - offset if self.is_rhd else offset) - self.position_y = rect.y + height - offset + self.position_x = self._rect.x + (width - offset if self.is_rhd else offset) + self.position_y = self._rect.y + height - offset # Pre-calculate the face lines positions positioned_keypoints = self.face_keypoints_transformed + np.array([self.position_x, self.position_y]) diff --git a/selfdrive/ui/onroad/exp_button.py b/selfdrive/ui/onroad/exp_button.py index 6ca1b4ca81..8c835090d0 100644 --- a/selfdrive/ui/onroad/exp_button.py +++ b/selfdrive/ui/onroad/exp_button.py @@ -1,6 +1,5 @@ import time import pyray as rl -from cereal.messaging import SubMaster from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.lib.widget import Widget @@ -28,8 +27,8 @@ class ExpButton(Widget): def set_rect(self, rect: rl.Rectangle) -> None: self._rect.x, self._rect.y = rect.x, rect.y - def update_state(self, sm: SubMaster) -> None: - selfdrive_state = sm["selfdriveState"] + def _update_state(self) -> None: + selfdrive_state = ui_state.sm["selfdriveState"] self._experimental_mode = selfdrive_state.experimentalMode self._engageable = selfdrive_state.engageable or selfdrive_state.enabled diff --git a/selfdrive/ui/onroad/hud_renderer.py b/selfdrive/ui/onroad/hud_renderer.py index f67527c8e2..da292d38d5 100644 --- a/selfdrive/ui/onroad/hud_renderer.py +++ b/selfdrive/ui/onroad/hud_renderer.py @@ -1,6 +1,5 @@ import pyray as rl from dataclasses import dataclass -from cereal.messaging import SubMaster from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus from openpilot.selfdrive.ui.onroad.exp_button import ExpButton from openpilot.system.ui.lib.application import gui_app, FontWeight @@ -72,8 +71,9 @@ class HudRenderer(Widget): self._exp_button = ExpButton(UI_CONFIG.button_size, UI_CONFIG.wheel_icon_size) - def _update_state(self, sm: SubMaster) -> None: + def _update_state(self) -> None: """Update HUD state based on car state and controls state.""" + sm = ui_state.sm if sm.recv_frame["carState"] < ui_state.started_frame: self.is_cruise_set = False self.set_speed = SET_SPEED_NA @@ -99,12 +99,8 @@ class HudRenderer(Widget): speed_conversion = CV.MS_TO_KPH if ui_state.is_metric else CV.MS_TO_MPH self.speed = max(0.0, v_ego * speed_conversion) - self._exp_button.update_state(sm) - def _render(self, rect: rl.Rectangle) -> None: """Render HUD elements to the screen.""" - self._update_state(ui_state.sm) - # Draw the header background rl.draw_rectangle_gradient_v( int(rect.x), diff --git a/system/ui/lib/widget.py b/system/ui/lib/widget.py index 8ec610d82c..f1161392ce 100644 --- a/system/ui/lib/widget.py +++ b/system/ui/lib/widget.py @@ -34,6 +34,8 @@ class Widget(abc.ABC): if rect is not None: self.set_rect(rect) + self._update_state() + if not self.is_visible: return None @@ -56,6 +58,9 @@ class Widget(abc.ABC): def _render(self, rect: rl.Rectangle) -> bool | int | None: """Render the widget within the given rectangle.""" + def _update_state(self): + """Optionally update the widget's non-layout state. This is called before rendering.""" + def _update_layout_rects(self) -> None: """Optionally update any layout rects on Widget rect change."""