1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-25 15:58:08 +00:00

refactor(core/rust/ui): add show_info and show_error

[no changelog]
This commit is contained in:
Martin Milata 2022-07-07 17:08:53 +02:00
parent f0d5f9069a
commit 4ff2c99f0a
7 changed files with 174 additions and 70 deletions

BIN
core/assets/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -26,9 +26,11 @@ static void _librust_qstrs(void) {
MP_QSTR_confirm_payment_request; MP_QSTR_confirm_payment_request;
MP_QSTR_confirm_text; MP_QSTR_confirm_text;
MP_QSTR_confirm_total; MP_QSTR_confirm_total;
MP_QSTR_show_error;
MP_QSTR_show_qr; MP_QSTR_show_qr;
MP_QSTR_show_success; MP_QSTR_show_success;
MP_QSTR_show_warning; MP_QSTR_show_warning;
MP_QSTR_show_info;
MP_QSTR_request_pin; MP_QSTR_request_pin;
MP_QSTR_request_passphrase; MP_QSTR_request_passphrase;
MP_QSTR_request_bip39; MP_QSTR_request_bip39;

View File

@ -432,42 +432,71 @@ extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *m
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
fn new_show_modal(
kwargs: &Map,
icon: &'static [u8],
button_style: ButtonStyleSheet,
) -> Result<Obj, Error> {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
let obj = if allow_cancel {
LayoutObj::new(
IconDialog::new(
icon,
title,
Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL).styled(theme::button_cancel()),
Button::with_text(button).styled(button_style),
2,
),
)
.with_description(description),
)?
.into()
} else {
LayoutObj::new(
IconDialog::new(
icon,
title,
Button::with_text(button).styled(button_style).map(|msg| {
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
}),
)
.with_description(description),
)?
.into()
};
Ok(obj)
}
extern "C" fn new_show_error(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
new_show_modal(kwargs, theme::IMAGE_ERROR, theme::button_default())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_show_warning(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_show_warning(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; new_show_modal(kwargs, theme::IMAGE_WARN, theme::button_reset())
let description: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let buttons = Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL).styled(theme::button_cancel()),
Button::with_text("CONTINUE").styled(theme::button_reset()),
2,
);
let obj = LayoutObj::new(
IconDialog::new(theme::IMAGE_WARN, title, buttons).with_description(description),
)?;
Ok(obj.into())
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
extern "C" fn new_show_success(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_show_success(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; new_show_modal(kwargs, theme::IMAGE_SUCCESS, theme::button_confirm())
let description: StrBuffer = };
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?; }
let buttons = component::Map::new( extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
Button::with_text(button).styled(theme::button_confirm()), let block = move |_args: &[Obj], kwargs: &Map| {
|msg| (matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed), new_show_modal(kwargs, theme::IMAGE_INFO, theme::button_info())
);
let obj = LayoutObj::new(
IconDialog::new(theme::IMAGE_SUCCESS, title, buttons).with_description(description),
)?;
Ok(obj.into())
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
@ -667,10 +696,22 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Decrease or increase transaction fee.""" /// """Decrease or increase transaction fee."""
Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(), Qstr::MP_QSTR_confirm_modify_fee => obj_fn_kw!(0, new_confirm_modify_fee).as_obj(),
/// def show_error(
/// *,
/// title: str,
/// button: str,
/// description: str = "",
/// allow_cancel: bool = False,
/// ) -> object:
/// """Error modal."""
Qstr::MP_QSTR_show_error => obj_fn_kw!(0, new_show_error).as_obj(),
/// def show_warning( /// def show_warning(
/// *, /// *,
/// title: str, /// title: str,
/// button: str,
/// description: str = "", /// description: str = "",
/// allow_cancel: bool = False,
/// ) -> object: /// ) -> object:
/// """Warning modal.""" /// """Warning modal."""
Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(), Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(),
@ -680,10 +721,21 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str, /// title: str,
/// button: str, /// button: str,
/// description: str = "", /// description: str = "",
/// allow_cancel: bool = False,
/// ) -> object: /// ) -> object:
/// """Success modal.""" /// """Success modal."""
Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(), Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(),
/// def show_info(
/// *,
/// title: str,
/// button: str,
/// description: str = "",
/// allow_cancel: bool = False,
/// ) -> object:
/// """Info modal."""
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(),
/// def confirm_payment_request( /// def confirm_payment_request(
/// *, /// *,
/// description: str, /// description: str,

Binary file not shown.

View File

@ -34,6 +34,7 @@ pub const YELLOW_DARK: Color = Color::rgb(154, 115, 6); // FIXME
pub const GREEN: Color = Color::rgb(57, 168, 20); // grass-green pub const GREEN: Color = Color::rgb(57, 168, 20); // grass-green
pub const GREEN_DARK: Color = Color::rgb(48, 147, 15); pub const GREEN_DARK: Color = Color::rgb(48, 147, 15);
pub const BLUE: Color = Color::rgb(0, 86, 190); // blue pub const BLUE: Color = Color::rgb(0, 86, 190); // blue
pub const BLUE_DARK: Color = Color::rgb(0, 68, 152); // FIXME
pub const OFF_WHITE: Color = Color::rgb(222, 222, 222); // very light grey pub const OFF_WHITE: Color = Color::rgb(222, 222, 222); // very light grey
pub const GREY_LIGHT: Color = Color::rgb(168, 168, 168); // greyish pub const GREY_LIGHT: Color = Color::rgb(168, 168, 168); // greyish
pub const GREY_MEDIUM: Color = Color::rgb(100, 100, 100); pub const GREY_MEDIUM: Color = Color::rgb(100, 100, 100);
@ -60,6 +61,7 @@ pub const ICON_NEXT: &[u8] = include_res!("model_tt/res/next.toif");
pub const IMAGE_WARN: &[u8] = include_res!("model_tt/res/warn.toif"); pub const IMAGE_WARN: &[u8] = include_res!("model_tt/res/warn.toif");
pub const IMAGE_SUCCESS: &[u8] = include_res!("model_tt/res/success.toif"); pub const IMAGE_SUCCESS: &[u8] = include_res!("model_tt/res/success.toif");
pub const IMAGE_ERROR: &[u8] = include_res!("model_tt/res/error.toif"); pub const IMAGE_ERROR: &[u8] = include_res!("model_tt/res/error.toif");
pub const IMAGE_INFO: &[u8] = include_res!("model_tt/res/info.toif");
// Scrollbar/PIN dots. // Scrollbar/PIN dots.
pub const DOT_ACTIVE: &[u8] = include_res!("model_tt/res/scroll-active.toif"); pub const DOT_ACTIVE: &[u8] = include_res!("model_tt/res/scroll-active.toif");
@ -250,6 +252,38 @@ pub fn button_reset() -> ButtonStyleSheet {
} }
} }
pub fn button_info() -> ButtonStyleSheet {
ButtonStyleSheet {
normal: &ButtonStyle {
font: FONT_BOLD,
text_color: FG,
button_color: BLUE,
background_color: BG,
border_color: BG,
border_radius: RADIUS,
border_width: 0,
},
active: &ButtonStyle {
font: FONT_BOLD,
text_color: FG,
button_color: BLUE_DARK,
background_color: BG,
border_color: FG,
border_radius: RADIUS,
border_width: 0,
},
disabled: &ButtonStyle {
font: FONT_BOLD,
text_color: GREY_LIGHT,
button_color: BLUE,
background_color: BG,
border_color: BG,
border_radius: RADIUS,
border_width: 0,
},
}
}
pub fn button_pin() -> ButtonStyleSheet { pub fn button_pin() -> ButtonStyleSheet {
ButtonStyleSheet { ButtonStyleSheet {
normal: &ButtonStyle { normal: &ButtonStyle {

View File

@ -146,11 +146,24 @@ def confirm_modify_fee(
"""Decrease or increase transaction fee.""" """Decrease or increase transaction fee."""
# rust/src/ui/model_tt/layout.rs
def show_error(
*,
title: str,
button: str,
description: str = "",
allow_cancel: bool = False,
) -> object:
"""Error modal."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def show_warning( def show_warning(
*, *,
title: str, title: str,
button: str,
description: str = "", description: str = "",
allow_cancel: bool = False,
) -> object: ) -> object:
"""Warning modal.""" """Warning modal."""
@ -161,10 +174,22 @@ def show_success(
title: str, title: str,
button: str, button: str,
description: str = "", description: str = "",
allow_cancel: bool = False,
) -> object: ) -> object:
"""Success modal.""" """Success modal."""
# rust/src/ui/model_tt/layout.rs
def show_info(
*,
title: str,
button: str,
description: str = "",
allow_cancel: bool = False,
) -> object:
"""Info modal."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def confirm_payment_request( def confirm_payment_request(
*, *,

View File

@ -208,6 +208,7 @@ async def confirm_path_warning(
trezorui2.show_warning( trezorui2.show_warning(
title="Unknown path", title="Unknown path",
description=path, description=path,
button="CONTINUE",
) )
), ),
"path_warning", "path_warning",
@ -317,71 +318,58 @@ def show_pubkey(
) )
async def _show_modal(
ctx: wire.GenericContext,
br_type: str,
br_code: ButtonRequestType,
header: str,
subheader: str | None,
content: str,
button_confirm: str | None,
button_cancel: str | None,
icon: str,
icon_color: int,
exc: ExceptionType = wire.ActionCancelled,
) -> None:
raise NotImplementedError
async def show_error_and_raise( async def show_error_and_raise(
ctx: wire.GenericContext, ctx: wire.GenericContext,
br_type: str, br_type: str,
content: str, content: str,
header: str = "Error", header: str = "Error",
subheader: str | None = None, subheader: str | None = None,
button: str = "Close", button: str = "CLOSE",
red: bool = False, red: bool = False,
exc: ExceptionType = wire.ActionCancelled, exc: ExceptionType = wire.ActionCancelled,
) -> NoReturn: ) -> NoReturn:
await _show_modal( await interact(
ctx, ctx,
br_type=br_type, _RustLayout(
br_code=ButtonRequestType.Other, trezorui2.show_error(
header=header, title=content.replace("\n", " "),
subheader=subheader, description=subheader or "",
content=content, button=button.upper(),
button_confirm=None, allow_cancel=False,
button_cancel=button, )
icon=ui.ICON_WRONG, ),
icon_color=ui.RED if red else ui.ORANGE_ICON, br_type,
exc=exc, ButtonRequestType.Other,
) )
raise exc raise exc
def show_warning( async def show_warning(
ctx: wire.GenericContext, ctx: wire.GenericContext,
br_type: str, br_type: str,
content: str, content: str,
header: str = "Warning", header: str = "Warning",
subheader: str | None = None, subheader: str | None = None,
button: str = "Try again", button: str = "TRY AGAIN",
br_code: ButtonRequestType = ButtonRequestType.Warning, br_code: ButtonRequestType = ButtonRequestType.Warning,
icon: str = ui.ICON_WRONG, icon: str = ui.ICON_WRONG,
icon_color: int = ui.RED, icon_color: int = ui.RED,
) -> Awaitable[None]: ) -> None:
return _show_modal( result = await interact(
ctx, ctx,
br_type=br_type, _RustLayout(
br_code=br_code, trezorui2.show_warning(
header=header, title=content.replace("\n", " "),
subheader=subheader, description=subheader or "",
content=content, button=button.upper(),
button_confirm=button, allow_cancel=False,
button_cancel=None,
icon=icon,
icon_color=icon_color,
) )
),
br_type,
br_code,
)
if result is not trezorui2.CONFIRMED:
raise wire.ActionCancelled
async def show_success( async def show_success(
@ -389,15 +377,16 @@ async def show_success(
br_type: str, br_type: str,
content: str, content: str,
subheader: str | None = None, subheader: str | None = None,
button: str = "Continue", button: str = "CONTINUE",
) -> None: ) -> None:
result = await interact( result = await interact(
ctx, ctx,
_RustLayout( _RustLayout(
trezorui2.show_success( trezorui2.show_success(
title=content, title=content.replace("\n", " "),
description=subheader or "", description=subheader or "",
button=button.upper(), button=button.upper(),
allow_cancel=False,
) )
), ),
br_type, br_type,
@ -666,11 +655,13 @@ async def confirm_metadata(
layout = trezorui2.show_warning( layout = trezorui2.show_warning(
title="Unusually high fee", title="Unusually high fee",
description=param or "", description=param or "",
button="CONTINUE",
) )
elif br_type == "change_count_over_threshold": elif br_type == "change_count_over_threshold":
layout = trezorui2.show_warning( layout = trezorui2.show_warning(
title="A lot of change-outputs", title="A lot of change-outputs",
description=f"{param} outputs" if param is not None else "", description=f"{param} outputs" if param is not None else "",
button="CONTINUE",
) )
else: else:
if param is not None: if param is not None: