mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-26 00:08:10 +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_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;
|
||||||
|
@ -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,
|
||||||
|
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: 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 {
|
||||||
|
@ -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(
|
||||||
*,
|
*,
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user