mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-08-05 08:16:06 +08:00
ui: add driving personality selector to settings (#35524)
* Add driving personality selector to settings * icon * format * type --------- Co-authored-by: Shane Smiskol <shane@smiskol.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from openpilot.system.ui.lib.list_view import ListView, toggle_item
|
||||
from openpilot.system.ui.lib.list_view import ListView, multiple_button_item, toggle_item
|
||||
from openpilot.system.ui.lib.widget import Widget
|
||||
from openpilot.common.params import Params
|
||||
|
||||
@@ -9,6 +9,11 @@ DESCRIPTIONS = {
|
||||
"Your attention is required at all times to use this feature."
|
||||
),
|
||||
"DisengageOnAccelerator": "When enabled, pressing the accelerator pedal will disengage openpilot.",
|
||||
"LongitudinalPersonality": (
|
||||
"Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. " +
|
||||
"In relaxed mode openpilot will stay further away from lead cars. On supported cars, you can cycle through these personalities with " +
|
||||
"your steering wheel distance button."
|
||||
),
|
||||
"IsLdwEnabled": (
|
||||
"Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line " +
|
||||
"without a turn signal activated while driving over 31 mph (50 km/h)."
|
||||
@@ -41,6 +46,15 @@ class TogglesLayout(Widget):
|
||||
self._params.get_bool("DisengageOnAccelerator"),
|
||||
icon="disengage_on_accelerator.png",
|
||||
),
|
||||
multiple_button_item(
|
||||
"Driving Personality",
|
||||
DESCRIPTIONS["LongitudinalPersonality"],
|
||||
buttons=["Aggressive", "Standard", "Relaxed"],
|
||||
button_width=255,
|
||||
callback=self._set_longitudinal_personality,
|
||||
selected_index=int(self._params.get("LongitudinalPersonality") or 0),
|
||||
icon="speed_limit.png"
|
||||
),
|
||||
toggle_item(
|
||||
"Enable Lane Departure Warnings",
|
||||
DESCRIPTIONS["IsLdwEnabled"],
|
||||
@@ -68,3 +82,6 @@ class TogglesLayout(Widget):
|
||||
|
||||
def _render(self, rect):
|
||||
self._list_widget.render(rect)
|
||||
|
||||
def _set_longitudinal_personality(self, button_index: int):
|
||||
self._params.put("LongitudinalPersonality", str(button_index))
|
||||
|
||||
@@ -149,6 +149,59 @@ class DualButtonAction(ItemAction):
|
||||
return False
|
||||
|
||||
|
||||
class MultipleButtonAction(ItemAction):
|
||||
def __init__(self, buttons: list[str], button_width: int, selected_index: int = 0, callback: Callable = None):
|
||||
super().__init__(width=len(buttons) * (button_width + 20), enabled=True)
|
||||
self.buttons = buttons
|
||||
self.button_width = button_width
|
||||
self.selected_button = selected_index
|
||||
self.callback = callback
|
||||
self._font = gui_app.font(FontWeight.MEDIUM)
|
||||
|
||||
def _render(self, rect: rl.Rectangle) -> bool:
|
||||
spacing = 20
|
||||
button_y = rect.y + (rect.height - 100) / 2
|
||||
clicked = -1
|
||||
|
||||
for i, text in enumerate(self.buttons):
|
||||
button_x = rect.x + i * (self.button_width + spacing)
|
||||
button_rect = rl.Rectangle(button_x, button_y, self.button_width, 100)
|
||||
|
||||
# Check button state
|
||||
mouse_pos = rl.get_mouse_position()
|
||||
is_hovered = rl.check_collision_point_rec(mouse_pos, button_rect)
|
||||
is_pressed = is_hovered and rl.is_mouse_button_down(rl.MouseButton.MOUSE_BUTTON_LEFT)
|
||||
is_selected = i == self.selected_button
|
||||
|
||||
# Button colors
|
||||
if is_selected:
|
||||
bg_color = rl.Color(51, 171, 76, 255) # Green
|
||||
elif is_pressed:
|
||||
bg_color = rl.Color(74, 74, 74, 255) # Dark gray
|
||||
else:
|
||||
bg_color = rl.Color(57, 57, 57, 255) # Gray
|
||||
|
||||
# Draw button
|
||||
rl.draw_rectangle_rounded(button_rect, 1.0, 20, bg_color)
|
||||
|
||||
# Draw text
|
||||
text_size = measure_text_cached(self._font, text, 40)
|
||||
text_x = button_x + (self.button_width - text_size.x) / 2
|
||||
text_y = button_y + (100 - text_size.y) / 2
|
||||
rl.draw_text_ex(self._font, text, rl.Vector2(text_x, text_y), 40, 0, rl.Color(228, 228, 228, 255))
|
||||
|
||||
# Handle click
|
||||
if is_hovered and rl.is_mouse_button_released(rl.MouseButton.MOUSE_BUTTON_LEFT):
|
||||
clicked = i
|
||||
|
||||
if clicked >= 0:
|
||||
self.selected_button = clicked
|
||||
if self.callback:
|
||||
self.callback(clicked)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ListItem:
|
||||
title: str
|
||||
@@ -391,3 +444,9 @@ def dual_button_item(left_text: str, right_text: str, left_callback: Callable =
|
||||
visible: bool | Callable[[], bool] = True) -> ListItem:
|
||||
action = DualButtonAction(left_text, right_text, left_callback, right_callback, enabled)
|
||||
return ListItem(title="", description=description, action_item=action, visible=visible)
|
||||
|
||||
|
||||
def multiple_button_item(title: str, description: str, buttons: list[str], selected_index: int,
|
||||
button_width: int = BUTTON_WIDTH, callback: Callable = None, icon: str = ""):
|
||||
action = MultipleButtonAction(buttons, button_width, selected_index, callback=callback)
|
||||
return ListItem(title=title, description=description, icon=icon, action_item=action)
|
||||
|
||||
Reference in New Issue
Block a user