From b4f17f35f9ab95fb2c309b99d38f5d6605c42939 Mon Sep 17 00:00:00 2001 From: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Date: Sun, 28 Jun 2026 02:59:08 -0400 Subject: [PATCH] BigUI WIP: Toggle tile panel standardization PT55 --- .../layouts/settings/starpilot/aethergrid.py | 81 +++++++++++++++---- .../ui/layouts/settings/starpilot/lateral.py | 16 ++-- .../ui/layouts/settings/starpilot/sounds.py | 4 +- .../settings/starpilot/system_settings.py | 2 +- .../ui/layouts/settings/starpilot/vehicle.py | 4 +- 5 files changed, 81 insertions(+), 26 deletions(-) diff --git a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py index a89e875bc..abd1ffdce 100644 --- a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py +++ b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py @@ -666,8 +666,7 @@ class PanelManagerView(AetherInteractiveMixin, Widget): PAGE_ANIM_DURATION = 0.28 PAGE_SNAP_DURATION = 0.20 - PAGE_DOT_RADIUS = 6.0 - PAGE_DOT_GAP = 20.0 + @property def _has_pagination(self) -> bool: @@ -791,7 +790,20 @@ class PanelManagerView(AetherInteractiveMixin, Widget): grid.render(rl.Rectangle(grid_rect.x + cur_offset, grid_rect.y, grid_rect.width, grid_rect.height)) self._page_scissor_pop() - self._draw_page_dots(rect) + self._draw_page_indicator(rect) + + if self._has_pagination: + glow_w = 60.0 + if self._current_page > 0: + rl.draw_rectangle_gradient_h( + int(rect.x), int(rect.y), int(glow_w), int(rect.height), + _with_alpha(self.PANEL_STYLE.accent, 10), rl.Color(0, 0, 0, 0), + ) + if self._current_page < self._page_count - 1: + rl.draw_rectangle_gradient_h( + int(rect.x + rect.width - glow_w), int(rect.y), int(glow_w), int(rect.height), + rl.Color(0, 0, 0, 0), _with_alpha(self.PANEL_STYLE.accent, 10), + ) # ── mouse handling ───────────────────────────────────────── @@ -850,22 +862,57 @@ class PanelManagerView(AetherInteractiveMixin, Widget): # ── page indicator ───────────────────────────────────────── - def _draw_page_dots(self, rect: rl.Rectangle) -> None: + def _get_page_indicator_progress(self) -> float: + if not self._has_pagination: + return 0.0 + page_w = self._scroll_rect.width + + if self._page_drag_active: + return max(0.0, min(self._page_count - 1, self._current_page + self._page_drag_offset / page_w)) + + if self._page_animating: + elapsed = time.monotonic() - self._page_anim_start + duration = self.PAGE_ANIM_DURATION if self._page_anim_committed else self.PAGE_SNAP_DURATION + if elapsed >= duration: + return float(self._current_page) + t = elapsed / duration + t = 1.0 - (1.0 - t) ** 3 + if self._page_anim_committed: + direction = 1 if self._page_anim_from < 0 else -1 + return self._current_page + direction * (t - 1) + else: + offset = self._page_anim_from * (1.0 - t) + return max(0.0, min(self._page_count - 1, self._current_page + offset / page_w)) + + return float(self._current_page) + + def _draw_page_indicator(self, rect: rl.Rectangle) -> None: if not self._has_pagination: return n = min(self._page_count, 8) - total_w = n * self.PAGE_DOT_RADIUS * 2 + max(0, n - 1) * self.PAGE_DOT_GAP - start_x = rect.x + (rect.width - total_w) / 2 - dot_y = rect.y + rect.height - 12 - for i in range(n): - cx = start_x + i * (self.PAGE_DOT_RADIUS * 2 + self.PAGE_DOT_GAP) + self.PAGE_DOT_RADIUS - fill = self.PANEL_STYLE.accent if i == self._current_page else _with_alpha(AetherListColors.MUTED, 100) - rl.draw_circle(int(cx), int(dot_y), self.PAGE_DOT_RADIUS, fill) + seg_w = 28.0 + track_h = 10.0 + track_w = seg_w * n + start_x = rect.x + (rect.width - track_w) / 2 + track_y = rect.y + rect.height - 16 + + label = f"{self._current_page + 1} / {self._page_count}" + lf = gui_app.font(FontWeight.MEDIUM) + ls = 16.0 + lw = measure_text_cached(lf, label, int(ls)).x + rl.draw_text_ex(lf, label, rl.Vector2(int(rect.x + (rect.width - lw) / 2), int(track_y - ls - 6)), int(ls), 0, _with_alpha(AetherListColors.MUTED, 200)) + + track_col = _with_alpha(AetherListColors.MUTED, 60) + rl.draw_rectangle_rounded(rl.Rectangle(start_x, track_y, track_w, track_h), 0.5, 8, track_col) + + progress = self._get_page_indicator_progress() + active_x = start_x + progress * seg_w + active_x = max(start_x, min(active_x, start_x + track_w - seg_w)) + rl.draw_rectangle_rounded(rl.Rectangle(active_x, track_y, seg_w, track_h), 0.5, 8, self.PANEL_STYLE.accent) + if self._page_count > 8: - more_x = start_x + n * (self.PAGE_DOT_RADIUS * 2 + self.PAGE_DOT_GAP) - rl.draw_text_ex( - gui_app.font(FontWeight.MEDIUM), "···", - rl.Vector2(more_x, dot_y - 8), 16, 0, AetherListColors.MUTED) + more_x = int(start_x + track_w + 10) + rl.draw_text_ex(lf, "···", rl.Vector2(more_x, int(track_y - 2)), 14, 0, AetherListColors.MUTED) # ── lifecycle ────────────────────────────────────────────── @@ -5546,6 +5593,8 @@ class TileGrid(Widget): if self.max_tile_height is not None: tile_h = min(self.max_tile_height, tile_h) uniform_tile_w = (rect.width - (self._gap * (cols - 1))) / cols if self._uniform_width else 0 + content_height = rows * tile_h + max(0, rows - 1) * self._gap + y_offset = max(0, (rect.height - content_height) / 2) tile_idx = 0 for r in range(rows): remaining = count - tile_idx @@ -5564,7 +5613,7 @@ class TileGrid(Widget): parent_rect = getattr(self, "_parent_rect", None) if parent_rect is not None and hasattr(tile, "set_parent_rect"): tile.set_parent_rect(parent_rect) - tile.render(_snap_rect(rl.Rectangle(row_x + c * (row_tile_w + self._gap), rect.y + r * (tile_h + self._gap), row_tile_w, tile_h))) + tile.render(_snap_rect(rl.Rectangle(row_x + c * (row_tile_w + self._gap), rect.y + y_offset + r * (tile_h + self._gap), row_tile_w, tile_h))) tile_idx += 1 diff --git a/selfdrive/ui/layouts/settings/starpilot/lateral.py b/selfdrive/ui/layouts/settings/starpilot/lateral.py index 407c3803e..f405aa227 100644 --- a/selfdrive/ui/layouts/settings/starpilot/lateral.py +++ b/selfdrive/ui/layouts/settings/starpilot/lateral.py @@ -83,7 +83,7 @@ class SteeringManagerView(PanelManagerView): self._controller = controller self._shell_rect = rl.Rectangle(0, 0, 0, 0) - self._toggle_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_width=100, min_tile_height=130.0, max_tile_height=180.0) + self._toggle_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_width=100, min_tile_height=130.0, max_tile_height=280.0) self._toggle_grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid()) self._child(self._toggle_grid) @@ -239,7 +239,7 @@ class SteeringManagerView(PanelManagerView): def _rebuild_toggle_grid(self): self._page_grid = self._toggle_grid defs = self._build_toggle_defs() - self._set_toggle_pages([defs[i:i+6] for i in range(0, len(defs), 6)]) + self._set_toggle_pages([defs[i:i+4] for i in range(0, len(defs), 4)]) def _measure_content_height(self, width: float) -> float: sections = self._build_left_sections() @@ -253,7 +253,14 @@ class SteeringManagerView(PanelManagerView): tiles_height = SECTION_GAP + self._section_block_height(tiles_content_h + 24) if self._uses_two_columns(width): - return self._compute_two_column_height(left_h) + column_w = self._column_width(width) + self._toggle_grid._columns = 2 + grid_content_h = self.measure_page_grid_height(self._toggle_grid, column_w - 24) + 24 + grid_container_h = grid_content_h + SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP + available_h = self._scroll_rect.height if self._scroll_rect else left_h + container_h = max(left_h, grid_container_h, available_h) + self._grid_container_h = container_h + return self._compute_two_column_height(container_h) return left_h + tiles_height def _draw_scroll_content(self, rect: rl.Rectangle, width: float): @@ -289,8 +296,7 @@ class SteeringManagerView(PanelManagerView): if self._toggle_grid.tiles: rx = x + column_w + self.COLUMN_GAP - left_h = curr_y - y - self._draw_two_column_tile_grid(self._toggle_grid, rx, y, column_w, left_h, title=tr("Toggles"), style=PANEL_STYLE) + self._draw_two_column_tile_grid(self._toggle_grid, rx, y, column_w, self._grid_container_h, title=tr("Toggles"), style=PANEL_STYLE) else: curr_y = y for section in sections: diff --git a/selfdrive/ui/layouts/settings/starpilot/sounds.py b/selfdrive/ui/layouts/settings/starpilot/sounds.py index 15990c315..9de85ea54 100644 --- a/selfdrive/ui/layouts/settings/starpilot/sounds.py +++ b/selfdrive/ui/layouts/settings/starpilot/sounds.py @@ -76,7 +76,7 @@ class SoundsManagerView(PanelManagerView): ) def _init_toggles(self): - self._toggle_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_height=130.0, max_tile_height=180.0) + self._toggle_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_height=130.0, max_tile_height=280.0) self._child(self._toggle_grid) self._page_grid = self._toggle_grid @@ -92,7 +92,7 @@ class SoundsManagerView(PanelManagerView): "disabled_label": tr(info.get("disabled_label", "")) if info.get("disabled_label") else "", }) - self._set_toggle_pages([toggle_defs[i:i+6] for i in range(0, len(toggle_defs), 6)]) + self._set_toggle_pages([toggle_defs[i:i+4] for i in range(0, len(toggle_defs), 4)]) def _set_active_adjustor(self, key: str, active: bool): if active: diff --git a/selfdrive/ui/layouts/settings/starpilot/system_settings.py b/selfdrive/ui/layouts/settings/starpilot/system_settings.py index 70b7f4b3c..88321e6e4 100644 --- a/selfdrive/ui/layouts/settings/starpilot/system_settings.py +++ b/selfdrive/ui/layouts/settings/starpilot/system_settings.py @@ -306,7 +306,7 @@ class SystemSettingsManagerView(PanelManagerView): self._basics_tile_grid_h = 0.0 - self._connectivity_tile_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_height=130.0, max_tile_height=180.0) + self._connectivity_tile_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_height=130.0, max_tile_height=280.0) for toggle_def in self._toggle_defs: tile = self._make_toggle_tile(toggle_def) self._connectivity_tile_grid.add_tile(tile) diff --git a/selfdrive/ui/layouts/settings/starpilot/vehicle.py b/selfdrive/ui/layouts/settings/starpilot/vehicle.py index 57c340694..735a7529f 100644 --- a/selfdrive/ui/layouts/settings/starpilot/vehicle.py +++ b/selfdrive/ui/layouts/settings/starpilot/vehicle.py @@ -106,7 +106,7 @@ class VehicleSettingsManagerView(PanelManagerView): self._controller = controller self._shell_rect = rl.Rectangle(0, 0, 0, 0) - self._toggle_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_width=100, min_tile_height=130.0, max_tile_height=180.0) + self._toggle_grid = TileGrid(columns=2, padding=12, force_square=True, min_tile_width=100, min_tile_height=130.0, max_tile_height=280.0) self.register_page_grid(self._toggle_grid) self._last_make = "" @@ -222,7 +222,7 @@ class VehicleSettingsManagerView(PanelManagerView): def _rebuild_toggle_grid(self): defs = self._build_driving_toggles() - self._set_toggle_pages([defs[i:i+6] for i in range(0, len(defs), 6)]) + self._set_toggle_pages([defs[i:i+4] for i in range(0, len(defs), 4)]) def _check_rebuild_grid(self): current_make = self._controller._get_display_make()