mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 06:48:16 +00:00
feat(core): confirm homescreen image with thumbnail
[no changelog]
This commit is contained in:
parent
d00e87ea80
commit
1359b21508
@ -20,6 +20,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_jpeg_info;
|
||||
MP_QSTR_jpeg_test;
|
||||
MP_QSTR_confirm_action;
|
||||
MP_QSTR_confirm_homescreen;
|
||||
MP_QSTR_confirm_blob;
|
||||
MP_QSTR_confirm_properties;
|
||||
MP_QSTR_confirm_coinjoin;
|
||||
@ -99,6 +100,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_min_count;
|
||||
MP_QSTR_max_count;
|
||||
MP_QSTR_items;
|
||||
MP_QSTR_image;
|
||||
MP_QSTR_active;
|
||||
MP_QSTR_info_button;
|
||||
MP_QSTR_time_ms;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#[cfg(feature = "jpeg")]
|
||||
use crate::ui::geometry::Offset;
|
||||
use crate::ui::{
|
||||
component::{Component, Event, EventCtx, Never},
|
||||
display,
|
||||
@ -64,3 +66,14 @@ pub fn image_painter(image: &'static [u8]) -> Painter<impl FnMut(Rect)> {
|
||||
let f = move |area: Rect| display::image(area.center(), image);
|
||||
Painter::new(f)
|
||||
}
|
||||
|
||||
#[cfg(feature = "jpeg")]
|
||||
pub fn jpeg_painter<'a>(
|
||||
image: impl Fn() -> &'a [u8],
|
||||
size: Offset,
|
||||
scale: u8,
|
||||
) -> Painter<impl FnMut(Rect)> {
|
||||
let off = Offset::new(size.x / (2 << scale), size.y / (2 << scale));
|
||||
let f = move |area: Rect| display::tjpgd::jpeg(image(), area.center() - off, scale);
|
||||
Painter::new(f)
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use core::{cmp::Ordering, convert::TryInto};
|
||||
use cstr_core::cstr;
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::{
|
||||
buffer::StrBuffer,
|
||||
buffer::{get_buffer, StrBuffer},
|
||||
gc::Gc,
|
||||
iter::{Iter, IterBuf},
|
||||
list::List,
|
||||
@ -28,6 +29,7 @@ use crate::{
|
||||
},
|
||||
Border, Component, Empty, Timeout, TimeoutMsg,
|
||||
},
|
||||
display::tjpgd::jpeg_info,
|
||||
geometry,
|
||||
layout::{
|
||||
obj::{ComponentMsgObj, LayoutObj},
|
||||
@ -466,6 +468,37 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_confirm_homescreen(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 data: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
|
||||
|
||||
// Layout needs to hold the Obj to play nice with GC. Obj is resolved to &[u8]
|
||||
// in every paint pass.
|
||||
// SAFETY: We expect no existing mutable reference. Resulting reference is
|
||||
// discarded before returning to micropython.
|
||||
let buffer_func = move || unsafe { unwrap!(get_buffer(data)) };
|
||||
|
||||
let size = match jpeg_info(buffer_func()) {
|
||||
Some(info) => info.0,
|
||||
_ => return Err(Error::ValueError(cstr!("Invalid image."))),
|
||||
};
|
||||
|
||||
let buttons = Button::cancel_confirm_text(None, "CONFIRM");
|
||||
let obj = LayoutObj::new(
|
||||
Frame::centered(
|
||||
theme::label_title(),
|
||||
title,
|
||||
Dialog::new(painter::jpeg_painter(buffer_func, size, 1), buttons),
|
||||
)
|
||||
.with_border(theme::borders()),
|
||||
)?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_confirm_reset_device(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()?;
|
||||
@ -1322,6 +1355,15 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// """Confirm action."""
|
||||
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(),
|
||||
|
||||
|
||||
/// def confirm_homescreen(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// image: bytes,
|
||||
/// ) -> object:
|
||||
/// """Confirm homescreen."""
|
||||
Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(),
|
||||
|
||||
/// def confirm_blob(
|
||||
/// *,
|
||||
/// title: str,
|
||||
|
@ -97,6 +97,15 @@ def confirm_action(
|
||||
"""Confirm action."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tt/layout.rs
|
||||
def confirm_homescreen(
|
||||
*,
|
||||
title: str,
|
||||
image: bytes,
|
||||
) -> object:
|
||||
"""Confirm homescreen."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tt/layout.rs
|
||||
def confirm_blob(
|
||||
*,
|
||||
|
@ -1,7 +1,7 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor.enums import ButtonRequestType
|
||||
from trezor.ui.layouts import confirm_action
|
||||
from trezor.ui.layouts import confirm_action, confirm_homescreen
|
||||
from trezor.wire import DataError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -73,7 +73,7 @@ async def apply_settings(ctx: Context, msg: ApplySettings) -> Success:
|
||||
|
||||
if homescreen is not None:
|
||||
_validate_homescreen(homescreen)
|
||||
await _require_confirm_change_homescreen(ctx)
|
||||
await _require_confirm_change_homescreen(ctx, homescreen)
|
||||
try:
|
||||
storage_device.set_homescreen(homescreen)
|
||||
except ValueError:
|
||||
@ -122,14 +122,22 @@ async def apply_settings(ctx: Context, msg: ApplySettings) -> Success:
|
||||
return Success(message="Settings applied")
|
||||
|
||||
|
||||
async def _require_confirm_change_homescreen(ctx: GenericContext) -> None:
|
||||
await confirm_action(
|
||||
ctx,
|
||||
"set_homescreen",
|
||||
"Set homescreen",
|
||||
description="Do you really want to change the homescreen image?",
|
||||
br_code=BRT_PROTECT_CALL,
|
||||
)
|
||||
async def _require_confirm_change_homescreen(
|
||||
ctx: GenericContext, homescreen: bytes
|
||||
) -> None:
|
||||
if homescreen == b"":
|
||||
await confirm_action(
|
||||
ctx,
|
||||
"set_homescreen",
|
||||
"Set homescreen",
|
||||
description="Do you really want to set default homescreen image?",
|
||||
br_code=BRT_PROTECT_CALL,
|
||||
)
|
||||
else:
|
||||
await confirm_homescreen(
|
||||
ctx,
|
||||
homescreen,
|
||||
)
|
||||
|
||||
|
||||
async def _require_confirm_change_label(ctx: GenericContext, label: str) -> None:
|
||||
|
@ -334,6 +334,25 @@ async def confirm_path_warning(
|
||||
)
|
||||
|
||||
|
||||
async def confirm_homescreen(
|
||||
ctx: GenericContext,
|
||||
image: bytes,
|
||||
) -> None:
|
||||
await raise_if_not_confirmed(
|
||||
interact(
|
||||
ctx,
|
||||
RustLayout(
|
||||
trezorui2.confirm_homescreen(
|
||||
title="SET HOMESCREEN",
|
||||
image=image,
|
||||
)
|
||||
),
|
||||
"set_homesreen",
|
||||
ButtonRequestType.ProtectCall,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _show_xpub(xpub: str, title: str, cancel: str | None) -> ui.Layout:
|
||||
content = RustLayout(
|
||||
trezorui2.confirm_blob(
|
||||
|
Loading…
Reference in New Issue
Block a user