From 7cc9f13605dc14b65927f95edb895bc001b284e9 Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Thu, 11 Nov 2021 13:46:12 +0100 Subject: [PATCH] refactor(core/rust): allow model_t1 and model_tt at once [no changelog] --- core/embed/rust/librust_qstr.h | 3 +- core/embed/rust/src/trezorhal/display.rs | 9 ++-- core/embed/rust/src/ui/component/base.rs | 10 +++- core/embed/rust/src/ui/component/text.rs | 51 +++++++++++++------ core/embed/rust/src/ui/display.rs | 14 ++--- core/embed/rust/src/ui/layout/obj.rs | 42 +++++++++++++-- core/embed/rust/src/ui/mod.rs | 2 + core/embed/rust/src/ui/model_t1/layout.rs | 2 +- core/embed/rust/src/ui/model_t1/theme.rs | 2 +- .../rust/src/ui/model_tt/component/button.rs | 2 +- .../rust/src/ui/model_tt/component/mod.rs | 3 +- .../rust/src/ui/model_tt/component/swipe.rs | 2 +- core/embed/rust/src/ui/model_tt/event.rs | 1 - core/embed/rust/src/ui/model_tt/layout.rs | 4 +- core/embed/rust/src/ui/model_tt/theme.rs | 16 ++++++ core/src/trezor/ui/__init__.py | 4 +- 16 files changed, 124 insertions(+), 43 deletions(-) diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index 0e37e4b67..d451a3ea2 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -12,7 +12,8 @@ static void _librust_qstrs(void) { // layout MP_QSTR_Layout; MP_QSTR_set_timer_fn; - MP_QSTR_hid_event; + MP_QSTR_touch_event; + MP_QSTR_button_event; MP_QSTR_timer; MP_QSTR_paint; MP_QSTR_trace; diff --git a/core/embed/rust/src/trezorhal/display.rs b/core/embed/rust/src/trezorhal/display.rs index 4a4f8fd46..15cecef0d 100644 --- a/core/embed/rust/src/trezorhal/display.rs +++ b/core/embed/rust/src/trezorhal/display.rs @@ -44,7 +44,10 @@ extern "C" { ) -> bool; } -use crate::ui::component::model::constants::{HEIGHT, WIDTH}; +#[cfg(not(feature = "model_tt"))] +use crate::ui::model_t1::constant; +#[cfg(feature = "model_tt")] +use crate::ui::model_tt::constant; pub struct ToifInfo { pub width: u16, @@ -53,11 +56,11 @@ pub struct ToifInfo { } pub fn width() -> i32 { - WIDTH + constant::WIDTH } pub fn height() -> i32 { - HEIGHT + constant::HEIGHT } pub fn backlight(val: i32) -> i32 { diff --git a/core/embed/rust/src/ui/component/base.rs b/core/embed/rust/src/ui/component/base.rs index ddd32d6b6..5d851ef1a 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -2,7 +2,10 @@ use core::{mem, time::Duration}; use heapless::Vec; -use crate::ui::{model_t1::event::ButtonEvent, model_tt::event::TouchEvent}; +#[cfg(feature = "model_t1")] +use crate::ui::model_t1::event::ButtonEvent; +#[cfg(feature = "model_tt")] +use crate::ui::model_tt::event::TouchEvent; /// Type used by components that do not return any messages. /// @@ -81,7 +84,10 @@ where #[derive(Copy, Clone, PartialEq, Eq)] pub enum Event { - HumanInput(HidEvent), + #[cfg(feature = "model_t1")] + Button(ButtonEvent), + #[cfg(feature = "model_tt")] + Touch(TouchEvent), Timer(TimerToken), } diff --git a/core/embed/rust/src/ui/component/text.rs b/core/embed/rust/src/ui/component/text.rs index aedfd168a..f51e28ea9 100644 --- a/core/embed/rust/src/ui/component/text.rs +++ b/core/embed/rust/src/ui/component/text.rs @@ -12,8 +12,6 @@ use crate::ui::{ geometry::{Offset, Point, Rect}, }; -use super::model::theme; - pub const MAX_ARGUMENTS: usize = 6; pub struct Text { @@ -23,9 +21,9 @@ pub struct Text { } impl Text { - pub fn new(area: Rect, format: F) -> Self { + pub fn new(area: Rect, format: F) -> Self { Self { - layout: TextLayout::new(area), + layout: TextLayout::new::(area), format, args: LinearMap::new(), } @@ -80,9 +78,9 @@ where self.format.as_ref(), |arg| match arg { Token::Literal(literal) => Some(Op::Text(literal)), - Token::Argument(b"mono") => Some(Op::Font(theme::FONT_MONO)), - Token::Argument(b"bold") => Some(Op::Font(theme::FONT_BOLD)), - Token::Argument(b"normal") => Some(Op::Font(theme::FONT_NORMAL)), + Token::Argument(b"mono") => Some(Op::Font(self.layout.mono_font)), + Token::Argument(b"bold") => Some(Op::Font(self.layout.bold_font)), + Token::Argument(b"normal") => Some(Op::Font(self.layout.normal_font)), Token::Argument(argument) => self .args .get(argument) @@ -204,21 +202,44 @@ pub struct TextLayout { pub ellipsis_font: Font, /// Foreground color used for drawing the ellipsis. pub ellipsis_color: Color, + + /// Font used to format `{normal}`. + pub normal_font: Font, + /// Font used to format `{bold}`. + pub bold_font: Font, + /// Font used to format `{mono}`. + pub mono_font: Font, +} + +pub trait DefaultTextTheme { + const BACKGROUND_COLOR: Color; + const TEXT_FONT: Font; + const TEXT_COLOR: Color; + const HYPHEN_FONT: Font; + const HYPHEN_COLOR: Color; + const ELLIPSIS_FONT: Font; + const ELLIPSIS_COLOR: Color; + const NORMAL_FONT: Font; + const BOLD_FONT: Font; + const MONO_FONT: Font; } impl TextLayout { - pub fn new(bounds: Rect) -> Self { + pub fn new(bounds: Rect) -> Self { Self { bounds, - background_color: theme::BG, - text_color: theme::FG, - text_font: theme::FONT_NORMAL, + background_color: T::BACKGROUND_COLOR, + text_color: T::TEXT_COLOR, + text_font: T::TEXT_FONT, line_breaking: LineBreaking::BreakAtWhitespace, - hyphen_font: theme::FONT_BOLD, - hyphen_color: theme::GREY_LIGHT, + hyphen_font: T::HYPHEN_FONT, + hyphen_color: T::HYPHEN_COLOR, page_breaking: PageBreaking::CutAndInsertEllipsis, - ellipsis_font: theme::FONT_BOLD, - ellipsis_color: theme::GREY_LIGHT, + ellipsis_font: T::ELLIPSIS_FONT, + ellipsis_color: T::ELLIPSIS_COLOR, + normal_font: T::NORMAL_FONT, + bold_font: T::BOLD_FONT, + mono_font: T::MONO_FONT, } } diff --git a/core/embed/rust/src/ui/display.rs b/core/embed/rust/src/ui/display.rs index b25648f91..77738373c 100644 --- a/core/embed/rust/src/ui/display.rs +++ b/core/embed/rust/src/ui/display.rs @@ -1,9 +1,11 @@ use crate::trezorhal::display; -use super::{ - component::model::constants, - geometry::{Offset, Point, Rect}, -}; +#[cfg(not(feature = "model_tt"))] +use crate::ui::model_t1::constant; +#[cfg(feature = "model_tt")] +use crate::ui::model_tt::constant; + +use super::geometry::{Offset, Point, Rect}; pub fn width() -> i32 { display::width() @@ -97,11 +99,11 @@ pub fn text_width(text: &[u8], font: Font) -> i32 { } pub fn text_height() -> i32 { - constants::TEXT_HEIGHT + constant::TEXT_HEIGHT } pub fn line_height() -> i32 { - constants::LINE_HEIGHT + constant::LINE_HEIGHT } #[derive(Copy, Clone, PartialEq, Eq)] diff --git a/core/embed/rust/src/ui/layout/obj.rs b/core/embed/rust/src/ui/layout/obj.rs index d2fa82b07..2623bd35a 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -13,10 +13,16 @@ use crate::{ qstr::Qstr, typ::Type, }, - ui::component::{model::HidEvent, Child, Component, Event, EventCtx, Never, TimerToken}, + ui::component::{Child, Component, Event, EventCtx, Never, TimerToken}, util, }; +#[cfg(feature = "model_tt")] +use crate::ui::model_tt::event::TouchEvent; + +#[cfg(feature = "model_t1")] +use crate::ui::model_t1::event::ButtonEvent; + /// Conversion trait implemented by components that know how to convert their /// message values into MicroPython `Obj`s. We can automatically implement /// `ComponentMsgObj` for components whose message types implement `TryInto`. @@ -204,7 +210,8 @@ impl LayoutObj { name: Qstr::MP_QSTR_Layout, locals: &obj_dict!(obj_map! { Qstr::MP_QSTR_set_timer_fn => obj_fn_2!(ui_layout_set_timer_fn).as_obj(), - Qstr::MP_QSTR_hid_event => obj_fn_var!(4, 4, ui_layout_hid_event).as_obj(), + Qstr::MP_QSTR_touch_event => obj_fn_var!(4, 4, ui_layout_touch_event).as_obj(), + Qstr::MP_QSTR_button_event => obj_fn_var!(3, 3, ui_layout_button_event).as_obj(), Qstr::MP_QSTR_timer => obj_fn_2!(ui_layout_timer).as_obj(), Qstr::MP_QSTR_paint => obj_fn_1!(ui_layout_paint).as_obj(), Qstr::MP_QSTR_trace => obj_fn_2!(ui_layout_trace).as_obj(), @@ -281,23 +288,48 @@ extern "C" fn ui_layout_set_timer_fn(this: Obj, timer_fn: Obj) -> Obj { unsafe { util::try_or_raise(block) } } -extern "C" fn ui_layout_hid_event(n_args: usize, args: *const Obj) -> Obj { +#[cfg(feature = "model_tt")] +extern "C" fn ui_layout_touch_event(n_args: usize, args: *const Obj) -> Obj { let block = |args: &[Obj], _kwargs: &Map| { if args.len() != 4 { return Err(Error::TypeError); } let this: Gc = args[0].try_into()?; - let event = HidEvent::new( + let event = TouchEvent::new( args[1].try_into()?, args[2].try_into()?, args[3].try_into()?, )?; - let msg = this.obj_event(Event::HumanInput(event))?; + let msg = this.obj_event(Event::Touch(event))?; Ok(msg) }; unsafe { util::try_with_args_and_kwargs(n_args, args, &Map::EMPTY, block) } } +#[cfg(not(feature = "model_tt"))] +extern "C" fn ui_layout_touch_event(_n_args: usize, _args: *const Obj) -> Obj { + Obj::const_none() +} + +#[cfg(feature = "model_t1")] +extern "C" fn ui_layout_button_event(n_args: usize, args: *const Obj) -> Obj { + let block = |args: &[Obj], _kwargs: &Map| { + if args.len() != 3 { + return Err(Error::TypeError); + } + let this: Gc = args[0].try_into()?; + let event = ButtonEvent::new(args[1].try_into()?, args[2].try_into()?)?; + let msg = this.obj_event(Event::Button(event))?; + Ok(msg) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, &Map::EMPTY, block) } +} + +#[cfg(not(feature = "model_t1"))] +extern "C" fn ui_layout_button_event(_n_args: usize, _args: *const Obj) -> Obj { + Obj::const_none() +} + extern "C" fn ui_layout_timer(this: Obj, token: Obj) -> Obj { let block = || { let this: Gc = this.try_into()?; diff --git a/core/embed/rust/src/ui/mod.rs b/core/embed/rust/src/ui/mod.rs index 20c33d6fd..7a9f827f0 100644 --- a/core/embed/rust/src/ui/mod.rs +++ b/core/embed/rust/src/ui/mod.rs @@ -6,5 +6,7 @@ pub mod display; pub mod geometry; pub mod layout; +#[cfg(feature = "model_t1")] pub mod model_t1; +#[cfg(feature = "model_tt")] pub mod model_tt; diff --git a/core/embed/rust/src/ui/model_t1/layout.rs b/core/embed/rust/src/ui/model_t1/layout.rs index 078a43fce..05b6f0b43 100644 --- a/core/embed/rust/src/ui/model_t1/layout.rs +++ b/core/embed/rust/src/ui/model_t1/layout.rs @@ -125,7 +125,7 @@ mod tests { let layout = Child::new(Dialog::new( display::screen(), |area| { - Text::new( + Text::new::( area, "Testing text layout, with some text, and some more text. And {param}", ) diff --git a/core/embed/rust/src/ui/model_t1/theme.rs b/core/embed/rust/src/ui/model_t1/theme.rs index 1de6ab09c..b10366daa 100644 --- a/core/embed/rust/src/ui/model_t1/theme.rs +++ b/core/embed/rust/src/ui/model_t1/theme.rs @@ -47,7 +47,7 @@ pub fn button_cancel() -> ButtonStyleSheet { } } -pub enum T1DefaultText {} +pub struct T1DefaultText; impl DefaultTextTheme for T1DefaultText { const BACKGROUND_COLOR: Color = BG; diff --git a/core/embed/rust/src/ui/model_tt/component/button.rs b/core/embed/rust/src/ui/model_tt/component/button.rs index ba2e7f79c..bd87700f4 100644 --- a/core/embed/rust/src/ui/model_tt/component/button.rs +++ b/core/embed/rust/src/ui/model_tt/component/button.rs @@ -1,9 +1,9 @@ +use super::event::TouchEvent; use crate::ui::{ component::{Component, Event, EventCtx}, display::{self, Color, Font}, geometry::{Offset, Rect}, }; -use super::event::TouchEvent; pub enum ButtonMsg { Clicked, diff --git a/core/embed/rust/src/ui/model_tt/component/mod.rs b/core/embed/rust/src/ui/model_tt/component/mod.rs index 2500dd5a0..b9e0eccd6 100644 --- a/core/embed/rust/src/ui/model_tt/component/mod.rs +++ b/core/embed/rust/src/ui/model_tt/component/mod.rs @@ -9,5 +9,4 @@ pub use button::{Button, ButtonContent, ButtonMsg, ButtonStyle, ButtonStyleSheet pub use dialog::{Dialog, DialogMsg}; pub use swipe::{Swipe, SwipeDirection}; -use super::event; -use super::theme; +use super::{event, theme}; diff --git a/core/embed/rust/src/ui/model_tt/component/swipe.rs b/core/embed/rust/src/ui/model_tt/component/swipe.rs index 1835f3cd9..0edd852bc 100644 --- a/core/embed/rust/src/ui/model_tt/component/swipe.rs +++ b/core/embed/rust/src/ui/model_tt/component/swipe.rs @@ -4,7 +4,7 @@ use crate::ui::{ geometry::{Point, Rect}, }; -use super::{theme, event::TouchEvent}; +use super::{event::TouchEvent, theme}; pub enum SwipeDirection { Up, diff --git a/core/embed/rust/src/ui/model_tt/event.rs b/core/embed/rust/src/ui/model_tt/event.rs index cfc7192e6..dd0bbfdf5 100644 --- a/core/embed/rust/src/ui/model_tt/event.rs +++ b/core/embed/rust/src/ui/model_tt/event.rs @@ -2,7 +2,6 @@ use core::convert::TryInto; use crate::{error, ui::geometry::Point}; - #[derive(Copy, Clone, PartialEq, Eq)] pub enum TouchEvent { TouchStart(Point), diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index f03807c0a..29e506285 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -39,7 +39,7 @@ extern "C" fn ui_layout_new_example(param: Obj) -> Obj { let layout = LayoutObj::new(Child::new(Dialog::new( display::screen(), |area| { - Text::new(area, param) + Text::new::(area, param) .with(b"some", "a few") .with(b"param", "xx") }, @@ -99,7 +99,7 @@ mod tests { let layout = Child::new(Dialog::new( display::screen(), |area| { - Text::new( + Text::new::( area, "Testing text layout, with some text, and some more text. And {param}", ) diff --git a/core/embed/rust/src/ui/model_tt/theme.rs b/core/embed/rust/src/ui/model_tt/theme.rs index 41f26492f..3ecce7fa6 100644 --- a/core/embed/rust/src/ui/model_tt/theme.rs +++ b/core/embed/rust/src/ui/model_tt/theme.rs @@ -91,3 +91,19 @@ pub fn button_cancel() -> ButtonStyleSheet { pub fn button_clear() -> ButtonStyleSheet { button_default() } + +pub struct TTDefaultText; + +impl DefaultTextTheme for TTDefaultText { + const BACKGROUND_COLOR: Color = BG; + const TEXT_FONT: Font = FONT_NORMAL; + const TEXT_COLOR: Color = FG; + const HYPHEN_FONT: Font = FONT_BOLD; + const HYPHEN_COLOR: Color = GREY_LIGHT; + const ELLIPSIS_FONT: Font = FONT_BOLD; + const ELLIPSIS_COLOR: Color = GREY_LIGHT; + + const NORMAL_FONT: Font = FONT_NORMAL; + const BOLD_FONT: Font = FONT_BOLD; + const MONO_FONT: Font = FONT_MONO; +} diff --git a/core/src/trezor/ui/__init__.py b/core/src/trezor/ui/__init__.py index bc1bc1931..881b86109 100644 --- a/core/src/trezor/ui/__init__.py +++ b/core/src/trezor/ui/__init__.py @@ -457,8 +457,8 @@ if utils.MODEL == "1": if event is RENDER: self.layout.paint() elif event in (io.BUTTON_PRESSED, io.BUTTON_RELEASED): - msg = self.layout.hid_event(event, x, 0) + msg = self.layout.button_event(event, x) # elif event in (io.TOUCH_START, io.TOUCH_MOVE, io.TOUCH_END): - # self.layout.hid_event(event, x, y) + # self.layout.touch_event(event, x, y) if msg is not None: raise Result(msg)