Files
StarPilot/selfdrive/ui/onroad/starpilot/personality_button.py
2026-04-12 01:11:17 -04:00

64 lines
2.3 KiB
Python

import pyray as rl
from cereal import log
from openpilot.common.params import Params
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.selfdrive.ui.layouts.settings.starpilot.asset_loader import starpilot_texture
from openpilot.system.ui.widgets import Widget
BTN_SIZE = 192
ICON_SIZE = 144
PERSONALITY_TO_INT = log.LongitudinalPersonality.schema.enumerants
class PersonalityButton(Widget):
def __init__(self):
super().__init__()
self._params_memory = Params(memory=True)
self._personality: int = 1 # default: standard
self._traffic_mode: bool = False
# 0=traffic, 1=aggressive, 2=standard, 3=relaxed
self._icons = [
starpilot_texture("stock_theme/distance_icons/traffic.png", ICON_SIZE, ICON_SIZE),
starpilot_texture("stock_theme/distance_icons/aggressive.png", ICON_SIZE, ICON_SIZE),
starpilot_texture("stock_theme/distance_icons/standard.png", ICON_SIZE, ICON_SIZE),
starpilot_texture("stock_theme/distance_icons/relaxed.png", ICON_SIZE, ICON_SIZE),
]
self._rect = rl.Rectangle(0, 0, BTN_SIZE, BTN_SIZE)
self._black_bg = rl.Color(0, 0, 0, 0)
self._white = rl.Color(255, 255, 255, 255)
self.set_visible(lambda: ui_state.started and ui_state.has_longitudinal_control)
@property
def is_interacting(self) -> bool:
return self.is_pressed
def _update_state(self):
sm = ui_state.sm
if sm.valid.get("selfdriveState", False):
self._personality = PERSONALITY_TO_INT[sm["selfdriveState"].personality]
self._traffic_mode = ui_state.traffic_mode_enabled
def _handle_mouse_press(self, _):
self._params_memory.put_bool("OnroadDistanceButtonPressed", True)
def _handle_mouse_release(self, _):
self._params_memory.put_bool("OnroadDistanceButtonPressed", False)
def _render(self, rect: rl.Rectangle):
center_x = int(self._rect.x + self._rect.width / 2)
center_y = int(self._rect.y + self._rect.height / 2)
opacity = 180 if self.is_pressed else 255
self._white.a = opacity
icon_idx = 0 if self._traffic_mode else min(self._personality + 1, len(self._icons) - 1)
icon = self._icons[icon_idx]
rl.draw_circle(center_x, center_y, self._rect.width / 2, self._black_bg)
rl.draw_texture(icon, center_x - icon.width // 2, center_y - icon.height // 2, self._white)