1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-31 19:08:28 +00:00

feat(core): allow cancellation via a custom layout

[no changelog]
This commit is contained in:
Roman Zeyde 2025-07-17 11:15:30 +03:00 committed by Roman Zeyde
parent 0b2fdf3667
commit a0fa0d8433

View File

@ -15,9 +15,16 @@ if TYPE_CHECKING:
T = TypeVar("T") T = TypeVar("T")
async def _cancel_default() -> trezorui_api.UiResult:
return trezorui_api.CONFIRMED
class Menu: class Menu:
def __init__( def __init__(
self, name: str, children: Sequence["Details"], cancel: str | None = None self,
name: str,
children: Sequence["Details"],
cancel: "Cancel | None" = None,
) -> None: ) -> None:
self.name = name self.name = name
self.children = children self.children = children
@ -25,8 +32,10 @@ class Menu:
@classmethod @classmethod
def root( def root(
cls, children: Iterable["Details"] = (), cancel: str | None = None cls, children: Iterable["Details"] = (), cancel: "str | Cancel | None" = None
) -> Self: ) -> Self:
if isinstance(cancel, str):
cancel = Cancel(cancel, _cancel_default)
return cls("", children=tuple(children), cancel=cancel) return cls("", children=tuple(children), cancel=cancel)
@ -45,6 +54,10 @@ class Details:
) )
class Cancel(Details):
pass
async def show_menu( async def show_menu(
root: Menu, root: Menu,
raise_on_cancel: ExceptionType = ActionCancelled, raise_on_cancel: ExceptionType = ActionCancelled,
@ -60,12 +73,19 @@ async def show_menu(
layout = trezorui_api.select_menu( layout = trezorui_api.select_menu(
items=[child.name for child in menu.children], items=[child.name for child in menu.children],
current=current_item, current=current_item,
cancel=menu.cancel, cancel=menu.cancel and menu.cancel.name,
) )
choice = await interact( choice = await interact(layout, br_name=None, raise_on_cancel=None)
layout, br_name=None, raise_on_cancel=raise_on_cancel if choice is trezorui_api.CANCELLED:
) if menu.cancel:
if isinstance(choice, int): result = await menu.cancel.factory()
assert result in (trezorui_api.CONFIRMED, trezorui_api.CANCELLED)
if result is trezorui_api.CONFIRMED:
# cancellation is confirmed - raise an exception
raise raise_on_cancel
# cancellation is not confirmed - back to the menu
continue
elif isinstance(choice, int):
# go one level down # go one level down
menu_path.append(choice) menu_path.append(choice)
current_item = 0 current_item = 0