mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-08 01:45:54 +08:00
BigUI WIP: Sound Panel Alignment
This commit is contained in:
@@ -227,7 +227,7 @@ class AetherListMetrics:
|
||||
toggle_right_inset: int = 34
|
||||
adjustor_row_height: int = 94
|
||||
adjustor_row_active_height: int = 154
|
||||
adjustor_preset_height: int = 30
|
||||
adjustor_preset_height: int = 44
|
||||
adjustor_preset_gap: int = 10
|
||||
adjustor_scrubber_height: int = 52
|
||||
adjustor_value_pill_height: int = 36
|
||||
@@ -1150,7 +1150,7 @@ class AetherInlineRangeControl(Widget):
|
||||
return
|
||||
|
||||
self._pending_drag = True
|
||||
self._started_on_thumb = rl.check_collision_point_rec(mouse_pos, _inflate_rect(self._thumb_rect, 8, 8))
|
||||
self._started_on_thumb = rl.check_collision_point_rec(mouse_pos, _inflate_rect(self._thumb_rect, 12, 12))
|
||||
self._press_start = rl.Vector2(mouse_pos.x, mouse_pos.y)
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
@@ -1269,7 +1269,7 @@ class AetherInlineRangeControl(Widget):
|
||||
fill_rect = _snap_rect(rl.Rectangle(self._track_rect.x, self._track_rect.y, fill_w, self._track_rect.height))
|
||||
rl.draw_rectangle_rounded(fill_rect, 1.0, 12, _with_alpha(self._color, 220))
|
||||
|
||||
thumb_w = 18 + self._thumb_focus * 4
|
||||
thumb_w = 22 + self._thumb_focus * 4
|
||||
thumb_h = 28 + self._thumb_focus * 4
|
||||
thumb_center_x = self._track_rect.x + fill_frac * self._track_rect.width
|
||||
thumb_center_y = rect.y + rect.height / 2
|
||||
@@ -1534,7 +1534,7 @@ class AetherAdjustorRow(Widget):
|
||||
self._preset_rects.clear()
|
||||
|
||||
if self._presets:
|
||||
chip_gap = 8.0
|
||||
chip_gap = 12.0
|
||||
chip_h = float(AETHER_LIST_METRICS.adjustor_preset_height)
|
||||
chip_w = max(68.0, (rect.width - 48 - chip_gap * (len(self._presets) - 1)) / max(1, len(self._presets)))
|
||||
chip_x = content_left
|
||||
@@ -2346,7 +2346,7 @@ class AetherTile(Widget):
|
||||
self,
|
||||
face: rl.Rectangle,
|
||||
*,
|
||||
icon: rl.Texture2D | None,
|
||||
icon: rl.Texture2D | None = None,
|
||||
title: str,
|
||||
primary: str,
|
||||
desc: str,
|
||||
@@ -3477,9 +3477,9 @@ class TileGrid(Widget):
|
||||
tile_idx += 1
|
||||
|
||||
|
||||
def draw_toggle_pill(rect: rl.Rectangle, is_on: bool, is_enabled: bool, title: str, status_str: str, hovered: bool, pressed: bool, style: PanelStyle = DEFAULT_PANEL_STYLE):
|
||||
def draw_toggle_pill(rect: rl.Rectangle, is_on: bool, is_enabled: bool, title: str, status_str: str, hovered: bool, pressed: bool, style: PanelStyle = DEFAULT_PANEL_STYLE, *, subtitle: str = ""):
|
||||
rect = _snap_rect(rect)
|
||||
bg_color = rl.Color(28, 32, 40, 170 if not is_enabled else 255)
|
||||
bg_color = rl.Color(28, 32, 40, 200 if not is_enabled else 255)
|
||||
accent = style.accent if is_on and is_enabled else rl.Color(255, 255, 255, 52 if is_enabled else 20)
|
||||
_draw_rounded_fill(rect, bg_color, radius_px=18)
|
||||
_draw_rounded_stroke(rect, _with_alpha(accent, 92 if is_on and is_enabled else accent.a), radius_px=18)
|
||||
@@ -3494,9 +3494,17 @@ def draw_toggle_pill(rect: rl.Rectangle, is_on: bool, is_enabled: bool, title: s
|
||||
font = gui_app.font(FontWeight.BOLD)
|
||||
title_size = max(16, min(22, int(rect.height * 0.26)))
|
||||
status_size = max(18, min(24, int(rect.height * 0.32)))
|
||||
title_y = rect.y + (rect.height - title_size) / 2
|
||||
rl.draw_text_ex(font, title, rl.Vector2(round(rect.x + 24), round(title_y)), title_size, 0, AetherListColors.SUBTEXT if is_enabled else AetherListColors.MUTED)
|
||||
|
||||
|
||||
if subtitle:
|
||||
title_y = rect.y + (rect.height - title_size - 18) / 2
|
||||
rl.draw_text_ex(font, title, rl.Vector2(round(rect.x + 24), round(title_y)), title_size, 0, AetherListColors.SUBTEXT if is_enabled else AetherListColors.MUTED)
|
||||
sub_font = gui_app.font(FontWeight.NORMAL)
|
||||
sub_size = max(12, min(16, int(rect.height * 0.18)))
|
||||
rl.draw_text_ex(sub_font, subtitle, rl.Vector2(round(rect.x + 24), round(title_y + title_size + 2)), sub_size, 0, AetherListColors.MUTED)
|
||||
else:
|
||||
title_y = rect.y + (rect.height - title_size) / 2
|
||||
rl.draw_text_ex(font, title, rl.Vector2(round(rect.x + 24), round(title_y)), title_size, 0, AetherListColors.SUBTEXT if is_enabled else AetherListColors.MUTED)
|
||||
|
||||
ts = measure_text_cached(font, status_str, status_size)
|
||||
status_x = rect.x + rect.width - ts.x - 24
|
||||
rl.draw_text_ex(font, status_str, rl.Vector2(round(status_x), round(rect.y + (rect.height - ts.y) / 2)), status_size, 0, AetherListColors.HEADER if is_enabled else AetherListColors.MUTED)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from __future__ import annotations
|
||||
from dataclasses import replace
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
@@ -6,30 +7,49 @@ import pyray as rl
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.starpilot.common.starpilot_variables import ACTIVE_THEME_PATH
|
||||
from openpilot.system.ui.lib.application import gui_app, MouseEvent, MousePos
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight, MouseEvent, MousePos
|
||||
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.lib.scroll_panel2 import GuiScrollPanel2
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.widgets.label import gui_label
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPage
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AETHER_LIST_METRICS,
|
||||
COMPACT_PANEL_METRICS,
|
||||
AetherAdjustorRow,
|
||||
AetherListColors,
|
||||
AetherScrollbar,
|
||||
TileGrid,
|
||||
ToggleTile,
|
||||
panel_style_from_color,
|
||||
_point_hits,
|
||||
draw_action_pill,
|
||||
draw_list_group_shell,
|
||||
draw_list_scroll_fades,
|
||||
draw_section_header,
|
||||
draw_settings_panel_header,
|
||||
draw_toggle_pill,
|
||||
init_list_panel,
|
||||
)
|
||||
|
||||
PANEL_STYLE = panel_style_from_color("#E63956")
|
||||
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
|
||||
|
||||
GROUP_HEADER_HEIGHT = 20
|
||||
GROUP_HEADER_GAP = 4
|
||||
GROUP_HAIRLINE_COLOR = rl.Color(255, 255, 255, 10)
|
||||
GROUP_HEADER_COLOR = rl.Color(255, 255, 255, 90)
|
||||
|
||||
SOUNDS_PANEL_METRICS = replace(
|
||||
COMPACT_PANEL_METRICS,
|
||||
outer_margin_y=14,
|
||||
panel_padding_top=16,
|
||||
panel_padding_bottom=14,
|
||||
header_height=88,
|
||||
)
|
||||
|
||||
|
||||
class SoundsManagerView(Widget):
|
||||
@@ -39,17 +59,19 @@ class SoundsManagerView(Widget):
|
||||
self._pressed_target: str | None = None
|
||||
self._adjustor_rows: dict[str, AetherAdjustorRow] = {}
|
||||
self._was_interacting: dict[str, bool] = {}
|
||||
self._toggle_rects: dict[str, rl.Rectangle] = {}
|
||||
self._active_adjustor_key: str | None = None
|
||||
self._can_click = True
|
||||
self._reset_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
|
||||
self._scroll_panel = GuiScrollPanel2(horizontal=False)
|
||||
self._scrollbar = AetherScrollbar()
|
||||
self._content_height = 0.0
|
||||
self._scroll_offset = 0.0
|
||||
self._scroll_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._tile_grid_h = 0.0
|
||||
|
||||
self._init_adjustors()
|
||||
self._init_toggles()
|
||||
self._forward_touch_valid()
|
||||
|
||||
def _forward_touch_valid(self):
|
||||
@@ -57,6 +79,25 @@ class SoundsManagerView(Widget):
|
||||
adjustor.set_touch_valid_callback(
|
||||
lambda: self._scroll_panel.is_touch_valid() or adjustor.is_interacting
|
||||
)
|
||||
self._toggle_grid.set_touch_valid_callback(
|
||||
lambda: self._scroll_panel.is_touch_valid()
|
||||
)
|
||||
|
||||
def _init_toggles(self):
|
||||
self._toggle_grid = TileGrid(columns=2, padding=12)
|
||||
for key in self._controller.CUSTOM_ALERTS_KEYS:
|
||||
info = self._controller.ALERT_INFO[key]
|
||||
tile = ToggleTile(
|
||||
title=tr(info["title"]),
|
||||
get_state=lambda k=key: self._controller._params.get_bool(k),
|
||||
set_state=lambda state, k=key: self._controller._params.put_bool(k, state),
|
||||
bg_color=PANEL_STYLE.accent,
|
||||
desc=tr(info.get("subtitle", "")),
|
||||
is_enabled=info.get("is_enabled"),
|
||||
disabled_label=tr(info.get("disabled_label", "")) if info.get("disabled_label") else "",
|
||||
)
|
||||
self._toggle_grid.add_tile(tile)
|
||||
self._child(self._toggle_grid)
|
||||
|
||||
def _set_active_adjustor(self, key: str, active: bool):
|
||||
if active:
|
||||
@@ -80,7 +121,7 @@ class SoundsManagerView(Widget):
|
||||
|
||||
adjustor = AetherAdjustorRow(
|
||||
tr(info["title"]),
|
||||
"",
|
||||
tr(info["subtitle"]),
|
||||
0.0, 101.0, 1.0,
|
||||
get_value=lambda k=key: float(self._controller._params.get_int(k, return_default=True, default=100)),
|
||||
on_change=on_change,
|
||||
@@ -96,13 +137,14 @@ class SoundsManagerView(Widget):
|
||||
self._adjustor_rows[key] = adjustor
|
||||
|
||||
cd_key = self._controller.COOLDOWN_KEY
|
||||
cd_info = self._controller.COOLDOWN_INFO
|
||||
def on_cd_commit(v):
|
||||
self._controller._params.put_int(cd_key, int(v))
|
||||
|
||||
cd_adjustor = AetherAdjustorRow(
|
||||
tr(self._controller.COOLDOWN_INFO["title"]),
|
||||
"",
|
||||
0.0, float(self._controller.COOLDOWN_INFO["max"]), 1.0,
|
||||
tr(cd_info["title"]),
|
||||
tr(cd_info["subtitle"]),
|
||||
0.0, float(cd_info["max"]), 1.0,
|
||||
get_value=lambda: float(self._controller._params.get_int(cd_key, return_default=True, default=0)),
|
||||
on_change=lambda _v: None,
|
||||
on_commit=on_cd_commit,
|
||||
@@ -121,10 +163,12 @@ class SoundsManagerView(Widget):
|
||||
self._can_click = True
|
||||
for adjustor in self._adjustor_rows.values():
|
||||
adjustor._handle_mouse_press(mouse_pos)
|
||||
self._toggle_grid._handle_mouse_press(mouse_pos)
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
for adjustor in self._adjustor_rows.values():
|
||||
adjustor._handle_mouse_release(mouse_pos)
|
||||
self._toggle_grid._handle_mouse_release(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:
|
||||
@@ -138,20 +182,16 @@ class SoundsManagerView(Widget):
|
||||
return
|
||||
for adjustor in self._adjustor_rows.values():
|
||||
adjustor._handle_mouse_event(mouse_event)
|
||||
self._toggle_grid._handle_mouse_event(mouse_event)
|
||||
|
||||
def _target_at(self, mouse_pos: MousePos) -> str | None:
|
||||
for key, rect in self._toggle_rects.items():
|
||||
if _point_hits(mouse_pos, rect, self._scroll_rect, pad_x=6, pad_y=0):
|
||||
return f"toggle:{key}"
|
||||
if _point_hits(mouse_pos, self._reset_rect, self._scroll_rect, pad_x=6, pad_y=0):
|
||||
return "action:restore_defaults"
|
||||
return None
|
||||
|
||||
def _activate_target(self, target: str):
|
||||
if target.startswith("toggle:"):
|
||||
key = target.split(":", 1)[1]
|
||||
info = self._controller.ALERT_INFO.get(key)
|
||||
if info and info.get("is_enabled", lambda: True)():
|
||||
current = self._controller._params.get_bool(key)
|
||||
self._controller._params.put_bool(key, not current)
|
||||
if target == "action:restore_defaults":
|
||||
self._controller._restore_defaults()
|
||||
|
||||
def show_event(self):
|
||||
super().show_event()
|
||||
@@ -165,9 +205,8 @@ class SoundsManagerView(Widget):
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
self._toggle_rects.clear()
|
||||
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, PANEL_STYLE)
|
||||
frame, scroll_rect, content_width = init_list_panel(rect, PANEL_STYLE, metrics=SOUNDS_PANEL_METRICS)
|
||||
self._scroll_rect = scroll_rect
|
||||
|
||||
self._draw_header(frame.header)
|
||||
@@ -206,26 +245,50 @@ class SoundsManagerView(Widget):
|
||||
left_h = 0.0
|
||||
for key in self._controller.VOLUME_KEYS:
|
||||
left_h += self._adjustor_rows[key].measure_height(col_width)
|
||||
right_h = self._adjustor_rows[self._controller.COOLDOWN_KEY].measure_height(col_width)
|
||||
right_h += AETHER_LIST_METRICS.utility_row_height * len(self._controller.CUSTOM_ALERTS_KEYS)
|
||||
return max(left_h, right_h)
|
||||
left_h += GROUP_HEADER_HEIGHT + GROUP_HEADER_GAP
|
||||
left_h += GROUP_HEADER_HEIGHT + GROUP_HEADER_GAP
|
||||
left_h += GROUP_HEADER_HEIGHT + GROUP_HEADER_GAP
|
||||
|
||||
cd_h = self._adjustor_rows[self._controller.COOLDOWN_KEY].measure_height(col_width)
|
||||
group_h = GROUP_HEADER_HEIGHT + GROUP_HEADER_GAP
|
||||
self._tile_grid_h = left_h - cd_h - group_h
|
||||
|
||||
right_h = cd_h + group_h + self._tile_grid_h
|
||||
|
||||
section_overhead = SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
return section_overhead + max(left_h, right_h) + 12.0
|
||||
|
||||
def _draw_header(self, rect: rl.Rectangle):
|
||||
draw_settings_panel_header(rect, tr("Sounds & Alerts"), tr("Manage system volumes and custom alert toggles."), subtitle_size=24)
|
||||
|
||||
btn_w = 120.0
|
||||
btn_h = 38.0
|
||||
btn_x = rect.x + rect.width - btn_w
|
||||
btn_y = rect.y + (rect.height - btn_h) / 2
|
||||
self._reset_rect = rl.Rectangle(btn_x, btn_y, btn_w, btn_h)
|
||||
|
||||
hovered = _point_hits(gui_app.last_mouse_event.pos, self._reset_rect, self._scroll_rect, pad_x=6, pad_y=0)
|
||||
pressed = self._pressed_target == "action:restore_defaults"
|
||||
draw_action_pill(
|
||||
self._reset_rect, tr("Reset All"),
|
||||
rl.Color(255, 255, 255, 8 if not pressed else 14),
|
||||
rl.Color(255, 255, 255, 18 if not pressed else 28),
|
||||
AetherListColors.SUBTEXT if not hovered else AetherListColors.HEADER,
|
||||
)
|
||||
|
||||
def _draw_scroll_content(self, rect: rl.Rectangle, content_width: float):
|
||||
y = rect.y + self._scroll_offset
|
||||
col_width = (content_width - SECTION_GAP) / 2
|
||||
|
||||
draw_section_header(
|
||||
rl.Rectangle(rect.x, y, col_width, AETHER_LIST_METRICS.section_header_height),
|
||||
rl.Rectangle(rect.x, y, col_width, SECTION_HEADER_HEIGHT),
|
||||
tr("Volume"), style=PANEL_STYLE
|
||||
)
|
||||
draw_section_header(
|
||||
rl.Rectangle(rect.x + col_width + SECTION_GAP, y, col_width, AETHER_LIST_METRICS.section_header_height),
|
||||
rl.Rectangle(rect.x + col_width + SECTION_GAP, y, col_width, SECTION_HEADER_HEIGHT),
|
||||
tr("Alerts"), style=PANEL_STYLE
|
||||
)
|
||||
y += AETHER_LIST_METRICS.section_header_height + AETHER_LIST_METRICS.section_header_gap
|
||||
y += SECTION_HEADER_HEIGHT + SECTION_HEADER_GAP
|
||||
|
||||
col_left = rl.Rectangle(rect.x, y, col_width, self._content_height)
|
||||
col_right = rl.Rectangle(rect.x + col_width + SECTION_GAP, y, col_width, self._content_height)
|
||||
@@ -233,16 +296,40 @@ class SoundsManagerView(Widget):
|
||||
self._draw_volume_column(col_left)
|
||||
self._draw_utility_column(col_right)
|
||||
|
||||
def _draw_group_header(self, x: float, y: float, width: float, label: str) -> float:
|
||||
gui_label(rl.Rectangle(x, y, width, GROUP_HEADER_HEIGHT), label, 14, GROUP_HEADER_COLOR, FontWeight.MEDIUM)
|
||||
y += GROUP_HEADER_HEIGHT
|
||||
rl.draw_line(int(x), int(y), int(x + width), int(y), GROUP_HAIRLINE_COLOR)
|
||||
return y + GROUP_HEADER_GAP
|
||||
|
||||
def _draw_volume_column(self, rect: rl.Rectangle):
|
||||
safety_keys = ["WarningImmediateVolume", "WarningSoftVolume", "RefuseVolume", "PromptDistractedVolume"]
|
||||
system_keys = ["EngageVolume", "DisengageVolume"]
|
||||
info_keys = ["PromptVolume", "BelowSteerSpeedVolume"]
|
||||
|
||||
groups = [
|
||||
(tr("SAFETY ALERTS"), safety_keys),
|
||||
(tr("SYSTEM STATE"), system_keys),
|
||||
(tr("INFORMATIONAL"), info_keys),
|
||||
]
|
||||
|
||||
total_h = sum(GROUP_HEADER_HEIGHT + GROUP_HEADER_GAP + sum(self._adjustor_rows[k].measure_height(rect.width) for k in keys) for _, keys in groups)
|
||||
draw_list_group_shell(
|
||||
rl.Rectangle(rect.x - 12, rect.y - 12, rect.width + 24, total_h + 24),
|
||||
style=PANEL_STYLE
|
||||
)
|
||||
|
||||
current_y = rect.y
|
||||
for key in self._controller.VOLUME_KEYS:
|
||||
adjustor = self._adjustor_rows[key]
|
||||
row_h = adjustor.measure_height(rect.width)
|
||||
row_rect = rl.Rectangle(rect.x, current_y, rect.width, row_h)
|
||||
adjustor.set_is_last(True)
|
||||
adjustor.set_parent_rect(self._scroll_rect)
|
||||
adjustor.render(row_rect)
|
||||
current_y += row_h
|
||||
for label, keys in groups:
|
||||
current_y = self._draw_group_header(rect.x, current_y, rect.width, label)
|
||||
for key in keys:
|
||||
adjustor = self._adjustor_rows[key]
|
||||
row_h = adjustor.measure_height(rect.width)
|
||||
row_rect = rl.Rectangle(rect.x, current_y, rect.width, row_h)
|
||||
adjustor.set_is_last(True)
|
||||
adjustor.set_parent_rect(self._scroll_rect)
|
||||
adjustor.render(row_rect)
|
||||
current_y += row_h
|
||||
|
||||
def _draw_utility_column(self, rect: rl.Rectangle):
|
||||
current_y = rect.y
|
||||
@@ -255,41 +342,28 @@ class SoundsManagerView(Widget):
|
||||
adjustor.render(rl.Rectangle(rect.x, current_y, rect.width, row_h))
|
||||
current_y += row_h
|
||||
|
||||
toggle_h = AETHER_LIST_METRICS.utility_row_height
|
||||
for i, key in enumerate(self._controller.CUSTOM_ALERTS_KEYS):
|
||||
row_rect = rl.Rectangle(rect.x, current_y, rect.width, toggle_h)
|
||||
self._draw_toggle_row(row_rect, key, self._controller.ALERT_INFO[key])
|
||||
current_y += toggle_h
|
||||
current_y = self._draw_group_header(rect.x, current_y, rect.width, tr("CUSTOM ALERTS"))
|
||||
|
||||
def _draw_toggle_row(self, rect: rl.Rectangle, key: str, info: dict):
|
||||
padded_rect = rl.Rectangle(rect.x, rect.y + 4, rect.width - 12, rect.height - 8)
|
||||
tile_grid_h = self._tile_grid_h
|
||||
|
||||
current_val = self._controller._params.get_bool(key)
|
||||
is_enabled = info.get("is_enabled", lambda: True)()
|
||||
tile_grid_rect = rl.Rectangle(rect.x - 12, current_y - 12, rect.width + 24, tile_grid_h + 24)
|
||||
draw_list_group_shell(tile_grid_rect, style=PANEL_STYLE)
|
||||
|
||||
mouse_pos = gui_app.last_mouse_event.pos
|
||||
hovered = _point_hits(mouse_pos, padded_rect, self._scroll_rect, pad_x=6, pad_y=0)
|
||||
pressed = self._pressed_target == f"toggle:{key}"
|
||||
|
||||
status_str = tr("ON") if current_val else tr("OFF")
|
||||
if not is_enabled: status_str = tr(info.get("disabled_label", "UNAVAILABLE"))
|
||||
|
||||
draw_toggle_pill(padded_rect, current_val, is_enabled, tr(info["title"]), status_str, hovered, pressed, style=PANEL_STYLE)
|
||||
|
||||
self._toggle_rects[key] = padded_rect
|
||||
self._toggle_grid.set_parent_rect(self._scroll_rect)
|
||||
self._toggle_grid.render(rl.Rectangle(rect.x, current_y, rect.width, tile_grid_h))
|
||||
|
||||
|
||||
class StarPilotSoundsLayout(_SettingsPage):
|
||||
COOLDOWN_KEY = "SwitchbackModeCooldown"
|
||||
VOLUME_KEYS = [
|
||||
"BelowSteerSpeedVolume",
|
||||
"DisengageVolume",
|
||||
"EngageVolume",
|
||||
"PromptVolume",
|
||||
"PromptDistractedVolume",
|
||||
"RefuseVolume",
|
||||
"WarningSoftVolume",
|
||||
"WarningImmediateVolume",
|
||||
"WarningSoftVolume",
|
||||
"RefuseVolume",
|
||||
"PromptDistractedVolume",
|
||||
"EngageVolume",
|
||||
"DisengageVolume",
|
||||
"PromptVolume",
|
||||
"BelowSteerSpeedVolume",
|
||||
]
|
||||
CUSTOM_ALERTS_KEYS = [
|
||||
"GreenLightAlert",
|
||||
@@ -298,16 +372,21 @@ class StarPilotSoundsLayout(_SettingsPage):
|
||||
"SpeedLimitChangedAlert",
|
||||
]
|
||||
|
||||
COOLDOWN_INFO = {"title": tr_noop("Switchback Mode Cooldown"), "min": 0, "max": 30}
|
||||
COOLDOWN_INFO = {
|
||||
"title": tr_noop("Switchback Mode Cooldown"),
|
||||
"subtitle": tr_noop("Time before switchback re-engages"),
|
||||
"min": 0,
|
||||
"max": 30,
|
||||
}
|
||||
VOLUME_INFO = {
|
||||
"BelowSteerSpeedVolume": {"title": tr_noop("Min Steer Speed Alert"), "min": 0},
|
||||
"DisengageVolume": {"title": tr_noop("Disengage Volume"), "min": 0},
|
||||
"EngageVolume": {"title": tr_noop("Engage Volume"), "min": 0},
|
||||
"PromptVolume": {"title": tr_noop("Prompt Volume"), "min": 0},
|
||||
"PromptDistractedVolume": {"title": tr_noop("Distracted Volume"), "min": 0},
|
||||
"RefuseVolume": {"title": tr_noop("Refuse Volume"), "min": 0},
|
||||
"WarningSoftVolume": {"title": tr_noop("Warning Soft"), "min": 25},
|
||||
"WarningImmediateVolume": {"title": tr_noop("Warning Immediate"), "min": 25},
|
||||
"WarningImmediateVolume": {"title": tr_noop("Immediate Warning"), "subtitle": tr_noop("Critical safety intervention"), "min": 25},
|
||||
"WarningSoftVolume": {"title": tr_noop("Soft Warning"), "subtitle": tr_noop("Approaching system limits"), "min": 25},
|
||||
"RefuseVolume": {"title": tr_noop("Engagement Refused"), "subtitle": tr_noop("Action refused by system"), "min": 0},
|
||||
"PromptDistractedVolume": {"title": tr_noop("Distracted Driver"), "subtitle": tr_noop("Driver attention required"), "min": 0},
|
||||
"EngageVolume": {"title": tr_noop("Engagement Chime"), "subtitle": tr_noop("System engaged confirmation"), "min": 0},
|
||||
"DisengageVolume": {"title": tr_noop("Disengagement Alert"), "subtitle": tr_noop("Handoff to manual control"), "min": 0},
|
||||
"PromptVolume": {"title": tr_noop("General Prompt"), "subtitle": tr_noop("System guidance prompt"), "min": 0},
|
||||
"BelowSteerSpeedVolume": {"title": tr_noop("Low Speed Alert"), "subtitle": tr_noop("Minimum speed for steering"), "min": 0},
|
||||
}
|
||||
|
||||
_sound_player_process = None
|
||||
@@ -317,15 +396,23 @@ class StarPilotSoundsLayout(_SettingsPage):
|
||||
self._init_sound_player()
|
||||
|
||||
self.ALERT_INFO = {
|
||||
"GreenLightAlert": {"title": tr_noop("Green Light")},
|
||||
"LeadDepartingAlert": {"title": tr_noop("Lead Departure")},
|
||||
"GreenLightAlert": {
|
||||
"title": tr_noop("Green Light"),
|
||||
"subtitle": tr_noop("When lead car moves at green light"),
|
||||
},
|
||||
"LeadDepartingAlert": {
|
||||
"title": tr_noop("Lead Departure"),
|
||||
"subtitle": tr_noop("When lead vehicle pulls away"),
|
||||
},
|
||||
"LoudBlindspotAlert": {
|
||||
"title": tr_noop("Loud Blindspot"),
|
||||
"subtitle": tr_noop("Blind spot collision warning"),
|
||||
"is_enabled": lambda: starpilot_state.car_state.hasBSM,
|
||||
"disabled_label": tr_noop("Needs BSM")
|
||||
},
|
||||
"SpeedLimitChangedAlert": {
|
||||
"title": tr_noop("Speed Limit"),
|
||||
"subtitle": tr_noop("When posted speed limit changes"),
|
||||
"is_enabled": lambda: self._params.get_bool("ShowSpeedLimits") or (
|
||||
starpilot_state.car_state.hasOpenpilotLongitudinal and self._params.get_bool("SpeedLimitController")
|
||||
),
|
||||
@@ -335,6 +422,14 @@ class StarPilotSoundsLayout(_SettingsPage):
|
||||
|
||||
self._manager_view = SoundsManagerView(self)
|
||||
|
||||
def _restore_defaults(self):
|
||||
for key in self.VOLUME_KEYS:
|
||||
default = 25 if "Warning" in key else 100
|
||||
self._params.put_int(key, default)
|
||||
self._params.put_int(self.COOLDOWN_KEY, 0)
|
||||
for key in self.CUSTOM_ALERTS_KEYS:
|
||||
self._params.put_bool(key, False)
|
||||
|
||||
@classmethod
|
||||
def _init_sound_player(cls):
|
||||
if cls._sound_player_process is not None and cls._sound_player_process.poll() is None: return
|
||||
|
||||
Reference in New Issue
Block a user