ui: setup widget->firehose settings navigation (#35531)

* setup widget->firehose settings navigation

* cleanup

---------

Co-authored-by: Shane Smiskol <shane@smiskol.com>
pull/35529/head^2
Dean Lee 2 weeks ago committed by GitHub
parent 79319d2447
commit 9d8e4acec9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 8
      selfdrive/ui/layouts/main.py
  2. 41
      selfdrive/ui/layouts/settings/settings.py
  3. 11
      selfdrive/ui/widgets/setup.py

@ -2,7 +2,7 @@ import pyray as rl
from enum import IntEnum from enum import IntEnum
from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH
from openpilot.selfdrive.ui.layouts.home import HomeLayout from openpilot.selfdrive.ui.layouts.home import HomeLayout
from openpilot.selfdrive.ui.layouts.settings.settings import SettingsLayout from openpilot.selfdrive.ui.layouts.settings.settings import SettingsLayout, PanelType
from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView
from openpilot.system.ui.lib.widget import Widget from openpilot.system.ui.lib.widget import Widget
@ -40,6 +40,7 @@ class MainLayout(Widget):
def _setup_callbacks(self): def _setup_callbacks(self):
self._sidebar.set_callbacks(on_settings=self._on_settings_clicked, self._sidebar.set_callbacks(on_settings=self._on_settings_clicked,
on_flag=self._on_flag_clicked) on_flag=self._on_flag_clicked)
self._layouts[MainState.HOME]._setup_widget.set_open_settings_callback(lambda: self.open_settings(PanelType.FIREHOSE))
self._layouts[MainState.SETTINGS].set_callbacks(on_close=self._set_mode_for_state) self._layouts[MainState.SETTINGS].set_callbacks(on_close=self._set_mode_for_state)
self._layouts[MainState.ONROAD].set_callbacks(on_click=self._on_onroad_clicked) self._layouts[MainState.ONROAD].set_callbacks(on_click=self._on_onroad_clicked)
@ -64,6 +65,11 @@ class MainLayout(Widget):
self._current_mode = MainState.HOME self._current_mode = MainState.HOME
self._sidebar_visible = True self._sidebar_visible = True
def open_settings(self, panel_type: PanelType):
self._layouts[MainState.SETTINGS].set_current_panel(panel_type)
self._current_mode = MainState.SETTINGS
self._sidebar_visible = False
def _on_settings_clicked(self): def _on_settings_clicked(self):
self._current_mode = MainState.SETTINGS self._current_mode = MainState.SETTINGS
self._sidebar_visible = False self._sidebar_visible = False

@ -2,7 +2,6 @@ import pyray as rl
from dataclasses import dataclass from dataclasses import dataclass
from enum import IntEnum from enum import IntEnum
from collections.abc import Callable from collections.abc import Callable
from openpilot.common.params import Params
from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout
from openpilot.selfdrive.ui.layouts.settings.device import DeviceLayout from openpilot.selfdrive.ui.layouts.settings.device import DeviceLayout
from openpilot.selfdrive.ui.layouts.settings.firehose import FirehoseLayout from openpilot.selfdrive.ui.layouts.settings.firehose import FirehoseLayout
@ -21,7 +20,6 @@ SIDEBAR_WIDTH = 500
CLOSE_BTN_SIZE = 200 CLOSE_BTN_SIZE = 200
NAV_BTN_HEIGHT = 80 NAV_BTN_HEIGHT = 80
PANEL_MARGIN = 50 PANEL_MARGIN = 50
SCROLL_SPEED = 30
# Colors # Colors
SIDEBAR_COLOR = rl.BLACK SIDEBAR_COLOR = rl.BLACK
@ -30,7 +28,6 @@ CLOSE_BTN_COLOR = rl.Color(41, 41, 41, 255)
CLOSE_BTN_PRESSED = rl.Color(59, 59, 59, 255) CLOSE_BTN_PRESSED = rl.Color(59, 59, 59, 255)
TEXT_NORMAL = rl.Color(128, 128, 128, 255) TEXT_NORMAL = rl.Color(128, 128, 128, 255)
TEXT_SELECTED = rl.Color(255, 255, 255, 255) TEXT_SELECTED = rl.Color(255, 255, 255, 255)
TEXT_PRESSED = rl.Color(173, 173, 173, 255)
class PanelType(IntEnum): class PanelType(IntEnum):
@ -46,24 +43,22 @@ class PanelType(IntEnum):
class PanelInfo: class PanelInfo:
name: str name: str
instance: object instance: object
button_rect: rl.Rectangle button_rect: rl.Rectangle = rl.Rectangle(0, 0, 0, 0)
class SettingsLayout(Widget): class SettingsLayout(Widget):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._params = Params()
self._current_panel = PanelType.DEVICE self._current_panel = PanelType.DEVICE
self._max_scroll = 0.0
# Panel configuration # Panel configuration
self._panels = { self._panels = {
PanelType.DEVICE: PanelInfo("Device", DeviceLayout(), rl.Rectangle(0, 0, 0, 0)), PanelType.DEVICE: PanelInfo("Device", DeviceLayout()),
PanelType.NETWORK: PanelInfo("Network", NetworkLayout(), rl.Rectangle(0, 0, 0, 0)), PanelType.NETWORK: PanelInfo("Network", NetworkLayout()),
PanelType.TOGGLES: PanelInfo("Toggles", TogglesLayout(), rl.Rectangle(0, 0, 0, 0)), PanelType.TOGGLES: PanelInfo("Toggles", TogglesLayout()),
PanelType.SOFTWARE: PanelInfo("Software", SoftwareLayout(), rl.Rectangle(0, 0, 0, 0)), PanelType.SOFTWARE: PanelInfo("Software", SoftwareLayout()),
PanelType.FIREHOSE: PanelInfo("Firehose", FirehoseLayout(), rl.Rectangle(0, 0, 0, 0)), PanelType.FIREHOSE: PanelInfo("Firehose", FirehoseLayout()),
PanelType.DEVELOPER: PanelInfo("Developer", DeveloperLayout(), rl.Rectangle(0, 0, 0, 0)), PanelType.DEVELOPER: PanelInfo("Developer", DeveloperLayout()),
} }
self._font_medium = gui_app.font(FontWeight.MEDIUM) self._font_medium = gui_app.font(FontWeight.MEDIUM)
@ -108,17 +103,11 @@ class SettingsLayout(Widget):
self._close_btn_rect = close_btn_rect self._close_btn_rect = close_btn_rect
# Navigation buttons # Navigation buttons
nav_start_y = rect.y + 300 y = rect.y + 300
button_spacing = 20 button_spacing = 20
i = 0
for panel_type, panel_info in self._panels.items(): for panel_type, panel_info in self._panels.items():
button_rect = rl.Rectangle( button_rect = rl.Rectangle(rect.x + 50, y, rect.width - 150, NAV_BTN_HEIGHT)
rect.x + 50,
nav_start_y + i * (NAV_BTN_HEIGHT + button_spacing),
rect.width - 150, # Right-aligned with margin
NAV_BTN_HEIGHT,
)
# Button styling # Button styling
is_selected = panel_type == self._current_panel is_selected = panel_type == self._current_panel
@ -132,7 +121,8 @@ class SettingsLayout(Widget):
# Store button rect for click detection # Store button rect for click detection
panel_info.button_rect = button_rect panel_info.button_rect = button_rect
i += 1
y += NAV_BTN_HEIGHT + button_spacing
def _draw_current_panel(self, rect: rl.Rectangle): def _draw_current_panel(self, rect: rl.Rectangle):
rl.draw_rectangle_rounded( rl.draw_rectangle_rounded(
@ -154,20 +144,15 @@ class SettingsLayout(Widget):
# Check navigation buttons # Check navigation buttons
for panel_type, panel_info in self._panels.items(): for panel_type, panel_info in self._panels.items():
if rl.check_collision_point_rec(mouse_pos, panel_info.button_rect): if rl.check_collision_point_rec(mouse_pos, panel_info.button_rect):
self._switch_to_panel(panel_type) self.set_current_panel(panel_type)
return True return True
return False return False
def _switch_to_panel(self, panel_type: PanelType): def set_current_panel(self, panel_type: PanelType):
if panel_type != self._current_panel: if panel_type != self._current_panel:
self._current_panel = panel_type self._current_panel = panel_type
def set_current_panel(self, index: int, param: str = ""):
panel_types = list(self._panels.keys())
if 0 <= index < len(panel_types):
self._switch_to_panel(panel_types[index])
def close_settings(self): def close_settings(self):
if self._close_callback: if self._close_callback:
self._close_callback() self._close_callback()

@ -11,9 +11,12 @@ from openpilot.system.ui.lib.widget import Widget
class SetupWidget(Widget): class SetupWidget(Widget):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._open_settings_callback = None
self._pairing_dialog: PairingDialog | None = None self._pairing_dialog: PairingDialog | None = None
def set_open_settings_callback(self, callback):
self._open_settings_callback = callback
def _render(self, rect: rl.Rectangle): def _render(self, rect: rl.Rectangle):
if ui_state.prime_state.get_type() == PrimeType.UNPAIRED: if ui_state.prime_state.get_type() == PrimeType.UNPAIRED:
self._render_registration(rect) self._render_registration(rect)
@ -78,16 +81,14 @@ class SetupWidget(Widget):
button_height = 48 + 64 # font size + padding button_height = 48 + 64 # font size + padding
button_rect = rl.Rectangle(x, y, w, button_height) button_rect = rl.Rectangle(x, y, w, button_height)
if gui_button(button_rect, "Open", button_style=ButtonStyle.PRIMARY): if gui_button(button_rect, "Open", button_style=ButtonStyle.PRIMARY):
self._open_firehose_settings() if self._open_settings_callback:
self._open_settings_callback()
def _show_pairing(self): def _show_pairing(self):
if not self._pairing_dialog: if not self._pairing_dialog:
self._pairing_dialog = PairingDialog() self._pairing_dialog = PairingDialog()
gui_app.set_modal_overlay(self._pairing_dialog, lambda result: setattr(self, '_pairing_dialog', None)) gui_app.set_modal_overlay(self._pairing_dialog, lambda result: setattr(self, '_pairing_dialog', None))
def _open_firehose_settings(self):
pass
def __del__(self): def __del__(self):
if self._pairing_dialog: if self._pairing_dialog:
del self._pairing_dialog del self._pairing_dialog

Loading…
Cancel
Save