mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 20:38:10 +00:00
feat(core): show new homescreen preview for T2B1
[no changelog]
This commit is contained in:
parent
1f7c78a4ed
commit
0c4540ae0a
@ -12,7 +12,7 @@ use crate::{
|
||||
|
||||
use super::{
|
||||
super::constant, common::display_center, theme, ButtonController, ButtonControllerMsg,
|
||||
ButtonLayout,
|
||||
ButtonLayout, ButtonPos, CancelConfirmMsg,
|
||||
};
|
||||
|
||||
const AREA: Rect = constant::screen();
|
||||
@ -220,6 +220,70 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConfirmHomescreen<T, F>
|
||||
where
|
||||
T: StringType,
|
||||
{
|
||||
title: Child<Label<T>>,
|
||||
buffer_func: F,
|
||||
buttons: Child<ButtonController<T>>,
|
||||
}
|
||||
|
||||
impl<T, F> ConfirmHomescreen<T, F>
|
||||
where
|
||||
T: StringType + Clone,
|
||||
{
|
||||
pub fn new(title: T, buffer_func: F) -> Self {
|
||||
let btn_layout = ButtonLayout::cancel_none_text("CHANGE".into());
|
||||
ConfirmHomescreen {
|
||||
title: Child::new(Label::centered(title, theme::TEXT_BOLD)),
|
||||
buffer_func,
|
||||
buttons: Child::new(ButtonController::new(btn_layout)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, F> Component for ConfirmHomescreen<T, F>
|
||||
where
|
||||
T: StringType + Clone,
|
||||
F: Fn() -> &'a [u8],
|
||||
{
|
||||
type Msg = CancelConfirmMsg;
|
||||
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
let (title_content_area, button_area) = bounds.split_bottom(theme::BUTTON_HEIGHT);
|
||||
let title_height = theme::TEXT_BOLD.text_font.line_height();
|
||||
let (title_area, _) = title_content_area.split_top(title_height);
|
||||
self.title.place(title_area);
|
||||
self.buttons.place(button_area);
|
||||
bounds
|
||||
}
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
// Left button cancels, right confirms
|
||||
if let Some(ButtonControllerMsg::Triggered(pos)) = self.buttons.event(ctx, event) {
|
||||
match pos {
|
||||
ButtonPos::Left => return Some(CancelConfirmMsg::Cancelled),
|
||||
ButtonPos::Right => return Some(CancelConfirmMsg::Confirmed),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn paint(&mut self) {
|
||||
// Drawing the image full-screen first and then other things on top
|
||||
let toif_data = unwrap!(Toif::new((self.buffer_func)()));
|
||||
toif_data.draw(TOP_CENTER, Alignment2D::TOP_CENTER, theme::FG, theme::BG);
|
||||
// Need to make all the title background black, so the title text is well
|
||||
// visible
|
||||
let title_area = self.title.inner().area();
|
||||
rect_fill(title_area, theme::BG);
|
||||
self.title.paint();
|
||||
self.buttons.paint();
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG-ONLY SECTION BELOW
|
||||
|
||||
#[cfg(feature = "ui_debug")]
|
||||
@ -243,3 +307,14 @@ where
|
||||
t.child("label", &self.label);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<T, F> crate::trace::Trace for ConfirmHomescreen<T, F>
|
||||
where
|
||||
T: StringType,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.component("ConfirmHomescreen");
|
||||
t.child("title", &self.title);
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ pub use flow::Flow;
|
||||
pub use flow_pages::{FlowPages, Page};
|
||||
pub use frame::{Frame, ScrollableContent, ScrollableFrame};
|
||||
#[cfg(feature = "micropython")]
|
||||
pub use homescreen::{Homescreen, Lockscreen};
|
||||
pub use homescreen::{ConfirmHomescreen, Homescreen, Lockscreen};
|
||||
pub use input_methods::{
|
||||
number_input::NumberInput,
|
||||
passphrase::PassphraseEntry,
|
||||
|
@ -6,8 +6,15 @@ use crate::{
|
||||
error::Error,
|
||||
maybe_trace::MaybeTrace,
|
||||
micropython::{
|
||||
buffer::StrBuffer, gc::Gc, iter::IterBuf, list::List, map::Map, module::Module, obj::Obj,
|
||||
qstr::Qstr, util,
|
||||
buffer::{get_buffer, StrBuffer},
|
||||
gc::Gc,
|
||||
iter::IterBuf,
|
||||
list::List,
|
||||
map::Map,
|
||||
module::Module,
|
||||
obj::Obj,
|
||||
qstr::Qstr,
|
||||
util,
|
||||
},
|
||||
strutil::StringType,
|
||||
ui::{
|
||||
@ -38,9 +45,10 @@ use crate::{
|
||||
use super::{
|
||||
component::{
|
||||
AddressDetails, ButtonActions, ButtonDetails, ButtonLayout, ButtonPage, CancelConfirmMsg,
|
||||
CancelInfoConfirmMsg, CoinJoinProgress, Flow, FlowPages, Frame, Homescreen, Lockscreen,
|
||||
NumberInput, Page, PassphraseEntry, PinEntry, Progress, ScrollableContent, ScrollableFrame,
|
||||
ShareWords, ShowMore, SimpleChoice, WelcomeScreen, WordlistEntry, WordlistType,
|
||||
CancelInfoConfirmMsg, CoinJoinProgress, ConfirmHomescreen, Flow, FlowPages, Frame,
|
||||
Homescreen, Lockscreen, NumberInput, Page, PassphraseEntry, PinEntry, Progress,
|
||||
ScrollableContent, ScrollableFrame, ShareWords, ShowMore, SimpleChoice, WelcomeScreen,
|
||||
WordlistEntry, WordlistType,
|
||||
},
|
||||
constant, theme,
|
||||
};
|
||||
@ -242,6 +250,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, F> ComponentMsgObj for ConfirmHomescreen<T, F>
|
||||
where
|
||||
T: StringType + Clone,
|
||||
F: Fn() -> &'a [u8],
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
CancelConfirmMsg::Confirmed => Ok(CONFIRMED.as_obj()),
|
||||
CancelConfirmMsg::Cancelled => Ok(CANCELLED.as_obj()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Function to create and call a `ButtonPage` dialog based on paginable content
|
||||
/// (e.g. `Paragraphs` or `FormattedText`).
|
||||
/// Has optional title (supply empty `StrBuffer` for that) and hold-to-confirm
|
||||
@ -392,6 +413,24 @@ 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 obj = LayoutObj::new(ConfirmHomescreen::new(title, buffer_func))?;
|
||||
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()?;
|
||||
@ -1587,6 +1626,14 @@ 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,
|
||||
|
@ -29,6 +29,15 @@ def confirm_action(
|
||||
"""Confirm action."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tr/layout.rs
|
||||
def confirm_homescreen(
|
||||
*,
|
||||
title: str,
|
||||
image: bytes,
|
||||
) -> object:
|
||||
"""Confirm homescreen."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tr/layout.rs
|
||||
def confirm_blob(
|
||||
*,
|
||||
|
@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
||||
import trezorui2
|
||||
from trezor import utils
|
||||
from trezor.enums import ButtonRequestType
|
||||
from trezor.ui.layouts import confirm_action, confirm_homescreen, confirm_single
|
||||
from trezor.ui.layouts import confirm_action
|
||||
from trezor.wire import DataError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -151,6 +151,8 @@ async def apply_settings(msg: ApplySettings) -> Success:
|
||||
|
||||
|
||||
async def _require_confirm_change_homescreen(homescreen: bytes) -> None:
|
||||
from trezor.ui.layouts import confirm_homescreen
|
||||
|
||||
if homescreen == b"":
|
||||
await confirm_action(
|
||||
"set_homescreen",
|
||||
@ -159,12 +161,12 @@ async def _require_confirm_change_homescreen(homescreen: bytes) -> None:
|
||||
br_code=BRT_PROTECT_CALL,
|
||||
)
|
||||
else:
|
||||
await confirm_homescreen(
|
||||
homescreen,
|
||||
)
|
||||
await confirm_homescreen(homescreen)
|
||||
|
||||
|
||||
async def _require_confirm_change_label(label: str) -> None:
|
||||
from trezor.ui.layouts import confirm_single
|
||||
|
||||
await confirm_single(
|
||||
"set_label",
|
||||
"Device name",
|
||||
|
@ -443,12 +443,17 @@ async def confirm_path_warning(
|
||||
async def confirm_homescreen(
|
||||
image: bytes,
|
||||
) -> None:
|
||||
# TODO: show homescreen preview?
|
||||
await confirm_action(
|
||||
"set_homescreen",
|
||||
"Set homescreen",
|
||||
description="Do you really want to set new homescreen image?",
|
||||
br_code=ButtonRequestType.ProtectCall,
|
||||
await raise_if_not_confirmed(
|
||||
interact(
|
||||
RustLayout(
|
||||
trezorui2.confirm_homescreen(
|
||||
title="CHANGE HOMESCREEN?",
|
||||
image=image,
|
||||
)
|
||||
),
|
||||
"set_homesreen",
|
||||
ButtonRequestType.ProtectCall,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user