You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.9 KiB
119 lines
3.9 KiB
from trezor import res, ui
|
|
from trezor.ui.button import Button, ButtonCancel, ButtonConfirm
|
|
from trezor.ui.loader import Loader, LoaderDefault
|
|
|
|
if False:
|
|
from typing import Optional
|
|
from trezor.ui.button import ButtonContent, ButtonStyleType
|
|
from trezor.ui.loader import LoaderStyleType
|
|
|
|
CONFIRMED = object()
|
|
CANCELLED = object()
|
|
|
|
|
|
class Confirm(ui.Layout):
|
|
DEFAULT_CONFIRM = res.load(ui.ICON_CONFIRM)
|
|
DEFAULT_CONFIRM_STYLE = ButtonConfirm
|
|
DEFAULT_CANCEL = res.load(ui.ICON_CANCEL)
|
|
DEFAULT_CANCEL_STYLE = ButtonCancel
|
|
|
|
def __init__(
|
|
self,
|
|
content: ui.Control,
|
|
confirm: Optional[ButtonContent] = DEFAULT_CONFIRM,
|
|
confirm_style: ButtonStyleType = DEFAULT_CONFIRM_STYLE,
|
|
cancel: Optional[ButtonContent] = DEFAULT_CANCEL,
|
|
cancel_style: ButtonStyleType = DEFAULT_CANCEL_STYLE,
|
|
major_confirm: bool = False,
|
|
) -> None:
|
|
self.content = content
|
|
|
|
if confirm is not None:
|
|
if cancel is None:
|
|
area = ui.grid(4, n_x=1)
|
|
elif major_confirm:
|
|
area = ui.grid(13, cells_x=2)
|
|
else:
|
|
area = ui.grid(9, n_x=2)
|
|
self.confirm = Button(
|
|
area, confirm, confirm_style
|
|
) # type: Optional[Button]
|
|
self.confirm.on_click = self.on_confirm # type: ignore
|
|
else:
|
|
self.confirm = None
|
|
|
|
if cancel is not None:
|
|
if confirm is None:
|
|
area = ui.grid(4, n_x=1)
|
|
elif major_confirm:
|
|
area = ui.grid(12, cells_x=1)
|
|
else:
|
|
area = ui.grid(8, n_x=2)
|
|
self.cancel = Button(area, cancel, cancel_style) # type: Optional[Button]
|
|
self.cancel.on_click = self.on_cancel # type: ignore
|
|
else:
|
|
self.cancel = None
|
|
|
|
def dispatch(self, event: int, x: int, y: int) -> None:
|
|
self.content.dispatch(event, x, y)
|
|
if self.confirm is not None:
|
|
self.confirm.dispatch(event, x, y)
|
|
if self.cancel is not None:
|
|
self.cancel.dispatch(event, x, y)
|
|
|
|
def on_confirm(self) -> None:
|
|
raise ui.Result(CONFIRMED)
|
|
|
|
def on_cancel(self) -> None:
|
|
raise ui.Result(CANCELLED)
|
|
|
|
|
|
class HoldToConfirm(ui.Layout):
|
|
DEFAULT_CONFIRM = "Hold To Confirm"
|
|
DEFAULT_CONFIRM_STYLE = ButtonConfirm
|
|
DEFAULT_LOADER_STYLE = LoaderDefault
|
|
|
|
def __init__(
|
|
self,
|
|
content: ui.Control,
|
|
confirm: str = DEFAULT_CONFIRM,
|
|
confirm_style: ButtonStyleType = DEFAULT_CONFIRM_STYLE,
|
|
loader_style: LoaderStyleType = DEFAULT_LOADER_STYLE,
|
|
):
|
|
self.content = content
|
|
|
|
self.loader = Loader(loader_style)
|
|
self.loader.on_start = self._on_loader_start # type: ignore
|
|
|
|
self.button = Button(ui.grid(4, n_x=1), confirm, confirm_style)
|
|
self.button.on_press_start = self._on_press_start # type: ignore
|
|
self.button.on_press_end = self._on_press_end # type: ignore
|
|
self.button.on_click = self._on_click # type: ignore
|
|
|
|
def _on_press_start(self) -> None:
|
|
self.loader.start()
|
|
|
|
def _on_press_end(self) -> None:
|
|
self.loader.stop()
|
|
|
|
def _on_loader_start(self) -> None:
|
|
# Loader has either started growing, or returned to the 0-position.
|
|
# In the first case we need to clear the content leftovers, in the latter
|
|
# we need to render the content again.
|
|
ui.display.bar(0, 0, ui.WIDTH, ui.HEIGHT - 60, ui.BG)
|
|
self.content.dispatch(ui.REPAINT, 0, 0)
|
|
|
|
def _on_click(self) -> None:
|
|
if self.loader.elapsed_ms() >= self.loader.target_ms:
|
|
self.on_confirm()
|
|
|
|
def dispatch(self, event: int, x: int, y: int) -> None:
|
|
if self.loader.start_ms is not None:
|
|
self.loader.dispatch(event, x, y)
|
|
else:
|
|
self.content.dispatch(event, x, y)
|
|
self.button.dispatch(event, x, y)
|
|
|
|
def on_confirm(self) -> None:
|
|
raise ui.Result(CONFIRMED)
|