mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-06-27 17:42:04 +08:00
BigUI WIP: Standardize single pane toggle tiles
This commit is contained in:
@@ -3736,32 +3736,59 @@ class ToggleTile(AetherTile):
|
||||
title_size = max(20, int(round(24 * text_scale)))
|
||||
|
||||
if not enabled:
|
||||
self._draw_text_fit(self._font, self.title,
|
||||
rl.Vector2(rx + content_pad, ry + int(rh * 0.40)),
|
||||
max_w, title_size, align_center=True, color=_HUD_TEXT_DIM)
|
||||
disabled_text = tr(self._disabled_label) if self._disabled_label else tr("LOCKED")
|
||||
title_lines = self._wrap_text(self._font, self.title, max_w, title_size, max_lines=2)
|
||||
desc_size = max(14, int(round(16 * text_scale)))
|
||||
self._draw_text_fit(self._font_desc, disabled_text,
|
||||
rl.Vector2(rx + content_pad, ry + int(rh * 0.68)),
|
||||
max_w, desc_size, align_center=True, color=_HUD_TEXT_DIM)
|
||||
disabled_text = tr(self._disabled_label) if self._disabled_label else tr("LOCKED")
|
||||
desc_lines = self._wrap_text(self._font_desc, disabled_text, max_w, desc_size, max_lines=2)
|
||||
|
||||
total_text_h = len(title_lines) * (title_size + 4) + len(desc_lines) * (desc_size + 2) + 6
|
||||
start_y = ry + (rh - total_text_h) / 2
|
||||
|
||||
curr_y = start_y
|
||||
for line in title_lines:
|
||||
self._draw_text_fit(self._font, line, rl.Vector2(rx + content_pad, curr_y), max_w, title_size, align_center=True, color=_HUD_TEXT_DIM)
|
||||
curr_y += title_size + 4
|
||||
curr_y += 6
|
||||
for line in desc_lines:
|
||||
self._draw_text_fit(self._font_desc, line, rl.Vector2(rx + content_pad, curr_y), max_w, desc_size, align_center=True, color=_HUD_TEXT_DIM)
|
||||
curr_y += desc_size + 2
|
||||
else:
|
||||
title_color = rl.WHITE if active else _HUD_TEXT_DIM
|
||||
if self.desc:
|
||||
desc_size = max(16, int(round(18 * text_scale)))
|
||||
self._draw_text_fit(self._font, self.title,
|
||||
rl.Vector2(rx + content_pad, ry + int(rh * 0.28)),
|
||||
max_w, title_size, align_center=True, color=title_color)
|
||||
self._draw_text_fit(self._font_desc, self.desc,
|
||||
rl.Vector2(rx + content_pad, ry + int(rh * 0.50)),
|
||||
max_w, desc_size, align_center=True, color=rl.Color(255, 255, 255, 140))
|
||||
title_lines = self._wrap_text(self._font, self.title, max_w, title_size, max_lines=2)
|
||||
desc_size = max(14, int(round(16 * text_scale)))
|
||||
desc_lines = self._wrap_text(self._font_desc, self.desc, max_w, desc_size, max_lines=2)
|
||||
|
||||
if len(title_lines) == 1:
|
||||
title_y = ry + int(rh * 0.22)
|
||||
else:
|
||||
title_y = ry + int(rh * 0.16)
|
||||
|
||||
curr_y = title_y
|
||||
for line in title_lines:
|
||||
self._draw_text_fit(self._font, line, rl.Vector2(rx + content_pad, curr_y), max_w, title_size, align_center=True, color=title_color)
|
||||
curr_y += title_size + 4
|
||||
|
||||
desc_y = title_y + len(title_lines) * (title_size + 4) + 6
|
||||
curr_y = desc_y
|
||||
for line in desc_lines:
|
||||
self._draw_text_fit(self._font_desc, line, rl.Vector2(rx + content_pad, curr_y), max_w, desc_size, align_center=True, color=rl.Color(255, 255, 255, 140))
|
||||
curr_y += desc_size + 2
|
||||
|
||||
led_cx = rx + rw // 2
|
||||
led_cy = ry + int(rh * 0.78)
|
||||
led_cy = ry + rh - 22
|
||||
else:
|
||||
self._draw_text_fit(self._font, self.title,
|
||||
rl.Vector2(rx + content_pad, ry + int(rh * 0.50)),
|
||||
max_w, title_size, align_center=True, color=title_color)
|
||||
title_lines = self._wrap_text(self._font, self.title, max_w, title_size, max_lines=2)
|
||||
led_cy = ry + rh - 24
|
||||
total_text_h = len(title_lines) * (title_size + 4)
|
||||
title_y = ry + (rh - 24 - total_text_h) / 2
|
||||
|
||||
curr_y = title_y
|
||||
for line in title_lines:
|
||||
self._draw_text_fit(self._font, line, rl.Vector2(rx + content_pad, curr_y), max_w, title_size, align_center=True, color=title_color)
|
||||
curr_y += title_size + 4
|
||||
|
||||
led_cx = rx + rw // 2
|
||||
led_cy = ry + int(rh * 0.75)
|
||||
|
||||
if active:
|
||||
rl.draw_circle(int(led_cx), int(led_cy), 11, rl.Color(accent.r, accent.g, accent.b, 24))
|
||||
@@ -5129,7 +5156,7 @@ class AetherSegmentedControl(Widget):
|
||||
|
||||
|
||||
class TileGrid(Widget):
|
||||
def __init__(self, columns: int | None = None, padding: int | None = None, uniform_width: bool = False, min_tile_width: int | None = None, tile_height: float | None = None, force_square: bool = False, carousel_rows: int | None = None, carousel_tile_width: float | None = None):
|
||||
def __init__(self, columns: int | None = None, padding: int | None = None, uniform_width: bool = False, min_tile_width: int | None = None, tile_height: float | None = None, force_square: bool = False, carousel_rows: int | None = None, carousel_tile_width: float | None = None, min_tile_height: float | None = None, max_tile_height: float | None = None):
|
||||
super().__init__()
|
||||
self._columns = columns
|
||||
self._gap = padding if padding is not None else SPACING.tile_gap
|
||||
@@ -5140,6 +5167,8 @@ class TileGrid(Widget):
|
||||
self.force_square = force_square
|
||||
self.carousel_rows = carousel_rows
|
||||
self.carousel_tile_width = carousel_tile_width
|
||||
self.min_tile_height = min_tile_height
|
||||
self.max_tile_height = max_tile_height
|
||||
|
||||
|
||||
@property
|
||||
@@ -5215,7 +5244,14 @@ class TileGrid(Widget):
|
||||
col_w = (width - (self._gap * (cols - 1))) / cols
|
||||
h = col_w
|
||||
else:
|
||||
h = self._tile_height if self._tile_height is not None else 130.0
|
||||
if self._tile_height is not None:
|
||||
h = self._tile_height
|
||||
else:
|
||||
h = 140.0 if rows == 1 else (160.0 if rows == 2 else 180.0)
|
||||
if self.min_tile_height is not None:
|
||||
h = max(h, self.min_tile_height)
|
||||
if self.max_tile_height is not None:
|
||||
h = min(h, self.max_tile_height)
|
||||
return rows * h + self.get_internal_gap_height(count, available_width=width)
|
||||
|
||||
def measure_width(self) -> float:
|
||||
@@ -5255,6 +5291,7 @@ class TileGrid(Widget):
|
||||
|
||||
cols = self.get_effective_column_count(rect.width, count)
|
||||
rows = self.get_row_count(count, available_width=rect.width)
|
||||
|
||||
if self.force_square:
|
||||
uniform_tile_w = (rect.width - (self._gap * (cols - 1))) / cols
|
||||
tile_h = uniform_tile_w
|
||||
@@ -5263,6 +5300,10 @@ class TileGrid(Widget):
|
||||
tile_h = self._tile_height
|
||||
else:
|
||||
tile_h = (rect.height - (self._gap * (rows - 1))) / rows
|
||||
if self.min_tile_height is not None:
|
||||
tile_h = max(self.min_tile_height, tile_h)
|
||||
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
|
||||
tile_idx = 0
|
||||
for r in range(rows):
|
||||
|
||||
@@ -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, min_tile_width=100)
|
||||
self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_width=100, min_tile_height=130.0, max_tile_height=180.0)
|
||||
self._toggle_grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid())
|
||||
self._child(self._toggle_grid)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class SoundsManagerView(PanelManagerView):
|
||||
)
|
||||
|
||||
def _init_toggles(self):
|
||||
self._toggle_grid = TileGrid(columns=2, padding=12)
|
||||
self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0, max_tile_height=180.0)
|
||||
self._child(self._toggle_grid)
|
||||
self._page_grid = self._toggle_grid
|
||||
|
||||
@@ -278,14 +278,6 @@ class SoundsManagerView(PanelManagerView):
|
||||
self._left_container_h = max_container_h
|
||||
self._tiles_container_h = max_container_h
|
||||
|
||||
# Right column tiles: self._tiles_container_h = tile_grid_container
|
||||
# Available height for grid: self._tiles_container_h - 24 (padding)
|
||||
right_available_for_grid = self._tiles_container_h - 24
|
||||
# The grid has 3 rows of tiles, with 2 gaps of 12px = 24px
|
||||
right_available_for_tile_rows = right_available_for_grid - 24
|
||||
tile_h = max(80.0, min(130.0, right_available_for_tile_rows / 3))
|
||||
self._toggle_grid._tile_height = tile_h
|
||||
|
||||
return self._compute_two_column_height(section_overhead + max_container_h)
|
||||
|
||||
def _draw_header(self, rect: rl.Rectangle):
|
||||
|
||||
@@ -305,7 +305,7 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
|
||||
self._basics_tile_grid_h = 0.0
|
||||
|
||||
self._connectivity_tile_grid = TileGrid(columns=2, padding=12)
|
||||
self._connectivity_tile_grid = TileGrid(columns=2, padding=12, min_tile_height=130.0, max_tile_height=180.0)
|
||||
for toggle_def in self._toggle_defs:
|
||||
tile = self._make_toggle_tile(toggle_def)
|
||||
self._connectivity_tile_grid.add_tile(tile)
|
||||
@@ -512,11 +512,7 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
|
||||
self._system_max_container_h = max_container_h
|
||||
|
||||
# Scale connectivity tiles
|
||||
right_available_for_grid = self._system_max_container_h - 24
|
||||
right_available_for_tile_rows = right_available_for_grid - 12
|
||||
tile_h = max(80.0, min(130.0, right_available_for_tile_rows / 2))
|
||||
self._connectivity_tile_grid._tile_height = tile_h
|
||||
pass
|
||||
|
||||
return self._compute_two_column_height(max_container_h)
|
||||
else:
|
||||
|
||||
@@ -105,7 +105,7 @@ class VehicleSettingsManagerView(PanelManagerView):
|
||||
self._controller = controller
|
||||
self._shell_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
|
||||
self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_width=100)
|
||||
self._toggle_grid = TileGrid(columns=2, padding=12, min_tile_width=100, min_tile_height=130.0, max_tile_height=180.0)
|
||||
self.register_page_grid(self._toggle_grid)
|
||||
|
||||
self._last_make = ""
|
||||
|
||||
@@ -414,6 +414,21 @@ class TestAethergridContracts(unittest.TestCase):
|
||||
h = grid.measure_height(500)
|
||||
self.assertEqual(h, 740)
|
||||
|
||||
def test_tile_grid_measure_height_with_min_max_clamping(self):
|
||||
mod = _import_aethergrid()
|
||||
grid = mod.TileGrid(columns=2, padding=10, tile_height=None, min_tile_height=100.0, max_tile_height=150.0)
|
||||
for _ in range(5):
|
||||
grid.add_tile(RenderSpy())
|
||||
|
||||
h = grid.measure_height(500)
|
||||
self.assertEqual(h, 790)
|
||||
|
||||
spy = RenderSpy()
|
||||
grid.add_tile(spy)
|
||||
grid.render(mod.rl.Rectangle(0, 0, 500, 1000))
|
||||
self.assertTrue(spy.rects)
|
||||
self.assertEqual(spy.rects[0].height, 150.0)
|
||||
|
||||
def test_tile_grid_measure_height_default_fallback(self):
|
||||
mod = _import_aethergrid()
|
||||
grid = mod.TileGrid(columns=2, padding=10, tile_height=None)
|
||||
@@ -421,7 +436,7 @@ class TestAethergridContracts(unittest.TestCase):
|
||||
grid.add_tile(RenderSpy())
|
||||
|
||||
h = grid.measure_height(500)
|
||||
self.assertEqual(h, 690)
|
||||
self.assertEqual(h, 940)
|
||||
|
||||
def test_tile_grid_render_top_left_aligned_with_tile_height(self):
|
||||
mod = _import_aethergrid()
|
||||
|
||||
Reference in New Issue
Block a user