1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-22 02:55:43 +00:00

feat(eckhart): implement homescreen flow

- Homescreen and device menu accessed by action bar
This commit is contained in:
obrusvit 2025-03-19 23:24:56 +01:00
parent 4e9cbc10fd
commit 71a9d9ccd0
6 changed files with 112 additions and 8 deletions

View File

@ -4,8 +4,11 @@ use crate::{
strutil::TString,
translations::TR,
ui::{
component::{text::TextStyle, Component, Event, EventCtx, Label, Never},
component::{
swipe_detect::SwipeConfig, text::TextStyle, Component, Event, EventCtx, Label, Never,
},
display::image::ImageInfo,
flow::Swipable,
geometry::{Insets, Offset, Rect},
layout::util::get_user_custom_image,
shape::{self, Renderer},
@ -14,7 +17,10 @@ use crate::{
};
use super::{
super::{component::Button, fonts},
super::{
component::{Button, ButtonMsg},
fonts,
},
constant::{HEIGHT, SCREEN, WIDTH},
theme::{self, firmware::button_homebar_style, BLACK, GREEN_DARK, GREEN_EXTRA_DARK},
ActionBar, ActionBarMsg, Hint, HoldToConfirmAnim,
@ -293,6 +299,17 @@ fn get_homescreen_image() -> Option<BinaryData<'static>> {
None
}
#[cfg(feature = "micropython")]
impl Swipable for Homescreen {
fn get_swipe_config(&self) -> SwipeConfig {
SwipeConfig::default()
}
fn get_pager(&self) -> Pager {
Pager::single_page()
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for Homescreen {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {

View File

@ -19,7 +19,7 @@ type VerticalMenuButtons = Vec<Button, MENU_MAX_ITEMS>;
pub struct VerticalMenu {
/// Bounds the sliding window of the menu.
bounds: Rect,
/// FUll bounds of the menu, including off-screen items.
/// Full bounds of the menu, including off-screen items.
virtual_bounds: Rect,
/// Menu items.
buttons: VerticalMenuButtons,

View File

@ -0,0 +1,85 @@
use crate::{
error,
strutil::TString,
ui::{
component::ComponentExt as _,
flow::{
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
geometry::Direction,
},
};
use super::super::{
component::Button,
firmware::{
Header, Homescreen, HomescreenMsg, VerticalMenu, VerticalMenuScreen, VerticalMenuScreenMsg,
},
};
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Home {
Homescreen,
DeviceMenu,
}
impl FlowController for Home {
#[inline]
fn index(&'static self) -> usize {
*self as usize
}
fn handle_swipe(&'static self, _direction: Direction) -> Decision {
self.do_nothing()
}
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Homescreen, FlowMsg::Cancelled) => self.return_msg(FlowMsg::Cancelled),
(Self::Homescreen, FlowMsg::Info) => Self::DeviceMenu.goto(),
(Self::DeviceMenu, FlowMsg::Cancelled) => Self::Homescreen.goto(),
_ => self.do_nothing(),
}
}
}
pub fn new_home(
label: TString<'static>,
lockable: bool,
locked: bool,
bootscreen: bool,
coinjoin_authorized: bool,
notification: Option<(TString<'static>, u8)>,
) -> Result<SwipeFlow, error::Error> {
let content_homescreen = Homescreen::new(
label,
lockable,
locked,
bootscreen,
coinjoin_authorized,
notification,
)?
.map(|msg| match msg {
HomescreenMsg::Dismissed => Some(FlowMsg::Cancelled),
HomescreenMsg::Menu => Some(FlowMsg::Info),
});
let menu = VerticalMenu::empty()
.item(Button::with_text("Bluetooth management".into()))
.item(Button::with_text("Device".into()))
.item(Button::with_text("Check backup".into()))
.item(Button::with_text("About".into()));
let content_device_menu = VerticalMenuScreen::new(menu)
.with_header(Header::new("Device menu".into()).with_close_button())
.map(|msg| match msg {
VerticalMenuScreenMsg::Selected(n) => Some(FlowMsg::Choice(n)),
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
_ => None,
});
let mut res = SwipeFlow::new(&Home::Homescreen)?;
res.add_page(&Home::Homescreen, content_homescreen)?
.add_page(&Home::DeviceMenu, content_device_menu)?;
Ok(res)
}

View File

@ -1,6 +1,7 @@
pub mod confirm_reset;
pub mod confirm_set_new_pin;
pub mod get_address;
pub mod homescreen;
pub mod prompt_backup;
pub mod request_passphrase;
pub mod show_danger;
@ -9,6 +10,7 @@ pub mod show_share_words;
pub use confirm_reset::new_confirm_reset;
pub use confirm_set_new_pin::new_set_new_pin;
pub use get_address::GetAddress;
pub use homescreen::new_home;
pub use prompt_backup::PromptBackup;
pub use request_passphrase::RequestPassphrase;
pub use show_danger::ShowDanger;

View File

@ -582,15 +582,15 @@ impl FirmwareUI for UIEckhart {
let bootscreen = false;
let coinjoin_authorized = false;
let notification = notification.map(|w| (w, notification_level));
let layout = RootComponent::new(Homescreen::new(
let flow = flow::homescreen::new_home(
label,
hold,
locked,
bootscreen,
coinjoin_authorized,
notification,
)?);
Ok(layout)
)?;
Ok(flow)
}
fn show_info(

View File

@ -56,8 +56,8 @@ class HomescreenBase(ui.Layout):
if not self.should_resume:
super()._first_paint()
storage_cache.homescreen_shown = self.RENDER_INDICATOR
# else:
# self._paint()
else:
self._paint()
class Homescreen(HomescreenBase):