From 33d7e977b4a0a6266910224aeb5e78bcd15730ab Mon Sep 17 00:00:00 2001 From: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:57:57 -0400 Subject: [PATCH] Big UI : Cleanup --- .../layouts/settings/starpilot/aethergrid.py | 123 +++++++++++++- .../layouts/settings/starpilot/appearance.py | 97 ++--------- .../ui/layouts/settings/starpilot/lateral.py | 74 +-------- .../settings/starpilot/longitudinal.py | 157 +++--------------- .../layouts/settings/starpilot/main_panel.py | 11 +- .../ui/layouts/settings/starpilot/panel.py | 7 +- .../ui/layouts/settings/starpilot/sounds.py | 44 +---- .../settings/starpilot/system_settings.py | 2 +- .../ui/layouts/settings/starpilot/vehicle.py | 5 +- 9 files changed, 187 insertions(+), 333 deletions(-) diff --git a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py index 3f0cc6d47..1f804698b 100644 --- a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py +++ b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py @@ -1033,6 +1033,71 @@ class PanelManagerView(AetherInteractiveMixin, Widget): self._on_page_changed() +# ═══════════════════════════════════════════════════════════════ +# AdjustorTogglesPanelView — shared adjustor+toggle-grid base +# ═══════════════════════════════════════════════════════════════ + +class AdjustorTogglesPanelView(PanelManagerView): + """PanelManagerView with AetherAdjustorRow sliders + paginated toggles. + + Subclasses must set ``self._adjustor_rows``, ``self._toggle_grid``, + and call ``super().__init__()``. May override ``_get_active_elements()`` + to control which children receive mouse events. + """ + + @property + def vertical_scrolling_disabled(self) -> bool: + return True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._pressed_target: str | None = None + self._adjustor_rows: dict[str, AetherAdjustorRow] = {} + self._can_click = True + self._active_adjustor_key = None + + def _set_active_adjustor(self, key: str, active: bool): + if active: + if self._active_adjustor_key and self._active_adjustor_key != key: + old = self._adjustor_rows.get(self._active_adjustor_key) + if old: + old.reset_interaction() + self._active_adjustor_key = key + elif self._active_adjustor_key == key: + self._active_adjustor_key = None + + def show_event(self): + super().show_event() + self._pressed_target = None + self._can_click = True + + def hide_event(self): + super().hide_event() + self._pressed_target = None + self._can_click = True + + def _get_active_elements(self): + elems = list(self._adjustor_rows.values()) + if hasattr(self, '_toggle_grid'): + elems.append(self._toggle_grid) + return elems + + def _handle_mouse_press(self, mouse_pos): + super()._handle_mouse_press(mouse_pos) + for el in self._get_active_elements(): + el._handle_mouse_press(mouse_pos) + + def _handle_mouse_release(self, mouse_pos): + for el in self._get_active_elements(): + el._handle_mouse_release(mouse_pos) + super()._handle_mouse_release(mouse_pos) + + def _handle_mouse_event(self, mouse_event): + super()._handle_mouse_event(mouse_event) + for el in self._get_active_elements(): + el._handle_mouse_event(mouse_event) + + class BreadcrumbController: EXPAND_DURATION: float = 2.5 @@ -3380,10 +3445,66 @@ class AetherSettingsView(PanelManagerView): action_text_color=action_text_color, action_fill=action_fill, action_border=action_border, - row_separator=self._panel_style.divider_color, + row_separator=self._panel_style.divider_color, ) +# ═══════════════════════════════════════════════════════════════ +# CardHubManagerView — shared HubTile card-grid landing page +# ═══════════════════════════════════════════════════════════════ + +class CardHubManagerView(AetherSettingsView): + """AetherSettingsView that renders a TileGrid of HubTile navigation cards. + + Subclasses override ``_build_cards()`` to return a list of card dicts + with keys ``title``, ``desc``, ``icon``, ``on_click``. + """ + + @property + def vertical_scrolling_disabled(self) -> bool: + return True + + def __init__(self, controller, sections, *, columns=3, padding=SPACING.tile_gap, **kwargs): + super().__init__(controller, sections, **kwargs) + self._grid = TileGrid(columns=columns, padding=padding) + self._grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid()) + self._child(self._grid) + self._init_cards() + + def _init_cards(self): + self._grid.clear() + for d in self._build_cards(): + self._grid.add_tile(HubTile( + title=d["title"], desc=d["desc"], icon_key=d["icon"], + on_click=d["on_click"], + )) + + def _build_cards(self) -> list[dict]: + raise NotImplementedError + + def _render(self, rect: rl.Rectangle): + self.set_rect(rect) + self._interactive_rects.clear() + mx = float(self._metrics.outer_margin_x) + my = float(self._metrics.outer_margin_y) + grid_x = rect.x + mx + grid_y = rect.y + my + grid_w = rect.width - mx * 2 + grid_h = rect.y + rect.height - grid_y - my + self._scroll_rect = rl.Rectangle(grid_x, grid_y, grid_w, grid_h) + self._content_height = grid_h + self._scroll_panel.set_enabled(self.is_visible) + self._scroll_offset = self._scroll_panel.update( + self._scroll_rect, self._scroll_rect.height) + self._scroll_offset = 0.0 + self._draw_scroll_content(self._scroll_rect, self._scroll_rect.width) + + def _draw_scroll_content(self, rect: rl.Rectangle, width: float): + y = rect.y + self._scroll_offset + self._grid.set_parent_rect(self._scroll_rect) + self._grid.render(rl.Rectangle(rect.x, y, width, rect.height)) + + def draw_back_button(pill_rect: rl.Rectangle, center_y: float, pressed: bool, hovered: bool) -> rl.Rectangle: back_size = 48 back_x = pill_rect.x + 12 diff --git a/selfdrive/ui/layouts/settings/starpilot/appearance.py b/selfdrive/ui/layouts/settings/starpilot/appearance.py index e38beca70..cdd7473bb 100644 --- a/selfdrive/ui/layouts/settings/starpilot/appearance.py +++ b/selfdrive/ui/layouts/settings/starpilot/appearance.py @@ -1,15 +1,13 @@ from __future__ import annotations import re -import math -from openpilot.system.ui.lib.application import gui_app, FontWeight +from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.lib.multilang import tr, tr_noop from openpilot.system.ui.widgets import DialogResult from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPage -import pyray as rl from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( AetherSliderDialog, DEFAULT_PANEL_STYLE, @@ -17,10 +15,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( SettingRow, SettingSection, AetherSettingsView, - TileGrid, - HubTile, - draw_list_group_shell, - AetherListColors, + CardHubManagerView, ) from openpilot.selfdrive.ui.layouts.settings.starpilot.simple_download_manager import SimpleDownloadManager from openpilot.starpilot.common.starpilot_variables import THEME_SAVE_PATH @@ -85,114 +80,53 @@ def _theme_display_name(value: str) -> str: return display # ═══════════════════════════════════════════════════════════════ -# Unified Appearance panel +# AppearanceManagerView — 6-card category hub # ═══════════════════════════════════════════════════════════════ -class AppearanceManagerView(AetherSettingsView): - @property - def vertical_scrolling_disabled(self) -> bool: - return True - +class AppearanceManagerView(CardHubManagerView): def __init__(self, controller, sections, **kwargs): super().__init__(controller, sections, **kwargs) - self._main_grid = TileGrid(columns=3, padding=12) - self._main_grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid()) - self._child(self._main_grid) - self._init_toggles() - - def _init_toggles(self): - hero_data = [ + def _build_cards(self): + return [ { "title": tr("Model & Path Visualization"), "desc": tr("Customize dynamic lane paths, road edges, and colors."), "icon": "steering", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("model") + "on_click": lambda: self._controller._navigate_to("model"), }, { "title": tr("Driving Widgets & HUD"), "desc": tr("Configure compass, dynamic pedals, signals, and screen borders."), "icon": "display", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("hud") + "on_click": lambda: self._controller._navigate_to("hud"), }, { "title": tr("Screen Declutter & Visibility"), "desc": tr("Toggle speed limits, alert banners, and driver monitoring icon."), "icon": "system", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("declutter") + "on_click": lambda: self._controller._navigate_to("declutter"), }, - ] - - standard_data = [ { "title": tr("Navigation & Mapping"), "desc": tr("Configure road names, Vienna signs, and offroad routes."), "icon": "navigate", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("nav") + "on_click": lambda: self._controller._navigate_to("nav"), }, { "title": tr("Camera & System Startup"), "desc": tr("Manage driver monitoring cameras, boot logos, and startup sounds."), "icon": "vehicle", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("system") + "on_click": lambda: self._controller._navigate_to("system"), }, { "title": tr("Advanced Metrics"), "desc": tr("Adjust radar plots, lead vehicle info, and stop sign metrics."), "icon": "sound", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("dev") + "on_click": lambda: self._controller._navigate_to("dev"), }, ] - all_data = hero_data + standard_data - self._main_grid.clear() - for d in all_data: - self._main_grid.add_tile( - HubTile( - title=d["title"], - desc=d["desc"], - icon_key=d["icon"], - on_click=d["on_click"], - bg_color=d["color"], - ) - ) - - def _render(self, rect: rl.Rectangle): - self.set_rect(rect) - self._interactive_rects.clear() - - margin_x = 10.0 - margin_y = 10.0 - - grid_x = rect.x + margin_x - grid_y = rect.y + margin_y - grid_w = rect.width - margin_x * 2 - grid_h = rect.y + rect.height - grid_y - margin_y - - self._scroll_rect = rl.Rectangle(grid_x, grid_y, grid_w, grid_h) - self._content_height = grid_h - - self._scroll_panel.set_enabled(self.is_visible) - self._scroll_offset = self._scroll_panel.update( - self._scroll_rect, self._scroll_rect.height - ) - - if self.vertical_scrolling_disabled: - self._scroll_offset = 0.0 - - self._draw_scroll_content(self._scroll_rect, self._scroll_rect.width) - - def _draw_scroll_content(self, rect: rl.Rectangle, width: float): - y = rect.y + self._scroll_offset - self._main_grid.set_parent_rect(self._scroll_rect) - self._main_grid.render(rl.Rectangle(rect.x, y, width, rect.height)) - class StarPilotAppearanceLayout(_SettingsPage): def __init__(self): @@ -393,10 +327,6 @@ class StarPilotAppearanceLayout(_SettingsPage): # ═══ 3. Screen Declutter & Visibility ═══ self._declutter_rows = [ - SettingRow("AdvancedCustomUI", "toggle", tr_noop("Advanced UI Controls"), - subtitle=tr_noop("Fine-tune which elements appear on screen."), - get_state=lambda: self._params.get_bool("AdvancedCustomUI"), - set_state=lambda s: self._params.put_bool("AdvancedCustomUI", s)), SettingRow("HideSpeed", "toggle", tr_noop("Hide Speed"), subtitle="", get_state=lambda: self._params.get_bool("HideSpeed"), @@ -583,6 +513,8 @@ class StarPilotAppearanceLayout(_SettingsPage): "Display the driving model path, lanes, and road edges.") pt_hud = self._make_parent("CustomUI", "Driving Screen Widgets", "Show interactive indicators on the driving screen.") + pt_declutter = self._make_parent("AdvancedCustomUI", "Advanced UI Controls", + "Fine-tune which elements appear on screen.") # Register subpanels for Level 2 slide transitions self._sub_panels["model"] = AetherSettingsView( @@ -606,6 +538,7 @@ class StarPilotAppearanceLayout(_SettingsPage): [SettingSection(title="", rows=self._declutter_rows)], header_title=tr_noop("Screen Declutter & Visibility"), header_subtitle=tr_noop("Toggle speed limits, alert banners, and driver monitoring icon."), + parent_toggle=pt_declutter, panel_style=PANEL_STYLE, ) self._sub_panels["nav"] = AetherSettingsView( diff --git a/selfdrive/ui/layouts/settings/starpilot/lateral.py b/selfdrive/ui/layouts/settings/starpilot/lateral.py index 30a1d984e..736867839 100644 --- a/selfdrive/ui/layouts/settings/starpilot/lateral.py +++ b/selfdrive/ui/layouts/settings/starpilot/lateral.py @@ -1,7 +1,5 @@ from __future__ import annotations -import pyray as rl - from openpilot.system.hardware import HARDWARE from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state from openpilot.system.ui.lib.application import gui_app, FontWeight @@ -12,11 +10,10 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPag from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( DEFAULT_PANEL_STYLE, AetherSettingsView, + CardHubManagerView, ParentToggle, SettingRow, SettingSection, - TileGrid, - HubTile, AetherSliderDialog, ) @@ -47,88 +44,35 @@ def _sync_parent(params, parent_key, child_keys): # ═══════════════════════════════════════════════════════════════ -# SteeringManagerView — clean 3-card category hub +# SteeringManagerView — 3-card category hub # ═══════════════════════════════════════════════════════════════ -class SteeringManagerView(AetherSettingsView): - @property - def vertical_scrolling_disabled(self) -> bool: - return True - +class SteeringManagerView(CardHubManagerView): def __init__(self, controller, **kwargs): - super().__init__(controller, [], panel_style=PANEL_STYLE, **kwargs) - self._grid = TileGrid(columns=3, padding=12) - self._grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid()) - self._child(self._grid) - self._init_toggles() + super().__init__(controller, [], **kwargs) - def _init_toggles(self): - cards = [ + def _build_cards(self): + return [ { "title": tr("Steering Behavior"), "desc": tr("Configure Always On Lateral (AOL), pause speed thresholds, and turn signal behaviors."), "icon": "steering", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("behavior") + "on_click": lambda: self._controller._navigate_to("behavior"), }, { "title": tr("Lane Changes"), "desc": tr("Configure automatic lane changes, speed/width thresholds, and smoothing parameters."), "icon": "road", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("lane_changes") + "on_click": lambda: self._controller._navigate_to("lane_changes"), }, { "title": tr("Advanced Lateral Tuning"), "desc": tr("Adjust actuator delay, steer ratio, Kp, friction, and neural network feedforward controllers."), "icon": "system", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("advanced") + "on_click": lambda: self._controller._navigate_to("advanced"), }, ] - self._grid.clear() - for d in cards: - self._grid.add_tile( - HubTile( - title=d["title"], - desc=d["desc"], - icon_key=d["icon"], - on_click=d["on_click"], - bg_color=d["color"], - ) - ) - - def _render(self, rect: rl.Rectangle): - self.set_rect(rect) - self._interactive_rects.clear() - - margin_x = 10.0 - margin_y = 10.0 - - grid_x = rect.x + margin_x - grid_y = rect.y + margin_y - grid_w = rect.width - margin_x * 2 - grid_h = rect.y + rect.height - grid_y - margin_y - - self._scroll_rect = rl.Rectangle(grid_x, grid_y, grid_w, grid_h) - self._content_height = grid_h - - self._scroll_panel.set_enabled(self.is_visible) - self._scroll_offset = self._scroll_panel.update( - self._scroll_rect, self._scroll_rect.height - ) - - if self.vertical_scrolling_disabled: - self._scroll_offset = 0.0 - - self._draw_scroll_content(self._scroll_rect, self._scroll_rect.width) - - def _draw_scroll_content(self, rect: rl.Rectangle, width: float): - y = rect.y + self._scroll_offset - self._grid.set_parent_rect(self._scroll_rect) - self._grid.render(rl.Rectangle(rect.x, y, width, rect.height)) - # ═══════════════════════════════════════════════════════════════ # StarPilotLateralLayout — controller diff --git a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py index 46b246044..58886f0f8 100644 --- a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py +++ b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py @@ -18,6 +18,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPag from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( AETHER_LIST_METRICS, COMPACT_PANEL_METRICS, + AdjustorTogglesPanelView, AetherAdjustorRow, AetherSegmentedControl, AetherSliderDialog, @@ -27,12 +28,14 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( SettingRow, SettingSection, AetherSettingsView, + CardHubManagerView, TileGrid, HubTile, TOGGLE_MIN_HEIGHT, TOGGLE_ROW_HEIGHT, RowToggleTile, ToggleTile, + SPACING, draw_section_header, draw_list_group_shell, SECTION_GAP, @@ -88,7 +91,7 @@ class AdaptiveSpeedView(Widget): super().__init__() self._header_title = tr_noop("Adaptive Speed Controls") self._controller = controller - self._grid = TileGrid(columns=2, padding=12) + self._grid = TileGrid(columns=2, padding=SPACING.tile_gap) self._child(self._grid) self._grid.add_tile(HubTile( @@ -96,7 +99,6 @@ class AdaptiveSpeedView(Widget): desc=tr("Configure automated switching between Experimental and Chill Modes based on set conditions."), icon_key="steering", on_click=lambda: controller._navigate_to("ce"), - bg_color="#8B5CF6", )) self._grid.add_tile(HubTile( @@ -104,130 +106,68 @@ class AdaptiveSpeedView(Widget): desc=tr("Configure speed control on curves and reset collected calibration data."), icon_key="navigate", on_click=lambda: controller._navigate_to("csc"), - bg_color="#8B5CF6", )) def _render(self, rect: rl.Rectangle): - margin_x = 10.0 - margin_y = 10.0 - grid_x = rect.x + margin_x - grid_y = rect.y + margin_y - grid_w = rect.width - margin_x * 2 - grid_h = rect.y + rect.height - grid_y - margin_y + mx = float(AETHER_LIST_METRICS.outer_margin_x) + my = float(AETHER_LIST_METRICS.outer_margin_y) + grid_x = rect.x + mx + grid_y = rect.y + my + grid_w = rect.width - mx * 2 + grid_h = rect.y + rect.height - grid_y - my self._grid.render(rl.Rectangle(grid_x, grid_y, grid_w, grid_h)) # ═══════════════════════════════════════════════════════════════ -# LongitudinalManagerView — main category grid +# LongitudinalManagerView — 6-card category hub # ═══════════════════════════════════════════════════════════════ -class LongitudinalManagerView(AetherSettingsView): - @property - def vertical_scrolling_disabled(self) -> bool: - return True - +class LongitudinalManagerView(CardHubManagerView): def __init__(self, controller, sections, **kwargs): super().__init__(controller, sections, **kwargs) - self._main_grid = TileGrid(columns=3, padding=12) - self._main_grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid()) - self._child(self._main_grid) - self._init_toggles() - - def _init_toggles(self): - hero_data = [ + def _build_cards(self): + return [ { "title": tr("Longitudinal Tuning"), "desc": tr("Configure acceleration profiles, lane changes, and route speed control."), "icon": "steering", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("tune") + "on_click": lambda: self._controller._navigate_to("tune"), }, { "title": tr("Advanced Actuators"), "desc": tr("Adjust actuator delay, EV/Truck tuning, and launch/stop speeds/rates."), "icon": "vehicle", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("advanced") + "on_click": lambda: self._controller._navigate_to("advanced"), }, { "title": tr("Speed Limit Controller"), "desc": tr("Manage auto speed matching, confirmation, offsets, and source priority."), "icon": "navigate", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("slc") + "on_click": lambda: self._controller._navigate_to("slc"), }, - ] - - standard_data = [ { "title": tr("Adaptive Speed Controls"), "desc": tr("Configure Curve Speed Controller and Conditional Experimental Mode triggers."), "icon": "display", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("adaptive_speed") + "on_click": lambda: self._controller._navigate_to("adaptive_speed"), }, { "title": tr("Driving Personalities"), "desc": tr("Customize follow distance and jerk/response metrics for each personality profile."), "icon": "system", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("personality") + "on_click": lambda: self._controller._navigate_to("personality"), }, { "title": tr("Quality of Life"), "desc": tr("Configure cruise intervals, standstill behaviors, gear mapping, and weather presets."), "icon": "sound", - "color": "#8B5CF6", - "on_click": lambda: self._controller._navigate_to("daily") + "on_click": lambda: self._controller._navigate_to("daily"), }, ] - all_data = hero_data + standard_data - self._main_grid.clear() - for d in all_data: - self._main_grid.add_tile( - HubTile( - title=d["title"], - desc=d["desc"], - icon_key=d["icon"], - on_click=d["on_click"], - bg_color=d["color"], - ) - ) - def _render(self, rect: rl.Rectangle): - self.set_rect(rect) - self._interactive_rects.clear() - - margin_x = 10.0 - margin_y = 10.0 - - grid_x = rect.x + margin_x - grid_y = rect.y + margin_y - grid_w = rect.width - margin_x * 2 - grid_h = rect.y + rect.height - grid_y - margin_y - - self._scroll_rect = rl.Rectangle(grid_x, grid_y, grid_w, grid_h) - self._content_height = grid_h - - self._scroll_panel.set_enabled(self.is_visible) - self._scroll_offset = self._scroll_panel.update( - self._scroll_rect, self._scroll_rect.height - ) - - if self.vertical_scrolling_disabled: - self._scroll_offset = 0.0 - - self._draw_scroll_content(self._scroll_rect, self._scroll_rect.width) - - def _draw_scroll_content(self, rect: rl.Rectangle, width: float): - y = rect.y + self._scroll_offset - self._main_grid.set_parent_rect(self._scroll_rect) - self._main_grid.render(rl.Rectangle(rect.x, y, width, rect.height)) - - -class ConditionalDriveModeView(PanelManagerView): +class ConditionalDriveModeView(AdjustorTogglesPanelView): METRICS = COMPACT_PANEL_METRICS TAB_HEIGHT = 98 TAB_BOTTOM_GAP = 26 @@ -240,18 +180,10 @@ class ConditionalDriveModeView(PanelManagerView): super().__init__() self._header_title = tr("Conditional Drive Mode") self._controller = controller - self._pressed_target: str | None = None - self._adjustor_rows: dict[str, AetherAdjustorRow] = {} - self._can_click = True - self._active_adjustor_key = None self._init_segmented_control() self._init_adjustors() self._init_toggles() - self._forward_touch_valid() - - def _forward_touch_valid(self): - pass def _init_segmented_control(self): self._drive_mode_control = self._child( @@ -343,16 +275,6 @@ class ConditionalDriveModeView(PanelManagerView): return cls(**kwargs) - def _set_active_adjustor(self, key: str, active: bool): - if active: - if self._active_adjustor_key and self._active_adjustor_key != key: - old = self._adjustor_rows.get(self._active_adjustor_key) - if old: - old.reset_interaction() - self._active_adjustor_key = key - elif self._active_adjustor_key == key: - self._active_adjustor_key = None - def _init_adjustors(self): speed_unit = self._controller._speed_unit() is_metric = self._controller._is_metric() @@ -417,16 +339,6 @@ class ConditionalDriveModeView(PanelManagerView): unit=spec["unit"], labels=spec["labels"], color=PANEL_STYLE.accent )) - def show_event(self): - super().show_event() - self._pressed_target = None - self._can_click = True - - def hide_event(self): - super().hide_event() - self._pressed_target = None - self._can_click = True - def _draw_header(self, rect: rl.Rectangle): pass @@ -539,30 +451,13 @@ class ConditionalDriveModeView(PanelManagerView): def _get_active_elements(self): mode = self._get_drive_mode_index() + elems = [self._drive_mode_control] if mode == 1: - return [self._adjustor_rows[k] for k in self._cem_keys] + [self._toggle_grid] + elems += [self._adjustor_rows[k] for k in self._cem_keys] elif mode == 2: - return [self._adjustor_rows[k] for k in self._ccm_keys] + [self._toggle_grid] - return [] - - def _handle_mouse_press(self, mouse_pos: MousePos): - super()._handle_mouse_press(mouse_pos) - for el in self._get_active_elements(): - el._handle_mouse_press(mouse_pos) - self._drive_mode_control._handle_mouse_press(mouse_pos) - - def _handle_mouse_release(self, mouse_pos: MousePos): - for el in self._get_active_elements(): - el._handle_mouse_release(mouse_pos) - self._drive_mode_control._handle_mouse_release(mouse_pos) - super()._handle_mouse_release(mouse_pos) - - def _handle_mouse_event(self, mouse_event: MouseEvent): - super()._handle_mouse_event(mouse_event) - for el in self._get_active_elements(): - el._handle_mouse_event(mouse_event) - self._drive_mode_control._handle_mouse_event(mouse_event) - + elems += [self._adjustor_rows[k] for k in self._ccm_keys] + elems.append(self._toggle_grid) + return elems # ═══════════════════════════════════════════════════════════════ diff --git a/selfdrive/ui/layouts/settings/starpilot/main_panel.py b/selfdrive/ui/layouts/settings/starpilot/main_panel.py index 9629496d3..de7c65d37 100644 --- a/selfdrive/ui/layouts/settings/starpilot/main_panel.py +++ b/selfdrive/ui/layouts/settings/starpilot/main_panel.py @@ -17,7 +17,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.system_settings import St from openpilot.selfdrive.ui.layouts.settings.starpilot.appearance import StarPilotAppearanceLayout from openpilot.selfdrive.ui.layouts.settings.starpilot.vehicle import StarPilotVehicleSettingsLayout -from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid, HubTile, SPACING, BreadcrumbController, AETHER_LIST_METRICS, draw_rounded_fill, draw_rounded_stroke, AetherTransitionManager +from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid, HubTile, SPACING, BreadcrumbController, AETHER_LIST_METRICS, AetherListColors, draw_rounded_fill, draw_rounded_stroke, AetherTransitionManager class StarPilotLayout(Widget): CATEGORIES = [ @@ -284,18 +284,21 @@ class StarPilotLayout(Widget): # 0. Draw top bar with HubTile-style purple glow glass_rect = rl.Rectangle(shell_x, rect.y + 2, shell_w, TOP_BAR_HEIGHT - 4) + GLOW = AetherListColors.PRIMARY + BAR_FILL = rl.Color(12, 10, 18, 255) + # 0a. Purple glow rings — 4 concentric, fading outward (HubTile parity) for i in range(4, 0, -1): off = i * 2.5 gr = rl.Rectangle(glass_rect.x - off, glass_rect.y - off, glass_rect.width + off * 2, glass_rect.height + off * 2) a = int(25 * (1.0 - i / 5)) - draw_rounded_fill(gr, rl.Color(139, 92, 246, max(0, min(255, a))), radius_px=34) + draw_rounded_fill(gr, rl.Color(GLOW.r, GLOW.g, GLOW.b, max(0, min(255, a))), radius_px=34) # 0b. Dark fill — strict parity with HubTile _HUD_BG_ON - draw_rounded_fill(glass_rect, rl.Color(12, 10, 18, 255), radius_px=34) + draw_rounded_fill(glass_rect, BAR_FILL, radius_px=34) # 0c. Full bright purple border — strict parity - draw_rounded_stroke(glass_rect, rl.Color(139, 92, 246, 255), radius_px=34) + draw_rounded_stroke(glass_rect, GLOW, radius_px=34) # 1. Draw breadcrumbs in top bar crumb_rect = rl.Rectangle(glass_rect.x, glass_rect.y, glass_rect.width, glass_rect.height) diff --git a/selfdrive/ui/layouts/settings/starpilot/panel.py b/selfdrive/ui/layouts/settings/starpilot/panel.py index 34fb32742..0b09f8f32 100644 --- a/selfdrive/ui/layouts/settings/starpilot/panel.py +++ b/selfdrive/ui/layouts/settings/starpilot/panel.py @@ -11,7 +11,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.widgets import DialogResult, Widget from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog -from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid, HubTile, ToggleTile, ValueTile, SliderTile, SPACING, AetherSliderDialog, AetherTransitionManager +from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid, HubTile, ToggleTile, ValueTile, SliderTile, SPACING, AetherSliderDialog, AetherTransitionManager, AetherListColors from openpilot.selfdrive.ui.layouts.settings.starpilot.sectioned_panel import SectionedTileLayout, TileSection import time @@ -92,11 +92,8 @@ class StarPilotPanelType(IntEnum): LATERAL = 4 MAPS = 5 DEVICE = 6 - UTILITIES = 7 VISUALS = 8 - THEMES = 9 VEHICLE = 10 - WHEEL = 11 SYSTEM = 12 @@ -349,7 +346,7 @@ class _SettingsPage(StarPilotPanel): shared slider and selector dialog helpers. """ - SLIDER_COLOR = "#8B5CF6" + SLIDER_COLOR = AetherListColors.PRIMARY def __init__(self): super().__init__() diff --git a/selfdrive/ui/layouts/settings/starpilot/sounds.py b/selfdrive/ui/layouts/settings/starpilot/sounds.py index a4400baca..df181c7f6 100644 --- a/selfdrive/ui/layouts/settings/starpilot/sounds.py +++ b/selfdrive/ui/layouts/settings/starpilot/sounds.py @@ -17,6 +17,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPag from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( AETHER_LIST_METRICS, COMPACT_PANEL_METRICS, + AdjustorTogglesPanelView, AetherAdjustorRow, AetherListColors, PanelManagerView, @@ -44,7 +45,7 @@ SOUNDS_PANEL_METRICS = replace( -class SoundsManagerView(PanelManagerView): +class SoundsManagerView(AdjustorTogglesPanelView): METRICS = SOUNDS_PANEL_METRICS @property @@ -54,9 +55,6 @@ class SoundsManagerView(PanelManagerView): def __init__(self, controller: StarPilotSoundsLayout): super().__init__() self._controller = controller - self._pressed_target: str | None = None - self._adjustor_rows: dict[str, AetherAdjustorRow] = {} - self._can_click = True self._reset_rect = rl.Rectangle(0, 0, 0, 0) self._tile_grid_h = 0.0 @@ -93,16 +91,6 @@ class SoundsManagerView(PanelManagerView): page_size = self._compute_page_size(TOGGLE_ROW_HEIGHT) self._set_toggle_pages([toggle_defs[i:i+page_size] for i in range(0, len(toggle_defs), page_size)]) - def _set_active_adjustor(self, key: str, active: bool): - if active: - if self._active_adjustor_key and self._active_adjustor_key != key: - old = self._adjustor_rows.get(self._active_adjustor_key) - if old: - old.reset_interaction() - self._active_adjustor_key = key - elif self._active_adjustor_key == key: - self._active_adjustor_key = None - def _init_adjustors(self): for key in self._controller.VOLUME_KEYS: info = self._controller.VOLUME_INFO[key] @@ -199,24 +187,6 @@ class SoundsManagerView(PanelManagerView): ) ) - def _handle_mouse_press(self, mouse_pos: MousePos): - super()._handle_mouse_press(mouse_pos) - for adjustor in self._adjustor_rows.values(): - adjustor._handle_mouse_press(mouse_pos) - self._toggle_grid._handle_mouse_press(mouse_pos) - - def _handle_mouse_release(self, mouse_pos: MousePos): - for adjustor in self._adjustor_rows.values(): - adjustor._handle_mouse_release(mouse_pos) - self._toggle_grid._handle_mouse_release(mouse_pos) - super()._handle_mouse_release(mouse_pos) - - def _handle_mouse_event(self, mouse_event: MouseEvent): - super()._handle_mouse_event(mouse_event) - for adjustor in self._adjustor_rows.values(): - adjustor._handle_mouse_event(mouse_event) - self._toggle_grid._handle_mouse_event(mouse_event) - def _target_at(self, mouse_pos: MousePos) -> str | None: if point_hits(mouse_pos, self._reset_rect, None, pad_x=6, pad_y=0): return "action:restore_defaults" @@ -226,16 +196,6 @@ class SoundsManagerView(PanelManagerView): if target == "action:restore_defaults": self._controller._restore_defaults() - def show_event(self): - super().show_event() - self._pressed_target = None - self._can_click = True - - def hide_event(self): - super().hide_event() - self._pressed_target = None - self._can_click = True - def _measure_content_height(self, content_width: float) -> float: col_width = (content_width - SECTION_GAP) / 2 diff --git a/selfdrive/ui/layouts/settings/starpilot/system_settings.py b/selfdrive/ui/layouts/settings/starpilot/system_settings.py index b217c6bf6..84ebf39b1 100644 --- a/selfdrive/ui/layouts/settings/starpilot/system_settings.py +++ b/selfdrive/ui/layouts/settings/starpilot/system_settings.py @@ -93,7 +93,7 @@ REPORT_CATEGORIES = [ ] -FADE_HEIGHT = AETHER_LIST_METRICS.fade_height + PANEL_STYLE = DEFAULT_PANEL_STYLE SYSTEM_PANEL_METRICS = AETHER_LIST_METRICS diff --git a/selfdrive/ui/layouts/settings/starpilot/vehicle.py b/selfdrive/ui/layouts/settings/starpilot/vehicle.py index 1be267d76..5f3a55548 100644 --- a/selfdrive/ui/layouts/settings/starpilot/vehicle.py +++ b/selfdrive/ui/layouts/settings/starpilot/vehicle.py @@ -15,6 +15,7 @@ from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog, alert_dial from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPage from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( + AETHER_LIST_METRICS, AetherSliderDialog, COMPACT_PANEL_METRICS, DEFAULT_PANEL_STYLE, @@ -73,7 +74,7 @@ def _lock_doors_timer_labels(): return labels -SECTION_GAP = 28 +SECTION_GAP = AETHER_LIST_METRICS.section_gap ROW_HEIGHT = 125.0 PANEL_STYLE = DEFAULT_PANEL_STYLE @@ -275,7 +276,7 @@ class VehicleSettingsManagerView(PanelManagerView): row_y += self._left_row_height if steering_rows: - row_y = draw_group_header(rect.x + 24, row_y, col_w - 48, tr("STEERING CONTROLS")) + row_y = draw_group_header(rect.x + 24, row_y, col_w - 48, tr("Steering Controls")) for i, row in enumerate(steering_rows): self._draw_row(rl.Rectangle(rect.x, row_y, col_w, self._left_row_height), row, i == len(steering_rows) - 1)