mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-11 20:32:13 +08:00
BigUI WIP: More Tab Stuff
(cherry picked from commit 9ba41d1a4a46cb95c5ef07901593e72d3d00ad7a)
This commit is contained in:
committed by
firestar5683
parent
355fe2a273
commit
0b0fb3957a
@@ -568,8 +568,8 @@ class RadioTileGroup(Widget):
|
||||
self._option_targets.append(0.0)
|
||||
for i in range(len(self._option_offsets)):
|
||||
self._option_offsets[i] += (self._option_targets[i] - self._option_offsets[i]) * (1 - math.exp(-dt / PLATE_TAU))
|
||||
padding = 20
|
||||
option_w = 240 if len(self.options) <= 3 else 200
|
||||
padding = 16
|
||||
option_w = 240 if len(self.options) <= 3 else 188
|
||||
total_width = len(self.options) * option_w + max(0, len(self.options) - 1) * padding
|
||||
if self.title:
|
||||
title_size = measure_text_cached(self._font_title, self.title, 40)
|
||||
@@ -591,10 +591,17 @@ class RadioTileGroup(Widget):
|
||||
rl.draw_rectangle_rounded(face_rect, TILE_RADIUS, 10, color)
|
||||
rl.draw_rectangle_rounded(rl.Rectangle(face_rect.x + 1, face_rect.y + 1, face_rect.width - 2, face_rect.height - 2), TILE_RADIUS, 10, rl.Color(0, 0, 0, 80))
|
||||
rl.draw_rectangle_rounded(rl.Rectangle(face_rect.x, face_rect.y, face_rect.width - 1.5, face_rect.height - 1.5), TILE_RADIUS, 10, rl.Color(255, 255, 255, 110))
|
||||
ts = measure_text_cached(self._font, opt.upper(), 35)
|
||||
font_size = 30
|
||||
spacing = round(font_size * 0.08)
|
||||
max_width = r.width - 28
|
||||
ts = measure_text_cached(self._font, opt, font_size, spacing=spacing)
|
||||
while font_size > 22 and ts.x > max_width:
|
||||
font_size -= 1
|
||||
spacing = round(font_size * 0.08)
|
||||
ts = measure_text_cached(self._font, opt, font_size, spacing=spacing)
|
||||
text_pos = rl.Vector2(face_x + (r.width - ts.x) / 2, face_y + (r.height - ts.y) / 2)
|
||||
rl.draw_text_ex(self._font, opt.upper(), rl.Vector2(round(text_pos.x + 1), round(text_pos.y + 2)), 35, 0, rl.Color(0, 0, 0, 90))
|
||||
rl.draw_text_ex(self._font, opt.upper(), rl.Vector2(round(text_pos.x), round(text_pos.y)), 35, 0, rl.WHITE)
|
||||
rl.draw_text_ex(self._font, opt, rl.Vector2(round(text_pos.x + 1), round(text_pos.y + 2)), font_size, spacing, rl.Color(0, 0, 0, 90))
|
||||
rl.draw_text_ex(self._font, opt, rl.Vector2(round(text_pos.x), round(text_pos.y)), font_size, spacing, rl.WHITE)
|
||||
|
||||
|
||||
class TileGrid(Widget):
|
||||
|
||||
@@ -30,7 +30,7 @@ class StarPilotDataLayout(StarPilotPanel):
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Manage Backups"), "panel": "backups", "icon": "toggle_icons/icon_system.png", "color": "#D43D8A"},
|
||||
{"title": tr_noop("Toggle Backups"), "panel": "toggle_backups", "icon": "toggle_icons/icon_system.png", "color": "#D43D8A"},
|
||||
{"title": tr_noop("Manage Storage"), "panel": "storage", "icon": "toggle_icons/icon_system.png", "color": "#D43D8A"},
|
||||
{"title": tr_noop("Driving Data Storage"), "type": "value", "get_value": self._get_storage, "on_click": lambda: None, "icon": "toggle_icons/icon_system.png", "color": "#D43D8A", "is_enabled": lambda: False},
|
||||
{
|
||||
"title": tr_noop("Delete Driving Data"),
|
||||
"type": "hub",
|
||||
@@ -50,7 +50,6 @@ class StarPilotDataLayout(StarPilotPanel):
|
||||
self._sub_panels = {
|
||||
"backups": StarPilotBackupsLayout(),
|
||||
"toggle_backups": StarPilotToggleBackupsLayout(),
|
||||
"storage": StarPilotStorageLayout(),
|
||||
}
|
||||
self._tile_grid = TileGrid(columns=2, padding=20, uniform_width=True)
|
||||
|
||||
@@ -89,6 +88,18 @@ class StarPilotDataLayout(StarPilotPanel):
|
||||
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("Delete all error logs?"), tr("Delete"), on_close=_do_delete))
|
||||
|
||||
def _get_storage(self):
|
||||
paths = ["/data/media/0/osm/offline", "/data/media/0/realdata", "/data/backups"]
|
||||
total = 0
|
||||
for p in paths:
|
||||
pp = Path(p)
|
||||
if pp.exists():
|
||||
total += sum(f.stat().st_size for f in pp.rglob('*') if f.is_file())
|
||||
mb = total / (1024 * 1024)
|
||||
if mb > 1024:
|
||||
return f"{(mb / 1024):.2f} GB"
|
||||
return f"{mb:.2f} MB"
|
||||
|
||||
|
||||
class StarPilotBackupsLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
@@ -231,25 +242,3 @@ class StarPilotToggleBackupsLayout(StarPilotPanel):
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Delete Toggle Backup"), backups, on_close=_on_select))
|
||||
|
||||
|
||||
class StarPilotStorageLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._tile_grid = TileGrid(columns=2, padding=20, uniform_width=True)
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Driving Data"), "type": "value", "get_value": self._get_storage, "on_click": lambda: None, "color": "#D43D8A", "is_enabled": lambda: False},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _get_storage(self):
|
||||
paths = ["/data/media/0/osm/offline", "/data/media/0/realdata", "/data/backups"]
|
||||
total = 0
|
||||
for p in paths:
|
||||
pp = Path(p)
|
||||
if pp.exists():
|
||||
total += sum(f.stat().st_size for f in pp.rglob('*') if f.is_file())
|
||||
mb = total / (1024 * 1024)
|
||||
if mb > 1024:
|
||||
return f"{(mb / 1024):.2f} GB"
|
||||
return f"{mb:.2f} MB"
|
||||
|
||||
@@ -5,7 +5,8 @@ from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.widgets import DialogResult
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.tabbed_panel import TabSectionSpec, TabbedSectionHost
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import AetherSliderDialog
|
||||
|
||||
class StarPilotAdvancedLateralLayout(StarPilotPanel):
|
||||
@@ -124,21 +125,41 @@ class StarPilotLateralQOLLayout(StarPilotPanel):
|
||||
class StarPilotLateralLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._sub_panels = {
|
||||
"advanced_lateral": StarPilotAdvancedLateralLayout(),
|
||||
"always_on_lateral": StarPilotAlwaysOnLateralLayout(),
|
||||
"lane_changes": StarPilotLaneChangesLayout(),
|
||||
"lateral_tune": StarPilotLateralTuneLayout(),
|
||||
"qol": StarPilotLateralQOLLayout(),
|
||||
}
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Advanced Lateral Tuning"), "panel": "advanced_lateral", "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
steering_panel = create_tile_panel([
|
||||
{"title": tr_noop("Always On Lateral"), "panel": "always_on_lateral", "icon": "toggle_icons/icon_always_on_lateral.png", "color": "#597497"},
|
||||
{"title": tr_noop("Lane Changes"), "panel": "lane_changes", "icon": "toggle_icons/icon_lane.png", "color": "#597497"},
|
||||
{"title": tr_noop("Lateral Tuning"), "panel": "lateral_tune", "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Quality of Life"), "panel": "qol", "icon": "toggle_icons/icon_quality_of_life.png", "color": "#597497"},
|
||||
]
|
||||
for name, panel in self._sub_panels.items():
|
||||
if hasattr(panel, 'set_navigate_callback'): panel.set_navigate_callback(self._navigate_to)
|
||||
if hasattr(panel, 'set_back_callback'): panel.set_back_callback(self._go_back)
|
||||
self._rebuild_grid()
|
||||
], {
|
||||
"always_on_lateral": StarPilotAlwaysOnLateralLayout(),
|
||||
"qol": StarPilotLateralQOLLayout(),
|
||||
})
|
||||
tune_panel = create_tile_panel([
|
||||
{"title": tr_noop("Advanced Tuning"), "panel": "advanced_lateral", "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Lateral Tuning"), "panel": "lateral_tune", "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497"},
|
||||
], {
|
||||
"advanced_lateral": StarPilotAdvancedLateralLayout(),
|
||||
"lateral_tune": StarPilotLateralTuneLayout(),
|
||||
})
|
||||
|
||||
self._section_tabs = TabbedSectionHost([
|
||||
TabSectionSpec("steering", "Steering", steering_panel),
|
||||
TabSectionSpec("lane", "Lane", StarPilotLaneChangesLayout()),
|
||||
TabSectionSpec("tune", "Tune", tune_panel),
|
||||
])
|
||||
|
||||
def set_navigate_callback(self, callback):
|
||||
self._section_tabs.set_navigate_callback(callback)
|
||||
|
||||
def set_back_callback(self, callback):
|
||||
self._section_tabs.set_back_callback(callback)
|
||||
|
||||
def _render(self, rect):
|
||||
self._section_tabs.render(rect)
|
||||
|
||||
def set_current_sub_panel(self, sub_panel: str):
|
||||
self._section_tabs.set_current_sub_panel(sub_panel)
|
||||
|
||||
def show_event(self):
|
||||
self._section_tabs.show_event()
|
||||
|
||||
def hide_event(self):
|
||||
self._section_tabs.hide_event()
|
||||
|
||||
@@ -6,56 +6,68 @@ from openpilot.system.ui.widgets import DialogResult
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.system.ui.widgets.input_dialog import InputDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.tabbed_panel import TabSectionSpec, TabbedSectionHost
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import AetherSliderDialog
|
||||
|
||||
|
||||
class StarPilotLongitudinalLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._sub_panels = {
|
||||
"advanced": StarPilotAdvancedLongitudinalLayout(),
|
||||
"conditional": StarPilotConditionalExperimentalLayout(),
|
||||
"curve": StarPilotCurveSpeedLayout(),
|
||||
"personalities": StarPilotPersonalitiesLayout(),
|
||||
tune_panel = create_tile_panel([
|
||||
{"title": tr_noop("Longitudinal Tuning"), "panel": "tuning", "icon": "toggle_icons/icon_longitudinal_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Advanced Tuning"), "panel": "advanced", "icon": "toggle_icons/icon_advanced_longitudinal_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Driving Personalities"), "panel": "personalities", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
||||
], {
|
||||
"tuning": StarPilotLongitudinalTuneLayout(),
|
||||
"qol": StarPilotLongitudinalQOLLayout(),
|
||||
"slc": StarPilotSpeedLimitControllerLayout(),
|
||||
"weather": StarPilotWeatherLayout(),
|
||||
# Personality Sub-panels
|
||||
"advanced": StarPilotAdvancedLongitudinalLayout(),
|
||||
"personalities": StarPilotPersonalitiesLayout(),
|
||||
"traffic_personality": StarPilotPersonalityProfileLayout("Traffic"),
|
||||
"aggressive_personality": StarPilotPersonalityProfileLayout("Aggressive"),
|
||||
"standard_personality": StarPilotPersonalityProfileLayout("Standard"),
|
||||
"relaxed_personality": StarPilotPersonalityProfileLayout("Relaxed"),
|
||||
# SLC Sub-panels
|
||||
"slc_offsets": StarPilotSLCOffsetsLayout(),
|
||||
"slc_qol": StarPilotSLCQOLLayout(),
|
||||
"slc_visuals": StarPilotSLCVisualsLayout(),
|
||||
# Weather Sub-panels
|
||||
})
|
||||
|
||||
adaptive_panel = create_tile_panel([
|
||||
{"title": tr_noop("Conditional Experimental"), "panel": "conditional", "icon": "toggle_icons/icon_conditional.png", "color": "#597497"},
|
||||
{"title": tr_noop("Curve Speed"), "panel": "curve", "icon": "toggle_icons/icon_speed_map.png", "color": "#597497"},
|
||||
{"title": tr_noop("Weather"), "panel": "weather", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
||||
], {
|
||||
"conditional": StarPilotConditionalExperimentalLayout(),
|
||||
"curve": StarPilotCurveSpeedLayout(),
|
||||
"weather": StarPilotWeatherLayout(),
|
||||
"low_visibility": StarPilotWeatherBase("LowVisibility"),
|
||||
"rain": StarPilotWeatherBase("Rain"),
|
||||
"rainstorm": StarPilotWeatherBase("RainStorm"),
|
||||
"snow": StarPilotWeatherBase("Snow"),
|
||||
}
|
||||
})
|
||||
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Advanced Longitudinal Tuning"), "panel": "advanced", "icon": "toggle_icons/icon_advanced_longitudinal_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Conditional Experimental Mode"), "panel": "conditional", "icon": "toggle_icons/icon_conditional.png", "color": "#597497"},
|
||||
{"title": tr_noop("Curve Speed Controller"), "panel": "curve", "icon": "toggle_icons/icon_speed_map.png", "color": "#597497"},
|
||||
{"title": tr_noop("Driving Personalities"), "panel": "personalities", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
||||
{"title": tr_noop("Longitudinal Tuning"), "panel": "tuning", "icon": "toggle_icons/icon_longitudinal_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Quality of Life"), "panel": "qol", "icon": "toggle_icons/icon_quality_of_life.png", "color": "#597497"},
|
||||
{"title": tr_noop("Speed Limit Controller"), "panel": "slc", "icon": "toggle_icons/icon_speed_limit.png", "color": "#597497"},
|
||||
{"title": tr_noop("Weather"), "panel": "weather", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
||||
]
|
||||
|
||||
for name, panel in self._sub_panels.items():
|
||||
if hasattr(panel, 'set_navigate_callback'):
|
||||
panel.set_navigate_callback(self._navigate_to)
|
||||
if hasattr(panel, 'set_back_callback'):
|
||||
panel.set_back_callback(self._go_back)
|
||||
self._section_tabs = TabbedSectionHost([
|
||||
TabSectionSpec("tune", "Tune", tune_panel),
|
||||
TabSectionSpec("adaptive", "Adaptive", adaptive_panel),
|
||||
TabSectionSpec("limits", "Limits", StarPilotSpeedLimitControllerLayout()),
|
||||
TabSectionSpec("daily", "Daily", StarPilotLongitudinalQOLLayout()),
|
||||
])
|
||||
self._rebuild_grid()
|
||||
|
||||
def set_navigate_callback(self, callback):
|
||||
self._section_tabs.set_navigate_callback(callback)
|
||||
|
||||
def set_back_callback(self, callback):
|
||||
self._section_tabs.set_back_callback(callback)
|
||||
|
||||
def _render(self, rect):
|
||||
self._section_tabs.render(rect)
|
||||
|
||||
def set_current_sub_panel(self, sub_panel: str):
|
||||
self._section_tabs.set_current_sub_panel(sub_panel)
|
||||
|
||||
def show_event(self):
|
||||
self._section_tabs.show_event()
|
||||
|
||||
def hide_event(self):
|
||||
self._section_tabs.hide_event()
|
||||
|
||||
|
||||
class StarPilotAdvancedLongitudinalLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
@@ -165,15 +177,6 @@ class StarPilotConditionalExperimentalLayout(StarPilotPanel):
|
||||
"icon": "toggle_icons/icon_conditional.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Conditional Experimental"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("ConditionalExperimental"),
|
||||
"set_state": lambda s: self._params.put_bool("ConditionalExperimental", s),
|
||||
"icon": "toggle_icons/icon_conditional.png",
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Below Speed"),
|
||||
"type": "value",
|
||||
@@ -302,16 +305,6 @@ class StarPilotCurveSpeedLayout(StarPilotPanel):
|
||||
"icon": "toggle_icons/icon_speed_map.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Curve Speed Controller"),
|
||||
"desc": tr_noop("Automatically slow down for upcoming curves using data learned from your driving style."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("CurveSpeedController"),
|
||||
"set_state": lambda s: self._params.put_bool("CurveSpeedController", s),
|
||||
"icon": "toggle_icons/icon_speed_map.png",
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("CurveSpeedController"),
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Status Widget"),
|
||||
"desc": tr_noop("Show the Curve Speed Controller ambient effect on the driving screen."),
|
||||
@@ -677,6 +670,11 @@ class StarPilotLongitudinalQOLLayout(StarPilotPanel):
|
||||
class StarPilotSpeedLimitControllerLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._sub_panels = {
|
||||
"slc_offsets": StarPilotSLCOffsetsLayout(),
|
||||
"slc_qol": StarPilotSLCQOLLayout(),
|
||||
"slc_visuals": StarPilotSLCVisualsLayout(),
|
||||
}
|
||||
self.CATEGORIES = [
|
||||
{
|
||||
"title": tr_noop("Speed Limit Controller"),
|
||||
@@ -712,6 +710,13 @@ class StarPilotSpeedLimitControllerLayout(StarPilotPanel):
|
||||
"color": "#597497",
|
||||
},
|
||||
]
|
||||
|
||||
for panel in self._sub_panels.values():
|
||||
if hasattr(panel, 'set_navigate_callback'):
|
||||
panel.set_navigate_callback(self._navigate_to)
|
||||
if hasattr(panel, 'set_back_callback'):
|
||||
panel.set_back_callback(self._go_back)
|
||||
|
||||
self._rebuild_grid()
|
||||
|
||||
def _get_priority_value(self):
|
||||
|
||||
@@ -110,6 +110,9 @@ class StarPilotLayout(Widget):
|
||||
StarPilotPanelType.LATERAL,
|
||||
StarPilotPanelType.NAVIGATION,
|
||||
StarPilotPanelType.MAPS,
|
||||
StarPilotPanelType.VISUALS,
|
||||
StarPilotPanelType.THEMES,
|
||||
StarPilotPanelType.VEHICLE,
|
||||
)
|
||||
|
||||
self._main_grid = TileGrid(columns=None, padding=20)
|
||||
@@ -162,7 +165,11 @@ class StarPilotLayout(Widget):
|
||||
self._depth_callback(depth)
|
||||
|
||||
def _push_sub_panel(self, sub_panel_name: str):
|
||||
self._panel_stack.append((self._current_panel, sub_panel_name))
|
||||
if sub_panel_name:
|
||||
self._panel_stack.append((self._current_panel, sub_panel_name))
|
||||
else:
|
||||
while self._panel_stack and self._panel_stack[-1][0] == self._current_panel:
|
||||
self._panel_stack.pop()
|
||||
self._update_sub_panel_visibility()
|
||||
self._update_depth()
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import pyray as rl
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid
|
||||
|
||||
|
||||
class StarPilotPanelType(IntEnum):
|
||||
@@ -121,3 +122,19 @@ class StarPilotPanel(Widget):
|
||||
self._sub_panels[self._current_sub_panel].show_event()
|
||||
elif self._scroller:
|
||||
self._scroller.show_event()
|
||||
|
||||
|
||||
def create_tile_panel(categories: list[dict], sub_panels: dict[str, Widget] | None = None) -> StarPilotPanel:
|
||||
panel = StarPilotPanel()
|
||||
panel.CATEGORIES = categories
|
||||
panel._sub_panels = sub_panels or {}
|
||||
panel._tile_grid = TileGrid(columns=2, padding=20, uniform_width=True)
|
||||
|
||||
for name, child in panel._sub_panels.items():
|
||||
if hasattr(child, 'set_navigate_callback'):
|
||||
child.set_navigate_callback(panel._navigate_to)
|
||||
if hasattr(child, 'set_back_callback'):
|
||||
child.set_back_callback(panel._go_back)
|
||||
|
||||
panel._rebuild_grid()
|
||||
return panel
|
||||
|
||||
@@ -58,7 +58,13 @@ class StarPilotSoundsLayout(StarPilotPanel):
|
||||
|
||||
def _on_section_change(self, index: int):
|
||||
if 0 <= index < len(self._section_names):
|
||||
self._set_active_section(self._section_names[index])
|
||||
previous_panel = self._sub_panels[self._active_section]
|
||||
if hasattr(previous_panel, 'set_current_sub_panel'):
|
||||
previous_panel.set_current_sub_panel("")
|
||||
self._current_sub_panel = ""
|
||||
self._set_active_section(self._section_names[index], "")
|
||||
if self._navigate_callback:
|
||||
self._navigate_callback("")
|
||||
|
||||
def _set_active_section(self, section_name: str, child_panel: str = ""):
|
||||
if section_name not in self._sub_panels:
|
||||
|
||||
@@ -38,7 +38,13 @@ class StarPilotSystemLayout(StarPilotPanel):
|
||||
|
||||
def _on_section_change(self, index: int):
|
||||
if 0 <= index < len(self._section_names):
|
||||
self._set_active_section(self._section_names[index])
|
||||
previous_panel = self._sub_panels[self._active_section]
|
||||
if hasattr(previous_panel, 'set_current_sub_panel'):
|
||||
previous_panel.set_current_sub_panel("")
|
||||
self._current_sub_panel = ""
|
||||
self._set_active_section(self._section_names[index], "")
|
||||
if self._navigate_callback:
|
||||
self._navigate_callback("")
|
||||
|
||||
def _set_active_section(self, section_name: str, child_panel: str = ""):
|
||||
if section_name not in self._sub_panels:
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
import pyray as rl
|
||||
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import RadioTileGroup
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TabSectionSpec:
|
||||
key: str
|
||||
label: str
|
||||
panel: Widget
|
||||
|
||||
|
||||
class TabbedSectionHost(Widget):
|
||||
def __init__(self, sections: list[TabSectionSpec]):
|
||||
super().__init__()
|
||||
if not sections:
|
||||
raise ValueError("TabbedSectionHost requires at least one section")
|
||||
|
||||
self._sections = {spec.key: spec.panel for spec in sections}
|
||||
self._section_order = [spec.key for spec in sections]
|
||||
self._active_section = self._section_order[0]
|
||||
self._navigate_callback: Callable | None = None
|
||||
self._back_callback: Callable | None = None
|
||||
self._current_sub_panel = ""
|
||||
self._tab_height = 110
|
||||
self._panel_top = 140
|
||||
self._section_tabs = RadioTileGroup("", [tr(spec.label) for spec in sections], 0, self._on_tab_change)
|
||||
|
||||
for key, panel in self._sections.items():
|
||||
if hasattr(panel, "set_navigate_callback"):
|
||||
panel.set_navigate_callback(lambda sub_panel, section_key=key: self._on_child_navigate(section_key, sub_panel))
|
||||
if hasattr(panel, "set_back_callback"):
|
||||
panel.set_back_callback(self._go_back)
|
||||
|
||||
def set_navigate_callback(self, callback: Callable):
|
||||
self._navigate_callback = callback
|
||||
|
||||
def set_back_callback(self, callback: Callable):
|
||||
self._back_callback = callback
|
||||
|
||||
def set_current_sub_panel(self, sub_panel: str):
|
||||
self._current_sub_panel = sub_panel
|
||||
if not sub_panel:
|
||||
panel = self._sections[self._active_section]
|
||||
if hasattr(panel, "set_current_sub_panel"):
|
||||
panel.set_current_sub_panel("")
|
||||
return
|
||||
|
||||
if ":" in sub_panel:
|
||||
section_key, child_panel = sub_panel.split(":", 1)
|
||||
self._activate_section(section_key, child_panel)
|
||||
elif sub_panel in self._sections:
|
||||
self._activate_section(sub_panel)
|
||||
else:
|
||||
panel = self._sections[self._active_section]
|
||||
if hasattr(panel, "set_current_sub_panel"):
|
||||
panel.set_current_sub_panel(sub_panel)
|
||||
|
||||
def _on_tab_change(self, index: int):
|
||||
if 0 <= index < len(self._section_order):
|
||||
self._current_sub_panel = ""
|
||||
self._activate_section(self._section_order[index], "")
|
||||
if self._navigate_callback:
|
||||
self._navigate_callback("")
|
||||
|
||||
def _activate_section(self, section_key: str, child_panel: str = ""):
|
||||
if section_key not in self._sections:
|
||||
return
|
||||
|
||||
previous = self._active_section
|
||||
if section_key != previous:
|
||||
previous_panel = self._sections[previous]
|
||||
if hasattr(previous_panel, "set_current_sub_panel"):
|
||||
previous_panel.set_current_sub_panel("")
|
||||
self._sections[previous].hide_event()
|
||||
self._active_section = section_key
|
||||
self._sections[section_key].show_event()
|
||||
|
||||
self._section_tabs.set_index(self._section_order.index(section_key))
|
||||
panel = self._sections[section_key]
|
||||
if hasattr(panel, "set_current_sub_panel"):
|
||||
panel.set_current_sub_panel(child_panel)
|
||||
|
||||
def _on_child_navigate(self, section_key: str, sub_panel: str):
|
||||
self._current_sub_panel = f"{section_key}:{sub_panel}" if sub_panel else section_key
|
||||
if self._navigate_callback:
|
||||
self._navigate_callback(self._current_sub_panel)
|
||||
|
||||
def _go_back(self):
|
||||
self._current_sub_panel = ""
|
||||
panel = self._sections[self._active_section]
|
||||
if hasattr(panel, "set_current_sub_panel"):
|
||||
panel.set_current_sub_panel("")
|
||||
if self._back_callback:
|
||||
self._back_callback()
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
tab_rect = rl.Rectangle(rect.x, rect.y, rect.width, self._tab_height)
|
||||
panel_rect = rl.Rectangle(rect.x, rect.y + self._panel_top, rect.width, rect.height - self._panel_top)
|
||||
self._section_tabs.render(tab_rect)
|
||||
self._sections[self._active_section].render(panel_rect)
|
||||
|
||||
def show_event(self):
|
||||
super().show_event()
|
||||
self._section_tabs.show_event()
|
||||
self._sections[self._active_section].show_event()
|
||||
|
||||
def hide_event(self):
|
||||
super().hide_event()
|
||||
self._section_tabs.hide_event()
|
||||
self._sections[self._active_section].hide_event()
|
||||
@@ -105,6 +105,7 @@ class StarPilotThemesLayout(StarPilotPanel):
|
||||
"icon": "toggle_icons/icon_frog.png",
|
||||
"color": "#542A71",
|
||||
"desc": tr_noop("Customize the overall look and feel."),
|
||||
"visible": lambda: self._params.get_bool("CustomThemes"),
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Holiday Themes"),
|
||||
@@ -179,13 +180,6 @@ class StarPilotPersonalizeLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{
|
||||
"title": tr_noop("Custom Themes"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("CustomThemes"),
|
||||
"set_state": lambda s: self._params.put_bool("CustomThemes", s),
|
||||
"color": "#542A71",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Boot Logo"),
|
||||
"type": "value",
|
||||
|
||||
@@ -4,108 +4,44 @@ from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.widgets import DialogResult
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.tabbed_panel import TabSectionSpec, TabbedSectionHost
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid, ToggleTile, AetherSliderDialog
|
||||
|
||||
|
||||
class StarPilotThemesLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._sub_panels = {
|
||||
"personalize": StarPilotPersonalizeLayout(),
|
||||
}
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Personalize openpilot"), "panel": "personalize", "icon": "toggle_icons/icon_frog.png", "color": "#8B5CF6"},
|
||||
{
|
||||
"title": tr_noop("Holiday Themes"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("HolidayThemes"),
|
||||
"set_state": lambda s: self._params.put_bool("HolidayThemes", s),
|
||||
"icon": "toggle_icons/icon_calendar.png",
|
||||
"color": "#8B5CF6",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Rainbow Path"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("RainbowPath"),
|
||||
"set_state": lambda s: self._params.put_bool("RainbowPath", s),
|
||||
"icon": "toggle_icons/icon_rainbow.png",
|
||||
"color": "#8B5CF6",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Random Events"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("RandomEvents"),
|
||||
"set_state": lambda s: self._params.put_bool("RandomEvents", s),
|
||||
"icon": "toggle_icons/icon_random.png",
|
||||
"color": "#8B5CF6",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Random Themes"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("RandomThemes"),
|
||||
"set_state": lambda s: self._params.put_bool("RandomThemes", s),
|
||||
"icon": "toggle_icons/icon_random_themes.png",
|
||||
"color": "#8B5CF6",
|
||||
},
|
||||
]
|
||||
for name, panel in self._sub_panels.items():
|
||||
if hasattr(panel, 'set_navigate_callback'):
|
||||
panel.set_navigate_callback(self._navigate_to)
|
||||
if hasattr(panel, 'set_back_callback'):
|
||||
panel.set_back_callback(self._go_back)
|
||||
self._rebuild_grid()
|
||||
|
||||
|
||||
class StarPilotPersonalizeLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Boot Logo"), "type": "hub", "on_click": lambda: self._show_theme_selector("BootLogo"), "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Color Scheme"), "type": "hub", "on_click": lambda: self._show_theme_selector("ColorScheme"), "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Distance Icons"), "type": "hub", "on_click": lambda: self._show_theme_selector("DistanceIconPack"), "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Icon Pack"), "type": "hub", "on_click": lambda: self._show_theme_selector("IconPack"), "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Turn Signals"), "type": "hub", "on_click": lambda: self._show_theme_selector("SignalAnimation"), "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Sound Pack"), "type": "hub", "on_click": lambda: self._show_theme_selector("SoundPack"), "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Steering Wheel"), "type": "hub", "on_click": lambda: self._show_theme_selector("WheelIcon"), "color": "#8B5CF6"},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _show_theme_selector(self, key):
|
||||
themes = ["Stock", "Frog", "Cyberpunk", "Minimal"]
|
||||
current = self._params.get(key, encoding='utf-8') or "Stock"
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put(key, val)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(key), themes, current, on_close=on_select))
|
||||
|
||||
|
||||
class StarPilotVisualsLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._sub_panels = {
|
||||
"advanced": StarPilotAdvancedVisualsLayout(),
|
||||
"widgets": StarPilotVisualWidgetsLayout(),
|
||||
"model": StarPilotModelUILayout(),
|
||||
"navigation": StarPilotNavigationVisualsLayout(),
|
||||
"qol": StarPilotVisualQOLLayout(),
|
||||
}
|
||||
self.CATEGORIES = [
|
||||
display_panel = create_tile_panel([
|
||||
{"title": tr_noop("Advanced UI Controls"), "panel": "advanced", "icon": "toggle_icons/icon_advanced_device.png", "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Driving Screen Widgets"), "panel": "widgets", "icon": "toggle_icons/icon_display.png", "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Model UI"), "panel": "model", "icon": "toggle_icons/icon_road.png", "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Navigation Widgets"), "panel": "navigation", "icon": "toggle_icons/icon_map.png", "color": "#8B5CF6"},
|
||||
{"title": tr_noop("Quality of Life"), "panel": "qol", "icon": "toggle_icons/icon_quality_of_life.png", "color": "#8B5CF6"},
|
||||
]
|
||||
for name, panel in self._sub_panels.items():
|
||||
if hasattr(panel, 'set_navigate_callback'):
|
||||
panel.set_navigate_callback(self._navigate_to)
|
||||
if hasattr(panel, 'set_back_callback'):
|
||||
panel.set_back_callback(self._go_back)
|
||||
self._rebuild_grid()
|
||||
], {
|
||||
"advanced": StarPilotAdvancedVisualsLayout(),
|
||||
"qol": StarPilotVisualQOLLayout(),
|
||||
})
|
||||
|
||||
self._section_tabs = TabbedSectionHost([
|
||||
TabSectionSpec("display", "Display", display_panel),
|
||||
TabSectionSpec("widgets", "Widgets", StarPilotVisualWidgetsLayout()),
|
||||
TabSectionSpec("model", "Model", StarPilotModelUILayout()),
|
||||
TabSectionSpec("navigation", "Nav", StarPilotNavigationVisualsLayout()),
|
||||
])
|
||||
|
||||
def set_navigate_callback(self, callback):
|
||||
self._section_tabs.set_navigate_callback(callback)
|
||||
|
||||
def set_back_callback(self, callback):
|
||||
self._section_tabs.set_back_callback(callback)
|
||||
|
||||
def _render(self, rect):
|
||||
self._section_tabs.render(rect)
|
||||
|
||||
def set_current_sub_panel(self, sub_panel: str):
|
||||
self._section_tabs.set_current_sub_panel(sub_panel)
|
||||
|
||||
def show_event(self):
|
||||
self._section_tabs.show_event()
|
||||
|
||||
def hide_event(self):
|
||||
self._section_tabs.hide_event()
|
||||
|
||||
|
||||
class StarPilotAdvancedVisualsLayout(StarPilotPanel):
|
||||
@@ -558,15 +494,6 @@ class StarPilotNavigationVisualsLayout(StarPilotPanel):
|
||||
"color": "#8B5CF6",
|
||||
"visible": lambda: self._params.get_bool("NavigationUI"),
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Mapbox Limits"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("SLCMapboxFiller"),
|
||||
"set_state": lambda s: self._params.put_bool("SLCMapboxFiller", s),
|
||||
"icon": "toggle_icons/icon_speed_limit.png",
|
||||
"color": "#8B5CF6",
|
||||
"visible": lambda: self._params.get_bool("NavigationUI") and self._params.get_bool("ShowSpeedLimits"),
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Vienna Signs"),
|
||||
"type": "toggle",
|
||||
|
||||
Reference in New Issue
Block a user