mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-09-24 08:23:51 +08:00
BigUI WIP: Cleanup/uniformity
This commit is contained in:
@@ -108,10 +108,7 @@ class DrivingModelManagerView(Widget):
|
||||
self._scroll_offset = 0.0
|
||||
self._pressed_target: str | None = None
|
||||
self._can_click = True
|
||||
self._row_rects: dict[str, rl.Rectangle] = {}
|
||||
self._action_rects: dict[str, rl.Rectangle] = {}
|
||||
self._utility_rects: dict[str, rl.Rectangle] = {}
|
||||
self._menu_sub_rects: dict[str, rl.Rectangle] = {}
|
||||
self._interactive_rects: dict[str, rl.Rectangle] = {}
|
||||
self._confirm_key: str | None = None
|
||||
self._confirm_until = 0.0
|
||||
self._transition_starts: dict[str, tuple[float, float]] = {}
|
||||
@@ -202,36 +199,26 @@ class DrivingModelManagerView(Widget):
|
||||
self._can_click = True
|
||||
|
||||
def _handle_mouse_event(self, mouse_event: MouseEvent):
|
||||
del mouse_event
|
||||
if not self._scroll_panel.is_touch_valid():
|
||||
self._can_click = False
|
||||
return
|
||||
if self._pressed_target is not None and self._target_at(mouse_event.pos) != self._pressed_target:
|
||||
self._pressed_target = None
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
target = self._target_at(mouse_pos)
|
||||
target = self._target_at(mouse_pos) if self._scroll_panel.is_touch_valid() else None
|
||||
if self._pressed_target is not None and self._pressed_target == target and self._can_click:
|
||||
self._activate_target(target)
|
||||
self._pressed_target = None
|
||||
self._can_click = True
|
||||
|
||||
def _target_at(self, mouse_pos: MousePos) -> str | None:
|
||||
for sub_key, rect in self._menu_sub_rects.items():
|
||||
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():
|
||||
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):
|
||||
return f"action:{key}"
|
||||
|
||||
for name, rect in self._utility_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):
|
||||
return f"utility:{name}"
|
||||
|
||||
for key, rect in self._row_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):
|
||||
return f"row:{key}"
|
||||
|
||||
for prefix in ("menu:", "action:", "utility:", "row:"):
|
||||
for target_id, rect in self._interactive_rects.items():
|
||||
if target_id.startswith(prefix):
|
||||
pad_y = 6 if prefix == "menu:" else 0
|
||||
if _point_hits(mouse_pos, rect, self._scroll_rect, pad_x=6, pad_y=pad_y):
|
||||
return target_id
|
||||
return None
|
||||
|
||||
def _activate_target(self, target: str | None):
|
||||
@@ -291,10 +278,7 @@ class DrivingModelManagerView(Widget):
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
self._row_rects.clear()
|
||||
self._action_rects.clear()
|
||||
self._utility_rects.clear()
|
||||
self._menu_sub_rects.clear()
|
||||
self._interactive_rects.clear()
|
||||
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, PANEL_STYLE)
|
||||
self._shell_rect = frame.shell
|
||||
@@ -389,7 +373,7 @@ class DrivingModelManagerView(Widget):
|
||||
|
||||
def _draw_empty_state(self, rect: rl.Rectangle):
|
||||
draw_empty_state_card(
|
||||
rl.Rectangle(rect.x, rect.y, rect.width - AETHER_LIST_METRICS.content_right_gutter, rect.height),
|
||||
rl.Rectangle(rect.x, rect.y, rect.width, rect.height),
|
||||
self._controller.empty_state_title(),
|
||||
self._controller.empty_state_body(),
|
||||
title_size=32,
|
||||
@@ -401,17 +385,20 @@ class DrivingModelManagerView(Widget):
|
||||
)
|
||||
|
||||
def _draw_model_section(self, x: float, y: float, width: float, title: str, entries: list[ModelCatalogEntry]) -> float:
|
||||
draw_section_header(rl.Rectangle(x, y, width - AETHER_LIST_METRICS.content_right_gutter, SECTION_HEADER_HEIGHT), title, style=PANEL_STYLE)
|
||||
draw_section_header(rl.Rectangle(x, y, width, SECTION_HEADER_HEIGHT), title, style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
group_rect = rl.Rectangle(x, y, width, len(entries) * ROW_HEIGHT)
|
||||
draw_list_group_shell(group_rect, style=PANEL_STYLE)
|
||||
|
||||
for index, entry in enumerate(entries):
|
||||
row_rect = rl.Rectangle(x, y + index * ROW_HEIGHT, width - AETHER_LIST_METRICS.content_right_gutter, ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(x, y + index * ROW_HEIGHT, width, ROW_HEIGHT)
|
||||
self._draw_model_row(row_rect, entry, is_last=index == len(entries) - 1)
|
||||
return y + len(entries) * ROW_HEIGHT
|
||||
|
||||
def _draw_model_row(self, rect: rl.Rectangle, entry: ModelCatalogEntry, is_last: bool):
|
||||
mouse_pos = gui_app.last_mouse_event.pos
|
||||
row_hovered = rl.check_collision_point_rec(mouse_pos, rect)
|
||||
row_hovered = bool(_point_hits(mouse_pos, rect, self._scroll_rect, pad_x=6, pad_y=0))
|
||||
target_key = f"row:{entry.key}"
|
||||
pressed = self._pressed_target == target_key
|
||||
current = self._controller.is_current_model(entry.key)
|
||||
@@ -446,7 +433,7 @@ class DrivingModelManagerView(Widget):
|
||||
info_rect = rl.Rectangle(draw_rect.x + 24, draw_rect.y + 18, draw_rect.width - ACTION_WIDTH - 42, draw_rect.height - 36)
|
||||
row_touchable = entry.installed and not self._controller._params.get_bool("ModelRandomizer")
|
||||
if row_touchable:
|
||||
self._row_rects[entry.key] = draw_rect
|
||||
self._interactive_rects[f"row:{entry.key}"] = draw_rect
|
||||
|
||||
self._draw_model_info(info_rect, entry, current)
|
||||
|
||||
@@ -456,10 +443,10 @@ class DrivingModelManagerView(Widget):
|
||||
elif not removable:
|
||||
self._draw_protected_action(action_rect)
|
||||
else:
|
||||
self._action_rects[entry.key] = action_rect
|
||||
self._interactive_rects[f"action:{entry.key}"] = action_rect
|
||||
self._draw_menu_action(action_rect, is_menu_open, entry)
|
||||
else:
|
||||
self._action_rects[entry.key] = action_rect
|
||||
self._interactive_rects[f"action:{entry.key}"] = action_rect
|
||||
if downloading:
|
||||
self._draw_downloading_action(action_rect, self._controller.download_progress_text())
|
||||
else:
|
||||
@@ -548,8 +535,8 @@ class DrivingModelManagerView(Widget):
|
||||
delete_rect = rl.Rectangle(rect.x + 10, start_y, rect.width - 20, btn_h)
|
||||
fav_rect = rl.Rectangle(rect.x + 10, start_y + btn_h + gap, rect.width - 20, btn_h)
|
||||
|
||||
self._menu_sub_rects[f"{entry.key}:delete"] = delete_rect
|
||||
self._menu_sub_rects[f"{entry.key}:favorite"] = fav_rect
|
||||
self._interactive_rects[f"menu:{entry.key}:delete"] = delete_rect
|
||||
self._interactive_rects[f"menu:{entry.key}:favorite"] = fav_rect
|
||||
|
||||
# Delete button
|
||||
draw_action_pill(delete_rect, tr("Delete"), AetherListColors.DANGER_SOFT, rl.Color(AetherListColors.DANGER.r, AetherListColors.DANGER.g, AetherListColors.DANGER.b, min(AetherListColors.DANGER.a, 70)), AetherListColors.DANGER)
|
||||
@@ -571,7 +558,7 @@ class DrivingModelManagerView(Widget):
|
||||
AetherChip(tr("Protected"), rl.Color(255, 255, 255, 10), AetherListColors.MUTED, AetherListColors.SUBTEXT, font_size=18).render(chip_rect)
|
||||
|
||||
def _draw_utility_section(self, x: float, y: float, width: float, rows: list[dict]):
|
||||
content_w = width - AETHER_LIST_METRICS.content_right_gutter
|
||||
content_w = width
|
||||
draw_section_header(rl.Rectangle(x, y, content_w, SECTION_HEADER_HEIGHT), tr("Automation and Tuning"), style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
@@ -584,9 +571,9 @@ class DrivingModelManagerView(Widget):
|
||||
|
||||
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)
|
||||
hovered = bool(_point_hits(mouse_pos, rect, self._scroll_rect, pad_x=6, pad_y=0))
|
||||
pressed = self._pressed_target == f"utility:{row['id']}"
|
||||
self._utility_rects[row["id"]] = rect
|
||||
self._interactive_rects[f"utility:{row['id']}"] = rect
|
||||
draw_settings_list_row(
|
||||
rect,
|
||||
title=row["title"],
|
||||
|
||||
@@ -85,7 +85,7 @@ 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(
|
||||
PANEL_STYLE = replace(
|
||||
DEFAULT_PANEL_STYLE,
|
||||
accent=MAPS_TILE_GREEN,
|
||||
current_fill=rl.Color(16, 185, 129, 16),
|
||||
@@ -180,7 +180,7 @@ class MapStatusCard(Widget):
|
||||
self._controller._on_remove()
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
draw_soft_card(rect, MAPS_PANEL_STYLE.surface_fill, MAPS_PANEL_STYLE.surface_border)
|
||||
draw_soft_card(rect, PANEL_STYLE.surface_fill, PANEL_STYLE.surface_border)
|
||||
|
||||
inset = STATUS_CARD_INSET
|
||||
content_x = rect.x + inset
|
||||
@@ -233,7 +233,7 @@ class MapStatusCard(Widget):
|
||||
(tr("Last Updated"), self._controller._last_updated_text()),
|
||||
],
|
||||
gap=STATUS_METRIC_GAP,
|
||||
style=MAPS_PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
label_top_offset=0,
|
||||
value_top_offset=14,
|
||||
divider_top_offset=2,
|
||||
@@ -247,7 +247,7 @@ class MapStatusCard(Widget):
|
||||
(tr("Last Updated"), self._controller._last_updated_text()),
|
||||
],
|
||||
gap=STATUS_METRIC_GAP,
|
||||
style=MAPS_PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
label_top_offset=0,
|
||||
value_top_offset=14,
|
||||
divider_top_offset=2,
|
||||
@@ -361,7 +361,7 @@ class MapBrowserCard(Widget):
|
||||
hovered=hovered,
|
||||
pressed=pressed,
|
||||
title_size=28,
|
||||
style=MAPS_PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _row_height(self, count: int, row_height: float) -> float:
|
||||
@@ -402,7 +402,7 @@ class MapBrowserCard(Widget):
|
||||
title_size=24,
|
||||
subtitle_size=17,
|
||||
show_underline=True,
|
||||
style=MAPS_PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _render_empty_state(self, rect: rl.Rectangle, title: str, body: str):
|
||||
@@ -416,7 +416,7 @@ class MapBrowserCard(Widget):
|
||||
title_top_padding=24,
|
||||
body_height=48,
|
||||
border=rl.Color(255, 255, 255, 10),
|
||||
style=MAPS_PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _render_region_rows(self, rect: rl.Rectangle, regions: list[dict]):
|
||||
@@ -451,9 +451,9 @@ class MapBrowserCard(Widget):
|
||||
action_pill_width=132 if selected else 108,
|
||||
title_size=34,
|
||||
subtitle_size=22,
|
||||
row_separator=MAPS_PANEL_STYLE.divider_color,
|
||||
current_bg=MAPS_PANEL_STYLE.current_fill,
|
||||
current_border=MAPS_PANEL_STYLE.current_border,
|
||||
row_separator=PANEL_STYLE.divider_color,
|
||||
current_bg=PANEL_STYLE.current_fill,
|
||||
current_border=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.HEADER,
|
||||
@@ -463,7 +463,7 @@ class MapBrowserCard(Widget):
|
||||
return self._controller._browse_regions_for_active_group()
|
||||
|
||||
def _render_section_header(self, rect: rl.Rectangle, title: str, *, count_text: str | None = None):
|
||||
draw_section_header(rect, title, trailing_text=count_text or "", title_size=28, trailing_size=22, style=MAPS_PANEL_STYLE)
|
||||
draw_section_header(rect, title, trailing_text=count_text or "", title_size=28, trailing_size=22, style=PANEL_STYLE)
|
||||
|
||||
def _measure_height(self, width: float) -> float:
|
||||
if self._controller._showing_source_picker():
|
||||
@@ -481,7 +481,7 @@ class MapBrowserCard(Widget):
|
||||
self.set_rect(rect)
|
||||
if not self._touch_valid():
|
||||
self._pressed_target = None
|
||||
draw_soft_card(rect, MAPS_PANEL_STYLE.surface_fill, MAPS_PANEL_STYLE.surface_border)
|
||||
draw_soft_card(rect, PANEL_STYLE.surface_fill, PANEL_STYLE.surface_border)
|
||||
self._source_rects.clear()
|
||||
self._context_tab_rects.clear()
|
||||
self._region_row_rects.clear()
|
||||
@@ -1130,7 +1130,7 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, MAPS_PANEL_STYLE, MAPS_METRICS)
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, PANEL_STYLE, MAPS_METRICS)
|
||||
|
||||
hdr = frame.header
|
||||
draw_settings_panel_header(hdr, tr("Map Data"), tr("Use offline maps for speed-limit control and keep only the regions you need."),
|
||||
|
||||
@@ -12,7 +12,7 @@ import pyray as rl
|
||||
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, MouseEvent, MousePos
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.lib.scroll_panel2 import GuiScrollPanel2
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.widgets import DialogResult, Widget
|
||||
@@ -65,17 +65,25 @@ EXCLUDED_KEYS = {
|
||||
}
|
||||
|
||||
REPORT_CATEGORIES = [
|
||||
"Acceleration feels harsh or jerky",
|
||||
"An alert was unclear and I'm not sure what it meant",
|
||||
"Braking is too sudden or uncomfortable",
|
||||
"I'm not sure if this is normal or a bug:",
|
||||
"My steering wheel buttons aren't working",
|
||||
"openpilot disengages when I don't expect it",
|
||||
"openpilot feels sluggish or slow to respond",
|
||||
"Something else (please describe)",
|
||||
tr_noop("Acceleration feels harsh or jerky"),
|
||||
tr_noop("An alert was unclear and I'm not sure what it meant"),
|
||||
tr_noop("Braking is too sudden or uncomfortable"),
|
||||
tr_noop("I'm not sure if this is normal or a bug:"),
|
||||
tr_noop("My steering wheel buttons aren't working"),
|
||||
tr_noop("openpilot disengages when I don't expect it"),
|
||||
tr_noop("openpilot feels sluggish or slow to respond"),
|
||||
tr_noop("Something else (please describe)"),
|
||||
]
|
||||
|
||||
|
||||
SECTION_GAP = AETHER_LIST_METRICS.section_gap
|
||||
SECTION_HEADER_HEIGHT = AETHER_LIST_METRICS.section_header_height
|
||||
SECTION_HEADER_GAP = AETHER_LIST_METRICS.section_header_gap
|
||||
ROW_HEIGHT = AETHER_LIST_METRICS.row_height
|
||||
FADE_HEIGHT = AETHER_LIST_METRICS.fade_height
|
||||
PANEL_STYLE = DEFAULT_PANEL_STYLE
|
||||
|
||||
|
||||
class SystemSettingsManagerView(Widget):
|
||||
HEADER_SUBTITLE_HEIGHT = 24
|
||||
HEADER_SUMMARY_GAP = 12
|
||||
@@ -83,18 +91,11 @@ class SystemSettingsManagerView(Widget):
|
||||
TAB_HEIGHT = 56
|
||||
TAB_GAP = 10
|
||||
TAB_BOTTOM_GAP = 18
|
||||
SECTION_GAP = AETHER_LIST_METRICS.section_gap
|
||||
SECTION_HEADER_HEIGHT = AETHER_LIST_METRICS.section_header_height
|
||||
SECTION_HEADER_GAP = AETHER_LIST_METRICS.section_header_gap
|
||||
ROW_HEIGHT = AETHER_LIST_METRICS.row_height
|
||||
FADE_HEIGHT = AETHER_LIST_METRICS.fade_height
|
||||
COLUMN_GAP = 22
|
||||
TWO_COLUMN_BREAKPOINT = 1180
|
||||
ACTION_PILL_WIDTH = 132
|
||||
DANGER_PILL_WIDTH = 112
|
||||
|
||||
PANEL_STYLE = DEFAULT_PANEL_STYLE
|
||||
|
||||
def __init__(self, controller: "StarPilotSystemLayout"):
|
||||
super().__init__()
|
||||
self._controller = controller
|
||||
@@ -216,8 +217,8 @@ class SystemSettingsManagerView(Widget):
|
||||
presets=spec.get("presets", []),
|
||||
is_active=lambda key=key: self._active_adjustor_key == key,
|
||||
set_active=lambda active, key=key: self._set_active_adjustor(key, active),
|
||||
style=self.PANEL_STYLE,
|
||||
color=self.PANEL_STYLE.accent,
|
||||
style=PANEL_STYLE,
|
||||
color=PANEL_STYLE.accent,
|
||||
)
|
||||
)
|
||||
adjustor.set_touch_valid_callback(lambda adjustor=adjustor: self._scroll_panel.is_touch_valid() or adjustor.is_interacting)
|
||||
@@ -361,7 +362,7 @@ class SystemSettingsManagerView(Widget):
|
||||
def _stacked_section_height(self, sections: list[float]) -> float:
|
||||
if not sections:
|
||||
return 0.0
|
||||
return max(0.0, sum(sections) - self.SECTION_GAP)
|
||||
return sum(sections) + SECTION_GAP * (len(sections) - 1)
|
||||
|
||||
def _uses_two_columns(self, width: float) -> bool:
|
||||
return width >= self.TWO_COLUMN_BREAKPOINT
|
||||
@@ -490,7 +491,7 @@ class SystemSettingsManagerView(Widget):
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, self.PANEL_STYLE)
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, PANEL_STYLE)
|
||||
self._scroll_rect = scroll_rect
|
||||
|
||||
self._drive_mode_control.set_parent_rect(frame.header)
|
||||
@@ -507,7 +508,7 @@ class SystemSettingsManagerView(Widget):
|
||||
if self._content_height > scroll_rect.height:
|
||||
self._scrollbar.render(scroll_rect, self._content_height, self._scroll_offset)
|
||||
|
||||
draw_list_scroll_fades(scroll_rect, self._content_height, self._scroll_offset, AetherListColors.PANEL_BG, fade_height=self.FADE_HEIGHT)
|
||||
draw_list_scroll_fades(scroll_rect, self._content_height, self._scroll_offset, AetherListColors.PANEL_BG, fade_height=FADE_HEIGHT)
|
||||
|
||||
def _draw_header(self, rect: rl.Rectangle):
|
||||
draw_settings_panel_header(rect, tr("System Settings"),
|
||||
@@ -519,7 +520,7 @@ class SystemSettingsManagerView(Widget):
|
||||
self._draw_summary_card(summary_rect)
|
||||
|
||||
def _draw_summary_card(self, rect: rl.Rectangle):
|
||||
draw_soft_card(rect, self.PANEL_STYLE.surface_fill, self.PANEL_STYLE.surface_border)
|
||||
draw_soft_card(rect, PANEL_STYLE.surface_fill, PANEL_STYLE.surface_border)
|
||||
inset = 18
|
||||
left_x = rect.x + inset
|
||||
left_w = rect.width * 0.40
|
||||
@@ -560,7 +561,7 @@ class SystemSettingsManagerView(Widget):
|
||||
def _measure_active_tab_height(self, width: float) -> float:
|
||||
display_h = self._section_block_height(self._slider_section_height(self._display_slider_keys, width))
|
||||
power_h = self._section_block_height(self._slider_section_height(self._power_slider_keys, width))
|
||||
backups_h = self._section_block_height(self._section_height(2, self.ROW_HEIGHT))
|
||||
backups_h = self._section_block_height(self._section_height(2, ROW_HEIGHT))
|
||||
maintenance_h = self._section_block_height(self._maintenance_section_content_height())
|
||||
if self._active_tab_key == "basics":
|
||||
if self._uses_two_columns(width):
|
||||
@@ -568,7 +569,7 @@ class SystemSettingsManagerView(Widget):
|
||||
return self._stacked_section_height([display_h, power_h])
|
||||
|
||||
if self._active_tab_key == "connectivity":
|
||||
group_heights = [self._section_block_height(self._section_height(len(self._toggle_defs_for_group(group)), self.ROW_HEIGHT)) for group in self._toggle_groups]
|
||||
group_heights = [self._section_block_height(self._section_height(len(self._toggle_defs_for_group(group)), ROW_HEIGHT)) for group in self._toggle_groups]
|
||||
if self._uses_two_columns(width):
|
||||
return max(group_heights)
|
||||
return self._stacked_section_height(group_heights)
|
||||
@@ -578,7 +579,7 @@ class SystemSettingsManagerView(Widget):
|
||||
return self._stacked_section_height([backups_h, maintenance_h])
|
||||
|
||||
def _section_block_height(self, content_height: float) -> float:
|
||||
return self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP + content_height + self.SECTION_GAP
|
||||
return SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP + content_height
|
||||
|
||||
def _slider_section_height(self, keys: list[str], width: float) -> float:
|
||||
total = 0.0
|
||||
@@ -588,8 +589,8 @@ class SystemSettingsManagerView(Widget):
|
||||
return total
|
||||
|
||||
def _maintenance_section_content_height(self) -> float:
|
||||
support_h = self._section_height(len(self._support_rows), self.ROW_HEIGHT)
|
||||
danger_h = self._section_height(len(self._danger_rows), self.ROW_HEIGHT)
|
||||
support_h = self._section_height(len(self._support_rows), ROW_HEIGHT)
|
||||
danger_h = self._section_height(len(self._danger_rows), ROW_HEIGHT)
|
||||
return support_h + 12 + 30 + danger_h
|
||||
|
||||
def _draw_scroll_content(self, rect: rl.Rectangle, width: float):
|
||||
@@ -624,7 +625,7 @@ class SystemSettingsManagerView(Widget):
|
||||
title_size=26,
|
||||
subtitle_size=17,
|
||||
show_underline=True,
|
||||
style=self.PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _draw_basics_tab(self, y: float, x: float, width: float):
|
||||
@@ -634,6 +635,7 @@ class SystemSettingsManagerView(Widget):
|
||||
self._draw_slider_section(y, x + column_w + self.COLUMN_GAP, column_w, tr("Power"), self._power_slider_keys)
|
||||
return
|
||||
y = self._draw_slider_section(y, x, width, tr("Display"), self._display_slider_keys)
|
||||
y += SECTION_GAP
|
||||
self._draw_slider_section(y, x, width, tr("Power"), self._power_slider_keys)
|
||||
|
||||
def _draw_connectivity_tab(self, y: float, x: float, width: float):
|
||||
@@ -643,8 +645,10 @@ class SystemSettingsManagerView(Widget):
|
||||
self._draw_toggle_group_section(y, x + column_w + self.COLUMN_GAP, column_w, self._toggle_groups[1])
|
||||
return
|
||||
current_y = y
|
||||
for group in self._toggle_groups:
|
||||
for i, group in enumerate(self._toggle_groups):
|
||||
current_y = self._draw_toggle_group_section(current_y, x, width, group)
|
||||
if i < len(self._toggle_groups) - 1:
|
||||
current_y += SECTION_GAP
|
||||
|
||||
def _draw_care_tab(self, y: float, x: float, width: float):
|
||||
if self._uses_two_columns(width):
|
||||
@@ -653,17 +657,18 @@ class SystemSettingsManagerView(Widget):
|
||||
self._draw_maintenance_section(y, x + column_w + self.COLUMN_GAP, column_w)
|
||||
return
|
||||
y = self._draw_backups_section(y, x, width)
|
||||
y += SECTION_GAP
|
||||
self._draw_maintenance_section(y, x, width)
|
||||
|
||||
def _draw_slider_section(self, y: float, x: float, width: float, title: str, keys: list[str]) -> float:
|
||||
draw_section_header(rl.Rectangle(x, y, width, self.SECTION_HEADER_HEIGHT), title, style=self.PANEL_STYLE)
|
||||
y += self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP
|
||||
draw_section_header(rl.Rectangle(x, y, width, SECTION_HEADER_HEIGHT), title, style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
group_rect = rl.Rectangle(x, y, width, self._slider_section_height(keys, width))
|
||||
draw_list_group_shell(group_rect)
|
||||
draw_list_group_shell(group_rect, style=PANEL_STYLE)
|
||||
current_y = group_rect.y
|
||||
for index, key in enumerate(keys):
|
||||
current_y = self._draw_slider_row(rl.Rectangle(group_rect.x, current_y, group_rect.width, 0), key, is_last=index == len(keys) - 1)
|
||||
return y + group_rect.height + self.SECTION_GAP
|
||||
return y + group_rect.height
|
||||
|
||||
def _draw_slider_row(self, rect: rl.Rectangle, key: str, is_last: bool) -> float:
|
||||
adjustor = self._adjustor_rows[key]
|
||||
@@ -687,13 +692,13 @@ class SystemSettingsManagerView(Widget):
|
||||
def _draw_toggle_group_section(self, y: float, x: float, width: float, group: dict) -> float:
|
||||
toggles = self._toggle_defs_for_group(group)
|
||||
trailing_text = tr("{} toggles").format(len(toggles))
|
||||
draw_section_header(rl.Rectangle(x, y, width, self.SECTION_HEADER_HEIGHT), group["title"], trailing_text=trailing_text, style=self.PANEL_STYLE)
|
||||
y += self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP
|
||||
toggle_rect = rl.Rectangle(x, y, width, self._section_height(len(toggles), self.ROW_HEIGHT))
|
||||
draw_list_group_shell(toggle_rect)
|
||||
draw_section_header(rl.Rectangle(x, y, width, SECTION_HEADER_HEIGHT), group["title"], trailing_text=trailing_text, style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
toggle_rect = rl.Rectangle(x, y, width, self._section_height(len(toggles), ROW_HEIGHT))
|
||||
draw_list_group_shell(toggle_rect, style=PANEL_STYLE)
|
||||
for index, toggle_def in enumerate(toggles):
|
||||
self._draw_toggle_row(rl.Rectangle(toggle_rect.x, toggle_rect.y + index * self.ROW_HEIGHT, toggle_rect.width, self.ROW_HEIGHT), toggle_def, is_last=index == len(toggles) - 1)
|
||||
return y + toggle_rect.height + self.SECTION_GAP
|
||||
self._draw_toggle_row(rl.Rectangle(toggle_rect.x, toggle_rect.y + index * ROW_HEIGHT, toggle_rect.width, ROW_HEIGHT), toggle_def, is_last=index == len(toggles) - 1)
|
||||
return y + toggle_rect.height
|
||||
|
||||
def _draw_toggle_row(self, rect: rl.Rectangle, toggle_def: dict, is_last: bool):
|
||||
target_id = f"toggle:{toggle_def['id']}"
|
||||
@@ -712,18 +717,18 @@ class SystemSettingsManagerView(Widget):
|
||||
show_chevron=False,
|
||||
title_size=34,
|
||||
subtitle_size=22,
|
||||
style=self.PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _draw_backups_section(self, y: float, x: float, width: float) -> float:
|
||||
draw_section_header(rl.Rectangle(x, y, width, self.SECTION_HEADER_HEIGHT), tr("Backups"), trailing_text=self._controller.backup_status_text(), style=self.PANEL_STYLE)
|
||||
y += self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP
|
||||
draw_section_header(rl.Rectangle(x, y, width, SECTION_HEADER_HEIGHT), tr("Backups"), trailing_text=self._controller.backup_status_text(), style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
summary_rect = rl.Rectangle(x, y, width, self.ROW_HEIGHT * 2)
|
||||
draw_list_group_shell(summary_rect)
|
||||
self._draw_backup_manager_row(rl.Rectangle(summary_rect.x, summary_rect.y, summary_rect.width, self.ROW_HEIGHT), "system", is_last=False)
|
||||
self._draw_backup_manager_row(rl.Rectangle(summary_rect.x, summary_rect.y + self.ROW_HEIGHT, summary_rect.width, self.ROW_HEIGHT), "toggle", is_last=True)
|
||||
return y + summary_rect.height + self.SECTION_GAP
|
||||
summary_rect = rl.Rectangle(x, y, width, ROW_HEIGHT * 2)
|
||||
draw_list_group_shell(summary_rect, style=PANEL_STYLE)
|
||||
self._draw_backup_manager_row(rl.Rectangle(summary_rect.x, summary_rect.y, summary_rect.width, ROW_HEIGHT), "system", is_last=False)
|
||||
self._draw_backup_manager_row(rl.Rectangle(summary_rect.x, summary_rect.y + ROW_HEIGHT, summary_rect.width, ROW_HEIGHT), "toggle", is_last=True)
|
||||
return y + summary_rect.height
|
||||
|
||||
def _draw_backup_manager_row(self, rect: rl.Rectangle, backup_kind: str, is_last: bool):
|
||||
target_id = f"backup:{backup_kind}"
|
||||
@@ -752,20 +757,20 @@ class SystemSettingsManagerView(Widget):
|
||||
title_size=34,
|
||||
subtitle_size=22,
|
||||
action_text_size=18,
|
||||
row_separator=self.PANEL_STYLE.divider_color,
|
||||
row_separator=PANEL_STYLE.divider_color,
|
||||
action_fill=AetherListColors.CURRENT_BG,
|
||||
action_border=rl.Color(89, 116, 151, 42),
|
||||
action_text_color=AetherListColors.HEADER,
|
||||
)
|
||||
|
||||
def _draw_maintenance_section(self, y: float, x: float, width: float):
|
||||
draw_section_header(rl.Rectangle(x, y, width, self.SECTION_HEADER_HEIGHT), tr("Support & Maintenance"), style=self.PANEL_STYLE)
|
||||
y += self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP
|
||||
draw_section_header(rl.Rectangle(x, y, width, SECTION_HEADER_HEIGHT), tr("Support & Maintenance"), style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
support_rect = rl.Rectangle(x, y, width, self._section_height(len(self._support_rows), self.ROW_HEIGHT))
|
||||
draw_list_group_shell(support_rect)
|
||||
support_rect = rl.Rectangle(x, y, width, self._section_height(len(self._support_rows), ROW_HEIGHT))
|
||||
draw_list_group_shell(support_rect, style=PANEL_STYLE)
|
||||
for index, row in enumerate(self._support_rows):
|
||||
row_rect = rl.Rectangle(support_rect.x, support_rect.y + index * self.ROW_HEIGHT, support_rect.width, self.ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(support_rect.x, support_rect.y + index * ROW_HEIGHT, support_rect.width, ROW_HEIGHT)
|
||||
self._draw_action_row(row_rect, row, is_last=index == len(self._support_rows) - 1)
|
||||
y += support_rect.height + 12
|
||||
|
||||
@@ -773,10 +778,10 @@ class SystemSettingsManagerView(Widget):
|
||||
gui_label(danger_title_rect, tr("Danger Zone"), 20, AetherListColors.DANGER, FontWeight.MEDIUM)
|
||||
y += 30
|
||||
|
||||
danger_rect = rl.Rectangle(x, y, width, self._section_height(len(self._danger_rows), self.ROW_HEIGHT))
|
||||
draw_list_group_shell(danger_rect, fill=rl.Color(173, 78, 90, 10), border=rl.Color(173, 78, 90, 30))
|
||||
danger_rect = rl.Rectangle(x, y, width, self._section_height(len(self._danger_rows), ROW_HEIGHT))
|
||||
draw_list_group_shell(danger_rect, fill=rl.Color(173, 78, 90, 10), border=rl.Color(173, 78, 90, 30), style=PANEL_STYLE)
|
||||
for index, row in enumerate(self._danger_rows):
|
||||
row_rect = rl.Rectangle(danger_rect.x, danger_rect.y + index * self.ROW_HEIGHT, danger_rect.width, self.ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(danger_rect.x, danger_rect.y + index * ROW_HEIGHT, danger_rect.width, ROW_HEIGHT)
|
||||
self._draw_action_row(row_rect, row, is_last=index == len(self._danger_rows) - 1, danger=True)
|
||||
|
||||
def _draw_action_row(self, rect: rl.Rectangle, row: dict, is_last: bool, *, danger: bool = False):
|
||||
@@ -800,7 +805,7 @@ class SystemSettingsManagerView(Widget):
|
||||
title_size=34,
|
||||
subtitle_size=22,
|
||||
action_text_size=18,
|
||||
row_separator=self.PANEL_STYLE.divider_color,
|
||||
row_separator=PANEL_STYLE.divider_color,
|
||||
action_fill=action_fill,
|
||||
action_border=action_border,
|
||||
action_text_color=action_text_color,
|
||||
|
||||
@@ -10,7 +10,7 @@ from openpilot.system.ui.widgets import DialogResult, Widget
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.label import gui_label
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPage
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AETHER_LIST_METRICS,
|
||||
AetherListColors,
|
||||
@@ -38,15 +38,15 @@ from openpilot.selfdrive.ui.mici.layouts.settings.fingerprint_catalog import (
|
||||
|
||||
|
||||
ACTION_OPTIONS = [
|
||||
{"id": 0, "name": "No Action"},
|
||||
{"id": 1, "name": "Change Personality", "requires_longitudinal": True},
|
||||
{"id": 2, "name": "Force Coast", "requires_longitudinal": True},
|
||||
{"id": 3, "name": "Pause Steering"},
|
||||
{"id": 4, "name": "Pause Accel/Brake", "requires_longitudinal": True},
|
||||
{"id": 5, "name": "Toggle Experimental", "requires_longitudinal": True},
|
||||
{"id": 6, "name": "Toggle Traffic", "requires_longitudinal": True},
|
||||
{"id": 7, "name": "Toggle Switchback"},
|
||||
{"id": 8, "name": "Create Bookmark"},
|
||||
{"id": 0, "name": tr_noop("No Action")},
|
||||
{"id": 1, "name": tr_noop("Change Personality"), "requires_longitudinal": True},
|
||||
{"id": 2, "name": tr_noop("Force Coast"), "requires_longitudinal": True},
|
||||
{"id": 3, "name": tr_noop("Pause Steering")},
|
||||
{"id": 4, "name": tr_noop("Pause Accel/Brake"), "requires_longitudinal": True},
|
||||
{"id": 5, "name": tr_noop("Toggle Experimental"), "requires_longitudinal": True},
|
||||
{"id": 6, "name": tr_noop("Toggle Traffic"), "requires_longitudinal": True},
|
||||
{"id": 7, "name": tr_noop("Toggle Switchback")},
|
||||
{"id": 8, "name": tr_noop("Create Bookmark")},
|
||||
]
|
||||
ACTION_NAMES = [o["name"] for o in ACTION_OPTIONS]
|
||||
ACTION_IDS = {o["name"]: o["id"] for o in ACTION_OPTIONS}
|
||||
@@ -60,6 +60,14 @@ def _lock_doors_timer_labels():
|
||||
return labels
|
||||
|
||||
|
||||
SECTION_GAP = AETHER_LIST_METRICS.section_gap
|
||||
SECTION_HEADER_HEIGHT = AETHER_LIST_METRICS.section_header_height
|
||||
SECTION_HEADER_GAP = AETHER_LIST_METRICS.section_header_gap
|
||||
ROW_HEIGHT = AETHER_LIST_METRICS.row_height
|
||||
FADE_HEIGHT = AETHER_LIST_METRICS.fade_height
|
||||
PANEL_STYLE = DEFAULT_PANEL_STYLE
|
||||
|
||||
|
||||
class VehicleSettingsManagerView(Widget):
|
||||
HEADER_SUBTITLE_HEIGHT = 24
|
||||
HEADER_SUMMARY_GAP = 12
|
||||
@@ -67,15 +75,8 @@ class VehicleSettingsManagerView(Widget):
|
||||
TAB_HEIGHT = 56
|
||||
TAB_GAP = 10
|
||||
TAB_BOTTOM_GAP = 18
|
||||
SECTION_GAP = AETHER_LIST_METRICS.section_gap
|
||||
SECTION_HEADER_HEIGHT = AETHER_LIST_METRICS.section_header_height
|
||||
SECTION_HEADER_GAP = AETHER_LIST_METRICS.section_header_gap
|
||||
ROW_HEIGHT = AETHER_LIST_METRICS.row_height
|
||||
FADE_HEIGHT = AETHER_LIST_METRICS.fade_height
|
||||
COLUMN_GAP = 22
|
||||
TWO_COLUMN_BREAKPOINT = 1180
|
||||
|
||||
PANEL_STYLE = DEFAULT_PANEL_STYLE
|
||||
COLUMN_GAP = 22
|
||||
|
||||
def __init__(self, controller: "StarPilotVehicleSettingsLayout"):
|
||||
super().__init__()
|
||||
@@ -109,12 +110,12 @@ class VehicleSettingsManagerView(Widget):
|
||||
def _section_block_height(self, content_height: float) -> float:
|
||||
if content_height <= 0:
|
||||
return 0.0
|
||||
return self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP + content_height + self.SECTION_GAP
|
||||
return SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP + content_height
|
||||
|
||||
def _stacked_section_height(self, sections: list[float]) -> float:
|
||||
if not sections:
|
||||
return 0.0
|
||||
return max(0.0, sum(sections) - self.SECTION_GAP)
|
||||
return max(0.0, sum(sections) - SECTION_GAP)
|
||||
|
||||
def _interactive_state(self, target_id: str, rect: rl.Rectangle, *, pad_y: float = 0) -> tuple[bool, bool]:
|
||||
self._interactive_rects[target_id] = rect
|
||||
@@ -194,9 +195,8 @@ class VehicleSettingsManagerView(Widget):
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
self._interactive_rects.clear()
|
||||
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, self.PANEL_STYLE)
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, PANEL_STYLE)
|
||||
self._shell_rect = frame.shell
|
||||
self._scroll_rect = scroll_rect
|
||||
|
||||
@@ -213,7 +213,7 @@ class VehicleSettingsManagerView(Widget):
|
||||
if self._content_height > scroll_rect.height:
|
||||
self._scrollbar.render(scroll_rect, self._content_height, self._scroll_offset)
|
||||
|
||||
draw_list_scroll_fades(scroll_rect, self._content_height, self._scroll_offset, AetherListColors.PANEL_BG, fade_height=self.FADE_HEIGHT)
|
||||
draw_list_scroll_fades(scroll_rect, self._content_height, self._scroll_offset, AetherListColors.PANEL_BG, fade_height=FADE_HEIGHT)
|
||||
|
||||
def _draw_header(self, rect: rl.Rectangle):
|
||||
draw_settings_panel_header(rect, tr("Vehicle Settings"),
|
||||
@@ -225,7 +225,7 @@ class VehicleSettingsManagerView(Widget):
|
||||
self._draw_summary_card(summary_rect)
|
||||
|
||||
def _draw_summary_card(self, rect: rl.Rectangle):
|
||||
draw_soft_card(rect, self.PANEL_STYLE.surface_fill, self.PANEL_STYLE.surface_border)
|
||||
draw_soft_card(rect, PANEL_STYLE.surface_fill, PANEL_STYLE.surface_border)
|
||||
inset = 18
|
||||
left_x = rect.x + inset
|
||||
left_w = rect.width * 0.40
|
||||
@@ -252,7 +252,7 @@ class VehicleSettingsManagerView(Widget):
|
||||
draw_metric_strip(
|
||||
rl.Rectangle(left_x, rect.y + 72, max(240.0, rect.width * 0.38), 30),
|
||||
metrics,
|
||||
style=self.PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
label_top_offset=0,
|
||||
value_top_offset=14,
|
||||
divider_top_offset=2,
|
||||
@@ -286,19 +286,19 @@ class VehicleSettingsManagerView(Widget):
|
||||
|
||||
def _measure_active_tab_height(self, width: float) -> float:
|
||||
if self._active_tab_key == "identity":
|
||||
return self._section_block_height(self._section_height(3, self.ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(3, ROW_HEIGHT))
|
||||
if self._active_tab_key == "features":
|
||||
rows = self._build_driving_rows()
|
||||
if self._uses_two_columns(width):
|
||||
max_per_col = (len(rows) + 1) // 2
|
||||
return self._section_block_height(self._section_height(max_per_col, self.ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(len(rows), self.ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(max_per_col, ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(len(rows), ROW_HEIGHT))
|
||||
if self._active_tab_key == "controls":
|
||||
rows = self._build_steering_rows()
|
||||
if self._uses_two_columns(width):
|
||||
max_per_col = (len(rows) + 1) // 2
|
||||
return self._section_block_height(self._section_height(max_per_col, self.ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(len(rows), self.ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(max_per_col, ROW_HEIGHT))
|
||||
return self._section_block_height(self._section_height(len(rows), ROW_HEIGHT))
|
||||
return 0
|
||||
|
||||
def _draw_scroll_content(self, rect: rl.Rectangle, width: float):
|
||||
@@ -333,7 +333,7 @@ class VehicleSettingsManagerView(Widget):
|
||||
title_size=26,
|
||||
subtitle_size=17,
|
||||
show_underline=True,
|
||||
style=self.PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _draw_identity_tab(self, y: float, x: float, width: float):
|
||||
@@ -346,12 +346,12 @@ class VehicleSettingsManagerView(Widget):
|
||||
"subtitle": tr("Manually select vehicle instead of auto-detecting."),
|
||||
"get_state": lambda: self._controller._params.get_bool("ForceFingerprint")},
|
||||
]
|
||||
draw_section_header(rl.Rectangle(x, y, width, self.SECTION_HEADER_HEIGHT), tr("Vehicle Identity"), style=self.PANEL_STYLE)
|
||||
y += self.SECTION_HEADER_HEIGHT + self.SECTION_HEADER_GAP
|
||||
container_rect = rl.Rectangle(x, y, width, len(rows) * self.ROW_HEIGHT)
|
||||
draw_list_group_shell(container_rect)
|
||||
draw_section_header(rl.Rectangle(x, y, width, SECTION_HEADER_HEIGHT), tr("Vehicle Identity"), style=PANEL_STYLE)
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
container_rect = rl.Rectangle(x, y, width, len(rows) * ROW_HEIGHT)
|
||||
draw_list_group_shell(container_rect, style=PANEL_STYLE)
|
||||
for index, row in enumerate(rows):
|
||||
row_rect = rl.Rectangle(x, y + index * self.ROW_HEIGHT, width, self.ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(x, y + index * ROW_HEIGHT, width, ROW_HEIGHT)
|
||||
self._draw_row(row_rect, row, is_last=index == len(rows) - 1)
|
||||
|
||||
def _draw_features_tab(self, y: float, x: float, width: float):
|
||||
@@ -381,12 +381,12 @@ class VehicleSettingsManagerView(Widget):
|
||||
def _draw_row_group(self, y: float, x: float, width: float, rows: list[dict]):
|
||||
if not rows:
|
||||
return y
|
||||
container_rect = rl.Rectangle(x, y, width, len(rows) * self.ROW_HEIGHT)
|
||||
draw_list_group_shell(container_rect)
|
||||
container_rect = rl.Rectangle(x, y, width, len(rows) * ROW_HEIGHT)
|
||||
draw_list_group_shell(container_rect, style=PANEL_STYLE)
|
||||
for index, row in enumerate(rows):
|
||||
row_rect = rl.Rectangle(x, y + index * self.ROW_HEIGHT, width, self.ROW_HEIGHT)
|
||||
row_rect = rl.Rectangle(x, y + index * ROW_HEIGHT, width, ROW_HEIGHT)
|
||||
self._draw_row(row_rect, row, is_last=index == len(rows) - 1)
|
||||
return y + len(rows) * self.ROW_HEIGHT + self.SECTION_GAP
|
||||
return y + len(rows) * ROW_HEIGHT
|
||||
|
||||
def _draw_row(self, rect: rl.Rectangle, row: dict, is_last: bool):
|
||||
target_id = row["target_id"]
|
||||
@@ -398,7 +398,7 @@ class VehicleSettingsManagerView(Widget):
|
||||
rect, title=row["title"], subtitle=row.get("subtitle", ""),
|
||||
toggle_value=row["get_state"](), hovered=hovered, pressed=pressed,
|
||||
is_last=is_last, show_chevron=False, title_size=34, subtitle_size=22,
|
||||
style=self.PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
elif row_type == "select":
|
||||
draw_selection_list_row(
|
||||
@@ -407,9 +407,9 @@ class VehicleSettingsManagerView(Widget):
|
||||
is_last=is_last, action_width=188, action_pill=True,
|
||||
action_pill_width=row.get("pill_width", 108), action_pill_height=44,
|
||||
title_size=34, subtitle_size=22, action_text_size=18,
|
||||
row_separator=self.PANEL_STYLE.divider_color,
|
||||
action_fill=self.PANEL_STYLE.current_fill,
|
||||
action_border=self.PANEL_STYLE.current_border,
|
||||
row_separator=PANEL_STYLE.divider_color,
|
||||
action_fill=PANEL_STYLE.current_fill,
|
||||
action_border=PANEL_STYLE.current_border,
|
||||
action_text_color=AetherListColors.HEADER,
|
||||
)
|
||||
elif row_type == "info":
|
||||
@@ -417,7 +417,7 @@ class VehicleSettingsManagerView(Widget):
|
||||
rect, title=row["title"], value=row["get_value"](),
|
||||
hovered=False, pressed=False, is_last=is_last,
|
||||
show_chevron=False, title_size=34, subtitle_size=22,
|
||||
style=self.PANEL_STYLE,
|
||||
style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
def _build_driving_rows(self) -> list[dict]:
|
||||
@@ -498,22 +498,12 @@ class VehicleSettingsManagerView(Widget):
|
||||
return rows
|
||||
|
||||
|
||||
class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
class StarPilotVehicleSettingsLayout(_SettingsPage):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._make_options, self._models_by_make, self._models_by_value, self._make_by_model = get_fingerprint_catalog()
|
||||
self._manager_view = VehicleSettingsManagerView(self)
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self._manager_view.render(rect)
|
||||
|
||||
def show_event(self):
|
||||
super().show_event()
|
||||
self._manager_view.show_event()
|
||||
|
||||
def hide_event(self):
|
||||
super().hide_event()
|
||||
self._manager_view.hide_event()
|
||||
|
||||
def _action_title(self, key: str) -> str:
|
||||
titles = {
|
||||
@@ -534,15 +524,15 @@ class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
if key == "LKASButtonControl" and self._params.get_bool("RemapCancelToDistance"):
|
||||
if self._params.get_int("LKASButtonControl") != 0:
|
||||
self._params.put_int("LKASButtonControl", 0)
|
||||
return ACTION_NAME_BY_ID[0]
|
||||
return tr(ACTION_NAME_BY_ID[0])
|
||||
idx = self._params.get_int(key)
|
||||
return ACTION_NAME_BY_ID.get(idx, ACTION_NAMES[0])
|
||||
return tr(ACTION_NAME_BY_ID.get(idx, ACTION_NAMES[0]))
|
||||
|
||||
def _get_available_actions(self, key: str | None = None) -> list[str]:
|
||||
if key == "LKASButtonControl" and self._params.get_bool("RemapCancelToDistance"):
|
||||
return [ACTION_NAME_BY_ID[0]]
|
||||
return [tr(ACTION_NAME_BY_ID[0])]
|
||||
cs = starpilot_state.car_state
|
||||
return [o["name"] for o in ACTION_OPTIONS if cs.hasOpenpilotLongitudinal or not o.get("requires_longitudinal", False)]
|
||||
return [tr(o["name"]) for o in ACTION_OPTIONS if cs.hasOpenpilotLongitudinal or not o.get("requires_longitudinal", False)]
|
||||
|
||||
def _on_toggle(self, param_key: str):
|
||||
if param_key == "DisableOpenpilotLongitudinal":
|
||||
|
||||
Reference in New Issue
Block a user