mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-04 15:56:04 +08:00
WIP BigUI: Fixes + Model Manager Stuff
This commit is contained in:
@@ -37,12 +37,14 @@ class MainLayout(Widget):
|
||||
# Set callbacks
|
||||
self._setup_callbacks()
|
||||
|
||||
gui_app.push_widget(self)
|
||||
|
||||
# Skip onboarding on desktop; keep normal flow on device.
|
||||
self._onboarding_window = None
|
||||
if not PC:
|
||||
self._onboarding_window = OnboardingWindow()
|
||||
if not self._onboarding_window.completed:
|
||||
gui_app.set_modal_overlay(self._onboarding_window)
|
||||
gui_app.push_widget(self._onboarding_window)
|
||||
|
||||
def _render(self, _):
|
||||
self._handle_onroad_transition()
|
||||
|
||||
@@ -6,6 +6,7 @@ from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.widgets import Widget, DialogResult
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.asset_loader import starpilot_texture
|
||||
|
||||
|
||||
GEOMETRY_OFFSET = 10
|
||||
@@ -207,7 +208,7 @@ class HubTile(AetherTile):
|
||||
self.title = title
|
||||
self.desc = desc
|
||||
if icon_path:
|
||||
if starpilot_icon: self._icon = gui_app.starpilot_texture(icon_path, 100, 100)
|
||||
if starpilot_icon: self._icon = starpilot_texture(icon_path, 100, 100)
|
||||
else: self._icon = gui_app.texture(icon_path, 100, 100)
|
||||
else: self._icon = None
|
||||
self._font_title = gui_app.font(FontWeight.BOLD)
|
||||
@@ -254,7 +255,7 @@ class ToggleTile(AetherTile):
|
||||
self.get_state = get_state
|
||||
self.set_state = set_state
|
||||
self.set_enabled(is_enabled or True)
|
||||
self._icon = gui_app.starpilot_texture(icon_path, 80, 80) if icon_path else None
|
||||
self._icon = starpilot_texture(icon_path, 80, 80) if icon_path else None
|
||||
self._font = gui_app.font(FontWeight.BOLD)
|
||||
self._font_desc = gui_app.font(FontWeight.NORMAL)
|
||||
self._active_color = self.surface_color
|
||||
@@ -302,7 +303,7 @@ class ValueTile(AetherTile):
|
||||
self.desc = desc
|
||||
self.get_value = get_value
|
||||
self._enabled = is_enabled or (lambda: True)
|
||||
self._icon = gui_app.starpilot_texture(icon_path, 80, 80) if icon_path else None
|
||||
self._icon = starpilot_texture(icon_path, 80, 80) if icon_path else None
|
||||
self._font = gui_app.font(FontWeight.BOLD)
|
||||
self._font_desc = gui_app.font(FontWeight.NORMAL)
|
||||
self._active_color = self.surface_color
|
||||
@@ -505,13 +506,13 @@ class AetherSliderDialog(Widget):
|
||||
if self._is_pressed_ok:
|
||||
self._ok_target = 0.0
|
||||
if rl.check_collision_point_rec(mouse_pos, self._ok_rect):
|
||||
gui_app.set_modal_overlay(None)
|
||||
gui_app.pop_widget()
|
||||
self._user_callback(DialogResult.CONFIRM, self._current_val)
|
||||
self._is_pressed_ok = False
|
||||
if self._is_pressed_cancel:
|
||||
self._cancel_target = 0.0
|
||||
if rl.check_collision_point_rec(mouse_pos, self._cancel_rect):
|
||||
gui_app.set_modal_overlay(None)
|
||||
gui_app.pop_widget()
|
||||
self._user_callback(DialogResult.CANCEL, self._current_val)
|
||||
self._is_pressed_cancel = False
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from importlib.resources import as_file, files
|
||||
|
||||
import pyray as rl
|
||||
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
|
||||
|
||||
def starpilot_texture(asset_path: str, width: int | None = None, height: int | None = None,
|
||||
alpha_premultiply: bool = False, keep_aspect_ratio: bool = True) -> rl.Texture:
|
||||
if width is not None:
|
||||
width = round(width)
|
||||
if height is not None:
|
||||
height = round(height)
|
||||
|
||||
cache_key = f"starpilot_{asset_path}_{width}_{height}_{alpha_premultiply}_{keep_aspect_ratio}"
|
||||
if cache_key in gui_app._textures:
|
||||
return gui_app._textures[cache_key]
|
||||
|
||||
starpilot_assets = files("openpilot.starpilot").joinpath("assets")
|
||||
with as_file(starpilot_assets.joinpath(asset_path)) as fspath:
|
||||
image_obj = gui_app._load_image_from_path(fspath.as_posix(), width, height, alpha_premultiply, keep_aspect_ratio)
|
||||
texture_obj = gui_app._load_texture_from_image(image_obj)
|
||||
|
||||
if gui_app._scale != 1.0 and width is not None and height is not None:
|
||||
texture_obj.width = width
|
||||
texture_obj.height = height
|
||||
|
||||
gui_app._textures[cache_key] = texture_obj
|
||||
return texture_obj
|
||||
@@ -10,8 +10,8 @@ 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.confirm_dialog import ConfirmDialog, alert_dialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.system.ui.widgets.input_dialog import InputDialog
|
||||
from openpilot.system.ui.widgets.keyboard import Keyboard
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid
|
||||
|
||||
@@ -27,6 +27,7 @@ LEGACY_STARPILOT_PARAM_RENAMES = {
|
||||
class StarPilotDataLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._keyboard = Keyboard(min_text_size=0)
|
||||
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"},
|
||||
@@ -134,44 +135,51 @@ class StarPilotBackupsLayout(StarPilotPanel):
|
||||
|
||||
threading.Thread(target=_task, daemon=True).start()
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Name your backup"), "", on_close=on_name))
|
||||
self._keyboard.reset(min_text_size=0)
|
||||
self._keyboard.set_title(tr("Name your backup"), "")
|
||||
self._keyboard.set_text("")
|
||||
self._keyboard.set_callback(lambda result: on_name(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
def _on_restore_backup(self):
|
||||
backups = self._get_backups()
|
||||
if not backups:
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("No backups found.")))
|
||||
return
|
||||
dialog = MultiOptionDialog(tr("Select Backup"), backups)
|
||||
|
||||
def _on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
def _on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("Restoring... device will reboot.")))
|
||||
|
||||
def _task():
|
||||
subprocess.run(["rm", "-rf", "/data/openpilot/*"])
|
||||
subprocess.run(["tar", "--use-compress-program=zstd", "-xf", f"/data/backups/{val}", "-C", "/"])
|
||||
subprocess.run(["tar", "--use-compress-program=zstd", "-xf", f"/data/backups/{dialog.selection}", "-C", "/"])
|
||||
os.system("reboot")
|
||||
|
||||
threading.Thread(target=_task, daemon=True).start()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Backup"), backups, on_close=_on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=_on_select)
|
||||
|
||||
def _on_delete_backup(self):
|
||||
backups = self._get_backups()
|
||||
if not backups:
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("No backups found.")))
|
||||
return
|
||||
dialog = MultiOptionDialog(tr("Delete Backup"), backups)
|
||||
|
||||
def _on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
os.remove(f"/data/backups/{val}")
|
||||
def _on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
os.remove(f"/data/backups/{dialog.selection}")
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Delete Backup"), backups, on_close=_on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=_on_select)
|
||||
|
||||
|
||||
class StarPilotToggleBackupsLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._keyboard = Keyboard(min_text_size=0)
|
||||
self._tile_grid = TileGrid(columns=2, padding=20, uniform_width=True)
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Create Toggle Backup"), "type": "hub", "on_click": self._on_create, "color": "#D43D8A"},
|
||||
@@ -199,20 +207,25 @@ class StarPilotToggleBackupsLayout(StarPilotPanel):
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("Toggle backup created.")))
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Name your toggle backup"), "", on_close=on_name))
|
||||
self._keyboard.reset(min_text_size=0)
|
||||
self._keyboard.set_title(tr("Name your toggle backup"), "")
|
||||
self._keyboard.set_text("")
|
||||
self._keyboard.set_callback(lambda result: on_name(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
def _on_restore(self):
|
||||
backups = self._get_backups()
|
||||
if not backups:
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("No toggle backups found.")))
|
||||
return
|
||||
dialog = MultiOptionDialog(tr("Select Toggle Backup"), backups)
|
||||
|
||||
def _on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
def _on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
|
||||
def on_confirm(r2):
|
||||
if r2 == DialogResult.CONFIRM:
|
||||
src = Path(f"/data/toggle_backups/{val}")
|
||||
src = Path(f"/data/toggle_backups/{dialog.selection}")
|
||||
params_dir = Path("/data/params/d")
|
||||
for old_key, new_key in LEGACY_STARPILOT_PARAM_RENAMES.items():
|
||||
if (src / old_key).exists():
|
||||
@@ -228,17 +241,18 @@ class StarPilotToggleBackupsLayout(StarPilotPanel):
|
||||
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("This will overwrite your current toggles."), tr("Restore"), on_close=on_confirm))
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Toggle Backup"), backups, on_close=_on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=_on_select)
|
||||
|
||||
def _on_delete(self):
|
||||
backups = self._get_backups()
|
||||
if not backups:
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("No toggle backups found.")))
|
||||
return
|
||||
dialog = MultiOptionDialog(tr("Delete Toggle Backup"), backups)
|
||||
|
||||
def _on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
shutil.rmtree(f"/data/toggle_backups/{val}", ignore_errors=True)
|
||||
def _on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
shutil.rmtree(f"/data/toggle_backups/{dialog.selection}", ignore_errors=True)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Delete Toggle Backup"), backups, on_close=_on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=_on_select)
|
||||
|
||||
@@ -7,7 +7,6 @@ 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.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.aethergrid import AetherSliderDialog, TileGrid
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,8 @@ 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.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.system.ui.widgets.input_dialog import InputDialog
|
||||
from openpilot.system.ui.widgets.keyboard import Keyboard
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_master_toggle_panel, 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
|
||||
@@ -653,13 +653,14 @@ class StarPilotLongitudinalTuneLayout(StarPilotPanel):
|
||||
option_labels = [tr(option_label) for _, option_label in options]
|
||||
label_to_value = {tr(option_label): option_value for option_value, option_label in options}
|
||||
default_option = next((tr(option_label) for option_value, option_label in options if option_value == current_value), option_labels[0])
|
||||
dialog = MultiOptionDialog(tr(title), option_labels, default_option)
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put_int(key, label_to_value[val])
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
self._params.put_int(key, label_to_value[dialog.selection])
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(title), option_labels, default_option, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
def _show_int_selector(self, key, min_v, max_v, unit=""):
|
||||
def on_close(res, val):
|
||||
@@ -847,45 +848,42 @@ class StarPilotSpeedLimitControllerLayout(StarPilotPanel):
|
||||
current_primary = self._params.get("SLCPriority1", encoding='utf-8') or "Map Data"
|
||||
current_secondary = self._params.get("SLCPriority2", encoding='utf-8') or "None"
|
||||
|
||||
def on_secondary_select(primary, res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
def on_secondary_select(primary, dialog, res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
self._params.put("SLCPriority1", primary)
|
||||
self._params.put("SLCPriority2", val)
|
||||
self._params.put("SLCPriority2", dialog.selection)
|
||||
self._rebuild_grid()
|
||||
|
||||
def show_secondary_dialog(primary):
|
||||
secondary_options = ["None"] + [option for option in ("Dashboard", "Map Data", "Vision") if option != primary]
|
||||
selected_secondary = current_secondary if current_secondary in secondary_options else "None"
|
||||
gui_app.set_modal_overlay(
|
||||
SelectionDialog(
|
||||
tr("SLC Secondary Priority"),
|
||||
secondary_options,
|
||||
selected_secondary,
|
||||
on_close=lambda res, val: on_secondary_select(primary, res, val),
|
||||
)
|
||||
)
|
||||
secondary_dialog = MultiOptionDialog(tr("SLC Secondary Priority"), secondary_options, selected_secondary)
|
||||
gui_app.set_modal_overlay(secondary_dialog, callback=lambda res: on_secondary_select(primary, secondary_dialog, res))
|
||||
|
||||
def on_primary_select(res, val):
|
||||
if res != DialogResult.CONFIRM:
|
||||
primary_dialog = MultiOptionDialog(tr("SLC Primary Priority"), primary_options, current_primary)
|
||||
|
||||
def on_primary_select(res):
|
||||
if res != DialogResult.CONFIRM or not primary_dialog.selection:
|
||||
return
|
||||
if val in ("Highest", "Lowest"):
|
||||
self._params.put("SLCPriority1", val)
|
||||
if primary_dialog.selection in ("Highest", "Lowest"):
|
||||
self._params.put("SLCPriority1", primary_dialog.selection)
|
||||
self._params.put("SLCPriority2", "None")
|
||||
self._rebuild_grid()
|
||||
return
|
||||
show_secondary_dialog(val)
|
||||
show_secondary_dialog(primary_dialog.selection)
|
||||
|
||||
gui_app.set_modal_overlay(
|
||||
SelectionDialog(tr("SLC Primary Priority"), primary_options, current_primary, on_close=on_primary_select)
|
||||
)
|
||||
gui_app.set_modal_overlay(primary_dialog, callback=on_primary_select)
|
||||
|
||||
def _show_selection(self, key, options):
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put(key, val)
|
||||
current = self._params.get(key, encoding='utf-8') or "None"
|
||||
dialog = MultiOptionDialog(tr(key), options, current)
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
self._params.put(key, dialog.selection)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(key), options, self._params.get(key, encoding='utf-8') or "None", on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
|
||||
class StarPilotSLCOffsetsLayout(StarPilotPanel):
|
||||
@@ -1006,6 +1004,7 @@ class StarPilotSLCVisualsLayout(StarPilotPanel):
|
||||
class StarPilotWeatherLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._keyboard = Keyboard(min_text_size=1)
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Low Visibility"), "panel": "low_visibility", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
||||
{"title": tr_noop("Rain"), "panel": "rain", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
||||
@@ -1022,18 +1021,23 @@ class StarPilotWeatherLayout(StarPilotPanel):
|
||||
|
||||
def _set_weather_key(self):
|
||||
options = ["ADD", "REMOVE"]
|
||||
dialog = MultiOptionDialog(tr("Weather API Key"), options, "ADD")
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
if val == "ADD":
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
if dialog.selection == "ADD":
|
||||
|
||||
def on_key(res, text):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("WeatherAPIKey", text)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Weather API Key"), on_close=on_key))
|
||||
elif val == "REMOVE":
|
||||
self._keyboard.reset(min_text_size=1)
|
||||
self._keyboard.set_title(tr("Weather API Key"), "")
|
||||
self._keyboard.set_text("")
|
||||
self._keyboard.set_callback(lambda result: on_key(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
elif dialog.selection == "REMOVE":
|
||||
|
||||
def on_confirm(res):
|
||||
if res == DialogResult.CONFIRM:
|
||||
@@ -1042,7 +1046,7 @@ class StarPilotWeatherLayout(StarPilotPanel):
|
||||
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("Remove API Key?"), tr("Confirm"), on_close=on_confirm))
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Weather API Key"), options, "ADD", on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
|
||||
class StarPilotWeatherBase(StarPilotPanel):
|
||||
|
||||
@@ -6,7 +6,7 @@ from pathlib import Path
|
||||
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.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog, alert_dialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.starpilot.common.maps_catalog import (
|
||||
@@ -117,13 +117,14 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
def _on_schedule(self):
|
||||
options = list(MAP_SCHEDULE_LABELS.values())
|
||||
current = schedule_label(self._params.get("PreferredSchedule"))
|
||||
dialog = MultiOptionDialog(tr("Auto Update Schedule"), options, current)
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("PreferredSchedule", schedule_param_value(val))
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
self._params.put("PreferredSchedule", schedule_param_value(dialog.selection))
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Auto Update Schedule"), options, current, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
def _on_download(self):
|
||||
current_selected = self._params.get("MapsSelected", encoding="utf-8") or ""
|
||||
|
||||
@@ -2,15 +2,15 @@ from __future__ import annotations
|
||||
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.system.ui.widgets.confirm_dialog import ConfirmDialog, alert_dialog
|
||||
from openpilot.system.ui.widgets.input_dialog import InputDialog
|
||||
from openpilot.system.ui.widgets.keyboard import Keyboard
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
|
||||
|
||||
class StarPilotNavigationLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._keyboard = Keyboard(min_text_size=1)
|
||||
self._sub_panels = {
|
||||
"mapbox": StarPilotMapboxLayout(),
|
||||
}
|
||||
@@ -60,7 +60,11 @@ class StarPilotNavigationLayout(StarPilotPanel):
|
||||
if res == DialogResult.CONFIRM and text:
|
||||
self._params.put("SearchAddress", text)
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Search Destination"), "", on_close=on_close))
|
||||
self._keyboard.reset(min_text_size=1)
|
||||
self._keyboard.set_title(tr("Search Destination"), "")
|
||||
self._keyboard.set_text("")
|
||||
self._keyboard.set_callback(lambda result: on_close(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
def _on_home(self):
|
||||
current = self._params.get("HomeAddress", encoding='utf-8') or ""
|
||||
@@ -70,7 +74,11 @@ class StarPilotNavigationLayout(StarPilotPanel):
|
||||
self._params.put("HomeAddress", text)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Home Address"), current, on_close=on_close))
|
||||
self._keyboard.reset(min_text_size=0)
|
||||
self._keyboard.set_title(tr("Home Address"), "")
|
||||
self._keyboard.set_text(current)
|
||||
self._keyboard.set_callback(lambda result: on_close(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
def _on_work(self):
|
||||
current = self._params.get("WorkAddress", encoding='utf-8') or ""
|
||||
@@ -80,12 +88,17 @@ class StarPilotNavigationLayout(StarPilotPanel):
|
||||
self._params.put("WorkAddress", text)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Work Address"), current, on_close=on_close))
|
||||
self._keyboard.reset(min_text_size=0)
|
||||
self._keyboard.set_title(tr("Work Address"), "")
|
||||
self._keyboard.set_text(current)
|
||||
self._keyboard.set_callback(lambda result: on_close(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
|
||||
class StarPilotMapboxLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._keyboard = Keyboard(min_text_size=1)
|
||||
self.CATEGORIES = [
|
||||
{
|
||||
"title": tr_noop("Public Mapbox Key"),
|
||||
@@ -131,4 +144,8 @@ class StarPilotMapboxLayout(StarPilotPanel):
|
||||
self._params.put(key, text)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr(f"Enter {key.replace('Mapbox', 'Mapbox ')}"), "", on_close=on_close))
|
||||
self._keyboard.reset(min_text_size=1)
|
||||
self._keyboard.set_title(tr(f"Enter {key.replace('Mapbox', 'Mapbox ')}"), "")
|
||||
self._keyboard.set_text("")
|
||||
self._keyboard.set_callback(lambda result: on_close(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
@@ -7,7 +7,7 @@ from openpilot.system.hardware.hw import Paths
|
||||
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.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
|
||||
if HARDWARE.get_device_type() == "pc":
|
||||
@@ -161,19 +161,21 @@ class StarPilotThemesLayout(StarPilotPanel):
|
||||
else:
|
||||
current = "Clear"
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
if val == "Stock":
|
||||
dialog = MultiOptionDialog(tr("Startup Alert"), options, current)
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
if dialog.selection == "Stock":
|
||||
self._params.put("StartupMessageTop", "Be ready to take over at any time")
|
||||
self._params.put("StartupMessageBottom", "Always keep hands on wheel and eyes on road")
|
||||
elif val == "StarPilot":
|
||||
elif dialog.selection == "StarPilot":
|
||||
self._params.put("StartupMessageTop", "Hop in and buckle up!")
|
||||
self._params.put("StartupMessageBottom", "Human-tested, frog-approved")
|
||||
else:
|
||||
self._params.remove("StartupMessageTop")
|
||||
self._params.remove("StartupMessageBottom")
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Startup Alert"), options, current, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
|
||||
class StarPilotPersonalizeLayout(StarPilotPanel):
|
||||
@@ -317,12 +319,14 @@ class StarPilotPersonalizeLayout(StarPilotPanel):
|
||||
if not themes:
|
||||
return
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
selected_slug = option_map.get(val)
|
||||
dialog = MultiOptionDialog(tr(key), themes, current)
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
selected_slug = option_map.get(dialog.selection)
|
||||
if selected_slug is None:
|
||||
return
|
||||
self._params.put(key, selected_slug)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(key), themes, current, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
@@ -5,8 +5,8 @@ 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.confirm_dialog import ConfirmDialog, alert_dialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.system.ui.widgets.input_dialog import InputDialog
|
||||
from openpilot.system.ui.widgets.keyboard import Keyboard
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import TileGrid
|
||||
|
||||
@@ -39,6 +39,7 @@ REPORT_CATEGORIES = [
|
||||
class StarPilotUtilitiesLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._keyboard = Keyboard(min_text_size=1)
|
||||
self._tile_grid = TileGrid(columns=2, padding=20, uniform_width=True)
|
||||
self.CATEGORIES = [
|
||||
{
|
||||
@@ -79,13 +80,15 @@ class StarPilotUtilitiesLayout(StarPilotPanel):
|
||||
|
||||
def _on_force_drive_state(self):
|
||||
options = [tr("Offroad"), tr("Onroad"), tr("Default")]
|
||||
current = self._get_force_drive_state()
|
||||
dialog = MultiOptionDialog(tr("Force Drive State"), options, current)
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
if val == tr("Offroad"):
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
if dialog.selection == tr("Offroad"):
|
||||
self._params.put_bool("ForceOffroad", True)
|
||||
self._params.put_bool("ForceOnroad", False)
|
||||
elif val == tr("Onroad"):
|
||||
elif dialog.selection == tr("Onroad"):
|
||||
self._params.put_bool("ForceOnroad", True)
|
||||
self._params.put_bool("ForceOffroad", False)
|
||||
else:
|
||||
@@ -93,25 +96,30 @@ class StarPilotUtilitiesLayout(StarPilotPanel):
|
||||
self._params.put_bool("ForceOnroad", False)
|
||||
self._rebuild_grid()
|
||||
|
||||
current = self._get_force_drive_state()
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Force Drive State"), options, current, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
def _on_report_issue(self):
|
||||
def on_category(res, val):
|
||||
if res != DialogResult.CONFIRM:
|
||||
dialog = MultiOptionDialog(tr("Select Issue"), REPORT_CATEGORIES)
|
||||
|
||||
def on_category(res):
|
||||
if res != DialogResult.CONFIRM or not dialog.selection:
|
||||
return
|
||||
discord_user = self._params.get("DiscordUsername", encoding='utf-8') or ""
|
||||
|
||||
def on_discord(res2, username):
|
||||
if res2 == DialogResult.CONFIRM and username:
|
||||
self._params.put("DiscordUsername", username)
|
||||
report = json.dumps({"DiscordUser": username, "Issue": val})
|
||||
report = json.dumps({"DiscordUser": username, "Issue": dialog.selection})
|
||||
self._params_memory.put("IssueReported", report)
|
||||
gui_app.set_modal_overlay(alert_dialog(tr("Issue reported. Thank you!")))
|
||||
|
||||
gui_app.set_modal_overlay(InputDialog(tr("Discord Username"), discord_user or "", on_close=on_discord))
|
||||
self._keyboard.reset(min_text_size=1)
|
||||
self._keyboard.set_title(tr("Discord Username"), "")
|
||||
self._keyboard.set_text(discord_user or "")
|
||||
self._keyboard.set_callback(lambda result: on_discord(result, self._keyboard.text))
|
||||
gui_app.push_widget(self._keyboard)
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Issue"), REPORT_CATEGORIES, on_close=on_category))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_category)
|
||||
|
||||
def _on_reset_defaults(self):
|
||||
def _do_reset(res):
|
||||
|
||||
@@ -5,7 +5,7 @@ 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.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import AetherSliderDialog, TileGrid, HubTile, ToggleTile, ValueTile
|
||||
from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
@@ -170,19 +170,22 @@ class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("No fingerprint list available."), tr("OK"), on_close=lambda r: None))
|
||||
return
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("CarMake", val)
|
||||
current_make = self._params.get("CarMake", encoding='utf-8') or ""
|
||||
default_make = current_make if current_make in makes else makes[0]
|
||||
|
||||
dialog = MultiOptionDialog(tr("Select Make"), makes, default_make)
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
self._params.put("CarMake", dialog.selection)
|
||||
current_model = self._params.get("CarModel", encoding='utf-8') or ""
|
||||
available_models = {option.value for option in self._models_by_make.get(val, ())}
|
||||
available_models = {option.value for option in self._models_by_make.get(dialog.selection, ())}
|
||||
if current_model not in available_models:
|
||||
self._params.remove("CarModel")
|
||||
self._params.remove("CarModelName")
|
||||
self._rebuild_grid()
|
||||
|
||||
current_make = self._params.get("CarMake", encoding='utf-8') or ""
|
||||
default_make = current_make if current_make in makes else makes[0]
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Make"), makes, default_make, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
def _on_select_model(self):
|
||||
make = self._params.get("CarMake", encoding='utf-8') or ""
|
||||
@@ -203,15 +206,17 @@ class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
if default_option is None:
|
||||
default_option = next((option.option_label for option in model_options if option.value == current_model), option_labels[0])
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
selected_option = selected_by_label[val]
|
||||
dialog = MultiOptionDialog(tr("Select Model"), option_labels, default_option)
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
selected_option = selected_by_label[dialog.selection]
|
||||
self._params.put("CarModel", selected_option.value)
|
||||
self._params.put("CarModelName", selected_option.label)
|
||||
self._params.put("CarMake", make)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Model"), option_labels, default_option, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
def _on_disable_long(self, state):
|
||||
if state:
|
||||
|
||||
@@ -3,7 +3,7 @@ from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
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.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
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
|
||||
@@ -453,15 +453,17 @@ class StarPilotModelUILayout(StarPilotPanel):
|
||||
presets = ["Stock", "#FFFFFF", "#178644", "#3B82F6", "#E63956", "#8B5CF6", "#F59E0B"]
|
||||
current = self._params.get(key, encoding='utf-8') or "Stock"
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
if val == "Stock":
|
||||
dialog = MultiOptionDialog(tr(key), presets, current)
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
if dialog.selection == "Stock":
|
||||
self._params.remove(key)
|
||||
else:
|
||||
self._params.put(key, val)
|
||||
self._params.put(key, dialog.selection)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(key), presets, current, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
|
||||
class StarPilotNavigationVisualsLayout(StarPilotPanel):
|
||||
@@ -554,10 +556,12 @@ class StarPilotVisualQOLLayout(StarPilotPanel):
|
||||
def _show_camera_view_selector(self):
|
||||
current = self._params.get_int("CameraView")
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
idx = self.CAMERA_VIEWS.index(val)
|
||||
dialog = MultiOptionDialog(tr("Camera View"), self.CAMERA_VIEWS, self.CAMERA_VIEWS[current])
|
||||
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
idx = self.CAMERA_VIEWS.index(dialog.selection)
|
||||
self._params.put_int("CameraView", idx)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Camera View"), self.CAMERA_VIEWS, self.CAMERA_VIEWS[current], on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
@@ -3,7 +3,7 @@ from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
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.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
|
||||
ACTION_OPTIONS = [
|
||||
@@ -107,14 +107,15 @@ class StarPilotWheelLayout(StarPilotPanel):
|
||||
current = self._get_action_name(key)
|
||||
if current not in actions:
|
||||
current = actions[0]
|
||||
dialog = MultiOptionDialog(tr(key), actions, current)
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put_int(key, ACTION_IDS.get(val, 0))
|
||||
def on_select(res):
|
||||
if res == DialogResult.CONFIRM and dialog.selection:
|
||||
self._params.put_int(key, ACTION_IDS.get(dialog.selection, 0))
|
||||
self._params_memory.put_bool("StarPilotTogglesUpdated", True)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(key), actions, current, on_close=on_select))
|
||||
gui_app.set_modal_overlay(dialog, callback=on_select)
|
||||
|
||||
def _rebuild_grid(self):
|
||||
if not self.CATEGORIES:
|
||||
|
||||
@@ -2,7 +2,7 @@ import pyray as rl
|
||||
from cereal import log
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.asset_loader import starpilot_texture
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
|
||||
BTN_SIZE = 192
|
||||
@@ -20,10 +20,10 @@ class PersonalityButton(Widget):
|
||||
|
||||
# 0=traffic, 1=aggressive, 2=standard, 3=relaxed
|
||||
self._icons = [
|
||||
gui_app.starpilot_texture("stock_theme/distance_icons/traffic.png", ICON_SIZE, ICON_SIZE),
|
||||
gui_app.starpilot_texture("stock_theme/distance_icons/aggressive.png", ICON_SIZE, ICON_SIZE),
|
||||
gui_app.starpilot_texture("stock_theme/distance_icons/standard.png", ICON_SIZE, ICON_SIZE),
|
||||
gui_app.starpilot_texture("stock_theme/distance_icons/relaxed.png", ICON_SIZE, ICON_SIZE),
|
||||
starpilot_texture("stock_theme/distance_icons/traffic.png", ICON_SIZE, ICON_SIZE),
|
||||
starpilot_texture("stock_theme/distance_icons/aggressive.png", ICON_SIZE, ICON_SIZE),
|
||||
starpilot_texture("stock_theme/distance_icons/standard.png", ICON_SIZE, ICON_SIZE),
|
||||
starpilot_texture("stock_theme/distance_icons/relaxed.png", ICON_SIZE, ICON_SIZE),
|
||||
]
|
||||
|
||||
self._rect = rl.Rectangle(0, 0, BTN_SIZE, BTN_SIZE)
|
||||
|
||||
@@ -8,6 +8,7 @@ from openpilot.system.ui.lib.application import gui_app, MouseEvent
|
||||
from openpilot.system.hardware import TICI
|
||||
from collections import deque
|
||||
|
||||
MOUSE_WHEEL_SCROLL_SPEED = 50
|
||||
MIN_VELOCITY = 10 # px/s, changes from auto scroll to steady state
|
||||
MIN_VELOCITY_FOR_CLICKING = 2 * 60 # px/s, accepts clicks while auto scrolling below this velocity
|
||||
MIN_DRAG_PIXELS = 12
|
||||
@@ -73,6 +74,14 @@ class GuiScrollPanel2:
|
||||
self._handle_mouse_event(mouse_event, bounds, bounds_size, content_size)
|
||||
self._previous_mouse_event = mouse_event
|
||||
|
||||
wheel_move = rl.get_mouse_wheel_move()
|
||||
if wheel_move != 0 and self.enabled and rl.check_collision_point_rec(rl.get_mouse_position(), bounds):
|
||||
scroll_delta = wheel_move * MOUSE_WHEEL_SCROLL_SPEED
|
||||
if self._horizontal:
|
||||
self._offset.x += scroll_delta
|
||||
else:
|
||||
self._offset.y += scroll_delta
|
||||
|
||||
self._update_state(bounds_size, content_size)
|
||||
|
||||
if DEBUG:
|
||||
|
||||
Reference in New Issue
Block a user