BigUI WIP: Vertical toggletile list?

This commit is contained in:
firestarsdog
2026-07-13 13:44:11 -04:00
parent 7e4f8d4154
commit 57bfc691bf
5 changed files with 80 additions and 28 deletions
@@ -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
@@ -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)
@@ -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
@@ -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)
@@ -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()