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.
trezor-firmware/core/src/trezor/ui/confirm.py

112 lines
3.3 KiB

from trezor import res, ui
from trezor.ui.button import Button, ButtonCancel, ButtonConfirm
from trezor.ui.loader import Loader, LoaderDefault
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,
confirm=DEFAULT_CONFIRM,
confirm_style=DEFAULT_CONFIRM_STYLE,
cancel=DEFAULT_CANCEL,
cancel_style=DEFAULT_CANCEL_STYLE,
major_confirm=False,
):
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)
self.confirm.on_click = self.on_confirm
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)
self.cancel.on_click = self.on_cancel
else:
self.cancel = None
def dispatch(self, event, x, y):
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):
raise ui.Result(CONFIRMED)
def on_cancel(self):
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,
confirm=DEFAULT_CONFIRM,
confirm_style=DEFAULT_CONFIRM_STYLE,
loader_style=DEFAULT_LOADER_STYLE,
):
self.content = content
self.loader = Loader(loader_style)
self.loader.on_start = self._on_loader_start
self.button = Button(ui.grid(4, n_x=1), confirm, confirm_style)
self.button.on_press_start = self._on_press_start
self.button.on_press_end = self._on_press_end
self.button.on_click = self._on_click
def _on_press_start(self):
self.loader.start()
def _on_press_end(self):
self.loader.stop()
def _on_loader_start(self):
# 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):
if self.loader.elapsed_ms() >= self.loader.target_ms:
self.on_confirm()
def dispatch(self, event, x, y):
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):
raise ui.Result(CONFIRMED)