mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 23:38:09 +00:00
refactor(core/rust/ui): add show_info and show_error
[no changelog]
This commit is contained in:
parent
f0d5f9069a
commit
4ff2c99f0a
BIN
core/assets/info.png
Normal file
BIN
core/assets/info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -26,9 +26,11 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_confirm_payment_request;
|
||||
MP_QSTR_confirm_text;
|
||||
MP_QSTR_confirm_total;
|
||||
MP_QSTR_show_error;
|
||||
MP_QSTR_show_qr;
|
||||
MP_QSTR_show_success;
|
||||
MP_QSTR_show_warning;
|
||||
MP_QSTR_show_info;
|
||||
MP_QSTR_request_pin;
|
||||
MP_QSTR_request_passphrase;
|
||||
MP_QSTR_request_bip39;
|
||||
|
@ -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) }
|
||||
}
|
||||
|
||||
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 {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
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())
|
||||
new_show_modal(kwargs, theme::IMAGE_WARN, theme::button_reset())
|
||||
};
|
||||
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 {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
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()?;
|
||||
new_show_modal(kwargs, theme::IMAGE_SUCCESS, theme::button_confirm())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
let buttons = component::Map::new(
|
||||
Button::with_text(button).styled(theme::button_confirm()),
|
||||
|msg| (matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed),
|
||||
);
|
||||
|
||||
let obj = LayoutObj::new(
|
||||
IconDialog::new(theme::IMAGE_SUCCESS, title, buttons).with_description(description),
|
||||
)?;
|
||||
Ok(obj.into())
|
||||
extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
new_show_modal(kwargs, theme::IMAGE_INFO, theme::button_info())
|
||||
};
|
||||
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."""
|
||||
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(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// button: str,
|
||||
/// description: str = "",
|
||||
/// allow_cancel: bool = False,
|
||||
/// ) -> object:
|
||||
/// """Warning modal."""
|
||||
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,
|
||||
/// button: str,
|
||||
/// description: str = "",
|
||||
/// allow_cancel: bool = False,
|
||||
/// ) -> object:
|
||||
/// """Success modal."""
|
||||
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(
|
||||
/// *,
|
||||
/// description: str,
|
||||
|
BIN
core/embed/rust/src/ui/model_tt/res/info.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/info.toif
Normal file
Binary file not shown.
@ -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_DARK: Color = Color::rgb(48, 147, 15);
|
||||
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 GREY_LIGHT: Color = Color::rgb(168, 168, 168); // greyish
|
||||
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_SUCCESS: &[u8] = include_res!("model_tt/res/success.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.
|
||||
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 {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
|
@ -146,11 +146,24 @@ def confirm_modify_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
|
||||
def show_warning(
|
||||
*,
|
||||
title: str,
|
||||
button: str,
|
||||
description: str = "",
|
||||
allow_cancel: bool = False,
|
||||
) -> object:
|
||||
"""Warning modal."""
|
||||
|
||||
@ -161,10 +174,22 @@ def show_success(
|
||||
title: str,
|
||||
button: str,
|
||||
description: str = "",
|
||||
allow_cancel: bool = False,
|
||||
) -> object:
|
||||
"""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
|
||||
def confirm_payment_request(
|
||||
*,
|
||||
|
@ -208,6 +208,7 @@ async def confirm_path_warning(
|
||||
trezorui2.show_warning(
|
||||
title="Unknown path",
|
||||
description=path,
|
||||
button="CONTINUE",
|
||||
)
|
||||
),
|
||||
"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(
|
||||
ctx: wire.GenericContext,
|
||||
br_type: str,
|
||||
content: str,
|
||||
header: str = "Error",
|
||||
subheader: str | None = None,
|
||||
button: str = "Close",
|
||||
button: str = "CLOSE",
|
||||
red: bool = False,
|
||||
exc: ExceptionType = wire.ActionCancelled,
|
||||
) -> NoReturn:
|
||||
await _show_modal(
|
||||
await interact(
|
||||
ctx,
|
||||
br_type=br_type,
|
||||
br_code=ButtonRequestType.Other,
|
||||
header=header,
|
||||
subheader=subheader,
|
||||
content=content,
|
||||
button_confirm=None,
|
||||
button_cancel=button,
|
||||
icon=ui.ICON_WRONG,
|
||||
icon_color=ui.RED if red else ui.ORANGE_ICON,
|
||||
exc=exc,
|
||||
_RustLayout(
|
||||
trezorui2.show_error(
|
||||
title=content.replace("\n", " "),
|
||||
description=subheader or "",
|
||||
button=button.upper(),
|
||||
allow_cancel=False,
|
||||
)
|
||||
),
|
||||
br_type,
|
||||
ButtonRequestType.Other,
|
||||
)
|
||||
raise exc
|
||||
|
||||
|
||||
def show_warning(
|
||||
async def show_warning(
|
||||
ctx: wire.GenericContext,
|
||||
br_type: str,
|
||||
content: str,
|
||||
header: str = "Warning",
|
||||
subheader: str | None = None,
|
||||
button: str = "Try again",
|
||||
button: str = "TRY AGAIN",
|
||||
br_code: ButtonRequestType = ButtonRequestType.Warning,
|
||||
icon: str = ui.ICON_WRONG,
|
||||
icon_color: int = ui.RED,
|
||||
) -> Awaitable[None]:
|
||||
return _show_modal(
|
||||
) -> None:
|
||||
result = await interact(
|
||||
ctx,
|
||||
br_type=br_type,
|
||||
br_code=br_code,
|
||||
header=header,
|
||||
subheader=subheader,
|
||||
content=content,
|
||||
button_confirm=button,
|
||||
button_cancel=None,
|
||||
icon=icon,
|
||||
icon_color=icon_color,
|
||||
_RustLayout(
|
||||
trezorui2.show_warning(
|
||||
title=content.replace("\n", " "),
|
||||
description=subheader or "",
|
||||
button=button.upper(),
|
||||
allow_cancel=False,
|
||||
)
|
||||
),
|
||||
br_type,
|
||||
br_code,
|
||||
)
|
||||
if result is not trezorui2.CONFIRMED:
|
||||
raise wire.ActionCancelled
|
||||
|
||||
|
||||
async def show_success(
|
||||
@ -389,15 +377,16 @@ async def show_success(
|
||||
br_type: str,
|
||||
content: str,
|
||||
subheader: str | None = None,
|
||||
button: str = "Continue",
|
||||
button: str = "CONTINUE",
|
||||
) -> None:
|
||||
result = await interact(
|
||||
ctx,
|
||||
_RustLayout(
|
||||
trezorui2.show_success(
|
||||
title=content,
|
||||
title=content.replace("\n", " "),
|
||||
description=subheader or "",
|
||||
button=button.upper(),
|
||||
allow_cancel=False,
|
||||
)
|
||||
),
|
||||
br_type,
|
||||
@ -666,11 +655,13 @@ async def confirm_metadata(
|
||||
layout = trezorui2.show_warning(
|
||||
title="Unusually high fee",
|
||||
description=param or "",
|
||||
button="CONTINUE",
|
||||
)
|
||||
elif br_type == "change_count_over_threshold":
|
||||
layout = trezorui2.show_warning(
|
||||
title="A lot of change-outputs",
|
||||
description=f"{param} outputs" if param is not None else "",
|
||||
button="CONTINUE",
|
||||
)
|
||||
else:
|
||||
if param is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user