1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-26 09:28:13 +00:00

refactor(core/mercury): confirm_homescreen

- implement Confirm Homescreen for mercury according to Figma
- implementation as SwipeFlow also allows using it as `impl
LayoutMaybeTrace` return type for the UiFeatures
This commit is contained in:
obrusvit 2024-10-31 12:54:43 +01:00
parent 765507b9e3
commit f202ea2703
5 changed files with 119 additions and 15 deletions

View File

@ -1,12 +1,16 @@
use crate::{ use crate::{
io::BinaryData, micropython::{ io::BinaryData,
micropython::{
macros::{obj_fn_1, obj_fn_kw, obj_module}, macros::{obj_fn_1, obj_fn_kw, obj_module},
map::Map, map::Map,
module::Module, module::Module,
obj::Obj, obj::Obj,
qstr::Qstr, qstr::Qstr,
util, util,
}, strutil::TString, trezorhal::model, ui::{ },
strutil::TString,
trezorhal::model,
ui::{
backlight::BACKLIGHT_LEVELS_OBJ, backlight::BACKLIGHT_LEVELS_OBJ,
layout::{ layout::{
base::LAYOUT_STATE, base::LAYOUT_STATE,
@ -16,7 +20,7 @@ use crate::{
}, },
ui_features::ModelUI, ui_features::ModelUI,
ui_features_fw::UIFeaturesFirmware, ui_features_fw::UIFeaturesFirmware,
} },
}; };
// free-standing functions exported to MicroPython mirror `trait // free-standing functions exported to MicroPython mirror `trait

View File

@ -0,0 +1,106 @@
use crate::{
error,
strutil::TString,
translations::TR,
ui::{
component::{swipe_detect::SwipeSettings, CachedJpeg, ComponentExt},
flow::{
base::{Decision, DecisionBuilder},
FlowController, FlowMsg, SwipeFlow,
},
geometry::Direction,
model_mercury::{
component::{
Frame, FrameMsg, PromptMsg, PromptScreen, SwipeContent, VerticalMenu,
VerticalMenuChoiceMsg,
},
theme,
},
},
};
/// Flow for a setting of homescreen wallpaper showing a preview of the image,
/// menu to cancel and tap to confirm prompt.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum ConfirmHomescreen {
Homescreen,
Menu,
Confirm,
}
impl FlowController for ConfirmHomescreen {
#[inline]
fn index(&'static self) -> usize {
*self as usize
}
fn handle_swipe(&'static self, direction: Direction) -> Decision {
match (self, direction) {
(Self::Homescreen, Direction::Left) => Self::Menu.swipe(direction),
(Self::Homescreen, Direction::Up) => Self::Confirm.swipe(direction),
(Self::Menu, Direction::Right) => Self::Homescreen.swipe(direction),
(Self::Confirm, Direction::Down) => Self::Homescreen.swipe(direction),
(Self::Confirm, Direction::Left) => Self::Menu.swipe(direction),
_ => self.do_nothing(),
}
}
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Homescreen, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Homescreen.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Confirm, FlowMsg::Info) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}
}
pub fn new_confirm_homescreen(
title: TString<'static>,
image: CachedJpeg,
) -> Result<SwipeFlow, error::Error> {
let content_homescreen = Frame::left_aligned(title, SwipeContent::new(image))
.with_menu_button()
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::buttons__change.into()),
)
.with_swipe(Direction::Up, SwipeSettings::default())
.map(|msg| match msg {
FrameMsg::Button(_) => Some(FlowMsg::Info),
_ => None,
});
let content_menu = Frame::left_aligned(
TString::empty(),
VerticalMenu::empty().danger(theme::ICON_CANCEL, TR::buttons__cancel.into()),
)
.with_cancel_button()
.with_swipe(Direction::Right, SwipeSettings::immediate())
.map(|msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});
let content_confirm = Frame::left_aligned(
TR::homescreen__title_set.into(),
SwipeContent::new(PromptScreen::new_tap_to_confirm()),
)
.with_menu_button()
.with_footer(TR::instructions__tap_to_confirm.into(), None)
.with_swipe(Direction::Down, SwipeSettings::default())
.with_swipe(Direction::Left, SwipeSettings::default())
.map(|msg| match msg {
FrameMsg::Content(PromptMsg::Confirmed) => Some(FlowMsg::Confirmed),
FrameMsg::Button(_) => Some(FlowMsg::Info),
_ => None,
});
let res = SwipeFlow::new(&ConfirmHomescreen::Homescreen)?
.with_page(&ConfirmHomescreen::Homescreen, content_homescreen)?
.with_page(&ConfirmHomescreen::Menu, content_menu)?
.with_page(&ConfirmHomescreen::Confirm, content_confirm)?;
Ok(res)
}

View File

@ -2,6 +2,7 @@ pub mod confirm_action;
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
pub mod confirm_fido; pub mod confirm_fido;
pub mod confirm_firmware_update; pub mod confirm_firmware_update;
pub mod confirm_homescreen;
pub mod confirm_output; pub mod confirm_output;
pub mod confirm_reset; pub mod confirm_reset;
pub mod confirm_set_new_pin; pub mod confirm_set_new_pin;
@ -24,6 +25,7 @@ pub use confirm_action::{
#[cfg(feature = "universal_fw")] #[cfg(feature = "universal_fw")]
pub use confirm_fido::new_confirm_fido; pub use confirm_fido::new_confirm_fido;
pub use confirm_firmware_update::new_confirm_firmware_update; pub use confirm_firmware_update::new_confirm_firmware_update;
pub use confirm_homescreen::new_confirm_homescreen;
pub use confirm_output::new_confirm_output; pub use confirm_output::new_confirm_output;
pub use confirm_reset::new_confirm_reset; pub use confirm_reset::new_confirm_reset;
pub use confirm_set_new_pin::SetNewPin; pub use confirm_set_new_pin::SetNewPin;

View File

@ -68,7 +68,6 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
TR::homescreen__set_default, TR::homescreen__set_default,
)]) )])
.into_paragraphs(); .into_paragraphs();
let paragraphs = paragraphs;
new_confirm_action_simple( new_confirm_action_simple(
paragraphs, paragraphs,
@ -87,16 +86,7 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
return Err(value_error!(c"Invalid image.")); return Err(value_error!(c"Invalid image."));
}; };
let obj = RootComponent::new(SwipeUpScreen::new( flow::confirm_homescreen::new_confirm_homescreen(title, CachedJpeg::new(image, 1))?
Frame::left_aligned(title, SwipeContent::new(CachedJpeg::new(image, 1)))
.with_cancel_button()
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::buttons__change.into()),
)
.with_swipe(Direction::Up, SwipeSettings::default()),
));
obj
}; };
Ok(layout) Ok(layout)
} }

View File

@ -6,7 +6,9 @@ use crate::{
translations::TR, translations::TR,
ui::{ ui::{
component::{ component::{
image::BlendedImage, text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt}, ComponentExt, Empty, Jpeg, Label, Timeout image::BlendedImage,
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt},
ComponentExt, Empty, Jpeg, Label, Timeout,
}, },
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},