From e000b526cc08374b4cd0fd8b8dc3170c715667f7 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 14 Mar 2024 22:45:54 +0100 Subject: [PATCH] refactor(core): extract common layout handling from bootloader ui implementations in rust [no changelog] --- core/embed/rust/src/ui/layout/mod.rs | 6 + core/embed/rust/src/ui/layout/simplified.rs | 129 ++++++++++++++++++ core/embed/rust/src/ui/mod.rs | 12 +- .../rust/src/ui/model_tr/bootloader/intro.rs | 14 +- .../rust/src/ui/model_tr/bootloader/menu.rs | 10 +- .../rust/src/ui/model_tr/bootloader/mod.rs | 95 ++----------- .../rust/src/ui/model_tt/bootloader/mod.rs | 94 +------------ 7 files changed, 172 insertions(+), 188 deletions(-) create mode 100644 core/embed/rust/src/ui/layout/simplified.rs diff --git a/core/embed/rust/src/ui/layout/mod.rs b/core/embed/rust/src/ui/layout/mod.rs index 0a67444f6..2126c59f1 100644 --- a/core/embed/rust/src/ui/layout/mod.rs +++ b/core/embed/rust/src/ui/layout/mod.rs @@ -1,3 +1,9 @@ +#[cfg(feature = "micropython")] pub mod obj; + +#[cfg(feature = "micropython")] pub mod result; +pub mod simplified; + +#[cfg(feature = "micropython")] pub mod util; diff --git a/core/embed/rust/src/ui/layout/simplified.rs b/core/embed/rust/src/ui/layout/simplified.rs new file mode 100644 index 000000000..0bfcb605c --- /dev/null +++ b/core/embed/rust/src/ui/layout/simplified.rs @@ -0,0 +1,129 @@ +#[cfg(feature = "button")] +use crate::trezorhal::io::io_button_read; +#[cfg(feature = "touch")] +use crate::trezorhal::io::io_touch_read; +#[cfg(feature = "button")] +use crate::ui::event::ButtonEvent; +#[cfg(feature = "touch")] +use crate::ui::event::TouchEvent; +use crate::ui::{ + component::{Component, Event, EventCtx, Never}, + constant::SCREEN, + display, +}; +use num_traits::ToPrimitive; + +#[cfg(feature = "backlight")] +use crate::ui::model::theme::{BACKLIGHT_DIM, BACKLIGHT_NORMAL}; + +pub trait ReturnToC { + fn return_to_c(self) -> u32; +} + +impl ReturnToC for Never { + fn return_to_c(self) -> u32 { + unreachable!() + } +} + +impl ReturnToC for T +where + T: ToPrimitive, +{ + fn return_to_c(self) -> u32 { + self.to_u32().unwrap() + } +} +#[cfg(feature = "button")] +fn button_eval() -> Option { + let event = io_button_read(); + if event == 0 { + return None; + } + + let event_type = event >> 24; + let event_btn = event & 0xFFFFFF; + + let event = ButtonEvent::new(event_type, event_btn); + + if let Ok(event) = event { + return Some(event); + } + None +} + +#[cfg(feature = "touch")] +fn touch_eval() -> Option { + let event = io_touch_read(); + if event == 0 { + return None; + } + let event_type = event >> 24; + let ex = ((event >> 12) & 0xFFF) as i16; + let ey = (event & 0xFFF) as i16; + + TouchEvent::new(event_type, ex as _, ey as _).ok() +} + +pub fn fadein() { + #[cfg(feature = "backlight")] + display::fade_backlight_duration(BACKLIGHT_NORMAL, 150); +} + +pub fn fadeout() { + #[cfg(feature = "backlight")] + display::fade_backlight_duration(BACKLIGHT_DIM, 150); +} + +pub fn run(frame: &mut F) -> u32 +where + F: Component, + F::Msg: ReturnToC, +{ + frame.place(SCREEN); + fadeout(); + display::sync(); + frame.paint(); + display::refresh(); + fadein(); + + #[cfg(feature = "button")] + while button_eval().is_some() {} + + loop { + #[cfg(all(feature = "button", not(feature = "touch")))] + let event = button_eval(); + #[cfg(feature = "touch")] + let event = touch_eval(); + if let Some(e) = event { + let mut ctx = EventCtx::new(); + #[cfg(all(feature = "button", not(feature = "touch")))] + let msg = frame.event(&mut ctx, Event::Button(e)); + #[cfg(feature = "touch")] + let msg = frame.event(&mut ctx, Event::Touch(e)); + + if let Some(message) = msg { + return message.return_to_c(); + } + display::sync(); + frame.paint(); + display::refresh(); + } + } +} + +pub fn show(frame: &mut F, fading: bool) +where + F: Component, +{ + frame.place(SCREEN); + if fading { + fadeout() + }; + display::sync(); + frame.paint(); + display::refresh(); + if fading { + fadein() + }; +} diff --git a/core/embed/rust/src/ui/mod.rs b/core/embed/rust/src/ui/mod.rs index 0b57e0306..07b1b965e 100644 --- a/core/embed/rust/src/ui/mod.rs +++ b/core/embed/rust/src/ui/mod.rs @@ -12,10 +12,20 @@ pub mod screens; #[macro_use] pub mod util; -#[cfg(feature = "micropython")] pub mod layout; #[cfg(feature = "model_tr")] pub mod model_tr; #[cfg(feature = "model_tt")] pub mod model_tt; + +#[cfg(all( + feature = "model_t1", + not(feature = "model_tr"), + not(feature = "model_tt") +))] +pub use model_t1 as model; +#[cfg(all(feature = "model_tr", not(feature = "model_tt")))] +pub use model_tr as model; +#[cfg(feature = "model_tt")] +pub use model_tt as model; diff --git a/core/embed/rust/src/ui/model_tr/bootloader/intro.rs b/core/embed/rust/src/ui/model_tr/bootloader/intro.rs index 4bef3f606..df114fc4c 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/intro.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/intro.rs @@ -1,17 +1,15 @@ use crate::ui::{ component::{Child, Component, Event, EventCtx, Label, Pad}, geometry::{Alignment, Alignment2D, Rect}, + layout::simplified::ReturnToC, }; -use super::{ - super::{ - component::{ButtonController, ButtonControllerMsg::Triggered, ButtonLayout, ButtonPos}, - theme::{ - bootloader::{BLD_BG, BLD_FG, TEXT_NORMAL}, - BUTTON_HEIGHT, ICON_WARN_TITLE, TITLE_AREA_HEIGHT, - }, +use super::super::{ + component::{ButtonController, ButtonControllerMsg::Triggered, ButtonLayout, ButtonPos}, + theme::{ + bootloader::{BLD_BG, BLD_FG, TEXT_NORMAL}, + BUTTON_HEIGHT, ICON_WARN_TITLE, TITLE_AREA_HEIGHT, }, - ReturnToC, }; const LEFT_BUTTON_TEXT: &str = "INSTALL FW"; diff --git a/core/embed/rust/src/ui/model_tr/bootloader/menu.rs b/core/embed/rust/src/ui/model_tr/bootloader/menu.rs index 9b26803d9..d0a5fa0e1 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/menu.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/menu.rs @@ -8,15 +8,13 @@ use crate::{ display, display::{Font, Icon}, geometry::{Alignment2D, Offset, Point, Rect}, + layout::simplified::ReturnToC, }, }; -use super::{ - super::{ - component::{ButtonLayout, Choice, ChoiceFactory, ChoicePage}, - theme::bootloader::{BLD_BG, BLD_FG, ICON_EXIT, ICON_REDO, ICON_TRASH}, - }, - ReturnToC, +use super::super::{ + component::{ButtonLayout, Choice, ChoiceFactory, ChoicePage}, + theme::bootloader::{BLD_BG, BLD_FG, ICON_EXIT, ICON_REDO, ICON_TRASH}, }; #[repr(u32)] diff --git a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs index 4d8c5c782..04eae0d2e 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs @@ -2,17 +2,14 @@ use heapless::String; use crate::{ strutil::hexlify, - trezorhal::{io::io_button_read, secbool::secbool}, + trezorhal::secbool::secbool, ui::{ - component::{ - connect::Connect, Component, Event, EventCtx, Label, LineBreaking::BreakWordsNoHyphen, - Never, - }, + component::{connect::Connect, Label, LineBreaking::BreakWordsNoHyphen}, constant, constant::{HEIGHT, SCREEN}, display::{self, Color, Font, Icon}, - event::ButtonEvent, geometry::{Alignment2D, Offset, Point, Rect}, + layout::simplified::{run, show, ReturnToC}, util::{from_c_array, from_c_str}, }, }; @@ -38,82 +35,12 @@ use welcome::Welcome; pub type BootloaderString = String<128>; -pub trait ReturnToC { - fn return_to_c(self) -> u32; -} - -impl ReturnToC for Never { - fn return_to_c(self) -> u32 { - unreachable!() - } -} - -impl ReturnToC for () { - fn return_to_c(self) -> u32 { - 0 - } -} - impl ReturnToC for ConfirmMsg { fn return_to_c(self) -> u32 { self as u32 } } -fn button_eval() -> Option { - let event = io_button_read(); - if event == 0 { - return None; - } - - let event_type = event >> 24; - let event_btn = event & 0xFFFFFF; - - let event = ButtonEvent::new(event_type, event_btn); - - if let Ok(event) = event { - return Some(event); - } - None -} - -fn run(frame: &mut F) -> u32 -where - F: Component, - F::Msg: ReturnToC, -{ - frame.place(SCREEN); - frame.paint(); - display::refresh(); - - while button_eval().is_some() {} - - loop { - let event = button_eval(); - if let Some(e) = event { - let mut ctx = EventCtx::new(); - let msg = frame.event(&mut ctx, Event::Button(e)); - - if let Some(message) = msg { - return message.return_to_c(); - } - - frame.paint(); - display::refresh(); - } - } -} - -fn show(frame: &mut F) -where - F: Component, -{ - frame.place(SCREEN); - display::sync(); - frame.paint(); - display::refresh(); -} - #[no_mangle] extern "C" fn screen_install_confirm( vendor_str: *const cty::c_char, @@ -193,7 +120,7 @@ extern "C" fn screen_unlock_bootloader_success() { Label::centered("Please reconnect the\ndevice", TEXT_NORMAL).vertically_centered(); let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] @@ -299,7 +226,7 @@ extern "C" fn screen_wipe_progress(progress: u16, initialize: bool) { #[no_mangle] extern "C" fn screen_connect(_initial_setup: bool) { let mut frame = Connect::new("Waiting for host...", BLD_FG, BLD_BG); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] @@ -310,7 +237,7 @@ extern "C" fn screen_wipe_success() { Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered(); let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] @@ -321,7 +248,7 @@ extern "C" fn screen_wipe_fail() { Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered(); let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_ALERT, title, content, true); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] @@ -329,7 +256,7 @@ extern "C" fn screen_boot_empty(_fading: bool) { display::rect_fill(SCREEN, BLD_BG); let mut frame = WelcomeScreen::new(true); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] @@ -340,7 +267,7 @@ extern "C" fn screen_install_fail() { Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered(); let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_ALERT, title, content, true); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] @@ -365,13 +292,13 @@ extern "C" fn screen_install_success( let content = Label::centered(reboot_msg.as_str(), TEXT_NORMAL).vertically_centered(); let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, complete_draw); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] extern "C" fn screen_welcome() { let mut frame = Welcome::new(); - show(&mut frame); + show(&mut frame, false); } #[no_mangle] diff --git a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs index 805d5be3b..20b3d6416 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs @@ -1,14 +1,12 @@ use heapless::String; -use num_traits::ToPrimitive; use crate::{ strutil::hexlify, - trezorhal::{io::io_touch_read, secbool::secbool}, + trezorhal::secbool::secbool, ui::{ - component::{connect::Connect, Component, Event, EventCtx, Label, Never}, - constant::{screen, HEIGHT}, + component::{connect::Connect, Label}, + constant::HEIGHT, display::{self, Color, Font, Icon}, - event::TouchEvent, geometry::Point, util::{from_c_array, from_c_str}, }, @@ -28,10 +26,11 @@ use super::{ FIRE40, RESULT_FW_INSTALL, RESULT_INITIAL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL, TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24, }, - BACKLIGHT_DIM, BACKLIGHT_NORMAL, BLACK, FG, WHITE, + BACKLIGHT_NORMAL, BLACK, FG, WHITE, }, }; +use crate::ui::layout::simplified::{fadein, fadeout, run, show}; use intro::Intro; use menu::Menu; @@ -43,89 +42,6 @@ pub type BootloaderString = String<128>; const RECONNECT_MESSAGE: &str = "PLEASE RECONNECT\nTHE DEVICE"; -pub trait ReturnToC { - fn return_to_c(self) -> u32; -} - -impl ReturnToC for Never { - fn return_to_c(self) -> u32 { - unreachable!() - } -} - -impl ReturnToC for T -where - T: ToPrimitive, -{ - fn return_to_c(self) -> u32 { - self.to_u32().unwrap() - } -} - -fn fadein() { - display::fade_backlight_duration(BACKLIGHT_NORMAL, 150); -} - -fn fadeout() { - display::fade_backlight_duration(BACKLIGHT_DIM, 150); -} - -fn run(frame: &mut F) -> u32 -where - F: Component, - F::Msg: ReturnToC, -{ - frame.place(constant::screen()); - fadeout(); - display::sync(); - frame.paint(); - display::refresh(); - fadein(); - - loop { - let event = touch_eval(); - if let Some(e) = event { - let mut ctx = EventCtx::new(); - let msg = frame.event(&mut ctx, Event::Touch(e)); - - if let Some(message) = msg { - return message.return_to_c(); - } - display::sync(); - frame.paint(); - display::refresh(); - } - } -} - -fn show(frame: &mut F, fading: bool) -where - F: Component, -{ - frame.place(screen()); - if fading { - fadeout() - }; - display::sync(); - frame.paint(); - display::refresh(); - if fading { - fadein() - }; -} - -fn touch_eval() -> Option { - let event = io_touch_read(); - if event == 0 { - return None; - } - let event_type = event >> 24; - let ex = ((event >> 12) & 0xFFF) as i16; - let ey = (event & 0xFFF) as i16; - - TouchEvent::new(event_type, ex as _, ey as _).ok() -} - #[no_mangle] extern "C" fn screen_install_confirm( vendor_str: *const cty::c_char,