1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 06:18:07 +00:00

feat(core/rust/ui): add model T title bar

[no changelog]
This commit is contained in:
Martin Milata 2022-01-18 12:57:12 +01:00
parent c7b33e2bc0
commit f167a2bef2
5 changed files with 94 additions and 12 deletions

View File

@ -5,13 +5,13 @@ use crate::ui::{
geometry::{Offset, Rect},
};
pub struct Title<T, U> {
pub struct Frame<T, U> {
area: Rect,
title: U,
content: Child<T>,
}
impl<T: Component, U: AsRef<[u8]>> Title<T, U> {
impl<T: Component, U: AsRef<[u8]>> Frame<T, U> {
pub fn new(area: Rect, title: U, content: impl FnOnce(Rect) -> T) -> Self {
let (title_area, content_area) = Self::areas(area);
Self {
@ -32,7 +32,7 @@ impl<T: Component, U: AsRef<[u8]>> Title<T, U> {
}
}
impl<T: Component, U: AsRef<[u8]>> Component for Title<T, U> {
impl<T: Component, U: AsRef<[u8]>> Component for Frame<T, U> {
type Msg = T::Msg;
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
@ -53,13 +53,13 @@ impl<T: Component, U: AsRef<[u8]>> Component for Title<T, U> {
}
#[cfg(feature = "ui_debug")]
impl<T, U> crate::trace::Trace for Title<T, U>
impl<T, U> crate::trace::Trace for Frame<T, U>
where
T: crate::trace::Trace,
U: crate::trace::Trace + AsRef<[u8]>,
{
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.open("Title");
t.open("Frame");
t.field("title", &self.title);
t.field("content", &self.content);
t.close();

View File

@ -1,11 +1,11 @@
mod button;
mod dialog;
mod frame;
mod page;
mod title;
use super::{event, theme};
pub use button::{Button, ButtonContent, ButtonMsg, ButtonPos, ButtonStyle, ButtonStyleSheet};
pub use dialog::{Dialog, DialogMsg};
pub use frame::Frame;
pub use page::ButtonPage;
pub use title::Title;

View File

@ -12,7 +12,7 @@ use crate::{
};
use super::{
component::{Button, ButtonPage, Title},
component::{Button, ButtonPage, Frame},
theme,
};
@ -56,7 +56,7 @@ extern "C" fn ui_layout_new_confirm_action(
let right = verb
.map(|label| |area, pos| Button::with_text(area, pos, label, theme::button_default()));
let obj = LayoutObj::new(Child::new(Title::new(display::screen(), title, |area| {
let obj = LayoutObj::new(Child::new(Frame::new(display::screen(), title, |area| {
ButtonPage::new(
area,
|area| {
@ -84,7 +84,7 @@ extern "C" fn ui_layout_new_confirm_text(
let description: Option<Buffer> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let obj = LayoutObj::new(Child::new(Title::new(display::screen(), title, |area| {
let obj = LayoutObj::new(Child::new(Frame::new(display::screen(), title, |area| {
ButtonPage::new(
area,
|area| {
@ -194,7 +194,7 @@ arameters! > left:<Button text:Left > right:<Button text:Right > >"#
#[test]
fn trace_layout_title() {
let layout = Child::new(Title::new(display::screen(), "Please confirm", |area| {
let layout = Child::new(Frame::new(display::screen(), "Please confirm", |area| {
Dialog::new(
area,
|area| {
@ -210,7 +210,7 @@ arameters! > left:<Button text:Left > right:<Button text:Right > >"#
}));
assert_eq!(
trace(&layout),
r#"<Title title:Please confirm content:<Dialog content:<Text content:Testing text layout,
r#"<Frame title:Please confirm content:<Dialog content:<Text content:Testing text layout,
with some text, and
some more text. And p-
arameters! > left:<Button text:Left > right:<Button text:Right > > >"#

View File

@ -0,0 +1,80 @@
use super::theme;
use crate::ui::{
component::{Child, Component, ComponentExt, Event, EventCtx},
display,
geometry::Rect,
};
pub struct Frame<T, U> {
area: Rect,
title: U,
content: Child<T>,
}
impl<T, U> Frame<T, U>
where
T: Component,
U: AsRef<[u8]>,
{
pub fn new(area: Rect, title: U, content: impl FnOnce(Rect) -> T) -> Self {
let (title_area, content_area) = Self::areas(area);
Self {
area: title_area,
title,
content: content(content_area).into_child(),
}
}
fn areas(area: Rect) -> (Rect, Rect) {
const HEADER_SPACE: i32 = 14;
let header_height = theme::FONT_BOLD.line_height() - theme::CONTENT_BORDER;
let (header_area, content_area) = area.hsplit(header_height);
let (_space, header_area) = header_area.vsplit(theme::CONTENT_BORDER);
let (_space, content_area) = content_area.hsplit(HEADER_SPACE);
(header_area, content_area)
}
}
impl<T, U> Component for Frame<T, U>
where
T: Component,
U: AsRef<[u8]>,
{
type Msg = T::Msg;
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
self.content.event(ctx, event)
}
fn paint(&mut self) {
display::text(
self.area.bottom_left(),
self.title.as_ref(),
theme::FONT_BOLD,
theme::GREY_LIGHT,
theme::BG,
);
self.content.paint();
}
}
#[cfg(feature = "ui_debug")]
impl<T, U> crate::trace::Trace for Frame<T, U>
where
T: crate::trace::Trace,
U: crate::trace::Trace + AsRef<[u8]>,
{
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.open("Frame");
t.field("title", &self.title);
t.field("content", &self.content);
t.close();
}
fn bounds(&self, sink: &dyn Fn(Rect)) {
sink(self.area);
self.content.bounds(sink);
}
}

View File

@ -1,6 +1,7 @@
mod button;
mod confirm;
mod dialog;
mod frame;
mod loader;
mod page;
mod passphrase;
@ -10,6 +11,7 @@ mod swipe;
pub use button::{Button, ButtonContent, ButtonMsg, ButtonStyle, ButtonStyleSheet};
pub use confirm::{HoldToConfirm, HoldToConfirmMsg};
pub use dialog::{Dialog, DialogLayout, DialogMsg};
pub use frame::Frame;
pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet};
pub use page::SwipePage;
pub use swipe::{Swipe, SwipeDirection};