mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-18 13:38:12 +00:00
refactor(core): extract common layout handling from bootloader ui implementations in rust
[no changelog]
This commit is contained in:
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;
|
||||
|
129
core/embed/rust/src/ui/layout/simplified.rs
Normal file
129
core/embed/rust/src/ui/layout/simplified.rs
Normal file
@ -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…
Reference in New Issue
Block a user