From 57bfc691bf1f0fd8d7bbecc84b3871018a9d69ba Mon Sep 17 00:00:00 2001 From: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:44:11 -0400 Subject: [PATCH] BigUI WIP: Vertical toggletile list? --- .../layouts/settings/starpilot/aethergrid.py | 17 ++++++-- .../settings/starpilot/longitudinal.py | 39 ++++++++++++++----- .../ui/layouts/settings/starpilot/sounds.py | 13 +++++-- .../settings/starpilot/system_settings.py | 19 ++++++--- .../ui/layouts/settings/starpilot/vehicle.py | 20 +++++++--- 5 files changed, 80 insertions(+), 28 deletions(-) diff --git a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py index 1327e73fd..12483c7e2 100644 --- a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py +++ b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py @@ -24,6 +24,8 @@ TILE_INSET = 1.0 TILE_RADIUS_PX = 18.0 TILE_SIGNAL_WIDTH = 1 MIN_TILE_WIDTH = 300 +TOGGLE_ROW_HEIGHT = 128 +TOGGLE_MIN_HEIGHT = 80 _HUD_BG_ON = rl.Color(12, 10, 18, 230) _HUD_BG_DISABLED = rl.Color(6, 5, 10, 235) @@ -359,6 +361,7 @@ class PanelStyle: danger_fill: rl.Color danger_border: rl.Color danger_text: rl.Color + toggle_row_mode: bool = False DEFAULT_PANEL_STYLE = PanelStyle( @@ -378,6 +381,7 @@ DEFAULT_PANEL_STYLE = PanelStyle( danger_fill=AetherListColors.DANGER_SOFT, danger_border=rl.Color(173, 78, 90, 50), danger_text=AetherListColors.DANGER, + toggle_row_mode=True, ) @@ -719,10 +723,10 @@ class PanelManagerView(AetherInteractiveMixin, Widget): def _compute_two_column_height(self, left_height: float) -> float: return max(self._scroll_rect.height if self._scroll_rect else 0.0, left_height) - def _draw_two_column_tile_grid(self, grid: TileGrid, x: float, y: float, column_width: float, matching_height: float, title: str | None = None, style: PanelStyle | None = None): + def _draw_two_column_tile_grid(self, grid: TileGrid, x: float, y: float, column_width: float, matching_height: float, title: str | None = None, style: PanelStyle | None = None, columns: int = 2): if style is None: style = self.PANEL_STYLE - grid._columns = 2 + grid._columns = columns if title: draw_section_header(rl.Rectangle(x, y, column_width, self.METRICS.section_header_height), title, style=style) draw_y = y + self.METRICS.section_header_height + self.METRICS.section_header_gap @@ -737,7 +741,8 @@ class PanelManagerView(AetherInteractiveMixin, Widget): # ── convenience builders ────────────────────────────────── def _make_toggle_tile(self, d: dict) -> ToggleTile: - return ToggleTile( + cls = RowToggleTile if self.PANEL_STYLE.toggle_row_mode else ToggleTile + return cls( title=d["title"], get_state=d["get_state"], set_state=d["set_state"], @@ -758,6 +763,12 @@ class PanelManagerView(AetherInteractiveMixin, Widget): is_enabled=d.get("is_enabled"), ) + def _compute_page_size(self, tile_height: float, default: int = 4) -> int: + if not self._scroll_rect or self._scroll_rect.height <= 0.0: + return default + available = self._scroll_rect.height - GROUP_OVERHEAD - 24 + return max(2, int((available + SPACING.tile_gap) / (tile_height + SPACING.tile_gap))) + # ── pagination ───────────────────────────────────────────── PAGE_COMMIT_RATIO = 0.20 diff --git a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py index 6bdabd3f2..e6f87eaea 100644 --- a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py +++ b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py @@ -29,6 +29,9 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( AetherSettingsView, TileGrid, HubTile, + TOGGLE_MIN_HEIGHT, + TOGGLE_ROW_HEIGHT, + RowToggleTile, ToggleTile, draw_section_header, draw_list_group_shell, @@ -269,7 +272,10 @@ class ConditionalDriveModeView(PanelManagerView): self._update_pagination() def _init_toggles(self): - self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) + if PANEL_STYLE.toggle_row_mode: + self._toggle_grid = TileGrid(columns=1, padding=12, min_tile_height=TOGGLE_MIN_HEIGHT) + else: + self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) self._child(self._toggle_grid) self.register_page_grid(self._toggle_grid) @@ -299,16 +305,18 @@ class ConditionalDriveModeView(PanelManagerView): def _update_pagination(self): mode = self._get_drive_mode_index() + page_size = self._compute_page_size(TOGGLE_ROW_HEIGHT) if mode == 1: - pages = [self._cem_toggle_defs[i:i+4] for i in range(0, len(self._cem_toggle_defs), 4)] + pages = [self._cem_toggle_defs[i:i+page_size] for i in range(0, len(self._cem_toggle_defs), page_size)] self._set_toggle_pages(pages) elif mode == 2: - pages = [self._ccm_toggle_defs[i:i+4] for i in range(0, len(self._ccm_toggle_defs), 4)] + pages = [self._ccm_toggle_defs[i:i+page_size] for i in range(0, len(self._ccm_toggle_defs), page_size)] self._set_toggle_pages(pages) else: self._set_toggle_pages([]) def _make_toggle_tile(self, info: dict) -> ToggleTile: + cls = RowToggleTile if PANEL_STYLE.toggle_row_mode else ToggleTile kwargs = { "title": info["title"], "desc": info.get("subtitle", ""), @@ -321,7 +329,7 @@ class ConditionalDriveModeView(PanelManagerView): if "disabled_label" in info: kwargs["disabled_label"] = info["disabled_label"] - return ToggleTile(**kwargs) + return cls(**kwargs) def _set_active_adjustor(self, key: str, active: bool): if active: @@ -422,16 +430,20 @@ class ConditionalDriveModeView(PanelManagerView): for key in keys: self._adjustor_rows[key].custom_row_height = None - grid._tile_height = None default_adjustor_h = float(AETHER_LIST_METRICS.adjustor_row_height) left_h = len(keys) * default_adjustor_h + 16.0 num_tiles = 4 if self._has_pagination else len(grid.tiles) - rows = (num_tiles + 1) // 2 if self._uses_two_columns(content_width) else num_tiles + if PANEL_STYLE.toggle_row_mode: + rows = num_tiles + tile_h = TOGGLE_ROW_HEIGHT + else: + rows = (num_tiles + 1) // 2 if self._uses_two_columns(content_width) else num_tiles + tile_h = grid.min_tile_height pagination_space = 32.0 if self._has_pagination else 0.0 - tiles_h = rows * grid.min_tile_height + (rows - 1) * grid.gap + grid.gap * 2 + pagination_space + tiles_h = rows * tile_h + (rows - 1) * grid.gap + grid.gap * 2 + pagination_space right_h = tiles_h @@ -485,14 +497,21 @@ class ConditionalDriveModeView(PanelManagerView): y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP self._draw_adjustors(y, rect.x, col_width, keys) - + + tg_columns = 1 if PANEL_STYLE.toggle_row_mode else 2 if self._uses_two_columns(content_width): - self._draw_two_column_tile_grid(grid, rect.x + col_width + SECTION_GAP, y, col_width, self._tiles_container_h, title=None, style=PANEL_STYLE) + self._draw_two_column_tile_grid( + grid, rect.x + col_width + SECTION_GAP, y, col_width, + self._tiles_container_h, title=None, style=PANEL_STYLE, + columns=tg_columns) else: y += self._left_container_h + SECTION_GAP draw_section_header(rl.Rectangle(rect.x, y, col_width, SECTION_HEADER_HEIGHT), tr("Triggers"), style=PANEL_STYLE) y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP - self._draw_two_column_tile_grid(grid, rect.x, y, col_width, self._tiles_container_h, title=None, style=PANEL_STYLE) + self._draw_two_column_tile_grid( + grid, rect.x, y, col_width, + self._tiles_container_h, title=None, style=PANEL_STYLE, + columns=tg_columns) def _draw_adjustors(self, y: float, x: float, width: float, keys: list[str]): draw_list_group_shell(rl.Rectangle(x, y, width, self._left_container_h), style=PANEL_STYLE) diff --git a/selfdrive/ui/layouts/settings/starpilot/sounds.py b/selfdrive/ui/layouts/settings/starpilot/sounds.py index cf40b66db..e79b57cfb 100644 --- a/selfdrive/ui/layouts/settings/starpilot/sounds.py +++ b/selfdrive/ui/layouts/settings/starpilot/sounds.py @@ -20,8 +20,10 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( AetherAdjustorRow, AetherListColors, PanelManagerView, + SPACING, TileGrid, - ToggleTile, + TOGGLE_MIN_HEIGHT, + TOGGLE_ROW_HEIGHT, DEFAULT_PANEL_STYLE, point_hits, draw_list_group_shell, @@ -69,7 +71,10 @@ class SoundsManagerView(PanelManagerView): ) def _init_toggles(self): - self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) + if self.PANEL_STYLE.toggle_row_mode: + self._toggle_grid = TileGrid(columns=1, padding=SPACING.md, min_tile_height=TOGGLE_MIN_HEIGHT) + else: + self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) self._child(self._toggle_grid) self._page_grid = self._toggle_grid @@ -85,7 +90,8 @@ class SoundsManagerView(PanelManagerView): "disabled_label": tr(info.get("disabled_label", "")) if info.get("disabled_label") else "", }) - self._set_toggle_pages([toggle_defs[i:i+4] for i in range(0, len(toggle_defs), 4)]) + 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: @@ -233,7 +239,6 @@ class SoundsManagerView(PanelManagerView): def _measure_content_height(self, content_width: float) -> float: col_width = (content_width - SECTION_GAP) / 2 - self._toggle_grid._tile_height = None for key in self._controller.VOLUME_KEYS: self._adjustor_rows[key].custom_row_height = None self._adjustor_rows[self._controller.COOLDOWN_KEY].custom_row_height = None diff --git a/selfdrive/ui/layouts/settings/starpilot/system_settings.py b/selfdrive/ui/layouts/settings/starpilot/system_settings.py index def4f0ada..5295f8ed7 100644 --- a/selfdrive/ui/layouts/settings/starpilot/system_settings.py +++ b/selfdrive/ui/layouts/settings/starpilot/system_settings.py @@ -33,7 +33,6 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( DEFAULT_PANEL_STYLE, PanelManagerView, TileGrid, - ToggleTile, draw_list_group_shell, draw_selection_list_row, draw_settings_panel_header, @@ -53,6 +52,9 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( wrap_text, SECTION_GAP, ROW_HEIGHT, + SPACING, + TOGGLE_MIN_HEIGHT, + TOGGLE_ROW_HEIGHT, ) from openpilot.starpilot.common.connect_server import prepare_konik_server_switch @@ -293,12 +295,16 @@ class SystemSettingsManagerView(PanelManagerView): self._basics_tile_grid_h = 0.0 - self._connectivity_tile_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) + if self.PANEL_STYLE.toggle_row_mode: + self._connectivity_tile_grid = TileGrid(columns=1, padding=SPACING.md, min_tile_height=TOGGLE_MIN_HEIGHT) + else: + self._connectivity_tile_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) for toggle_def in self._toggle_defs: tile = self._make_toggle_tile(toggle_def) self._connectivity_tile_grid.add_tile(tile) self.register_page_grid(self._connectivity_tile_grid) - self._set_toggle_pages([self._toggle_defs[i:i+4] for i in range(0, len(self._toggle_defs), 4)]) + page_size = self._compute_page_size(TOGGLE_ROW_HEIGHT) + self._set_toggle_pages([self._toggle_defs[i:i+page_size] for i in range(0, len(self._toggle_defs), page_size)]) self._drive_mode_control = self._child( AetherSegmentedControl( @@ -487,7 +493,6 @@ class SystemSettingsManagerView(PanelManagerView): # Reset custom heights to calculate natural measurements first for key in self._display_slider_keys + self._power_slider_keys: self._adjustor_rows[key].custom_row_height = None - self._connectivity_tile_grid._tile_height = None display_container_h = self._slider_section_height(self._display_slider_keys, column_w) power_container_h = self._slider_section_height(self._power_slider_keys, column_w) @@ -522,7 +527,6 @@ class SystemSettingsManagerView(PanelManagerView): # Ensure defaults are restored in single column mode for key in self._display_slider_keys + self._power_slider_keys: self._adjustor_rows[key].custom_row_height = None - self._connectivity_tile_grid._tile_height = None tiles_content_h = self.measure_page_grid_height(self._connectivity_tile_grid, width - 24) return self._stacked_section_height([display_h, power_h, tiles_content_h + 24]) @@ -555,7 +559,10 @@ class SystemSettingsManagerView(PanelManagerView): for index, key in enumerate(self._power_slider_keys): current_y = self._draw_slider_row(rl.Rectangle(x, current_y, column_w, 0), key, is_last=index == len(self._power_slider_keys) - 1) - self._draw_two_column_tile_grid(self._connectivity_tile_grid, x + column_w + self.COLUMN_GAP, y, column_w, self._system_max_container_h) + tg_cols = 1 if self.PANEL_STYLE.toggle_row_mode else 2 + self._draw_two_column_tile_grid( + self._connectivity_tile_grid, x + column_w + self.COLUMN_GAP, y, column_w, + self._system_max_container_h, columns=tg_cols) return y = self._draw_slider_section(y, x, width, tr("Display"), self._display_slider_keys) diff --git a/selfdrive/ui/layouts/settings/starpilot/vehicle.py b/selfdrive/ui/layouts/settings/starpilot/vehicle.py index 554fa5739..fae28932b 100644 --- a/selfdrive/ui/layouts/settings/starpilot/vehicle.py +++ b/selfdrive/ui/layouts/settings/starpilot/vehicle.py @@ -18,8 +18,11 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( COMPACT_PANEL_METRICS, DEFAULT_PANEL_STYLE, PanelManagerView, + SPACING, SettingRow, TileGrid, + TOGGLE_MIN_HEIGHT, + TOGGLE_ROW_HEIGHT, GROUP_HEADER_GAP, GROUP_HEADER_HEIGHT, GROUP_HEADER_LINE_GAP, @@ -77,7 +80,10 @@ class VehicleSettingsManagerView(PanelManagerView): super().__init__() self._controller = controller self._shell_rect = rl.Rectangle(0, 0, 0, 0) - self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) + if PANEL_STYLE.toggle_row_mode: + self._toggle_grid = TileGrid(columns=1, padding=SPACING.md, min_tile_height=TOGGLE_MIN_HEIGHT) + else: + self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0) self.register_page_grid(self._toggle_grid) self._last_make = "" self._last_model = "" @@ -218,7 +224,8 @@ class VehicleSettingsManagerView(PanelManagerView): y += SECTION_GAP if self._toggle_grid.tiles: - self._toggle_grid._columns = 3 + if not PANEL_STYLE.toggle_row_mode: + self._toggle_grid._columns = 3 avail = width - 24 th = self.measure_page_grid_height(self._toggle_grid, avail) hdr_oh = GROUP_HEADER_HEIGHT + GROUP_HEADER_LINE_GAP + GROUP_HEADER_GAP @@ -237,11 +244,13 @@ class VehicleSettingsManagerView(PanelManagerView): tiles_h = 0.0 if self._toggle_grid.tiles: if self._uses_two_columns(width): - self._toggle_grid._columns = 2 + if not PANEL_STYLE.toggle_row_mode: + self._toggle_grid._columns = 2 col_w = self._column_width(width) tiles_h = self.measure_page_grid_height(self._toggle_grid, col_w - 24) else: - self._toggle_grid._columns = 3 + if not PANEL_STYLE.toggle_row_mode: + self._toggle_grid._columns = 3 tiles_h = self.measure_page_grid_height(self._toggle_grid, width - 24) if self._uses_two_columns(width): @@ -384,7 +393,8 @@ class VehicleSettingsManagerView(PanelManagerView): def _rebuild_toggle_grid(self): defs = self._build_driving_toggles() - self._set_toggle_pages([defs[i:i+4] for i in range(0, len(defs), 4)]) + page_size = self._compute_page_size(TOGGLE_ROW_HEIGHT) + self._set_toggle_pages([defs[i:i+page_size] for i in range(0, len(defs), page_size)]) def _check_rebuild_grid(self): current_make = self._controller._get_display_make()