raylib ui: common state update function (#35546)
* add _update_state * nonlya * visible already does this for us! * do hud renderer and exp button * temp * this really needs some type of timer like QT * this really needs some type of timer like QT * todo * use in model renderer * Revert "use in model renderer" This reverts commit d35f774155c9875209d06b8cd0b4849b1d8a60c4. * no passing rect * cl * unused now
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user