mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-20 15:54:13 +08:00
Switcharoo
This commit is contained in:
@@ -1161,31 +1161,36 @@ class BreadcrumbController:
|
||||
if not layout:
|
||||
return
|
||||
|
||||
if target == "action:home":
|
||||
while len(gui_app._nav_stack) > 1:
|
||||
gui_app.pop_widget()
|
||||
layout._panel_stack.clear()
|
||||
layout._update_sub_panel_visibility()
|
||||
layout._current_category_idx = None
|
||||
layout._set_current_panel(StarPilotPanelType.MAIN)
|
||||
elif target == "action:category":
|
||||
while len(gui_app._nav_stack) > 1:
|
||||
gui_app.pop_widget()
|
||||
layout._panel_stack.clear()
|
||||
nav_stack = getattr(gui_app, "_nav_stack", [])
|
||||
|
||||
cat = layout.CATEGORIES[layout._current_category_idx]
|
||||
if "buttons" in cat:
|
||||
layout._set_current_panel(StarPilotPanelType.MAIN)
|
||||
else:
|
||||
if target == "action:home":
|
||||
while len(nav_stack) > 1:
|
||||
gui_app.pop_widget()
|
||||
layout.reset_to_root()
|
||||
elif target.startswith("action:hub:"):
|
||||
target_depth = int(target.split(":")[-1])
|
||||
while len(nav_stack) > 1:
|
||||
gui_app.pop_widget()
|
||||
layout.navigate_to_hub_depth(target_depth)
|
||||
elif target == "action:category":
|
||||
# Compatibility with the former single-category breadcrumb action.
|
||||
while len(nav_stack) > 1:
|
||||
gui_app.pop_widget()
|
||||
if getattr(layout, "_hub_path", None):
|
||||
layout.navigate_to_hub_depth(1)
|
||||
elif layout._current_panel != StarPilotPanelType.MAIN:
|
||||
layout._panel_stack.clear()
|
||||
layout._commit_navigation()
|
||||
else:
|
||||
layout.reset_to_root()
|
||||
elif target == "action:panel":
|
||||
while len(gui_app._nav_stack) > 1:
|
||||
while len(nav_stack) > 1:
|
||||
gui_app.pop_widget()
|
||||
layout._panel_stack.clear()
|
||||
layout._commit_navigation()
|
||||
elif target.startswith("action:nav_stack:"):
|
||||
target_idx = int(target.split(":")[-1])
|
||||
while len(gui_app._nav_stack) > target_idx + 1:
|
||||
while len(nav_stack) > target_idx + 1:
|
||||
gui_app.pop_widget()
|
||||
elif target.startswith("action:panel_stack:"):
|
||||
target_idx = int(target.split(":")[-1])
|
||||
@@ -1203,22 +1208,20 @@ class BreadcrumbController:
|
||||
if not layout:
|
||||
return path
|
||||
|
||||
pushed_widgets = gui_app._nav_stack[1:]
|
||||
|
||||
cat_title = ""
|
||||
is_folder = False
|
||||
if layout._current_category_idx is not None:
|
||||
cat = layout.CATEGORIES[layout._current_category_idx]
|
||||
cat_title = cat["title"]
|
||||
is_folder = "buttons" in cat
|
||||
path.append((cat_title, "action:category"))
|
||||
hub_path = getattr(layout, "_hub_path", [])
|
||||
for i, folder in enumerate(hub_path, start=1):
|
||||
path.append((tr(folder["title"]), f"action:hub:{i}"))
|
||||
|
||||
if layout._current_panel != StarPilotPanelType.MAIN:
|
||||
panel_info = layout._panels[layout._current_panel]
|
||||
if panel_info.name:
|
||||
if is_folder or layout._current_category_idx is None:
|
||||
panel_title = panel_info.name
|
||||
path.append((panel_title, "action:panel"))
|
||||
selected_leaf = getattr(layout, "_selected_leaf", None)
|
||||
if selected_leaf is not None:
|
||||
panel_title = selected_leaf["title"]
|
||||
else:
|
||||
panel_title = layout._panels[layout._current_panel].name
|
||||
if panel_title:
|
||||
path.append((tr(panel_title), "action:panel"))
|
||||
|
||||
pushed_widgets = getattr(gui_app, "_nav_stack", [])[1:]
|
||||
|
||||
for i, widget in enumerate(pushed_widgets):
|
||||
if hasattr(widget, '_header_title') and widget._header_title:
|
||||
@@ -5473,6 +5476,3 @@ class TileGrid(Widget):
|
||||
tile.render(snap_rect(rl.Rectangle(row_x + c * (row_tile_w + self._gap), rect.y + y_offset + r * (tile_h + self._gap), row_tile_w, tile_h)))
|
||||
tile_idx += 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -27,14 +27,25 @@ class StarPilotLayout(Widget):
|
||||
"panel": "SOUNDS",
|
||||
},
|
||||
{
|
||||
"title": "Driving Controls",
|
||||
"icon": "steering",
|
||||
"buttons": [("Driving Model", "DRIVING_MODEL", "aicar"), ("Gas / Brake", "LONGITUDINAL", "road"), ("Steering", "LATERAL", "steering")],
|
||||
"title": "Driving Model",
|
||||
"icon": "aicar",
|
||||
"panel": "DRIVING_MODEL",
|
||||
},
|
||||
{
|
||||
"title": "Navigation & Maps",
|
||||
"icon": "navigate",
|
||||
"buttons": [("Map Data", "MAPS", "navigate"), ("Navigation", "NAVIGATION", "road")],
|
||||
"title": "Driving Controls",
|
||||
"icon": "steering",
|
||||
"children": [
|
||||
{
|
||||
"title": "Navigation & Maps",
|
||||
"icon": "navigate",
|
||||
"children": [
|
||||
{"title": "Map Data", "panel": "MAPS", "icon": "navigate"},
|
||||
{"title": "Navigation", "panel": "NAVIGATION", "icon": "road"},
|
||||
],
|
||||
},
|
||||
{"title": "Gas / Brake", "panel": "LONGITUDINAL", "icon": "road"},
|
||||
{"title": "Steering", "panel": "LATERAL", "icon": "steering"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "System",
|
||||
@@ -53,11 +64,27 @@ class StarPilotLayout(Widget):
|
||||
},
|
||||
]
|
||||
|
||||
PANEL_TYPE_MAP = {
|
||||
"SOUNDS": StarPilotPanelType.SOUNDS,
|
||||
"SYSTEM": StarPilotPanelType.SYSTEM,
|
||||
"DRIVING_MODEL": StarPilotPanelType.DRIVING_MODEL,
|
||||
"LONGITUDINAL": StarPilotPanelType.LONGITUDINAL,
|
||||
"LATERAL": StarPilotPanelType.LATERAL,
|
||||
"MAPS": StarPilotPanelType.MAPS,
|
||||
"NAVIGATION": StarPilotPanelType.NAVIGATION,
|
||||
"VISUALS": StarPilotPanelType.VISUALS,
|
||||
"VEHICLE": StarPilotPanelType.VEHICLE,
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._params = FrameCachedParams()
|
||||
|
||||
self._current_panel = StarPilotPanelType.MAIN
|
||||
self._hub_path: list[dict] = []
|
||||
self._selected_leaf: dict | None = None
|
||||
# Kept as a compatibility alias for callers that only need the top-level
|
||||
# folder index. Nested hub navigation is represented by _hub_path.
|
||||
self._current_category_idx: int | None = None
|
||||
self._depth_callback: Callable | None = None
|
||||
self._settings_layout = None
|
||||
@@ -101,38 +128,69 @@ class StarPilotLayout(Widget):
|
||||
def set_settings_layout(self, settings_layout):
|
||||
self._settings_layout = settings_layout
|
||||
|
||||
@property
|
||||
def hub_path(self) -> tuple[dict, ...]:
|
||||
return tuple(self._hub_path)
|
||||
|
||||
def navigate_back(self):
|
||||
if self._panel_stack:
|
||||
self._panel_stack.pop()
|
||||
self._commit_navigation()
|
||||
elif self._current_panel != StarPilotPanelType.MAIN:
|
||||
if self._current_category_idx is not None:
|
||||
cat_info = self.CATEGORIES[self._current_category_idx]
|
||||
if "buttons" in cat_info:
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
else:
|
||||
self._current_category_idx = None
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
else:
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
elif self._current_category_idx is not None:
|
||||
self._current_category_idx = None
|
||||
# A panel always returns to the folder that launched it.
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
elif self._hub_path:
|
||||
# Once the grid is visible, each back step removes one hub folder.
|
||||
self._hub_path.pop()
|
||||
self._selected_leaf = None
|
||||
self._sync_legacy_category_idx()
|
||||
self._rebuild_grid()
|
||||
self._commit_navigation()
|
||||
|
||||
def reset_to_root(self):
|
||||
"""Close nested content and restore the primary six-tile hub."""
|
||||
self._hub_path.clear()
|
||||
self._selected_leaf = None
|
||||
self._sync_legacy_category_idx()
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
|
||||
def navigate_to_hub_depth(self, depth: int):
|
||||
"""Jump to a folder in the current hub path from a breadcrumb."""
|
||||
depth = max(0, min(depth, len(self._hub_path)))
|
||||
self._hub_path = self._hub_path[:depth]
|
||||
self._selected_leaf = None
|
||||
self._sync_legacy_category_idx()
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
|
||||
def _sync_legacy_category_idx(self):
|
||||
if self._hub_path:
|
||||
self._current_category_idx = self.CATEGORIES.index(self._hub_path[0])
|
||||
else:
|
||||
self._current_category_idx = None
|
||||
|
||||
def _open_folder(self, folder: dict):
|
||||
if "children" not in folder:
|
||||
return
|
||||
self._hub_path.append(folder)
|
||||
self._selected_leaf = None
|
||||
self._sync_legacy_category_idx()
|
||||
self._set_current_panel(StarPilotPanelType.MAIN)
|
||||
|
||||
def _open_leaf(self, leaf: dict):
|
||||
panel_key = leaf.get("panel")
|
||||
if panel_key is None:
|
||||
return
|
||||
self._selected_leaf = leaf
|
||||
self._set_current_panel(self.PANEL_TYPE_MAP[panel_key])
|
||||
|
||||
def _update_depth(self):
|
||||
depth = 0
|
||||
# Root = 0, each visible hub folder = 1, and an open backend panel adds
|
||||
# one more level. Existing panel sub-pages remain below that panel.
|
||||
depth = len(self._hub_path)
|
||||
if self._current_panel != StarPilotPanelType.MAIN:
|
||||
if self._current_category_idx is not None:
|
||||
cat_info = self.CATEGORIES[self._current_category_idx]
|
||||
depth = 2 if "buttons" in cat_info else 1
|
||||
else:
|
||||
depth = 1
|
||||
# Deep nesting check
|
||||
if self._panel_stack:
|
||||
depth += len(self._panel_stack)
|
||||
elif self._current_category_idx is not None:
|
||||
depth = 1
|
||||
|
||||
depth += 1
|
||||
depth += len(self._panel_stack)
|
||||
|
||||
if self._depth_callback:
|
||||
self._depth_callback(depth)
|
||||
|
||||
@@ -166,70 +224,28 @@ class StarPilotLayout(Widget):
|
||||
panel.set_navigate_callback(self._push_sub_panel)
|
||||
|
||||
def _rebuild_grid(self):
|
||||
state = (self._current_category_idx,)
|
||||
state = tuple(id(folder) for folder in self._hub_path)
|
||||
if getattr(self, "_last_grid_state", None) == state:
|
||||
return
|
||||
self._last_grid_state = state
|
||||
self._main_grid.clear()
|
||||
|
||||
panel_type_map = {
|
||||
"SOUNDS": StarPilotPanelType.SOUNDS,
|
||||
"SYSTEM": StarPilotPanelType.SYSTEM,
|
||||
"DRIVING_MODEL": StarPilotPanelType.DRIVING_MODEL,
|
||||
"LONGITUDINAL": StarPilotPanelType.LONGITUDINAL,
|
||||
"LATERAL": StarPilotPanelType.LATERAL,
|
||||
"MAPS": StarPilotPanelType.MAPS,
|
||||
"NAVIGATION": StarPilotPanelType.NAVIGATION,
|
||||
"VISUALS": StarPilotPanelType.VISUALS,
|
||||
"VEHICLE": StarPilotPanelType.VEHICLE,
|
||||
}
|
||||
|
||||
if self._current_category_idx is None:
|
||||
# Main Categories Grid
|
||||
for i, cat in enumerate(self.CATEGORIES):
|
||||
def on_click(idx=i):
|
||||
cat_info = self.CATEGORIES[idx]
|
||||
self._current_category_idx = idx
|
||||
panel_key = cat_info.get("panel")
|
||||
if panel_key is not None:
|
||||
self._set_current_panel(panel_type_map[panel_key])
|
||||
else:
|
||||
self._rebuild_grid()
|
||||
if self._depth_callback:
|
||||
self._depth_callback(1)
|
||||
|
||||
tile = HubTile(
|
||||
title=tr(cat["title"]),
|
||||
desc=tr(cat.get("desc", "")),
|
||||
icon_key=cat["icon"],
|
||||
on_click=on_click,
|
||||
bg_color=cat.get("color")
|
||||
)
|
||||
self._main_grid.add_tile(tile)
|
||||
else:
|
||||
# Sub-buttons Grid for selected Category
|
||||
cat = self.CATEGORIES[self._current_category_idx]
|
||||
visible_buttons = cat["buttons"]
|
||||
|
||||
for button_info in visible_buttons:
|
||||
if len(button_info) == 3:
|
||||
label, panel_key, btn_icon = button_info
|
||||
visible_nodes = self.CATEGORIES if not self._hub_path else self._hub_path[-1]["children"]
|
||||
for node in visible_nodes:
|
||||
def on_click(item=node):
|
||||
if "children" in item:
|
||||
self._open_folder(item)
|
||||
else:
|
||||
label, panel_key = button_info
|
||||
btn_icon = cat["icon"]
|
||||
|
||||
p_type = panel_type_map[panel_key]
|
||||
def on_btn_click(p=p_type):
|
||||
self._set_current_panel(p)
|
||||
self._open_leaf(item)
|
||||
|
||||
tile = HubTile(
|
||||
title=tr(label),
|
||||
desc="",
|
||||
icon_key=btn_icon,
|
||||
on_click=on_btn_click,
|
||||
bg_color=cat.get("color")
|
||||
)
|
||||
self._main_grid.add_tile(tile)
|
||||
tile = HubTile(
|
||||
title=tr(node["title"]),
|
||||
desc=tr(node.get("desc", "")),
|
||||
icon_key=node["icon"],
|
||||
on_click=on_click,
|
||||
bg_color=node.get("color")
|
||||
)
|
||||
self._main_grid.add_tile(tile)
|
||||
|
||||
def _set_current_panel(self, panel_type: StarPilotPanelType):
|
||||
if panel_type != self._current_panel:
|
||||
@@ -244,8 +260,10 @@ class StarPilotLayout(Widget):
|
||||
if panel_type != StarPilotPanelType.MAIN:
|
||||
self._panels[panel_type].instance.show_event()
|
||||
else:
|
||||
self._selected_leaf = None
|
||||
self._rebuild_grid()
|
||||
elif panel_type == StarPilotPanelType.MAIN:
|
||||
self._selected_leaf = None
|
||||
self._rebuild_grid()
|
||||
self._panel_stack.clear()
|
||||
|
||||
|
||||
@@ -1,20 +1,241 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.main_panel import StarPilotLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.navigation import StarPilotNavigationLayout
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanelType
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import BreadcrumbController, gui_app
|
||||
|
||||
|
||||
def test_navigation_and_maps_is_the_parent_folder_for_map_data_and_navigation():
|
||||
category = next(item for item in StarPilotLayout.CATEGORIES if item["title"] == "Navigation & Maps")
|
||||
|
||||
assert "panel" not in category
|
||||
assert category["buttons"] == [
|
||||
("Map Data", "MAPS", "navigate"),
|
||||
("Navigation", "NAVIGATION", "road"),
|
||||
def test_root_hub_contains_the_six_categories_in_order():
|
||||
assert [item["title"] for item in StarPilotLayout.CATEGORIES] == [
|
||||
"Sounds & Alerts",
|
||||
"Driving Model",
|
||||
"Driving Controls",
|
||||
"System",
|
||||
"Appearance",
|
||||
"Vehicle Settings",
|
||||
]
|
||||
assert all(item["title"] != "Map Data" for item in StarPilotLayout.CATEGORIES)
|
||||
assert len(StarPilotLayout.CATEGORIES) == 6
|
||||
assert all(item["title"] != "Navigation & Maps" for item in StarPilotLayout.CATEGORIES)
|
||||
|
||||
|
||||
def test_driving_controls_contains_nested_navigation_folder_and_leaf_routes():
|
||||
controls = next(item for item in StarPilotLayout.CATEGORIES if item["title"] == "Driving Controls")
|
||||
|
||||
assert "panel" not in controls
|
||||
assert [item["title"] for item in controls["children"]] == [
|
||||
"Navigation & Maps",
|
||||
"Gas / Brake",
|
||||
"Steering",
|
||||
]
|
||||
|
||||
navigation_maps = controls["children"][0]
|
||||
assert "panel" not in navigation_maps
|
||||
assert navigation_maps["children"] == [
|
||||
{"title": "Map Data", "panel": "MAPS", "icon": "navigate"},
|
||||
{"title": "Navigation", "panel": "NAVIGATION", "icon": "road"},
|
||||
]
|
||||
|
||||
assert controls["children"][1]["panel"] == "LONGITUDINAL"
|
||||
assert controls["children"][2]["panel"] == "LATERAL"
|
||||
|
||||
|
||||
def test_driving_model_is_a_root_leaf_and_existing_panel_routes_are_preserved():
|
||||
driving_model = next(item for item in StarPilotLayout.CATEGORIES if item["title"] == "Driving Model")
|
||||
|
||||
assert driving_model["panel"] == "DRIVING_MODEL"
|
||||
assert driving_model["icon"] == "aicar"
|
||||
assert "children" not in driving_model
|
||||
assert StarPilotLayout.PANEL_TYPE_MAP["DRIVING_MODEL"] == StarPilotPanelType.DRIVING_MODEL
|
||||
assert StarPilotLayout.PANEL_TYPE_MAP["MAPS"] == StarPilotPanelType.MAPS
|
||||
assert StarPilotLayout.PANEL_TYPE_MAP["NAVIGATION"] == StarPilotPanelType.NAVIGATION
|
||||
assert StarPilotPanelType.NAVIGATION.value == 13
|
||||
|
||||
|
||||
class _FakeHubTile:
|
||||
def __init__(self, title, desc, icon_key, on_click, bg_color=None):
|
||||
self.title = title
|
||||
self.desc = desc
|
||||
self.icon_key = icon_key
|
||||
self.on_click = on_click
|
||||
self.bg_color = bg_color
|
||||
|
||||
|
||||
class _FakeGrid:
|
||||
def __init__(self):
|
||||
self.tiles = []
|
||||
|
||||
def clear(self):
|
||||
self.tiles.clear()
|
||||
|
||||
def add_tile(self, tile):
|
||||
self.tiles.append(tile)
|
||||
|
||||
|
||||
class _PanelSpy:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.show_count = 0
|
||||
self.hide_count = 0
|
||||
self.current_sub_panel = ""
|
||||
|
||||
def show_event(self):
|
||||
self.show_count += 1
|
||||
|
||||
def hide_event(self):
|
||||
self.hide_count += 1
|
||||
|
||||
def set_current_sub_panel(self, sub_panel):
|
||||
self.current_sub_panel = sub_panel
|
||||
|
||||
|
||||
def _make_layout(monkeypatch):
|
||||
import openpilot.selfdrive.ui.layouts.settings.starpilot.main_panel as main_panel
|
||||
|
||||
monkeypatch.setattr(main_panel, "HubTile", _FakeHubTile)
|
||||
|
||||
layout = object.__new__(StarPilotLayout)
|
||||
layout._current_panel = StarPilotPanelType.MAIN
|
||||
layout._hub_path = []
|
||||
layout._selected_leaf = None
|
||||
layout._current_category_idx = None
|
||||
layout._panel_stack = []
|
||||
layout._depth_callback = None
|
||||
layout._main_grid = _FakeGrid()
|
||||
layout._panels = {}
|
||||
for panel_type in StarPilotPanelType:
|
||||
layout._panels[panel_type] = SimpleNamespace(
|
||||
name=panel_type.name,
|
||||
instance=None if panel_type == StarPilotPanelType.MAIN else _PanelSpy(panel_type.name),
|
||||
)
|
||||
|
||||
depths = []
|
||||
layout.set_depth_callback(depths.append)
|
||||
StarPilotLayout.active_instance = layout
|
||||
layout._rebuild_grid()
|
||||
return layout, depths
|
||||
|
||||
|
||||
def _click_title(layout, title):
|
||||
tile = next(tile for tile in layout._main_grid.tiles if tile.title == title)
|
||||
tile.on_click()
|
||||
|
||||
|
||||
def test_nested_hub_navigation_back_and_depth_values(monkeypatch):
|
||||
layout, depths = _make_layout(monkeypatch)
|
||||
assert len(layout._main_grid.tiles) == 6
|
||||
assert depths == []
|
||||
|
||||
_click_title(layout, "Driving Controls")
|
||||
assert [folder["title"] for folder in layout._hub_path] == ["Driving Controls"]
|
||||
assert layout._current_panel == StarPilotPanelType.MAIN
|
||||
layout._update_depth()
|
||||
assert depths[-1] == 1
|
||||
|
||||
_click_title(layout, "Navigation & Maps")
|
||||
assert [folder["title"] for folder in layout._hub_path] == ["Driving Controls", "Navigation & Maps"]
|
||||
layout._update_depth()
|
||||
assert depths[-1] == 2
|
||||
|
||||
_click_title(layout, "Map Data")
|
||||
assert layout._current_panel == StarPilotPanelType.MAPS
|
||||
assert layout._selected_leaf["title"] == "Map Data"
|
||||
assert depths[-1] == 3
|
||||
maps_panel = layout._panels[StarPilotPanelType.MAPS].instance
|
||||
assert (maps_panel.show_count, maps_panel.hide_count) == (1, 0)
|
||||
|
||||
layout.navigate_back()
|
||||
assert layout._current_panel == StarPilotPanelType.MAIN
|
||||
assert [folder["title"] for folder in layout._hub_path] == ["Driving Controls", "Navigation & Maps"]
|
||||
assert depths[-1] == 2
|
||||
assert (maps_panel.show_count, maps_panel.hide_count) == (1, 1)
|
||||
|
||||
layout.navigate_back()
|
||||
assert [folder["title"] for folder in layout._hub_path] == ["Driving Controls"]
|
||||
assert depths[-1] == 1
|
||||
|
||||
layout.navigate_back()
|
||||
assert layout._hub_path == []
|
||||
assert depths[-1] == 0
|
||||
|
||||
|
||||
def test_root_driving_model_opens_directly_and_sub_panel_depth_is_additive(monkeypatch):
|
||||
layout, depths = _make_layout(monkeypatch)
|
||||
|
||||
_click_title(layout, "Driving Model")
|
||||
assert layout._hub_path == []
|
||||
assert layout._current_panel == StarPilotPanelType.DRIVING_MODEL
|
||||
assert depths[-1] == 1
|
||||
|
||||
layout._panel_stack.append((StarPilotPanelType.DRIVING_MODEL, "details"))
|
||||
layout._commit_navigation()
|
||||
assert depths[-1] == 2
|
||||
|
||||
layout.navigate_back()
|
||||
assert layout._current_panel == StarPilotPanelType.DRIVING_MODEL
|
||||
assert layout._panel_stack == []
|
||||
assert depths[-1] == 1
|
||||
|
||||
layout.navigate_back()
|
||||
assert layout._current_panel == StarPilotPanelType.MAIN
|
||||
assert depths[-1] == 0
|
||||
|
||||
|
||||
def test_breadcrumb_paths_and_folder_jump_back(monkeypatch):
|
||||
layout, _ = _make_layout(monkeypatch)
|
||||
monkeypatch.setattr(gui_app, "_nav_stack", [layout], raising=False)
|
||||
|
||||
assert BreadcrumbController.build_path() == [("StarPilot", "action:home")]
|
||||
|
||||
_click_title(layout, "Driving Controls")
|
||||
assert BreadcrumbController.build_path() == [
|
||||
("StarPilot", "action:home"),
|
||||
("Driving Controls", "action:hub:1"),
|
||||
]
|
||||
|
||||
_click_title(layout, "Navigation & Maps")
|
||||
assert BreadcrumbController.build_path() == [
|
||||
("StarPilot", "action:home"),
|
||||
("Driving Controls", "action:hub:1"),
|
||||
("Navigation & Maps", "action:hub:2"),
|
||||
]
|
||||
|
||||
_click_title(layout, "Map Data")
|
||||
assert BreadcrumbController.build_path()[-1] == ("Map Data", "action:panel")
|
||||
|
||||
nav_stack = [layout, object()]
|
||||
monkeypatch.setattr(gui_app, "_nav_stack", nav_stack, raising=False)
|
||||
monkeypatch.setattr(gui_app, "pop_widget", lambda: nav_stack.pop(), raising=False)
|
||||
BreadcrumbController().handle_click("action:hub:1")
|
||||
|
||||
assert nav_stack == [layout]
|
||||
assert layout._current_panel == StarPilotPanelType.MAIN
|
||||
assert [folder["title"] for folder in layout._hub_path] == ["Driving Controls"]
|
||||
assert BreadcrumbController.build_path()[-1] == ("Driving Controls", "action:hub:1")
|
||||
|
||||
|
||||
def test_home_breadcrumb_clears_hub_path_panel_stack_and_active_panel(monkeypatch):
|
||||
layout, _ = _make_layout(monkeypatch)
|
||||
_click_title(layout, "Driving Controls")
|
||||
_click_title(layout, "Navigation & Maps")
|
||||
_click_title(layout, "Map Data")
|
||||
layout._panel_stack.append((StarPilotPanelType.MAPS, "details"))
|
||||
|
||||
nav_stack = [layout, object(), object()]
|
||||
monkeypatch.setattr(gui_app, "_nav_stack", nav_stack, raising=False)
|
||||
monkeypatch.setattr(gui_app, "pop_widget", lambda: nav_stack.pop(), raising=False)
|
||||
BreadcrumbController().handle_click("action:home")
|
||||
|
||||
maps_panel = layout._panels[StarPilotPanelType.MAPS].instance
|
||||
assert nav_stack == [layout]
|
||||
assert layout._hub_path == []
|
||||
assert layout._selected_leaf is None
|
||||
assert layout._panel_stack == []
|
||||
assert layout._current_panel == StarPilotPanelType.MAIN
|
||||
assert maps_panel.hide_count == 1
|
||||
assert BreadcrumbController.build_path() == [("StarPilot", "action:home")]
|
||||
|
||||
|
||||
def test_navigation_start_is_the_summary_action_not_a_duplicate_rail_target():
|
||||
layout = object.__new__(StarPilotNavigationLayout)
|
||||
layout._draft_destination = {
|
||||
|
||||
Reference in New Issue
Block a user