mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-06-30 02:52:04 +08:00
BigUI WIP: Finish nuking nav from ui
This commit is contained in:
@@ -3,108 +3,211 @@ from __future__ import annotations
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
import pyray as rl
|
||||
|
||||
from openpilot.system.ui.lib.application import FontWeight, MousePos, gui_app
|
||||
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||
from openpilot.system.ui.widgets import DialogResult
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
from openpilot.system.ui.lib.scroll_panel2 import GuiScrollPanel2
|
||||
from openpilot.system.ui.widgets import DialogResult, Widget
|
||||
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 (
|
||||
COUNTRY_REGION_GROUPS,
|
||||
MAP_SCHEDULE_LABELS,
|
||||
MAP_SECTIONS,
|
||||
STATE_REGION_GROUPS,
|
||||
sanitize_selected_locations_csv,
|
||||
schedule_label,
|
||||
schedule_param_value,
|
||||
from openpilot.system.ui.widgets.label import gui_label
|
||||
from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog
|
||||
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AetherChip,
|
||||
AetherScrollbar,
|
||||
HubTile,
|
||||
TileGrid,
|
||||
ToggleTile,
|
||||
ValueTile,
|
||||
build_list_panel_frame,
|
||||
draw_action_pill,
|
||||
draw_list_panel_shell,
|
||||
draw_list_scroll_fades,
|
||||
draw_soft_card,
|
||||
)
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.starpilot.common.maps_catalog import MAPS_CATALOG, MAP_SCHEDULE_LABELS, sanitize_selected_locations_csv, schedule_label, schedule_param_value
|
||||
|
||||
|
||||
class StarPilotMapRegionLayout(StarPilotPanel):
|
||||
def __init__(self, region_map: dict[str, str], prefix: str):
|
||||
TOP_ACTION_ROW_HEIGHT = 132
|
||||
GROUP_HEADER_HEIGHT = 52
|
||||
GROUP_BODY_GAP = 14
|
||||
GROUP_CARD_GAP = 18
|
||||
GROUP_TILE_HEIGHT = 124
|
||||
|
||||
|
||||
class MapGroupCard(Widget):
|
||||
def __init__(self, controller: "StarPilotMapsLayout", section_title: str, group: dict):
|
||||
super().__init__()
|
||||
self._prefix = prefix
|
||||
self.CATEGORIES = []
|
||||
self._controller = controller
|
||||
self._title = group["title"]
|
||||
self._regions = group["regions"]
|
||||
self._tile_grid = self._child(TileGrid(columns=None, padding=14, uniform_width=True))
|
||||
self._action_rect = rl.Rectangle(0, 0, 0, 0)
|
||||
self._action_pressed = False
|
||||
|
||||
for key, name in sorted(region_map.items(), key=lambda item: item[1]):
|
||||
self.CATEGORIES.append({
|
||||
"title": name,
|
||||
"type": "toggle",
|
||||
"get_state": lambda k=key: self._get_map_state(k),
|
||||
"set_state": lambda s, k=key: self._set_map_state(k, s),
|
||||
"color": "#68ACA3"
|
||||
})
|
||||
self._rebuild_grid()
|
||||
for region in self._regions:
|
||||
token = region["token"]
|
||||
self._tile_grid.add_tile(
|
||||
ToggleTile(
|
||||
title=tr_noop(region["label"]),
|
||||
get_state=lambda token=token: self._controller._get_map_state(token),
|
||||
set_state=lambda state, token=token: self._controller._set_map_state(token, state),
|
||||
bg_color="#68ACA3",
|
||||
)
|
||||
)
|
||||
|
||||
def _get_map_state(self, key):
|
||||
selected = set(sanitize_selected_locations_csv(self._params.get("MapsSelected", encoding="utf-8") or "").split(","))
|
||||
selected.discard("")
|
||||
return f"{self._prefix}{key}" in selected
|
||||
def _selected_count(self) -> int:
|
||||
return sum(1 for region in self._regions if self._controller._get_map_state(region["token"]))
|
||||
|
||||
def _set_map_state(self, key, state):
|
||||
selected = set(sanitize_selected_locations_csv(self._params.get("MapsSelected", encoding="utf-8") or "").split(","))
|
||||
selected.discard("")
|
||||
def _all_selected(self) -> bool:
|
||||
return self._selected_count() == len(self._regions)
|
||||
|
||||
prefixed_key = f"{self._prefix}{key}"
|
||||
if state:
|
||||
selected.add(prefixed_key)
|
||||
else:
|
||||
selected.discard(prefixed_key)
|
||||
def _toggle_all(self):
|
||||
state = not self._all_selected()
|
||||
for region in self._regions:
|
||||
self._controller._set_map_state(region["token"], state)
|
||||
|
||||
self._params.put("MapsSelected", sanitize_selected_locations_csv(sorted(selected)))
|
||||
def _measure_height(self, width: float) -> float:
|
||||
content_w = max(0.0, width - 32)
|
||||
rows = self._tile_grid.get_row_count(available_width=content_w)
|
||||
body_h = rows * GROUP_TILE_HEIGHT + self._tile_grid.gap * max(0, rows - 1)
|
||||
return GROUP_HEADER_HEIGHT + GROUP_BODY_GAP + body_h + 28
|
||||
|
||||
def _handle_mouse_press(self, mouse_pos: MousePos):
|
||||
if rl.check_collision_point_rec(mouse_pos, self._action_rect):
|
||||
self._action_pressed = True
|
||||
|
||||
class StarPilotMapCountriesLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop(group["title"]), "panel": group["key"], "icon": "toggle_icons/icon_map.png", "color": "#68ACA3"}
|
||||
for group in COUNTRY_REGION_GROUPS
|
||||
]
|
||||
self._rebuild_grid()
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
if self._action_pressed:
|
||||
self._action_pressed = False
|
||||
if rl.check_collision_point_rec(mouse_pos, self._action_rect):
|
||||
self._toggle_all()
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
draw_soft_card(rect, rl.Color(255, 255, 255, 4), rl.Color(255, 255, 255, 15), radius=0.08, segments=18)
|
||||
|
||||
class StarPilotMapStatesLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop(group["title"]), "panel": group["key"], "icon": "toggle_icons/icon_map.png", "color": "#68ACA3"}
|
||||
for group in STATE_REGION_GROUPS
|
||||
]
|
||||
self._rebuild_grid()
|
||||
header_rect = rl.Rectangle(rect.x + 16, rect.y + 12, rect.width - 32, GROUP_HEADER_HEIGHT)
|
||||
title_w = max(0.0, header_rect.width - 160)
|
||||
title_rect = rl.Rectangle(header_rect.x, header_rect.y, title_w, 28)
|
||||
gui_label(title_rect, self._title, 28, rl.Color(236, 242, 250, 255), FontWeight.SEMI_BOLD)
|
||||
|
||||
count = self._selected_count()
|
||||
count_label = tr(f"{count}/{len(self._regions)} selected")
|
||||
chip = AetherChip(count_label, rl.Color(89, 116, 151, 26), rl.Color(116, 136, 168, 52), rl.Color(236, 242, 250, 255), pill=True)
|
||||
chip_w = min(136, max(96, header_rect.width * 0.26))
|
||||
chip_rect = rl.Rectangle(header_rect.x + max(0.0, header_rect.width - chip_w - 68), header_rect.y + 2, chip_w, 34)
|
||||
chip.render(chip_rect)
|
||||
|
||||
action_text = tr("Clear All") if self._all_selected() else tr("Select All")
|
||||
self._action_rect = rl.Rectangle(header_rect.x + header_rect.width - 60, header_rect.y + 2, 60, 34)
|
||||
draw_action_pill(self._action_rect, action_text, rl.Color(89, 116, 151, 20), rl.Color(255, 255, 255, 26), rl.Color(236, 242, 250, 255), font_size=16)
|
||||
|
||||
content_x = rect.x + 16
|
||||
content_y = header_rect.y + GROUP_HEADER_HEIGHT + GROUP_BODY_GAP
|
||||
content_w = rect.width - 32
|
||||
rows = self._tile_grid.get_row_count(available_width=content_w)
|
||||
body_h = rows * GROUP_TILE_HEIGHT + self._tile_grid.gap * max(0, rows - 1)
|
||||
grid_rect = rl.Rectangle(content_x, content_y, content_w, body_h)
|
||||
self._tile_grid.set_parent_rect(rect)
|
||||
self._tile_grid.render(grid_rect)
|
||||
|
||||
|
||||
class StarPilotMapsLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._scroll_panel = GuiScrollPanel2(horizontal=False)
|
||||
self._scrollbar = AetherScrollbar()
|
||||
self._content_height = 0.0
|
||||
self._scroll_offset = 0.0
|
||||
self._selected_count = 0
|
||||
self._storage_text = "0 MB"
|
||||
self._storage_updated_at = 0.0
|
||||
|
||||
self._sub_panels = {
|
||||
"countries": StarPilotMapCountriesLayout(),
|
||||
"states": StarPilotMapStatesLayout(),
|
||||
}
|
||||
|
||||
for section in MAP_SECTIONS:
|
||||
for group in section["groups"]:
|
||||
self._sub_panels[group["key"]] = StarPilotMapRegionLayout(group["regions"], section["prefix"])
|
||||
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Download Maps"), "type": "hub", "on_click": self._on_download, "icon": "toggle_icons/icon_map.png", "color": "#68ACA3"},
|
||||
{"title": tr_noop("Auto Update Schedule"), "type": "value", "get_value": lambda: schedule_label(self._params.get("PreferredSchedule")), "on_click": self._on_schedule, "icon": "toggle_icons/icon_calendar.png", "color": "#68ACA3"},
|
||||
{"title": tr_noop("Countries"), "panel": "countries", "icon": "toggle_icons/icon_map.png", "color": "#68ACA3"},
|
||||
{"title": tr_noop("U.S. States"), "panel": "states", "icon": "toggle_icons/icon_map.png", "color": "#68ACA3"},
|
||||
{"title": tr_noop("Storage Used"), "type": "value", "get_value": self._get_storage, "on_click": lambda: None, "icon": "toggle_icons/icon_system.png", "color": "#68ACA3"},
|
||||
{"title": tr_noop("Remove Maps"), "type": "hub", "on_click": self._on_remove, "icon": "toggle_icons/icon_map.png", "color": "#68ACA3"},
|
||||
self._action_grid = TileGrid(columns=None, padding=16, uniform_width=True)
|
||||
self._action_tiles = [
|
||||
HubTile(
|
||||
title=tr_noop("Download Maps"),
|
||||
desc=tr_noop("Download the selected regions."),
|
||||
icon_path="toggle_icons/icon_map.png",
|
||||
on_click=self._on_download,
|
||||
starpilot_icon=True,
|
||||
bg_color="#68ACA3",
|
||||
),
|
||||
ValueTile(
|
||||
title=tr_noop("Auto Update Schedule"),
|
||||
get_value=lambda: schedule_label(self._params.get("PreferredSchedule")),
|
||||
on_click=self._on_schedule,
|
||||
icon_path="toggle_icons/icon_calendar.png",
|
||||
bg_color="#68ACA3",
|
||||
),
|
||||
ValueTile(
|
||||
title=tr_noop("Storage Used"),
|
||||
get_value=self._get_storage,
|
||||
on_click=lambda: None,
|
||||
icon_path="toggle_icons/icon_system.png",
|
||||
bg_color="#68ACA3",
|
||||
),
|
||||
HubTile(
|
||||
title=tr_noop("Remove Maps"),
|
||||
desc=tr_noop("Delete downloaded map files."),
|
||||
icon_path="toggle_icons/icon_map.png",
|
||||
on_click=self._on_remove,
|
||||
starpilot_icon=True,
|
||||
bg_color="#A64D5A",
|
||||
),
|
||||
]
|
||||
for tile in self._action_tiles:
|
||||
self._action_grid.add_tile(self._child(tile))
|
||||
|
||||
for _, 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._sections: list[tuple[str, list[MapGroupCard]]] = []
|
||||
for section in MAPS_CATALOG:
|
||||
cards = [self._child(MapGroupCard(self, section["title"], group)) for group in section["groups"]]
|
||||
self._sections.append((section["title"], cards))
|
||||
|
||||
self._rebuild_grid()
|
||||
self._refresh_storage_cache(force=True)
|
||||
self._sync_selected_count()
|
||||
|
||||
def _get_storage(self) -> str:
|
||||
def show_event(self):
|
||||
super().show_event()
|
||||
self._scroll_offset = 0.0
|
||||
self._refresh_storage_cache(force=True)
|
||||
self._sync_selected_count()
|
||||
|
||||
def hide_event(self):
|
||||
super().hide_event()
|
||||
self._scroll_offset = 0.0
|
||||
|
||||
def _refresh_storage_cache(self, force: bool = False):
|
||||
now = rl.get_time()
|
||||
if not force and (now - self._storage_updated_at) < 5.0:
|
||||
return
|
||||
self._storage_text = self._calculate_storage_used()
|
||||
self._storage_updated_at = now
|
||||
|
||||
def _sync_selected_count(self):
|
||||
selected = set(sanitize_selected_locations_csv(self._params.get("MapsSelected", encoding="utf-8") or "").split(","))
|
||||
selected.discard("")
|
||||
self._selected_count = len(selected)
|
||||
|
||||
def _get_map_state(self, token: str) -> bool:
|
||||
selected = set(sanitize_selected_locations_csv(self._params.get("MapsSelected", encoding="utf-8") or "").split(","))
|
||||
selected.discard("")
|
||||
return token in selected
|
||||
|
||||
def _set_map_state(self, token: str, state: bool):
|
||||
selected = set(sanitize_selected_locations_csv(self._params.get("MapsSelected", encoding="utf-8") or "").split(","))
|
||||
selected.discard("")
|
||||
if state:
|
||||
selected.add(token)
|
||||
else:
|
||||
selected.discard(token)
|
||||
self._params.put("MapsSelected", sanitize_selected_locations_csv(sorted(selected)))
|
||||
self._sync_selected_count()
|
||||
|
||||
def _calculate_storage_used(self) -> str:
|
||||
maps_path = Path("/data/media/0/osm/offline")
|
||||
if not maps_path.exists():
|
||||
return "0 MB"
|
||||
@@ -114,6 +217,10 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
return f"{(mb / 1024):.2f} GB"
|
||||
return f"{mb:.2f} MB"
|
||||
|
||||
def _get_storage(self) -> str:
|
||||
self._refresh_storage_cache()
|
||||
return self._storage_text
|
||||
|
||||
def _on_schedule(self):
|
||||
options = list(MAP_SCHEDULE_LABELS.values())
|
||||
current = schedule_label(self._params.get("PreferredSchedule"))
|
||||
@@ -122,7 +229,6 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
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.push_widget(dialog, callback=on_select)
|
||||
|
||||
@@ -131,8 +237,7 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
selected_raw = sanitize_selected_locations_csv(current_selected)
|
||||
if selected_raw != current_selected:
|
||||
self._params.put("MapsSelected", selected_raw)
|
||||
selected = [k.strip() for k in selected_raw.split(",") if k.strip()]
|
||||
if not selected:
|
||||
if not selected_raw:
|
||||
gui_app.push_widget(alert_dialog(tr("Please select at least one region or state first!")))
|
||||
return
|
||||
|
||||
@@ -150,6 +255,74 @@ class StarPilotMapsLayout(StarPilotPanel):
|
||||
if maps_path.exists():
|
||||
shutil.rmtree(maps_path, ignore_errors=True)
|
||||
gui_app.push_widget(alert_dialog(tr("Maps removed.")))
|
||||
self._rebuild_grid()
|
||||
self._refresh_storage_cache(force=True)
|
||||
|
||||
gui_app.push_widget(ConfirmDialog(tr("Delete all downloaded map data?"), tr("Remove"), on_close=on_confirm))
|
||||
|
||||
def _measure_content_height(self, width: float) -> float:
|
||||
action_rows = self._action_grid.get_row_count(available_width=width)
|
||||
total = action_rows * TOP_ACTION_ROW_HEIGHT + self._action_grid.gap * max(0, action_rows - 1)
|
||||
total += 30
|
||||
|
||||
for _section_title, cards in self._sections:
|
||||
total += 34 + GROUP_CARD_GAP
|
||||
for card in cards:
|
||||
total += card._measure_height(width) + GROUP_CARD_GAP
|
||||
total += 12
|
||||
|
||||
return total
|
||||
|
||||
def _draw_section_title(self, rect: rl.Rectangle, title: str):
|
||||
gui_label(rect, title, 26, rl.Color(236, 242, 250, 230), FontWeight.SEMI_BOLD)
|
||||
|
||||
def _draw_scroll_content(self, rect: rl.Rectangle, width: float):
|
||||
y = rect.y + self._scroll_offset
|
||||
|
||||
action_rows = self._action_grid.get_row_count(available_width=width)
|
||||
action_h = action_rows * TOP_ACTION_ROW_HEIGHT + self._action_grid.gap * max(0, action_rows - 1)
|
||||
self._action_grid.render(rl.Rectangle(rect.x, y, width, action_h))
|
||||
y += action_h + 30
|
||||
|
||||
for section_title, cards in self._sections:
|
||||
title_rect = rl.Rectangle(rect.x, y, width, 34)
|
||||
self._draw_section_title(title_rect, section_title)
|
||||
y += 34 + GROUP_CARD_GAP
|
||||
for card in cards:
|
||||
card_h = card._measure_height(width)
|
||||
card.render(rl.Rectangle(rect.x, y, width, card_h))
|
||||
y += card_h + GROUP_CARD_GAP
|
||||
y += 12
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
self.set_rect(rect)
|
||||
frame = build_list_panel_frame(rect)
|
||||
draw_list_panel_shell(frame)
|
||||
|
||||
hdr = frame.header
|
||||
chip_w = min(140, max(104, int(hdr.width * 0.18)))
|
||||
title_w = max(0, hdr.width - chip_w - 20)
|
||||
gui_label(rl.Rectangle(hdr.x, hdr.y + 4, title_w, 40), tr("Map Data"), 40, rl.Color(236, 242, 250, 255), FontWeight.SEMI_BOLD)
|
||||
gui_label(
|
||||
rl.Rectangle(hdr.x, hdr.y + 48, title_w, 36),
|
||||
tr("Select regions, schedule updates, and manage offline map storage."),
|
||||
24,
|
||||
rl.Color(164, 177, 196, 255),
|
||||
FontWeight.NORMAL,
|
||||
)
|
||||
chip = AetherChip(tr(f"{self._selected_count} selected"), rl.Color(89, 116, 151, 26), rl.Color(116, 136, 168, 52), rl.Color(236, 242, 250, 255), pill=True)
|
||||
chip.render(rl.Rectangle(hdr.x + max(0.0, hdr.width - chip_w), hdr.y + 12, chip_w, 34))
|
||||
|
||||
scroll_rect = frame.scroll
|
||||
content_width = scroll_rect.width - 18
|
||||
self._content_height = self._measure_content_height(content_width)
|
||||
self._scroll_panel.set_enabled(self.is_visible)
|
||||
self._scroll_offset = self._scroll_panel.update(scroll_rect, max(self._content_height, scroll_rect.height))
|
||||
|
||||
rl.begin_scissor_mode(int(scroll_rect.x), int(scroll_rect.y), int(scroll_rect.width), int(scroll_rect.height))
|
||||
self._draw_scroll_content(scroll_rect, content_width)
|
||||
rl.end_scissor_mode()
|
||||
|
||||
if self._content_height > scroll_rect.height:
|
||||
self._scrollbar.render(scroll_rect, self._content_height, self._scroll_offset)
|
||||
|
||||
draw_list_scroll_fades(scroll_rect, self._content_height, self._scroll_offset, rl.Color(8, 8, 10, 255))
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
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.confirm_dialog import ConfirmDialog, alert_dialog
|
||||
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(),
|
||||
}
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Mapbox Credentials"), "panel": "mapbox", "icon": "toggle_icons/icon_navigate.png", "color": "#68ACA3"},
|
||||
{"title": tr_noop("Setup Instructions"), "type": "hub", "on_click": self._on_setup, "icon": "toggle_icons/icon_navigate.png", "color": "#68ACA3"},
|
||||
{
|
||||
"title": tr_noop("Speed Limit Filler"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("SpeedLimitFiller"),
|
||||
"set_state": lambda s: self._params.put_bool("SpeedLimitFiller", s),
|
||||
"icon": "toggle_icons/icon_speed_limit.png",
|
||||
"color": "#68ACA3",
|
||||
},
|
||||
{"title": tr_noop("Search Destination"), "type": "hub", "on_click": self._on_search, "icon": "toggle_icons/icon_navigate.png", "color": "#68ACA3"},
|
||||
{
|
||||
"title": tr_noop("Home Address"),
|
||||
"type": "value",
|
||||
"get_value": lambda: self._params.get("HomeAddress", encoding='utf-8') or tr("Not set"),
|
||||
"on_click": self._on_home,
|
||||
"icon": "toggle_icons/icon_navigate.png",
|
||||
"color": "#68ACA3",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Work Address"),
|
||||
"type": "value",
|
||||
"get_value": lambda: self._params.get("WorkAddress", encoding='utf-8') or tr("Not set"),
|
||||
"on_click": self._on_work,
|
||||
"icon": "toggle_icons/icon_navigate.png",
|
||||
"color": "#68ACA3",
|
||||
},
|
||||
]
|
||||
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()
|
||||
|
||||
def _on_setup(self):
|
||||
gui_app.push_widget(
|
||||
alert_dialog(tr("Mapbox Setup:\n1. Create account at mapbox.com\n2. Generate Public/Secret keys\n3. Add keys in 'Mapbox Credentials'"))
|
||||
)
|
||||
|
||||
def _on_search(self):
|
||||
def on_close(res, text):
|
||||
if res == DialogResult.CONFIRM and text:
|
||||
self._params.put("SearchAddress", text)
|
||||
|
||||
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 ""
|
||||
|
||||
def on_close(res, text):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("HomeAddress", text)
|
||||
self._rebuild_grid()
|
||||
|
||||
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 ""
|
||||
|
||||
def on_close(res, text):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("WorkAddress", text)
|
||||
self._rebuild_grid()
|
||||
|
||||
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"),
|
||||
"type": "value",
|
||||
"get_value": self._get_key_display,
|
||||
"on_click": lambda: self._on_key("MapboxPublicKey", "pk."),
|
||||
"color": "#68ACA3",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Secret Mapbox Key"),
|
||||
"type": "value",
|
||||
"get_value": self._get_secret_display,
|
||||
"on_click": lambda: self._on_key("MapboxSecretKey", "sk."),
|
||||
"color": "#68ACA3",
|
||||
},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _get_key_display(self):
|
||||
v = self._params.get("MapboxPublicKey", encoding='utf-8') or ""
|
||||
return f"{v[:8]}..." if v else tr("Not set")
|
||||
|
||||
def _get_secret_display(self):
|
||||
v = self._params.get("MapboxSecretKey", encoding='utf-8') or ""
|
||||
return "********" if v else tr("Not set")
|
||||
|
||||
def _on_key(self, key, prefix):
|
||||
current = self._params.get(key, encoding='utf-8') or ""
|
||||
if current:
|
||||
|
||||
def on_remove(res):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.remove(key)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.push_widget(ConfirmDialog(tr(f"Remove your {key.replace('Mapbox', '')} key?"), tr("Remove"), on_close=on_remove))
|
||||
else:
|
||||
|
||||
def on_close(res, text):
|
||||
if res == DialogResult.CONFIRM and text:
|
||||
if not text.startswith(prefix):
|
||||
text = prefix + text
|
||||
self._params.put(key, text)
|
||||
self._rebuild_grid()
|
||||
|
||||
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)
|
||||
@@ -19,15 +19,14 @@ class StarPilotPanelType(IntEnum):
|
||||
LONGITUDINAL = 3
|
||||
LATERAL = 4
|
||||
MAPS = 5
|
||||
NAVIGATION = 6
|
||||
DATA = 7
|
||||
DEVICE = 8
|
||||
UTILITIES = 9
|
||||
VISUALS = 10
|
||||
THEMES = 11
|
||||
VEHICLE = 12
|
||||
WHEEL = 13
|
||||
SYSTEM = 14
|
||||
DATA = 6
|
||||
DEVICE = 7
|
||||
UTILITIES = 8
|
||||
VISUALS = 9
|
||||
THEMES = 10
|
||||
VEHICLE = 11
|
||||
WHEEL = 12
|
||||
SYSTEM = 13
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
Reference in New Issue
Block a user