diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs index d68315f23b..1a15fcf46c 100644 --- a/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs +++ b/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs @@ -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> { 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) { diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs index 4e68a5f663..99ae244bec 100644 --- a/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs +++ b/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs @@ -19,7 +19,7 @@ type VerticalMenuButtons = Vec; 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, diff --git a/core/embed/rust/src/ui/layout_eckhart/flow/homescreen.rs b/core/embed/rust/src/ui/layout_eckhart/flow/homescreen.rs new file mode 100644 index 0000000000..24186ce552 --- /dev/null +++ b/core/embed/rust/src/ui/layout_eckhart/flow/homescreen.rs @@ -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 { + 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) +} diff --git a/core/embed/rust/src/ui/layout_eckhart/flow/mod.rs b/core/embed/rust/src/ui/layout_eckhart/flow/mod.rs index 8172bf6978..c8c50706be 100644 --- a/core/embed/rust/src/ui/layout_eckhart/flow/mod.rs +++ b/core/embed/rust/src/ui/layout_eckhart/flow/mod.rs @@ -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; diff --git a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs index 00dd65cf6b..5b2e6cb259 100644 --- a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs @@ -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( diff --git a/core/src/trezor/ui/layouts/homescreen.py b/core/src/trezor/ui/layouts/homescreen.py index 5ed1a4f3c8..ebad72eba0 100644 --- a/core/src/trezor/ui/layouts/homescreen.py +++ b/core/src/trezor/ui/layouts/homescreen.py @@ -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):