mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-03 08:46:05 +00:00
refactor(core/rust): allow model_t1 and model_tt at once
[no changelog]
This commit is contained in:
parent
52f719ad81
commit
7cc9f13605
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,6 @@ use crate::ui::{
|
||||
geometry::{Offset, Point, Rect},
|
||||
};
|
||||
|
||||
use super::model::theme;
|
||||
|
||||
pub const MAX_ARGUMENTS: usize = 6;
|
||||
|
||||
pub struct Text<F, T> {
|
||||
@ -23,9 +21,9 @@ pub struct Text<F, T> {
|
||||
}
|
||||
|
||||
impl<F, T> Text<F, T> {
|
||||
pub fn new(area: Rect, format: F) -> Self {
|
||||
pub fn new<D: DefaultTextTheme>(area: Rect, format: F) -> Self {
|
||||
Self {
|
||||
layout: TextLayout::new(area),
|
||||
layout: TextLayout::new::<D>(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<T: DefaultTextTheme>(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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)]
|
||||
|
@ -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<LayoutObj> = 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<LayoutObj> = 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<LayoutObj> = this.try_into()?;
|
||||
|
@ -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;
|
||||
|
@ -125,7 +125,7 @@ mod tests {
|
||||
let layout = Child::new(Dialog::new(
|
||||
display::screen(),
|
||||
|area| {
|
||||
Text::new(
|
||||
Text::new::<theme::T1DefaultText>(
|
||||
area,
|
||||
"Testing text layout, with some text, and some more text. And {param}",
|
||||
)
|
||||
|
@ -47,7 +47,7 @@ pub fn button_cancel() -> ButtonStyleSheet {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum T1DefaultText {}
|
||||
pub struct T1DefaultText;
|
||||
|
||||
impl DefaultTextTheme for T1DefaultText {
|
||||
const BACKGROUND_COLOR: Color = BG;
|
||||
|
@ -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,
|
||||
|
@ -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};
|
||||
|
@ -4,7 +4,7 @@ use crate::ui::{
|
||||
geometry::{Point, Rect},
|
||||
};
|
||||
|
||||
use super::{theme, event::TouchEvent};
|
||||
use super::{event::TouchEvent, theme};
|
||||
|
||||
pub enum SwipeDirection {
|
||||
Up,
|
||||
|
@ -2,7 +2,6 @@ use core::convert::TryInto;
|
||||
|
||||
use crate::{error, ui::geometry::Point};
|
||||
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum TouchEvent {
|
||||
TouchStart(Point),
|
||||
|
@ -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::<theme::TTDefaultText>(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::<theme::TTDefaultText>(
|
||||
area,
|
||||
"Testing text layout, with some text, and some more text. And {param}",
|
||||
)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user