Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions selfdrive/ui/mici/layouts/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,6 @@ def show_event(self):
def _update_params(self):
self._experimental_mode = ui_state.params.get_bool("ExperimentalMode")

def _handle_long_press(self, _):
# long gating for experimental mode - only allow toggle if longitudinal control is available
if ui_state.has_longitudinal_control:
self._experimental_mode = not self._experimental_mode
ui_state.params.put("ExperimentalMode", self._experimental_mode)

def _update_state(self):
if rl.get_time() - self._last_refresh > 5.0:
device_state = ui_state.sm['deviceState']
Expand All @@ -143,6 +137,12 @@ def _update_network_status(self, device_state):
def set_callbacks(self, on_settings: Callable | None = None):
self._on_settings_click = on_settings

def _handle_long_press(self, _):
# long gating for experimental mode - only allow toggle if longitudinal control is available
if ui_state.has_longitudinal_control:
self._experimental_mode = not self._experimental_mode
ui_state.params.put("ExperimentalMode", self._experimental_mode)

def _handle_mouse_release(self, mouse_pos: MousePos):
if self._on_settings_click:
self._on_settings_click()
Expand Down
19 changes: 12 additions & 7 deletions selfdrive/ui/mici/layouts/settings/toggles.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.widgets import NavWidget
from openpilot.selfdrive.ui.layouts.settings.toggles import DESCRIPTIONS
from openpilot.selfdrive.ui.layouts.settings.common import restart_needed_callback
from openpilot.selfdrive.ui.ui_state import ui_state

Expand All @@ -17,14 +18,18 @@ def __init__(self, back_callback: Callable):
super().__init__()
self.set_back_callback(back_callback)

self._personality_toggle = BigMultiParamToggle("driving personality", "LongitudinalPersonality", ["aggressive", "standard", "relaxed"])
self._personality_toggle = BigMultiParamToggle("driving personality", "LongitudinalPersonality", ["aggressive", "standard", "relaxed"],
description=DESCRIPTIONS["LongitudinalPersonality"])
self._experimental_btn = BigParamControl("experimental mode", "ExperimentalMode")
is_metric_toggle = BigParamControl("use metric units", "IsMetric")
ldw_toggle = BigParamControl("lane departure warnings", "IsLdwEnabled")
always_on_dm_toggle = BigParamControl("always-on driver monitor", "AlwaysOnDM")
record_front = BigParamControl("record & upload driver camera", "RecordFront", toggle_callback=restart_needed_callback)
record_mic = BigParamControl("record & upload mic audio", "RecordAudio", toggle_callback=restart_needed_callback)
enable_openpilot = BigParamControl("enable openpilot", "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback)
is_metric_toggle = BigParamControl("use metric units", "IsMetric", description=DESCRIPTIONS["IsMetric"])
ldw_toggle = BigParamControl("lane departure warnings", "IsLdwEnabled", description=DESCRIPTIONS["IsLdwEnabled"])
always_on_dm_toggle = BigParamControl("always-on driver monitor", "AlwaysOnDM", description=DESCRIPTIONS["AlwaysOnDM"])
record_front = BigParamControl("record & upload driver camera", "RecordFront", toggle_callback=restart_needed_callback,
description=DESCRIPTIONS["RecordFront"])
record_mic = BigParamControl("record & upload mic audio", "RecordAudio", toggle_callback=restart_needed_callback,
description=DESCRIPTIONS["RecordAudio"])
enable_openpilot = BigParamControl("enable openpilot", "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback,
description=DESCRIPTIONS["OpenpilotEnabledToggle"])

self._scroller = Scroller([
self._personality_toggle,
Expand Down
27 changes: 18 additions & 9 deletions selfdrive/ui/mici/widgets/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ def _render(self, _):
class BigButton(Widget):
"""A lightweight stand-in for the Qt BigButton, drawn & updated each frame."""

def __init__(self, text: str, value: str = "", icon: Union[str, rl.Texture] = ""):
def __init__(self, text: str, value: str = "", icon: Union[str, rl.Texture] = "", description: str | None = None):
super().__init__()
self.set_rect(rl.Rectangle(0, 0, 402, 180))
self.text = text
self.value = value
self.set_icon(icon)
self.description = description

self._scale_filter = BounceFilter(1.0, 0.1, 1 / gui_app.target_fps)

Expand All @@ -136,6 +137,13 @@ def __init__(self, text: str, value: str = "", icon: Union[str, rl.Texture] = ""
def set_icon(self, icon: Union[str, rl.Texture]):
self._txt_icon = gui_app.texture(icon, 64, 64) if isinstance(icon, str) and len(icon) else icon

def _handle_long_press(self, mouse_pos: MousePos) -> None:
if not self.description:
return
# Import inside to avoid circular imports
from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog
gui_app.set_modal_overlay(BigDialog(self.text, self.description))

def set_rotate_icon(self, rotate: bool):
if rotate and self._rotate_icon_t is not None:
return
Expand Down Expand Up @@ -251,8 +259,9 @@ def _render(self, _):


class BigToggle(BigButton):
def __init__(self, text: str, value: str = "", initial_state: bool = False, toggle_callback: Callable = None):
super().__init__(text, value, "")
def __init__(self, text: str, value: str = "", initial_state: bool = False, toggle_callback: Callable = None,
description: str | None = None):
super().__init__(text, value, "", description=description)
self._checked = initial_state
self._toggle_callback = toggle_callback

Expand Down Expand Up @@ -289,8 +298,8 @@ def _render(self, _):

class BigMultiToggle(BigToggle):
def __init__(self, text: str, options: list[str], toggle_callback: Callable = None,
select_callback: Callable = None):
super().__init__(text, "", toggle_callback=toggle_callback)
select_callback: Callable = None, description: str | None = None):
super().__init__(text, "", toggle_callback=toggle_callback, description=description)
assert len(options) > 0
self._options = options
self._select_callback = select_callback
Expand Down Expand Up @@ -328,8 +337,8 @@ def _render(self, _):

class BigMultiParamToggle(BigMultiToggle):
def __init__(self, text: str, param: str, options: list[str], toggle_callback: Callable = None,
select_callback: Callable = None):
super().__init__(text, options, toggle_callback, select_callback)
select_callback: Callable = None, description: str | None = None):
super().__init__(text, options, toggle_callback, select_callback, description=description)
self._param = param

self._params = Params()
Expand All @@ -345,8 +354,8 @@ def _handle_mouse_release(self, mouse_pos: MousePos):


class BigParamControl(BigToggle):
def __init__(self, text: str, param: str, toggle_callback: Callable = None):
super().__init__(text, "", toggle_callback=toggle_callback)
def __init__(self, text: str, param: str, toggle_callback: Callable = None, description: str | None = None):
super().__init__(text, "", toggle_callback=toggle_callback, description=description)
self.param = param
self.params = Params()
self.set_checked(self.params.get_bool(self.param, False))
Expand Down
60 changes: 35 additions & 25 deletions selfdrive/ui/mici/widgets/dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ def __init__(self,
right_btn: str | None = None,
right_btn_callback: Callable | None = None):
super().__init__(right_btn, right_btn_callback)
self._title = title
self._description = description
self._title_label = UnifiedLabel(title, font_size=50, text_color=rl.Color(255, 255, 255, int(255 * 0.9)), font_weight=FontWeight.BOLD)
self._description_label = UnifiedLabel(description, font_size=30, text_color=rl.Color(255, 255, 255, int(255 * 0.58)), )
self._scroller = Scroller([
self._title_label,
self._description_label
], horizontal=False, snap_items=False)

def _render(self, _) -> DialogResult:
super()._render(_)
Expand All @@ -73,26 +77,33 @@ def _render(self, _) -> DialogResult:
if self._right_btn:
max_width -= self._right_btn._rect.width

title_wrapped = '\n'.join(wrap_text(gui_app.font(FontWeight.BOLD), self._title, 50, int(max_width)))
title_size = measure_text_cached(gui_app.font(FontWeight.BOLD), title_wrapped, 50)
text_x_offset = 0
title_rect = rl.Rectangle(int(self._rect.x + text_x_offset + PADDING),
int(self._rect.y + PADDING),
int(max_width),
int(title_size.y))
gui_label(title_rect, title_wrapped, 50, font_weight=FontWeight.BOLD,
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)

# draw description
desc_wrapped = '\n'.join(wrap_text(gui_app.font(FontWeight.MEDIUM), self._description, 30, int(max_width)))
desc_size = measure_text_cached(gui_app.font(FontWeight.MEDIUM), desc_wrapped, 30)
desc_rect = rl.Rectangle(int(self._rect.x + text_x_offset + PADDING),
int(self._rect.y + self._rect.height / 3),
int(max_width),
int(desc_size.y))
# TODO: text align doesn't seem to work properly with newlines
gui_label(desc_rect, desc_wrapped, 30, font_weight=FontWeight.MEDIUM,
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)
self._scroller.render(self._rect)
# title_height = self._title_label.get_text_height(int(max_width))
# self._title_label.render(rl.Rectangle(
# self._rect.x,
# self._rect.y
# ))

# title_wrapped = '\n'.join(wrap_text(gui_app.font(FontWeight.BOLD), self._title, 50, int(max_width)))
# title_size = measure_text_cached(gui_app.font(FontWeight.BOLD), title_wrapped, 50)
# text_x_offset = 0
# title_rect = rl.Rectangle(int(self._rect.x + text_x_offset + PADDING),
# int(self._rect.y + PADDING),
# int(max_width),
# int(title_size.y))
# gui_label(title_rect, title_wrapped, 50, font_weight=FontWeight.BOLD,
# alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)
#
# # draw description
# desc_wrapped = '\n'.join(wrap_text(gui_app.font(FontWeight.MEDIUM), self._description, 30, int(max_width)))
# desc_size = measure_text_cached(gui_app.font(FontWeight.MEDIUM), desc_wrapped, 30)
# desc_rect = rl.Rectangle(int(self._rect.x + text_x_offset + PADDING),
# int(self._rect.y + self._rect.height / 3),
# int(max_width),
# int(desc_size.y))
# # TODO: text align doesn't seem to work properly with newlines
# gui_label(desc_rect, desc_wrapped, 30, font_weight=FontWeight.MEDIUM,
# alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)

return self._ret

Expand Down Expand Up @@ -400,11 +411,10 @@ def _render(self, _):

class BigDialogButton(BigButton):
def __init__(self, text: str, value: str = "", icon: Union[str, rl.Texture] = "", description: str = ""):
super().__init__(text, value, icon)
self._description = description
super().__init__(text, value, icon, description=description)

def _handle_mouse_release(self, mouse_pos: MousePos):
super()._handle_mouse_release(mouse_pos)

dlg = BigDialog(self.text, self._description)
dlg = BigDialog(self.text, self.description)
gui_app.set_modal_overlay(dlg)
Loading