mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-07 22:52:06 +08:00
BigUI WIP: Dedup/remove junk
This commit is contained in:
@@ -36,6 +36,11 @@ _CONST_TERTIARY = rl.Color(145, 155, 175, 255)
|
||||
_NODE_NUM_MIN = 3
|
||||
_NODE_NUM_MAX = 5
|
||||
|
||||
# Custom vector icon layout constants (scribble.py coordinate system)
|
||||
CUSTOM_ICON_BASE_SIZE = 100.0
|
||||
CUSTOM_ICON_SCALE_MULT = 1.25
|
||||
CUSTOM_ICON_CANVAS_SIZE = 60.0
|
||||
|
||||
|
||||
class SPACING:
|
||||
xs: int = 4
|
||||
@@ -78,6 +83,28 @@ def with_alpha(color, alpha: int) -> rl.Color:
|
||||
return rl.Color(r, g, b, max(0, min(a, int(alpha))))
|
||||
|
||||
|
||||
def clamp_and_snap(value: float, min_val: float, max_val: float, step: float) -> float:
|
||||
if step <= 0:
|
||||
return max(min_val, min(max_val, value))
|
||||
snapped = round((value - min_val) / step) * step + min_val
|
||||
return max(min_val, min(max_val, snapped))
|
||||
|
||||
|
||||
def value_fraction(value: float, min_val: float, max_val: float) -> float:
|
||||
val_range = max_val - min_val
|
||||
if val_range == 0:
|
||||
return 0.0
|
||||
return max(0.0, min(1.0, (value - min_val) / val_range))
|
||||
|
||||
|
||||
def update_val_from_mouse(mouse_pos: MousePos, track_rect: rl.Rectangle, min_val: float, max_val: float, step: float) -> float:
|
||||
if track_rect.width <= 0:
|
||||
return min_val
|
||||
rel_x = max(0.0, min(1.0, (mouse_pos.x - track_rect.x) / track_rect.width))
|
||||
val = min_val + rel_x * (max_val - min_val)
|
||||
return clamp_and_snap(val, min_val, max_val, step)
|
||||
|
||||
|
||||
def mix_colors(base, accent, weight: float, alpha: int | None = None) -> rl.Color:
|
||||
br, bg, bb, ba = _get_rgba(base)
|
||||
ar, ag, ab, aa = _get_rgba(accent)
|
||||
@@ -674,11 +701,11 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
def _make_toggle_tile(self, d: dict) -> ToggleTile:
|
||||
return ToggleTile(
|
||||
title=d["title"],
|
||||
get_state=d.get("get_state", d.get("get")),
|
||||
set_state=d.get("set_state", d.get("set")),
|
||||
get_state=d["get_state"],
|
||||
set_state=d["set_state"],
|
||||
bg_color=self.PANEL_STYLE.accent,
|
||||
desc=d.get("subtitle", d.get("desc", "")),
|
||||
is_enabled=d.get("is_enabled", d.get("enabled")),
|
||||
desc=d.get("subtitle", ""),
|
||||
is_enabled=d.get("is_enabled"),
|
||||
disabled_label=d.get("disabled_label", ""),
|
||||
)
|
||||
|
||||
@@ -686,11 +713,11 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
return AetherMultiSelectTile(
|
||||
title=d["title"],
|
||||
options=d["options"],
|
||||
get_values=d.get("get_values", d.get("get")),
|
||||
set_values=d.get("set_values", d.get("set")),
|
||||
get_values=d["get_values"],
|
||||
set_values=d["set_values"],
|
||||
bg_color=self.PANEL_STYLE.accent,
|
||||
desc=d.get("subtitle", d.get("desc", "")),
|
||||
is_enabled=d.get("is_enabled", d.get("enabled")),
|
||||
desc=d.get("subtitle", ""),
|
||||
is_enabled=d.get("is_enabled"),
|
||||
)
|
||||
|
||||
# ── pagination ─────────────────────────────────────────────
|
||||
@@ -1924,10 +1951,7 @@ class AetherInlineRangeControl(Widget):
|
||||
self.reset_interaction()
|
||||
|
||||
def _clamp_and_snap(self, value: float) -> float:
|
||||
if self.step <= 0:
|
||||
return max(self.min_val, min(self.max_val, value))
|
||||
snapped = round((value - self.min_val) / self.step) * self.step + self.min_val
|
||||
return max(self.min_val, min(self.max_val, snapped))
|
||||
return clamp_and_snap(value, self.min_val, self.max_val, self.step)
|
||||
|
||||
def _step_value(self, direction: int) -> bool:
|
||||
new_val = self._clamp_and_snap(self.current_val + direction * self.step)
|
||||
@@ -1939,19 +1963,12 @@ class AetherInlineRangeControl(Widget):
|
||||
return True
|
||||
|
||||
def _value_fraction(self, value: float) -> float:
|
||||
value_range = self.max_val - self.min_val
|
||||
if value_range == 0:
|
||||
return 0.0
|
||||
return max(0.0, min(1.0, (value - self.min_val) / value_range))
|
||||
return value_fraction(value, self.min_val, self.max_val)
|
||||
|
||||
def _update_val_from_mouse(self, mouse_pos: MousePos) -> None:
|
||||
if self._track_rect.width <= 0:
|
||||
return
|
||||
rel_x = max(0.0, min(1.0, (mouse_pos.x - self._track_rect.x) / self._track_rect.width))
|
||||
value = self.min_val + rel_x * (self.max_val - self.min_val)
|
||||
snapped = self._clamp_and_snap(value)
|
||||
if snapped != self.current_val:
|
||||
self.current_val = snapped
|
||||
new_val = update_val_from_mouse(mouse_pos, self._track_rect, self.min_val, self.max_val, self.step)
|
||||
if new_val != self.current_val:
|
||||
self.current_val = new_val
|
||||
self._on_change(self.current_val)
|
||||
|
||||
def _commit_if_needed(self) -> None:
|
||||
@@ -3260,6 +3277,7 @@ class AetherTile(Widget):
|
||||
self._plate_offset: float = 0.0
|
||||
self._plate_target: float = 0.0
|
||||
self._is_pressed: bool = False
|
||||
self._squish: float = 1.0
|
||||
|
||||
def _surface_rect(self, rect: rl.Rectangle) -> rl.Rectangle:
|
||||
return _inset_rect(snap_rect(rect), TILE_INSET)
|
||||
@@ -3283,6 +3301,7 @@ class AetherTile(Widget):
|
||||
if rl.check_collision_point_rec(mouse_pos, self._hit_rect):
|
||||
self._is_pressed = True
|
||||
self._plate_target = 1.0
|
||||
self._squish = 0.95
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
if not self.enabled:
|
||||
@@ -3307,6 +3326,14 @@ class AetherTile(Widget):
|
||||
return
|
||||
self._plate_offset += (self._plate_target - self._plate_offset) * (1 - math.exp(-dt / PLATE_TAU))
|
||||
|
||||
def _update_squish(self):
|
||||
dt = rl.get_frame_time()
|
||||
if self._squish < 1.0:
|
||||
self._squish += (1.0 - self._squish) * 15.0 * dt
|
||||
|
||||
def _update_state(self):
|
||||
self._update_squish()
|
||||
|
||||
def _render_layers(self, rect: rl.Rectangle, radius: float = TILE_RADIUS, segments: int = TILE_SEGMENTS):
|
||||
self._animate_plate(rl.get_frame_time())
|
||||
snapped_rect = snap_rect(rect)
|
||||
@@ -3496,12 +3523,6 @@ class AetherTile(Widget):
|
||||
desc_size: int = 18,
|
||||
custom_icon_key: str | None = None,
|
||||
):
|
||||
# Parameters for custom vector icons: base 100x100 layout footprint,
|
||||
# 25% scale increase, and 60x60 canvas size defined in scribble.py coordinates.
|
||||
custom_icon_base_size = 100.0
|
||||
custom_icon_scale_mult = 1.25
|
||||
custom_icon_canvas_size = 60.0
|
||||
|
||||
content_pad = SPACING.tile_content
|
||||
max_w = face.width - (content_pad * 2)
|
||||
scale = max(0.82, min(1.12, min(face.width / 360.0, face.height / 205.0)))
|
||||
@@ -3512,7 +3533,7 @@ class AetherTile(Widget):
|
||||
has_icon = (icon is not None) or (custom_icon_key is not None)
|
||||
icon_scale = min(0.80, max(0.56, scale * 0.72)) if has_icon else 0.0
|
||||
if custom_icon_key:
|
||||
icon_height = custom_icon_base_size * custom_icon_scale_mult * icon_scale
|
||||
icon_height = CUSTOM_ICON_BASE_SIZE * CUSTOM_ICON_SCALE_MULT * icon_scale
|
||||
elif icon:
|
||||
icon_height = icon.height * icon_scale
|
||||
else:
|
||||
@@ -3529,9 +3550,9 @@ class AetherTile(Widget):
|
||||
)
|
||||
|
||||
if custom_icon_key:
|
||||
icon_width = custom_icon_base_size * custom_icon_scale_mult * icon_scale
|
||||
icon_width = CUSTOM_ICON_BASE_SIZE * CUSTOM_ICON_SCALE_MULT * icon_scale
|
||||
icon_x = face.x + (face.width - icon_width) / 2
|
||||
s = icon_scale * (custom_icon_base_size / custom_icon_canvas_size) * custom_icon_scale_mult
|
||||
s = icon_scale * (CUSTOM_ICON_BASE_SIZE / CUSTOM_ICON_CANVAS_SIZE) * CUSTOM_ICON_SCALE_MULT
|
||||
self._draw_custom_icon(custom_icon_key, icon_x, layout["top"], s, mix_colors(rl.Color(255, 255, 255, 255), self.surface_color, 0.08))
|
||||
elif icon:
|
||||
icon_width = icon.width * icon_scale
|
||||
@@ -3655,7 +3676,7 @@ class AetherTile(Widget):
|
||||
rl.draw_circle(nx, ny, int(core_r), rl.Color(col.r, col.g, col.b, min(255, ca)))
|
||||
|
||||
def _render_hud_background(self, rect: rl.Rectangle, accent: rl.Color, glow: float = 1.0) -> tuple[rl.Rectangle, rl.Color]:
|
||||
sq = getattr(self, '_squish', 1.0)
|
||||
sq = self._squish
|
||||
snapped = snap_rect(rect)
|
||||
sw = snapped.width * sq
|
||||
sh = snapped.height * sq
|
||||
@@ -3690,20 +3711,6 @@ class HubTile(AetherTile):
|
||||
self._icon = None
|
||||
self._font_title = gui_app.font(FontWeight.BOLD)
|
||||
self._font_desc = gui_app.font(FontWeight.MEDIUM)
|
||||
self._squish: float = 1.0
|
||||
|
||||
def _update_state(self):
|
||||
dt = rl.get_frame_time()
|
||||
if self._squish < 1.0:
|
||||
self._squish += (1.0 - self._squish) * 15.0 * dt
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos):
|
||||
if not self.enabled:
|
||||
return
|
||||
if rl.check_collision_point_rec(mouse_pos, self._hit_rect):
|
||||
self._is_pressed = True
|
||||
self._plate_target = 1.0
|
||||
self._squish = 0.95
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self._animate_plate(rl.get_frame_time())
|
||||
@@ -3725,23 +3732,17 @@ class HubTile(AetherTile):
|
||||
|
||||
icon_h = 0.0
|
||||
if self.custom_icon_key:
|
||||
icon_base_size = 100.0
|
||||
icon_scale_mult = 1.25
|
||||
icon_canvas_size = 60.0
|
||||
icon_scale = min(0.80, max(0.56, text_scale * 0.72))
|
||||
icon_h = icon_base_size * icon_scale_mult * icon_scale
|
||||
icon_h = CUSTOM_ICON_BASE_SIZE * CUSTOM_ICON_SCALE_MULT * icon_scale
|
||||
|
||||
total_h = icon_h + (gap if icon_h > 0 else 0) + title_size + (gap if desc_to_render else 0) + desc_size
|
||||
content_top = ry + max(0, (rh - total_h) / 2)
|
||||
|
||||
if self.custom_icon_key:
|
||||
icon_base_size = 100.0
|
||||
icon_scale_mult = 1.25
|
||||
icon_canvas_size = 60.0
|
||||
icon_scale = min(0.80, max(0.56, text_scale * 0.72))
|
||||
icon_width = icon_base_size * icon_scale_mult * icon_scale
|
||||
icon_width = CUSTOM_ICON_BASE_SIZE * CUSTOM_ICON_SCALE_MULT * icon_scale
|
||||
icon_x = rx + (rw - icon_width) / 2
|
||||
s = icon_scale * (icon_base_size / icon_canvas_size) * icon_scale_mult
|
||||
s = icon_scale * (CUSTOM_ICON_BASE_SIZE / CUSTOM_ICON_CANVAS_SIZE) * CUSTOM_ICON_SCALE_MULT
|
||||
self._draw_custom_icon(self.custom_icon_key, icon_x, content_top, s, mix_colors(rl.Color(255, 255, 255, 255), accent, 0.08))
|
||||
content_top += icon_h + gap
|
||||
|
||||
@@ -3799,22 +3800,12 @@ class ToggleTile(AetherTile):
|
||||
self._disabled_label = disabled_label
|
||||
self._show_led = show_led
|
||||
self._glow: float = 1.0 if (self.get_state() and (is_enabled or True)) else 0.0
|
||||
self._squish: float = 1.0
|
||||
|
||||
def _update_state(self):
|
||||
super()._update_state()
|
||||
dt = rl.get_frame_time()
|
||||
target = 1.0 if self.get_state() and self.enabled else 0.0
|
||||
self._glow += (target - self._glow) * 10.0 * dt
|
||||
if self._squish < 1.0:
|
||||
self._squish += (1.0 - self._squish) * 15.0 * dt
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos):
|
||||
if not self.enabled:
|
||||
return
|
||||
if rl.check_collision_point_rec(mouse_pos, self._hit_rect):
|
||||
self._is_pressed = True
|
||||
self._plate_target = 1.0
|
||||
self._squish = 0.95
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
if self._is_pressed:
|
||||
@@ -3983,20 +3974,6 @@ class ValueTile(AetherTile):
|
||||
self._font_desc = gui_app.font(FontWeight.MEDIUM)
|
||||
self._active_color = self.surface_color
|
||||
self._disabled_color = rl.Color(120, 120, 120, 255)
|
||||
self._squish: float = 1.0
|
||||
|
||||
def _update_state(self):
|
||||
dt = rl.get_frame_time()
|
||||
if self._squish < 1.0:
|
||||
self._squish += (1.0 - self._squish) * 15.0 * dt
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos):
|
||||
if not self.enabled:
|
||||
return
|
||||
if rl.check_collision_point_rec(mouse_pos, self._hit_rect):
|
||||
self._is_pressed = True
|
||||
self._plate_target = 1.0
|
||||
self._squish = 0.95
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
enabled = self.enabled
|
||||
@@ -4103,12 +4080,6 @@ class SliderTile(AetherTile):
|
||||
self._press_start_x = 0.0
|
||||
self._press_start_time: float | None = None
|
||||
self._long_press_triggered = False
|
||||
self._squish: float = 1.0
|
||||
|
||||
def _update_state(self):
|
||||
dt = rl.get_frame_time()
|
||||
if self._squish < 1.0:
|
||||
self._squish += (1.0 - self._squish) * 15.0 * dt
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos):
|
||||
if rl.check_collision_point_rec(mouse_pos, self._hit_rect) and self.enabled:
|
||||
@@ -4308,10 +4279,7 @@ class AetherSlider(Widget):
|
||||
self.on_commit(self.current_val)
|
||||
|
||||
def _clamp_and_snap(self, val: float) -> float:
|
||||
if self.step <= 0:
|
||||
return max(self.min_val, min(self.max_val, val))
|
||||
snapped = round((val - self.min_val) / self.step) * self.step + self.min_val
|
||||
return max(self.min_val, min(self.max_val, snapped))
|
||||
return clamp_and_snap(val, self.min_val, self.max_val, self.step)
|
||||
|
||||
def _button_width(self, rect: rl.Rectangle) -> int:
|
||||
return min(SLIDER_BUTTON_SIZE, max(44, int(rect.width * 0.14)))
|
||||
@@ -4463,11 +4431,8 @@ class AetherSlider(Widget):
|
||||
button_w = self._button_width(self._rect)
|
||||
track_x = self._rect.x + button_w
|
||||
track_w = self._rect.width - 2 * button_w
|
||||
if track_w <= 0:
|
||||
return
|
||||
rel_x = max(0.0, min(1.0, (mouse_pos.x - track_x) / track_w))
|
||||
val = self.min_val + rel_x * (self.max_val - self.min_val)
|
||||
snapped = self._clamp_and_snap(val)
|
||||
track_rect = rl.Rectangle(track_x, self._rect.y, track_w, self._rect.height)
|
||||
snapped = update_val_from_mouse(mouse_pos, track_rect, self.min_val, self.max_val, self.step)
|
||||
if snapped != self.current_val:
|
||||
self.current_val = snapped
|
||||
self.on_change(self.current_val)
|
||||
@@ -4520,23 +4485,14 @@ class AetherSliderDialog(Widget):
|
||||
self._thumb_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
|
||||
def _value_fraction(self, value: float) -> float:
|
||||
val_range = self.max_val - self.min_val
|
||||
if val_range == 0:
|
||||
return 0.0
|
||||
return max(0.0, min(1.0, (value - self.min_val) / val_range))
|
||||
return value_fraction(value, self.min_val, self.max_val)
|
||||
|
||||
def _clamp_and_snap(self, val: float) -> float:
|
||||
if self.step <= 0:
|
||||
return max(self.min_val, min(self.max_val, val))
|
||||
snapped = round((val - self.min_val) / self.step) * self.step + self.min_val
|
||||
return max(self.min_val, min(self.max_val, snapped))
|
||||
return clamp_and_snap(val, self.min_val, self.max_val, self.step)
|
||||
|
||||
def _update_val_from_mouse(self, mouse_pos: MousePos) -> None:
|
||||
if self._track_rect.width <= 0:
|
||||
return
|
||||
rel_x = max(0.0, min(1.0, (mouse_pos.x - self._track_rect.x) / self._track_rect.width))
|
||||
val = self.min_val + rel_x * (self.max_val - self.min_val)
|
||||
self._current_val = self._clamp_and_snap(val)
|
||||
new_val = update_val_from_mouse(mouse_pos, self._track_rect, self.min_val, self.max_val, self.step)
|
||||
self._current_val = new_val
|
||||
|
||||
def formatted_value(self) -> str:
|
||||
return format_adjustor_value(self._current_val, step=self.step, unit=self._unit, labels=self._labels)
|
||||
@@ -5035,20 +4991,6 @@ class AetherMultiSelectTile(AetherTile):
|
||||
self._font_desc = gui_app.font(FontWeight.MEDIUM)
|
||||
self._active_color = self.surface_color
|
||||
self._disabled_color = rl.Color(120, 120, 120, 255)
|
||||
self._squish: float = 1.0
|
||||
|
||||
def _update_state(self):
|
||||
dt = rl.get_frame_time()
|
||||
if self._squish < 1.0:
|
||||
self._squish += (1.0 - self._squish) * 15.0 * dt
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos):
|
||||
if not self.enabled:
|
||||
return
|
||||
if rl.check_collision_point_rec(mouse_pos, self._hit_rect):
|
||||
self._is_pressed = True
|
||||
self._plate_target = 1.0
|
||||
self._squish = 0.95
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
if self._is_pressed:
|
||||
|
||||
@@ -190,14 +190,14 @@ class SteeringSubPanelView(PanelManagerView):
|
||||
wrapped = []
|
||||
for d in visible:
|
||||
entry = dict(d)
|
||||
original_set = entry.get("set")
|
||||
original_set = entry.get("set_state")
|
||||
if original_set:
|
||||
def make_wrapped(orig):
|
||||
def fn(state):
|
||||
orig(state)
|
||||
self._rebuild_content()
|
||||
return fn
|
||||
entry["set"] = make_wrapped(original_set)
|
||||
entry["set_state"] = make_wrapped(original_set)
|
||||
wrapped.append(entry)
|
||||
pages = [wrapped[i:i+4] for i in range(0, len(wrapped), 4)]
|
||||
|
||||
@@ -477,20 +477,20 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("Always On Lateral"),
|
||||
"subtitle": tr("Steering stays active when ACC is off."),
|
||||
"get": lambda: p.get_bool("AlwaysOnLateral"),
|
||||
"set": lambda s: _confirm_reboot_toggle(p, "AlwaysOnLateral", s) if s else p.put_bool("AlwaysOnLateral", False),
|
||||
"get_state": lambda: p.get_bool("AlwaysOnLateral"),
|
||||
"set_state": lambda s: _confirm_reboot_toggle(p, "AlwaysOnLateral", s) if s else p.put_bool("AlwaysOnLateral", False),
|
||||
},
|
||||
{
|
||||
"title": tr("Turn Signal Only"),
|
||||
"subtitle": tr("Only pause steering when turn signal is active."),
|
||||
"get": lambda: p.get_bool("PauseLateralOnSignal"),
|
||||
"set": lambda s: p.put_bool("PauseLateralOnSignal", s),
|
||||
"get_state": lambda: p.get_bool("PauseLateralOnSignal"),
|
||||
"set_state": lambda s: p.put_bool("PauseLateralOnSignal", s),
|
||||
},
|
||||
{
|
||||
"title": tr("Use Route Desires"),
|
||||
"subtitle": tr("Allow navigation to request lane keep and turns."),
|
||||
"get": lambda: p.get_bool("NavDesiresAllowed"),
|
||||
"set": lambda s: p.put_bool("NavDesiresAllowed", s),
|
||||
"get_state": lambda: p.get_bool("NavDesiresAllowed"),
|
||||
"set_state": lambda s: p.put_bool("NavDesiresAllowed", s),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -536,21 +536,21 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("Lane Changes"),
|
||||
"subtitle": tr("Allow openpilot to change lanes."),
|
||||
"get": lambda: p.get_bool("LaneChanges"),
|
||||
"set": lambda s: p.put_bool("LaneChanges", s),
|
||||
"get_state": lambda: p.get_bool("LaneChanges"),
|
||||
"set_state": lambda s: p.put_bool("LaneChanges", s),
|
||||
},
|
||||
{
|
||||
"title": tr("Auto Lane Changes"),
|
||||
"subtitle": tr("Signal triggers automatic lane change."),
|
||||
"get": lambda: p.get_bool("NudgelessLaneChange"),
|
||||
"set": lambda s: p.put_bool("NudgelessLaneChange", s),
|
||||
"get_state": lambda: p.get_bool("NudgelessLaneChange"),
|
||||
"set_state": lambda s: p.put_bool("NudgelessLaneChange", s),
|
||||
"visible": lc_on,
|
||||
},
|
||||
{
|
||||
"title": tr("One Per Signal"),
|
||||
"subtitle": tr("One lane change per signal activation."),
|
||||
"get": lambda: p.get_bool("OneLaneChange"),
|
||||
"set": lambda s: p.put_bool("OneLaneChange", s),
|
||||
"get_state": lambda: p.get_bool("OneLaneChange"),
|
||||
"set_state": lambda s: p.put_bool("OneLaneChange", s),
|
||||
"visible": nlc_on,
|
||||
},
|
||||
]
|
||||
@@ -606,8 +606,8 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("Advanced Lateral Tuning"),
|
||||
"subtitle": tr("Fine-tune steering response and auto-tuning."),
|
||||
"get": lambda: p.get_bool("AdvancedLateralTune"),
|
||||
"set": _on_advanced_toggle,
|
||||
"get_state": lambda: p.get_bool("AdvancedLateralTune"),
|
||||
"set_state": _on_advanced_toggle,
|
||||
},
|
||||
# Standard toggles
|
||||
*sb_toggles,
|
||||
@@ -616,8 +616,8 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("NNFF"),
|
||||
"subtitle": tr("Neural net feedforward steering controller."),
|
||||
"get": lambda: p.get_bool("NNFF"),
|
||||
"set": lambda s: (p.put_bool("NNFF", s),
|
||||
"get_state": lambda: p.get_bool("NNFF"),
|
||||
"set_state": lambda s: (p.put_bool("NNFF", s),
|
||||
s and p.put_bool("NNFFLite", False),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
"is_enabled": lambda: cs.hasNNFFLog and not cs.isAngleCar,
|
||||
@@ -627,8 +627,8 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("NNFF Lite"),
|
||||
"subtitle": tr("Lightweight NNFF when full model is off."),
|
||||
"get": lambda: p.get_bool("NNFFLite"),
|
||||
"set": lambda s: (p.put_bool("NNFFLite", s),
|
||||
"get_state": lambda: p.get_bool("NNFFLite"),
|
||||
"set_state": lambda s: (p.put_bool("NNFFLite", s),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
"is_enabled": lambda: not cs.isAngleCar,
|
||||
"disabled_label": tr("Not Available"),
|
||||
@@ -637,8 +637,8 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("Force Torque Ctrl"),
|
||||
"subtitle": tr("Torque-based steering for smoother lane keeping."),
|
||||
"get": lambda: p.get_bool("ForceTorqueController"),
|
||||
"set": lambda s: (p.put_bool("ForceTorqueController", s),
|
||||
"get_state": lambda: p.get_bool("ForceTorqueController"),
|
||||
"set_state": lambda s: (p.put_bool("ForceTorqueController", s),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
"is_enabled": lambda: not cs.isTorqueCar and not cs.isAngleCar,
|
||||
"disabled_label": tr("Not Available"),
|
||||
@@ -647,16 +647,16 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("Force Turn Desires"),
|
||||
"subtitle": tr("Follow turn intent below min lane change speed."),
|
||||
"get": lambda: p.get_bool("TurnDesires"),
|
||||
"set": lambda s: (p.put_bool("TurnDesires", s),
|
||||
"get_state": lambda: p.get_bool("TurnDesires"),
|
||||
"set_state": lambda s: (p.put_bool("TurnDesires", s),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
"visible": alt_on,
|
||||
},
|
||||
{
|
||||
"title": tr("Force Auto-Tune On"),
|
||||
"subtitle": tr("Force-enable live auto-tuning for friction and lateral accel."),
|
||||
"get": lambda: p.get_bool("ForceAutoTune"),
|
||||
"set": lambda s: (p.put_bool("ForceAutoTune", s),
|
||||
"get_state": lambda: p.get_bool("ForceAutoTune"),
|
||||
"set_state": lambda s: (p.put_bool("ForceAutoTune", s),
|
||||
s and p.put_bool("ForceAutoTuneOff", False),
|
||||
_sync_parent(p, "AdvancedLateralTune", _ADVANCED_LATERAL_KEYS)),
|
||||
"is_enabled": lambda: not cs.hasAutoTune and cs.isTorqueCar and not cs.isAngleCar,
|
||||
@@ -666,8 +666,8 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
{
|
||||
"title": tr("Force Auto-Tune Off"),
|
||||
"subtitle": tr("Force-disable auto-tuning and use your set values."),
|
||||
"get": lambda: p.get_bool("ForceAutoTuneOff"),
|
||||
"set": lambda s: (p.put_bool("ForceAutoTuneOff", s),
|
||||
"get_state": lambda: p.get_bool("ForceAutoTuneOff"),
|
||||
"set_state": lambda s: (p.put_bool("ForceAutoTuneOff", s),
|
||||
s and p.put_bool("ForceAutoTune", False),
|
||||
_sync_parent(p, "AdvancedLateralTune", _ADVANCED_LATERAL_KEYS)),
|
||||
"is_enabled": lambda: cs.hasAutoTune and cs.isTorqueCar and not cs.isAngleCar,
|
||||
|
||||
@@ -86,8 +86,8 @@ class SoundsManagerView(PanelManagerView):
|
||||
toggle_defs.append({
|
||||
"title": tr(info["title"]),
|
||||
"subtitle": tr(info.get("subtitle", "")),
|
||||
"get": lambda k=key: self._controller._params.get_bool(k),
|
||||
"set": lambda state, k=key: self._controller._params.put_bool(k, state),
|
||||
"get_state": lambda k=key: self._controller._params.get_bool(k),
|
||||
"set_state": lambda state, k=key: self._controller._params.put_bool(k, state),
|
||||
"is_enabled": info.get("is_enabled"),
|
||||
"disabled_label": tr(info.get("disabled_label", "")) if info.get("disabled_label") else "",
|
||||
})
|
||||
|
||||
@@ -244,62 +244,54 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
|
||||
self._toggle_defs = [
|
||||
{
|
||||
"id": "StandbyMode",
|
||||
"title": tr("Standby Mode"),
|
||||
"subtitle": tr("Keep the device ready for faster wake-ups."),
|
||||
"get": lambda: self._controller._params.get_bool("StandbyMode"),
|
||||
"set": lambda v: self._controller._params.put_bool("StandbyMode", v),
|
||||
"get_state": lambda: self._controller._params.get_bool("StandbyMode"),
|
||||
"set_state": lambda v: self._controller._params.put_bool("StandbyMode", v),
|
||||
},
|
||||
{
|
||||
"id": "UseKonikServer",
|
||||
"title": tr("Use Konik Server"),
|
||||
"subtitle": tr("Switch remote services to the Konik endpoint."),
|
||||
"get": self._controller._get_konik_state,
|
||||
"set": self._controller._on_konik_toggle,
|
||||
"get_state": self._controller._get_konik_state,
|
||||
"set_state": self._controller._on_konik_toggle,
|
||||
},
|
||||
{
|
||||
"id": "DebugMode",
|
||||
"title": tr("Debug Mode"),
|
||||
"subtitle": tr("Expose additional debugging and developer toggles."),
|
||||
"get": lambda: self._controller._params.get_bool("DebugMode"),
|
||||
"set": lambda v: self._controller._params.put_bool("DebugMode", v),
|
||||
"get_state": lambda: self._controller._params.get_bool("DebugMode"),
|
||||
"set_state": lambda v: self._controller._params.put_bool("DebugMode", v),
|
||||
},
|
||||
{
|
||||
"id": "ShowFPS",
|
||||
"title": tr("Show FPS"),
|
||||
"subtitle": tr("Display screen refresh rate and system performance metrics onroad."),
|
||||
"get": lambda: self._controller._params.get_bool("ShowFPS"),
|
||||
"set": lambda v: self._controller._params.put_bool("ShowFPS", v),
|
||||
"get_state": lambda: self._controller._params.get_bool("ShowFPS"),
|
||||
"set_state": lambda v: self._controller._params.put_bool("ShowFPS", v),
|
||||
},
|
||||
{
|
||||
"id": "NoUploads",
|
||||
"title": tr("Disable Uploads"),
|
||||
"subtitle": tr("Stop all cloud uploads from this device."),
|
||||
"get": lambda: self._controller._params.get_bool("NoUploads"),
|
||||
"set": lambda v: self._controller._params.put_bool("NoUploads", v),
|
||||
"get_state": lambda: self._controller._params.get_bool("NoUploads"),
|
||||
"set_state": lambda v: self._controller._params.put_bool("NoUploads", v),
|
||||
},
|
||||
{
|
||||
"id": "DisableOnroadUploads",
|
||||
"title": tr("Disable Onroad Uploads"),
|
||||
"subtitle": tr("Block uploads while the car is onroad."),
|
||||
"get": lambda: self._controller._params.get_bool("DisableOnroadUploads"),
|
||||
"set": lambda v: self._controller._params.put_bool("DisableOnroadUploads", v),
|
||||
"get_state": lambda: self._controller._params.get_bool("DisableOnroadUploads"),
|
||||
"set_state": lambda v: self._controller._params.put_bool("DisableOnroadUploads", v),
|
||||
"is_enabled": lambda: not self._controller._params.get_bool("NoUploads"),
|
||||
"disabled_label": tr("Turn off Disable Uploads first"),
|
||||
},
|
||||
{
|
||||
"id": "NoLogging",
|
||||
"title": tr("Disable Logging"),
|
||||
"subtitle": tr("Stop writing standard log data to storage."),
|
||||
"get": lambda: self._controller._params.get_bool("NoLogging"),
|
||||
"set": lambda v: self._controller._params.put_bool("NoLogging", v),
|
||||
"get_state": lambda: self._controller._params.get_bool("NoLogging"),
|
||||
"set_state": lambda v: self._controller._params.put_bool("NoLogging", v),
|
||||
},
|
||||
{
|
||||
"id": "HigherBitrate",
|
||||
"title": tr("High Bitrate Recording"),
|
||||
"subtitle": tr("Capture higher-quality onroad footage."),
|
||||
"get": lambda: self._controller._params.get_bool("HigherBitrate"),
|
||||
"set": self._controller._on_higher_bitrate_toggle,
|
||||
"get_state": lambda: self._controller._params.get_bool("HigherBitrate"),
|
||||
"set_state": self._controller._on_higher_bitrate_toggle,
|
||||
"is_enabled": lambda: not self._controller._params.get_bool("DisableOnroadUploads") and not self._controller._params.get_bool("NoUploads"),
|
||||
"disabled_label": tr("Uploads must stay enabled"),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user