mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-07-26 20:32:04 +08:00
BigUI WIP: LED
This commit is contained in:
@@ -636,13 +636,21 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
|
||||
# active drag
|
||||
if self._page_drag_active:
|
||||
self._page_scissor_push(clip_rect)
|
||||
grid.render(rl.Rectangle(rect.x + self._page_drag_offset, rect.y, rect.width, rect.height))
|
||||
drag_off = self._page_drag_offset
|
||||
drag_clip = rl.Rectangle(
|
||||
clip_rect.x + min(0, drag_off),
|
||||
clip_rect.y,
|
||||
clip_rect.width + abs(drag_off),
|
||||
clip_rect.height,
|
||||
)
|
||||
self._page_scissor_push(drag_clip)
|
||||
grid.render(rl.Rectangle(rect.x + drag_off, rect.y, rect.width, rect.height))
|
||||
self._page_scissor_pop()
|
||||
return
|
||||
|
||||
# no animation
|
||||
if not self._page_animating:
|
||||
grid.set_parent_rect(self._scroll_rect)
|
||||
grid.render(rect)
|
||||
return
|
||||
|
||||
@@ -652,6 +660,7 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
if elapsed >= duration:
|
||||
self._page_animating = False
|
||||
self._page_anim_prev_tiles.clear()
|
||||
grid.set_parent_rect(self._scroll_rect)
|
||||
grid.render(rect)
|
||||
return
|
||||
|
||||
@@ -665,8 +674,8 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
old_target = -direction * rect.width
|
||||
prev_offset = self._page_anim_from + (old_target - self._page_anim_from) * t
|
||||
|
||||
self._page_scissor_push(rl.Rectangle(clip_rect.x, clip_rect.y,
|
||||
clip_rect.width + rect.width, clip_rect.height))
|
||||
self._page_scissor_push(rl.Rectangle(clip_rect.x - rect.width, clip_rect.y,
|
||||
clip_rect.width + rect.width * 2, clip_rect.height))
|
||||
if self._page_anim_prev_tiles:
|
||||
old_grid = TileGrid(columns=grid.get_column_count(), padding=grid.gap)
|
||||
old_grid.tiles.extend(self._page_anim_prev_tiles)
|
||||
@@ -686,7 +695,10 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos) -> None:
|
||||
super()._handle_mouse_press(mouse_pos)
|
||||
if self._has_pagination and not self._page_animating:
|
||||
if self._has_pagination:
|
||||
if self._page_animating:
|
||||
self._page_animating = False
|
||||
self._page_anim_prev_tiles.clear()
|
||||
self._page_drag_start_x = mouse_pos.x
|
||||
self._page_drag_start_y = mouse_pos.y
|
||||
self._page_drag_active = True
|
||||
@@ -719,11 +731,13 @@ class PanelManagerView(AetherInteractiveMixin, Widget):
|
||||
self._start_drag_commit(offset)
|
||||
self._current_page = new_page
|
||||
self._on_page_changed()
|
||||
return
|
||||
elif abs(offset) > 8:
|
||||
self._start_drag_snap(offset)
|
||||
return
|
||||
elif abs(offset) > 8:
|
||||
self._start_drag_snap(offset)
|
||||
return
|
||||
return
|
||||
super()._handle_mouse_release(mouse_pos)
|
||||
|
||||
# ── page indicator ─────────────────────────────────────────
|
||||
@@ -2787,6 +2801,8 @@ class AetherTile(Widget):
|
||||
color=AetherListColors.MUTED,
|
||||
)
|
||||
|
||||
return layout
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
pass
|
||||
|
||||
@@ -2906,6 +2922,7 @@ class ToggleTile(AetherTile):
|
||||
desc: str = "",
|
||||
is_enabled: Callable[[], bool] | None = None,
|
||||
disabled_label: str = "",
|
||||
show_led: bool = False,
|
||||
):
|
||||
if bg_color:
|
||||
super().__init__(surface_color=bg_color)
|
||||
@@ -2922,6 +2939,7 @@ class ToggleTile(AetherTile):
|
||||
self._inactive_color = rl.Color(120, 120, 120, 255)
|
||||
self._disabled_color = rl.Color(75, 75, 75, 255)
|
||||
self._disabled_label = disabled_label
|
||||
self._show_led = show_led
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
if self._is_pressed:
|
||||
@@ -2947,17 +2965,44 @@ class ToggleTile(AetherTile):
|
||||
else:
|
||||
state_text = tr(self._disabled_label) if self._disabled_label else tr("LOCKED")
|
||||
self._draw_signal_edge(face, self._active_color if enabled and active else self.surface_color, width=TILE_SIGNAL_WIDTH, alpha=62 if enabled and active else 28)
|
||||
self._render_tile_stack(
|
||||
face,
|
||||
title=self.title,
|
||||
primary=state_text,
|
||||
desc=self.desc,
|
||||
title_font=self._font,
|
||||
primary_font=self._font,
|
||||
desc_font=self._font_desc,
|
||||
title_size=28,
|
||||
primary_size=30,
|
||||
)
|
||||
|
||||
if self._show_led and enabled:
|
||||
layout = self._render_tile_stack(
|
||||
face,
|
||||
title=self.title,
|
||||
primary="",
|
||||
desc=self.desc,
|
||||
title_font=self._font,
|
||||
primary_font=self._font,
|
||||
desc_font=self._font_desc,
|
||||
title_size=28,
|
||||
primary_size=30,
|
||||
)
|
||||
primary_y = layout["primary_y"]
|
||||
content_pad = SPACING.tile_content
|
||||
scale = max(0.82, min(1.12, min(face.width / 360.0, face.height / 205.0)))
|
||||
ps = max(18, int(round(30 * scale)))
|
||||
cx = face.x + face.width - content_pad - 10
|
||||
cy = primary_y + ps / 2
|
||||
if active:
|
||||
glow_color = _with_alpha(self._active_color, 24)
|
||||
rl.draw_circle(int(cx), int(cy), 10, glow_color)
|
||||
rl.draw_circle(int(cx), int(cy), 6, self._active_color)
|
||||
else:
|
||||
rl.draw_circle(int(cx), int(cy), 7, rl.Color(14, 16, 22, 255))
|
||||
rl.draw_ring(rl.Vector2(cx, cy), 5, 6, 0, 360, 24, rl.Color(70, 78, 95, 140))
|
||||
else:
|
||||
self._render_tile_stack(
|
||||
face,
|
||||
title=self.title,
|
||||
primary=state_text,
|
||||
desc=self.desc,
|
||||
title_font=self._font,
|
||||
primary_font=self._font,
|
||||
desc_font=self._font_desc,
|
||||
title_size=28,
|
||||
primary_size=30,
|
||||
)
|
||||
|
||||
|
||||
class ValueTile(AetherTile):
|
||||
|
||||
@@ -115,7 +115,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "AdvancedLateralTune",
|
||||
"title": tr("Advanced Lateral Tuning"),
|
||||
"subtitle": tr("Advanced steering control changes to fine-tune how openpilot drives."),
|
||||
"subtitle": tr("Fine-tune steering response and auto-tuning."),
|
||||
"get": lambda: p.get_bool("AdvancedLateralTune"),
|
||||
"set": lambda s: p.put_bool("AdvancedLateralTune", s),
|
||||
})
|
||||
@@ -123,7 +123,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "AlwaysOnLateral",
|
||||
"title": tr("Always On Lateral"),
|
||||
"subtitle": tr("Keep lateral control active even without openpilot engaged."),
|
||||
"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)),
|
||||
@@ -140,7 +140,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "PauseLateralOnSignal",
|
||||
"title": tr("Turn Signal Only"),
|
||||
"subtitle": tr("Only pause steering below the set speed when the turn signal is active."),
|
||||
"subtitle": tr("Only pause steering when turn signal is active."),
|
||||
"get": lambda: p.get_bool("PauseLateralOnSignal"),
|
||||
"set": lambda s: p.put_bool("PauseLateralOnSignal", s),
|
||||
})
|
||||
@@ -148,7 +148,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "NudgelessLaneChange",
|
||||
"title": tr("Auto Lane Changes"),
|
||||
"subtitle": tr("When the turn signal is on, openpilot will automatically change lanes without a nudge."),
|
||||
"subtitle": tr("Signal triggers automatic lane change."),
|
||||
"get": lambda: p.get_bool("NudgelessLaneChange"),
|
||||
"set": lambda s: p.put_bool("NudgelessLaneChange", s),
|
||||
})
|
||||
@@ -156,7 +156,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "OneLaneChange",
|
||||
"title": tr("One Per Signal"),
|
||||
"subtitle": tr("Limit automatic lane changes to one per turn-signal activation."),
|
||||
"subtitle": tr("One lane change per signal activation."),
|
||||
"get": lambda: p.get_bool("OneLaneChange"),
|
||||
"set": lambda s: p.put_bool("OneLaneChange", s),
|
||||
})
|
||||
@@ -164,7 +164,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "TurnDesires",
|
||||
"title": tr("Force Turn Desires"),
|
||||
"subtitle": tr("While driving below the minimum lane change speed with an active turn signal, instruct openpilot to turn."),
|
||||
"subtitle": tr("Follow turn intent below min lane change speed."),
|
||||
"get": lambda: p.get_bool("TurnDesires"),
|
||||
"set": lambda s: (p.put_bool("TurnDesires", s),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
@@ -173,7 +173,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "NavDesiresAllowed",
|
||||
"title": tr("Use Route Desires"),
|
||||
"subtitle": tr("Allow an active navigation route to request keep-left, keep-right, and low-speed turn 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),
|
||||
})
|
||||
@@ -181,7 +181,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "NNFF",
|
||||
"title": tr("NNFF"),
|
||||
"subtitle": tr("Neural Network FeedForward controller — uses a trained model to predict steering torque."),
|
||||
"subtitle": tr("Neural net feedforward steering controller."),
|
||||
"get": lambda: p.get_bool("NNFF"),
|
||||
"set": lambda s: (p.put_bool("NNFF", s),
|
||||
s and p.put_bool("NNFFLite", False),
|
||||
@@ -193,7 +193,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "NNFFLite",
|
||||
"title": tr("NNFF Lite"),
|
||||
"subtitle": tr("Lightweight NNFF steering logic when the full model is off."),
|
||||
"subtitle": tr("Lightweight NNFF when full model is off."),
|
||||
"get": lambda: p.get_bool("NNFFLite"),
|
||||
"set": lambda s: (p.put_bool("NNFFLite", s),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
@@ -204,7 +204,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "ForceAutoTune",
|
||||
"title": tr("Force Auto-Tune On"),
|
||||
"subtitle": tr("Force-enable live auto-tuning for friction and lateral acceleration."),
|
||||
"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),
|
||||
s and p.put_bool("ForceAutoTuneOff", False),
|
||||
@@ -216,7 +216,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "ForceAutoTuneOff",
|
||||
"title": tr("Force Auto-Tune Off"),
|
||||
"subtitle": tr("Force-disable live auto-tuning and use your set values instead."),
|
||||
"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),
|
||||
s and p.put_bool("ForceAutoTune", False),
|
||||
@@ -228,7 +228,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
toggles.append({
|
||||
"key": "ForceTorqueController",
|
||||
"title": tr("Force Torque Ctrl"),
|
||||
"subtitle": tr("Use torque-based steering control instead of angle-based for smoother lane keeping, especially in curves."),
|
||||
"subtitle": tr("Torque-based steering for smoother lane keeping."),
|
||||
"get": lambda: p.get_bool("ForceTorqueController"),
|
||||
"set": lambda s: (p.put_bool("ForceTorqueController", s),
|
||||
_sync_parent(p, "LateralTune", _LATERAL_TUNE_KEYS)),
|
||||
@@ -249,6 +249,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
desc=td.get("subtitle", ""),
|
||||
is_enabled=td.get("enabled", True),
|
||||
disabled_label=td.get("disabled_label", ""),
|
||||
show_led=True,
|
||||
))
|
||||
|
||||
def _measure_content_height(self, width: float) -> float:
|
||||
@@ -402,7 +403,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
rows.append({
|
||||
"target_id": "select:SteerDelay",
|
||||
"title": tr("Actuator Delay"),
|
||||
"subtitle": tr("The time between openpilot's steering command and the vehicle's response."),
|
||||
"subtitle": tr("Time between steering command and vehicle response."),
|
||||
"get_value": lambda: f"{p.get_float('SteerDelay'):.2f}s",
|
||||
"pill_width": 120,
|
||||
})
|
||||
@@ -434,7 +435,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
rows.append({
|
||||
"target_id": "select:SteerRatio",
|
||||
"title": tr("Steer Ratio"),
|
||||
"subtitle": tr("Adjust the relationship between steering wheel input and road-wheel angle."),
|
||||
"subtitle": tr("Relationship between steering wheel and road-wheel angle."),
|
||||
"get_value": lambda: f"{p.get_float('SteerRatio'):.2f}",
|
||||
"pill_width": 120,
|
||||
})
|
||||
@@ -449,7 +450,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
aol_rows = [{
|
||||
"target_id": "select:PauseAOLOnBrake",
|
||||
"title": tr("Pause AOL On Brake"),
|
||||
"subtitle": tr("Pause Always On Lateral below this speed while the brake is pressed."),
|
||||
"subtitle": tr("Pause AOL below this speed while brake is pressed."),
|
||||
"get_value": lambda: f"{p.get_int('PauseAOLOnBrake')} mph",
|
||||
"pill_width": 140,
|
||||
}]
|
||||
@@ -480,14 +481,14 @@ class SteeringManagerView(PanelManagerView):
|
||||
lc_rows.append({
|
||||
"target_id": "select:LaneDetectionWidth",
|
||||
"title": tr("Min Lane Width"),
|
||||
"subtitle": tr("Prevent automatic lane changes into lanes narrower than this width."),
|
||||
"subtitle": tr("Prevent lane changes into narrower lanes."),
|
||||
"get_value": lambda: f"{p.get_float('LaneDetectionWidth'):.1f} ft",
|
||||
"pill_width": 120,
|
||||
})
|
||||
lc_rows.append({
|
||||
"target_id": "select:LaneChangeSmoothing",
|
||||
"title": tr("Lane Change Smoothing"),
|
||||
"subtitle": tr("How smoothly openpilot commits to a lane change. 10 = Stock, 1 = Smoothest."),
|
||||
"subtitle": tr("Smoothness of lane change commit. 10 = Stock, 1 = Smoothest."),
|
||||
"get_value": lambda: tr("Stock") if p.get_int("LaneChangeSmoothing") == 10
|
||||
else f"{p.get_int('LaneChangeSmoothing')}",
|
||||
"pill_width": 120,
|
||||
@@ -510,7 +511,7 @@ class SteeringManagerView(PanelManagerView):
|
||||
paus_rows.append({
|
||||
"target_id": "select:LateralResumeDelay",
|
||||
"title": tr("Resume Delay"),
|
||||
"subtitle": tr("Delay before lateral resumes after the turn signal is turned off. 0 = Off."),
|
||||
"subtitle": tr("Delay before lateral resumes after signal off. 0 = Off."),
|
||||
"get_value": lambda: tr("Off") if p.get_float("LateralResumeDelay") == 0
|
||||
else f"{p.get_float('LateralResumeDelay'):.1f}s",
|
||||
"pill_width": 120,
|
||||
|
||||
@@ -310,6 +310,8 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
self._connectivity_tile_grid.add_tile(tile)
|
||||
self._connectivity_tile_grid.set_touch_valid_callback(lambda: self._scroll_panel.is_touch_valid())
|
||||
self._child(self._connectivity_tile_grid)
|
||||
self._page_grid = self._connectivity_tile_grid
|
||||
self._set_toggle_pages([self._toggle_defs[i:i+4] for i in range(0, len(self._toggle_defs), 4)])
|
||||
|
||||
self._drive_mode_control = self._child(
|
||||
AetherSegmentedControl(
|
||||
@@ -554,7 +556,7 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
|
||||
def _draw_connectivity_tiles_column(self, y: float, x: float, width: float, height: float):
|
||||
draw_list_group_shell(rl.Rectangle(x, y, width, height), style=PANEL_STYLE)
|
||||
self._connectivity_tile_grid.render(rl.Rectangle(x + 12, y + 12, width - 24, height - 24))
|
||||
self._render_page_grid(self._connectivity_tile_grid, rl.Rectangle(x + 12, y + 12, width - 24, height - 24))
|
||||
|
||||
def _draw_connectivity_tiles_section(self, y: float, x: float, width: float):
|
||||
tile_rows = self._connectivity_tile_grid.get_row_count(len(self._connectivity_tile_grid.tiles), available_width=width)
|
||||
@@ -562,7 +564,7 @@ class SystemSettingsManagerView(PanelManagerView):
|
||||
tiles_content_h = tile_rows * 130 + tile_gaps
|
||||
|
||||
draw_list_group_shell(rl.Rectangle(x, y, width, tiles_content_h + 24), style=PANEL_STYLE)
|
||||
self._connectivity_tile_grid.render(rl.Rectangle(x + 12, y + 12, width - 24, tiles_content_h))
|
||||
self._render_page_grid(self._connectivity_tile_grid, rl.Rectangle(x + 12, y + 12, width - 24, tiles_content_h))
|
||||
|
||||
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, SECTION_HEADER_HEIGHT), title, style=PANEL_STYLE)
|
||||
|
||||
Reference in New Issue
Block a user