refactor(core): extract common layout handling from bootloader ui implementations in rust

[no changelog]
pull/3609/head
tychovrahe 2 months ago committed by TychoVrahe
parent 945382fbaa
commit e000b526cc

@ -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;

@ -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<T> ReturnToC for T
where
T: ToPrimitive,
{
fn return_to_c(self) -> u32 {
self.to_u32().unwrap()
}
}
#[cfg(feature = "button")]
fn button_eval() -> Option<ButtonEvent> {
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<TouchEvent> {
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<F>(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<F>(frame: &mut F, fading: bool)
where
F: Component,
{
frame.place(SCREEN);
if fading {
fadeout()
};
display::sync();
frame.paint();
display::refresh();
if fading {
fadein()
};
}

@ -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;

@ -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";

@ -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)]

@ -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<ButtonEvent> {
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<F>(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<F>(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]

@ -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<T> 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<F>(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<F>(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<TouchEvent> {
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,

Loading…
Cancel
Save