refactor(core/rust): allow model_t1 and model_tt at once

[no changelog]
pull/1948/head
Martin Milata 3 years ago
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…
Cancel
Save