mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-06 05:52:12 +08:00
BigUI WIP: Extraction
This commit is contained in:
@@ -232,6 +232,7 @@ class AetherListFrame:
|
||||
|
||||
|
||||
AETHER_LIST_METRICS = AetherListMetrics()
|
||||
AETHER_COMPACT_ROW_HEIGHT = AETHER_LIST_METRICS.utility_row_height
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
@@ -582,6 +583,155 @@ def draw_metric_strip(
|
||||
)
|
||||
|
||||
|
||||
def draw_section_header(
|
||||
rect: rl.Rectangle,
|
||||
title: str = "",
|
||||
*,
|
||||
trailing_text: str = "",
|
||||
title_size: int = 26,
|
||||
trailing_size: int = 20,
|
||||
title_color: rl.Color | None = None,
|
||||
trailing_color: rl.Color | None = None,
|
||||
style: PanelStyle = DEFAULT_PANEL_STYLE,
|
||||
):
|
||||
if title:
|
||||
trailing_reserved = min(320.0, rect.width * 0.38) if trailing_text else 0.0
|
||||
title_rect = rl.Rectangle(rect.x, rect.y + (rect.height - title_size) / 2, max(1.0, rect.width - trailing_reserved), title_size + 4)
|
||||
gui_label(title_rect, title, title_size, title_color or style.subtitle_color, FontWeight.MEDIUM)
|
||||
|
||||
if trailing_text:
|
||||
trailing_rect = rl.Rectangle(rect.x, rect.y + (rect.height - trailing_size) / 2, rect.width, trailing_size + 4)
|
||||
gui_label(
|
||||
trailing_rect,
|
||||
trailing_text,
|
||||
trailing_size,
|
||||
trailing_color or style.subtitle_color,
|
||||
FontWeight.NORMAL,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT,
|
||||
)
|
||||
|
||||
|
||||
def draw_empty_state_card(
|
||||
rect: rl.Rectangle,
|
||||
title: str,
|
||||
body: str,
|
||||
*,
|
||||
title_size: int = 30,
|
||||
body_size: int = 22,
|
||||
body_inset_x: int = 48,
|
||||
title_gap: int = 14,
|
||||
title_top_padding: float | None = None,
|
||||
body_height: float | None = None,
|
||||
fill: rl.Color | None = None,
|
||||
border: rl.Color | None = None,
|
||||
radius: float = 0.08,
|
||||
segments: int = 18,
|
||||
style: PanelStyle = DEFAULT_PANEL_STYLE,
|
||||
):
|
||||
card_rect = _snap_rect(rect)
|
||||
resolved_fill = fill if fill is not None else style.surface_fill
|
||||
resolved_border = border if border is not None else style.surface_border
|
||||
draw_soft_card(card_rect, resolved_fill, resolved_border, radius=radius, segments=segments)
|
||||
|
||||
title_h = max(34.0, title_size + 8)
|
||||
title_y = card_rect.y + (title_top_padding if title_top_padding is not None else max(24.0, min(42.0, card_rect.height * 0.22)))
|
||||
inset_x = min(float(body_inset_x), max(18.0, card_rect.width * 0.22))
|
||||
body_y = title_y + title_h + title_gap
|
||||
resolved_body_h = body_height if body_height is not None else max(40.0, card_rect.height - (body_y - card_rect.y) - 24.0)
|
||||
|
||||
gui_label(
|
||||
rl.Rectangle(card_rect.x, title_y, card_rect.width, title_h),
|
||||
title,
|
||||
title_size,
|
||||
style.title_color,
|
||||
FontWeight.MEDIUM,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
)
|
||||
gui_label(
|
||||
rl.Rectangle(card_rect.x + inset_x, body_y, max(1.0, card_rect.width - inset_x * 2), resolved_body_h),
|
||||
body,
|
||||
body_size,
|
||||
style.subtitle_color,
|
||||
FontWeight.NORMAL,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
)
|
||||
|
||||
|
||||
def draw_list_group_shell(
|
||||
rect: rl.Rectangle,
|
||||
*,
|
||||
fill: rl.Color | None = None,
|
||||
border: rl.Color | None = None,
|
||||
radius: float = 0.055,
|
||||
segments: int = 18,
|
||||
style: PanelStyle = DEFAULT_PANEL_STYLE,
|
||||
):
|
||||
draw_soft_card(rect, fill if fill is not None else style.surface_fill, border if border is not None else style.surface_border, radius=radius, segments=segments)
|
||||
|
||||
|
||||
def draw_settings_list_row(
|
||||
rect: rl.Rectangle,
|
||||
*,
|
||||
title: str,
|
||||
subtitle: str = "",
|
||||
value: str = "",
|
||||
toggle_value: bool | None = None,
|
||||
hovered: bool = False,
|
||||
pressed: bool = False,
|
||||
is_last: bool = False,
|
||||
show_chevron: bool = True,
|
||||
title_size: int = 28,
|
||||
subtitle_size: int = 20,
|
||||
value_size: int = 24,
|
||||
separator_inset: int = 22,
|
||||
value_color: rl.Color | None = None,
|
||||
style: PanelStyle = DEFAULT_PANEL_STYLE,
|
||||
):
|
||||
draw_rect = _snap_rect(rect)
|
||||
draw_list_row_shell(
|
||||
draw_rect,
|
||||
hovered=hovered,
|
||||
pressed=pressed,
|
||||
is_last=is_last,
|
||||
row_bg=rl.Color(255, 255, 255, 0),
|
||||
row_border=rl.Color(255, 255, 255, 0),
|
||||
row_separator=style.divider_color,
|
||||
current_bg=rl.Color(255, 255, 255, 0),
|
||||
current_border=rl.Color(255, 255, 255, 0),
|
||||
separator_inset=separator_inset,
|
||||
)
|
||||
|
||||
label_rect = rl.Rectangle(draw_rect.x + 24, draw_rect.y + 14, draw_rect.width * 0.55, 28)
|
||||
subtitle_rect = rl.Rectangle(draw_rect.x + 24, draw_rect.y + 46, draw_rect.width * 0.60, 24)
|
||||
gui_label(label_rect, title, title_size, style.title_color, FontWeight.MEDIUM)
|
||||
if subtitle:
|
||||
gui_label(subtitle_rect, subtitle, subtitle_size, style.subtitle_color, FontWeight.NORMAL)
|
||||
|
||||
if toggle_value is not None:
|
||||
draw_toggle_switch(draw_rect, bool(toggle_value), track_color=style.accent)
|
||||
return
|
||||
|
||||
if value:
|
||||
value_rect = rl.Rectangle(draw_rect.x + draw_rect.width - AETHER_LIST_METRICS.utility_value_right, draw_rect.y + 20, AETHER_LIST_METRICS.utility_value_width, 28)
|
||||
gui_label(
|
||||
value_rect,
|
||||
value,
|
||||
value_size,
|
||||
value_color or style.title_color,
|
||||
FontWeight.MEDIUM,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT,
|
||||
)
|
||||
if show_chevron:
|
||||
gui_label(
|
||||
rl.Rectangle(draw_rect.x + draw_rect.width - AETHER_LIST_METRICS.utility_chevron_right, draw_rect.y + 18, 26, 26),
|
||||
"›",
|
||||
32,
|
||||
style.muted_color,
|
||||
FontWeight.MEDIUM,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
)
|
||||
|
||||
|
||||
def draw_selection_list_row(
|
||||
rect: rl.Rectangle,
|
||||
*,
|
||||
@@ -606,9 +756,28 @@ def draw_selection_list_row(
|
||||
action_fill: rl.Color = AetherListColors.CURRENT_BG,
|
||||
action_border: rl.Color = AetherListColors.CURRENT_BORDER,
|
||||
action_text_color: rl.Color = AetherListColors.HEADER,
|
||||
row_bg: rl.Color = AetherListColors.ROW_BG,
|
||||
row_border: rl.Color = AetherListColors.ROW_BORDER,
|
||||
row_separator: rl.Color = AetherListColors.ROW_SEPARATOR,
|
||||
row_hover: rl.Color = AetherListColors.ROW_HOVER,
|
||||
current_bg: rl.Color = AetherListColors.CURRENT_BG,
|
||||
current_border: rl.Color = AetherListColors.CURRENT_BORDER,
|
||||
):
|
||||
draw_rect = _snap_rect(rect)
|
||||
draw_list_row_shell(draw_rect, current=current, hovered=hovered, pressed=pressed, is_last=is_last, alpha=alpha)
|
||||
draw_list_row_shell(
|
||||
draw_rect,
|
||||
current=current,
|
||||
hovered=hovered,
|
||||
pressed=pressed,
|
||||
is_last=is_last,
|
||||
alpha=alpha,
|
||||
row_bg=row_bg,
|
||||
row_border=row_border,
|
||||
row_separator=row_separator,
|
||||
row_hover=row_hover,
|
||||
current_bg=current_bg,
|
||||
current_border=current_border,
|
||||
)
|
||||
action_rect = rl.Rectangle(draw_rect.x + draw_rect.width - action_width, draw_rect.y, action_width, draw_rect.height)
|
||||
if not action_pill:
|
||||
action_rect = draw_action_rail(draw_rect, action_width, current=current, alpha=alpha)
|
||||
|
||||
@@ -38,18 +38,21 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AetherListColors,
|
||||
AetherScrollbar,
|
||||
AetherSliderDialog,
|
||||
_point_hits,
|
||||
draw_action_rail,
|
||||
draw_action_pill,
|
||||
draw_busy_ring,
|
||||
draw_download_icon,
|
||||
draw_empty_state_card,
|
||||
draw_heart_icon,
|
||||
draw_list_panel_shell,
|
||||
draw_list_group_shell,
|
||||
build_list_panel_frame,
|
||||
draw_list_row_shell,
|
||||
draw_list_scroll_fades,
|
||||
draw_soft_card,
|
||||
draw_section_header,
|
||||
draw_settings_list_row,
|
||||
draw_status_led,
|
||||
draw_toggle_switch,
|
||||
draw_overflow_dots,
|
||||
)
|
||||
|
||||
@@ -224,8 +227,7 @@ class DrivingModelManagerView(Widget):
|
||||
|
||||
def _target_at(self, mouse_pos: MousePos) -> str | None:
|
||||
for sub_key, rect in self._menu_sub_rects.items():
|
||||
visible_rect = rl.get_collision_rec(rect, self._scroll_rect)
|
||||
if visible_rect.width > 0 and visible_rect.height > 0 and rl.check_collision_point_rec(mouse_pos, visible_rect):
|
||||
if _point_hits(mouse_pos, rect, self._scroll_rect, pad_x=6, pad_y=6):
|
||||
return f"menu:{sub_key}"
|
||||
|
||||
for key, rect in self._action_rects.items():
|
||||
@@ -411,32 +413,25 @@ class DrivingModelManagerView(Widget):
|
||||
self._draw_utility_section(rect.x, y, width, utility_rows)
|
||||
|
||||
def _draw_empty_state(self, rect: rl.Rectangle):
|
||||
state_rect = rl.Rectangle(rect.x, rect.y, rect.width - 18, rect.height)
|
||||
draw_soft_card(state_rect, rl.Color(255, 255, 255, 5), rl.Color(255, 255, 255, 14), radius=0.08, segments=18)
|
||||
gui_label(
|
||||
rl.Rectangle(state_rect.x, state_rect.y + 42, state_rect.width, 40),
|
||||
draw_empty_state_card(
|
||||
rl.Rectangle(rect.x, rect.y, rect.width - AETHER_LIST_METRICS.content_right_gutter, rect.height),
|
||||
self._controller.empty_state_title(),
|
||||
32,
|
||||
MODEL_HEADER_TEXT,
|
||||
FontWeight.MEDIUM,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
)
|
||||
gui_label(
|
||||
rl.Rectangle(state_rect.x + 48, state_rect.y + 88, state_rect.width - 96, 72),
|
||||
self._controller.empty_state_body(),
|
||||
24,
|
||||
MODEL_SUBTEXT,
|
||||
FontWeight.NORMAL,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
title_size=32,
|
||||
body_size=24,
|
||||
body_inset_x=48,
|
||||
title_top_padding=42,
|
||||
body_height=72,
|
||||
fill=rl.Color(255, 255, 255, 5),
|
||||
border=rl.Color(255, 255, 255, 14),
|
||||
)
|
||||
|
||||
def _draw_model_section(self, x: float, y: float, width: float, title: str, entries: list[ModelCatalogEntry]) -> float:
|
||||
title_rect = rl.Rectangle(x, y, width - 18, SECTION_HEADER_HEIGHT)
|
||||
gui_label(title_rect, title, 26, MODEL_SUBTEXT, FontWeight.MEDIUM)
|
||||
draw_section_header(rl.Rectangle(x, y, width - AETHER_LIST_METRICS.content_right_gutter, SECTION_HEADER_HEIGHT), title)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
for index, entry in enumerate(entries):
|
||||
row_rect = rl.Rectangle(x, y + index * ROW_HEIGHT, width - 18, ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(x, y + index * ROW_HEIGHT, width - AETHER_LIST_METRICS.content_right_gutter, ROW_HEIGHT)
|
||||
self._draw_model_row(row_rect, entry, is_last=index == len(entries) - 1)
|
||||
return y + len(entries) * ROW_HEIGHT
|
||||
|
||||
@@ -571,7 +566,7 @@ class DrivingModelManagerView(Widget):
|
||||
)
|
||||
else:
|
||||
# Expanded sub-button menu
|
||||
btn_h = 40
|
||||
btn_h = 44
|
||||
gap = 8
|
||||
total_h = btn_h * 2 + gap
|
||||
start_y = rect.y + (rect.height - total_h) / 2
|
||||
@@ -602,46 +597,32 @@ class DrivingModelManagerView(Widget):
|
||||
AetherChip(tr("Protected"), rl.Color(255, 255, 255, 10), MODEL_MUTED, MODEL_SUBTEXT, font_size=18).render(chip_rect)
|
||||
|
||||
def _draw_utility_section(self, x: float, y: float, width: float, rows: list[dict]):
|
||||
title_rect = rl.Rectangle(x, y, width - 18, SECTION_HEADER_HEIGHT)
|
||||
gui_label(title_rect, tr("Automation and Tuning"), 26, MODEL_SUBTEXT, FontWeight.MEDIUM)
|
||||
content_w = width - AETHER_LIST_METRICS.content_right_gutter
|
||||
draw_section_header(rl.Rectangle(x, y, content_w, SECTION_HEADER_HEIGHT), tr("Automation and Tuning"))
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
container_rect = rl.Rectangle(x, y, width - 18, len(rows) * UTILITY_ROW_HEIGHT)
|
||||
draw_soft_card(container_rect, rl.Color(255, 255, 255, 4), rl.Color(255, 255, 255, 15), radius=0.055, segments=18)
|
||||
container_rect = rl.Rectangle(x, y, content_w, len(rows) * UTILITY_ROW_HEIGHT)
|
||||
draw_list_group_shell(container_rect, fill=rl.Color(255, 255, 255, 4), border=rl.Color(255, 255, 255, 15))
|
||||
|
||||
for index, row in enumerate(rows):
|
||||
row_rect = rl.Rectangle(x, y + index * UTILITY_ROW_HEIGHT, width - 18, UTILITY_ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(x, y + index * UTILITY_ROW_HEIGHT, content_w, UTILITY_ROW_HEIGHT)
|
||||
self._draw_utility_row(row_rect, row, is_last=index == len(rows) - 1)
|
||||
|
||||
def _draw_utility_row(self, rect: rl.Rectangle, row: dict, is_last: bool):
|
||||
mouse_pos = gui_app.last_mouse_event.pos
|
||||
hovered = rl.check_collision_point_rec(mouse_pos, rect)
|
||||
pressed = self._pressed_target == f"utility:{row['id']}"
|
||||
bg = rl.Color(255, 255, 255, 8 if hovered else 0)
|
||||
if pressed:
|
||||
bg = rl.Color(255, 255, 255, 14)
|
||||
if bg.a:
|
||||
rl.draw_rectangle_rounded(rect, ROW_RADIUS, 18, bg)
|
||||
|
||||
if not is_last:
|
||||
line_y = int(rect.y + rect.height - 1)
|
||||
rl.draw_line(int(rect.x + 22), line_y, int(rect.x + rect.width - 22), line_y, MODEL_ROW_SEPARATOR)
|
||||
|
||||
self._utility_rects[row["id"]] = rect
|
||||
label_rect = rl.Rectangle(rect.x + 24, rect.y + 14, rect.width * 0.55, 28)
|
||||
subtitle_rect = rl.Rectangle(rect.x + 24, rect.y + 46, rect.width * 0.60, 24)
|
||||
gui_label(label_rect, row["title"], 28, MODEL_HEADER_TEXT, FontWeight.MEDIUM)
|
||||
if row.get("subtitle"):
|
||||
gui_label(subtitle_rect, row["subtitle"], 20, MODEL_SUBTEXT, FontWeight.NORMAL)
|
||||
|
||||
if row["type"] == "toggle":
|
||||
draw_toggle_switch(rect, bool(row["value"]))
|
||||
else:
|
||||
value_rect = rl.Rectangle(rect.x + rect.width - AETHER_LIST_METRICS.utility_value_right, rect.y + 20, AETHER_LIST_METRICS.utility_value_width, 28)
|
||||
gui_label(value_rect, row["value"], 24, MODEL_HEADER_TEXT, FontWeight.MEDIUM, alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT)
|
||||
gui_label(
|
||||
rl.Rectangle(rect.x + rect.width - AETHER_LIST_METRICS.utility_chevron_right, rect.y + 18, 26, 26), "›", 32, MODEL_MUTED, FontWeight.MEDIUM, alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER
|
||||
)
|
||||
draw_settings_list_row(
|
||||
rect,
|
||||
title=row["title"],
|
||||
subtitle=row.get("subtitle", ""),
|
||||
value="" if row["type"] == "toggle" else row["value"],
|
||||
toggle_value=bool(row["value"]) if row["type"] == "toggle" else None,
|
||||
hovered=hovered,
|
||||
pressed=pressed,
|
||||
is_last=is_last,
|
||||
)
|
||||
|
||||
def _draw_scrollbar(self, rect: rl.Rectangle):
|
||||
self._scrollbar.render(rect, self._content_height, self._scroll_offset)
|
||||
|
||||
@@ -20,16 +20,19 @@ from openpilot.system.ui.widgets.label import gui_label, gui_text_box
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AETHER_COMPACT_ROW_HEIGHT,
|
||||
AETHER_LIST_METRICS,
|
||||
AetherButton,
|
||||
AetherChip,
|
||||
AetherListColors,
|
||||
AetherScrollbar,
|
||||
DEFAULT_PANEL_STYLE,
|
||||
build_list_panel_frame,
|
||||
draw_action_pill,
|
||||
draw_busy_ring,
|
||||
draw_empty_state_card,
|
||||
draw_list_panel_shell,
|
||||
draw_metric_strip,
|
||||
draw_section_header,
|
||||
draw_tab_card,
|
||||
draw_selection_list_row,
|
||||
draw_list_scroll_fades,
|
||||
@@ -62,17 +65,16 @@ NETWORK_TYPE_LABELS = {
|
||||
|
||||
OFFLINE_MAPS_PATH = Path("/data/media/0/osm/offline")
|
||||
CANCEL_REQUEST_TIMEOUT = 3.0
|
||||
HEADER_TOP_OFFSET = 10
|
||||
HEADER_TOP_OFFSET = 4
|
||||
HEADER_TITLE_HEIGHT = 40
|
||||
HEADER_SUBTITLE_HEIGHT = 28
|
||||
HEADER_SUBTITLE_HEIGHT = 24
|
||||
HEADER_BOTTOM_GAP = 12
|
||||
BROWSER_TOOLBAR_HEIGHT = 64
|
||||
BROWSER_SECTION_HEADER_HEIGHT = 34
|
||||
BROWSER_INSET = 18
|
||||
BROWSER_TAB_GAP = 12
|
||||
BROWSER_CONTEXT_TAB_GAP = 10
|
||||
BROWSER_SECTION_HEADER_HEIGHT = AETHER_LIST_METRICS.section_header_height
|
||||
BROWSER_SECTION_HEADER_GAP = AETHER_LIST_METRICS.section_header_gap
|
||||
BROWSER_INSET = AETHER_LIST_METRICS.content_right_gutter
|
||||
BROWSER_TAB_GAP = AETHER_LIST_METRICS.section_header_gap
|
||||
BROWSER_CONTEXT_TAB_HEIGHT = 52
|
||||
BROWSER_REGION_ROW_HEIGHT = 88
|
||||
BROWSER_REGION_ROW_HEIGHT = AETHER_COMPACT_ROW_HEIGHT
|
||||
BROWSER_EMPTY_STATE_HEIGHT = 128
|
||||
STATUS_CARD_INSET = BROWSER_INSET
|
||||
STATUS_BUTTON_HEIGHT = 52
|
||||
@@ -81,7 +83,13 @@ STATUS_REMOVE_HEIGHT = 40
|
||||
STATUS_METRIC_GAP = 18
|
||||
STATUS_SELECTION_CHIP_HEIGHT = 30
|
||||
MAPS_TILE_GREEN = rl.Color(16, 185, 129, 255)
|
||||
MAPS_PANEL_STYLE = replace(DEFAULT_PANEL_STYLE, accent=MAPS_TILE_GREEN)
|
||||
MAPS_PANEL_STYLE = replace(
|
||||
DEFAULT_PANEL_STYLE,
|
||||
accent=MAPS_TILE_GREEN,
|
||||
current_fill=rl.Color(16, 185, 129, 16),
|
||||
current_border=rl.Color(16, 185, 129, 42),
|
||||
underline_color=rl.Color(16, 185, 129, 150),
|
||||
)
|
||||
|
||||
COUNTRIES_SECTION = next(section for section in MAPS_CATALOG if section["key"] == "countries")
|
||||
STATES_SECTION = next(section for section in MAPS_CATALOG if section["key"] == "states")
|
||||
@@ -389,23 +397,17 @@ class MapBrowserCard(Widget):
|
||||
)
|
||||
|
||||
def _render_empty_state(self, rect: rl.Rectangle, title: str, body: str):
|
||||
state_rect = rl.Rectangle(rect.x, rect.y, rect.width, rect.height)
|
||||
draw_soft_card(state_rect, MAPS_PANEL_STYLE.surface_fill, rl.Color(255, 255, 255, 10))
|
||||
gui_label(
|
||||
rl.Rectangle(state_rect.x, state_rect.y + 24, state_rect.width, 32),
|
||||
draw_empty_state_card(
|
||||
rect,
|
||||
title,
|
||||
26,
|
||||
AetherListColors.HEADER,
|
||||
FontWeight.MEDIUM,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
)
|
||||
gui_label(
|
||||
rl.Rectangle(state_rect.x + 40, state_rect.y + 60, state_rect.width - 80, 44),
|
||||
body,
|
||||
19,
|
||||
AetherListColors.SUBTEXT,
|
||||
FontWeight.NORMAL,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER,
|
||||
title_size=26,
|
||||
body_size=19,
|
||||
body_inset_x=40,
|
||||
title_top_padding=24,
|
||||
body_height=44,
|
||||
border=rl.Color(255, 255, 255, 10),
|
||||
style=MAPS_PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _render_region_rows(self, rect: rl.Rectangle, regions: list[dict]):
|
||||
@@ -436,29 +438,23 @@ class MapBrowserCard(Widget):
|
||||
action_width=142,
|
||||
action_pill=True,
|
||||
action_text_size=15,
|
||||
action_pill_height=36,
|
||||
action_pill_height=40,
|
||||
action_pill_width=112 if selected else 84,
|
||||
title_size=26,
|
||||
subtitle_size=17,
|
||||
row_separator=MAPS_PANEL_STYLE.divider_color,
|
||||
current_bg=MAPS_PANEL_STYLE.current_fill,
|
||||
current_border=MAPS_PANEL_STYLE.current_border,
|
||||
action_fill=rl.Color(94, 168, 130, 18) if selected else rl.Color(255, 255, 255, 8),
|
||||
action_border=rl.Color(94, 168, 130, 38) if selected else rl.Color(255, 255, 255, 24),
|
||||
action_text_color=AetherListColors.SUBTEXT if selected else AetherListColors.HEADER,
|
||||
action_text_color=AetherListColors.HEADER,
|
||||
)
|
||||
|
||||
def _active_browse_regions(self) -> list[dict]:
|
||||
return self._controller._browse_regions_for_active_group()
|
||||
|
||||
def _render_section_header(self, rect: rl.Rectangle, title: str, *, count_text: str | None = None):
|
||||
del title
|
||||
if count_text:
|
||||
gui_label(
|
||||
rl.Rectangle(rect.x, rect.y + (rect.height - 22) / 2, rect.width, 22),
|
||||
count_text,
|
||||
20,
|
||||
AetherListColors.SUBTEXT,
|
||||
FontWeight.NORMAL,
|
||||
alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT,
|
||||
)
|
||||
draw_section_header(rect, title, trailing_text=count_text or "", title_size=24, trailing_size=20, style=MAPS_PANEL_STYLE)
|
||||
|
||||
def _measure_height(self, width: float) -> float:
|
||||
if self._controller._showing_source_picker():
|
||||
@@ -466,8 +462,8 @@ class MapBrowserCard(Widget):
|
||||
return BROWSER_CONTEXT_TAB_HEIGHT + 20
|
||||
|
||||
total = 10.0
|
||||
total += self._measure_context_tabs_height(width) + 12
|
||||
total += BROWSER_SECTION_HEADER_HEIGHT + 2
|
||||
total += self._measure_context_tabs_height(width) + BROWSER_SECTION_HEADER_GAP
|
||||
total += BROWSER_SECTION_HEADER_HEIGHT + BROWSER_SECTION_HEADER_GAP
|
||||
region_count = len(self._active_browse_regions())
|
||||
total += self._row_height(region_count, BROWSER_REGION_ROW_HEIGHT) if region_count else BROWSER_EMPTY_STATE_HEIGHT
|
||||
return total + 10
|
||||
@@ -491,14 +487,14 @@ class MapBrowserCard(Widget):
|
||||
|
||||
context_tabs_h = self._measure_context_tabs_height(content_w)
|
||||
self._render_context_tabs(rl.Rectangle(content_x, y, content_w, context_tabs_h))
|
||||
y += context_tabs_h + 12
|
||||
y += context_tabs_h + BROWSER_SECTION_HEADER_GAP
|
||||
|
||||
self._render_section_header(
|
||||
rl.Rectangle(content_x, y, content_w, BROWSER_SECTION_HEADER_HEIGHT),
|
||||
"",
|
||||
tr("Regions"),
|
||||
count_text=self._controller._active_group_count_text(),
|
||||
)
|
||||
y += BROWSER_SECTION_HEADER_HEIGHT + 2
|
||||
y += BROWSER_SECTION_HEADER_HEIGHT + BROWSER_SECTION_HEADER_GAP
|
||||
|
||||
regions = self._active_browse_regions()
|
||||
region_h = self._row_height(len(regions), BROWSER_REGION_ROW_HEIGHT) if regions else BROWSER_EMPTY_STATE_HEIGHT
|
||||
@@ -1130,15 +1126,16 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
|
||||
hdr = frame.header
|
||||
title_y = hdr.y + HEADER_TOP_OFFSET
|
||||
subtitle_y = hdr.y + 48
|
||||
gui_label(rl.Rectangle(hdr.x, title_y, hdr.width, HEADER_TITLE_HEIGHT), tr("Map Data"), 40, AetherListColors.HEADER, FontWeight.SEMI_BOLD)
|
||||
gui_label(rl.Rectangle(hdr.x, title_y + 40, hdr.width * 0.72, HEADER_SUBTITLE_HEIGHT), tr("Use offline maps for speed-limit control and keep only the regions you need."), 22, AetherListColors.SUBTEXT, FontWeight.NORMAL)
|
||||
gui_label(rl.Rectangle(hdr.x, subtitle_y, hdr.width * 0.60, HEADER_SUBTITLE_HEIGHT), tr("Use offline maps for speed-limit control and keep only the regions you need."), 22, AetherListColors.SUBTEXT, FontWeight.NORMAL)
|
||||
|
||||
header_status_y = title_y + HEADER_TITLE_HEIGHT + HEADER_SUBTITLE_HEIGHT + 8
|
||||
header_status_y = subtitle_y + HEADER_SUBTITLE_HEIGHT + 12
|
||||
header_status_rect = rl.Rectangle(hdr.x, header_status_y, hdr.width, hdr.y + hdr.height - header_status_y - HEADER_BOTTOM_GAP)
|
||||
self._status_card.render(header_status_rect)
|
||||
|
||||
scroll_rect = frame.scroll
|
||||
content_width = scroll_rect.width - 18
|
||||
content_width = scroll_rect.width - AETHER_LIST_METRICS.content_right_gutter
|
||||
scroll_content_rect = rl.Rectangle(scroll_rect.x, scroll_rect.y, scroll_rect.width, scroll_rect.height)
|
||||
self._content_height = self._measure_content_height(content_width)
|
||||
self._scroll_panel.set_enabled(self.is_visible)
|
||||
|
||||
Reference in New Issue
Block a user