1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-10 23:40:58 +00:00

refactor(core/rust): model-agnostic Paginated

[no changelog]
This commit is contained in:
Martin Milata 2021-12-07 13:09:45 +01:00 committed by matejcik
parent c236dfc814
commit 7f224ab36d
4 changed files with 70 additions and 47 deletions

View File

@ -5,6 +5,7 @@ pub mod empty;
pub mod label; pub mod label;
pub mod map; pub mod map;
pub mod pad; pub mod pad;
pub mod paginated;
pub mod text; pub mod text;
pub mod tuple; pub mod tuple;
@ -12,6 +13,7 @@ pub use base::{Child, Component, ComponentExt, Event, EventCtx, Never, TimerToke
pub use empty::Empty; pub use empty::Empty;
pub use label::{Label, LabelStyle}; pub use label::{Label, LabelStyle};
pub use pad::Pad; pub use pad::Pad;
pub use paginated::{Paginate, Paginated};
pub use text::{ pub use text::{
formatted::FormattedText, formatted::FormattedText,
layout::{LineBreaking, PageBreaking, TextLayout}, layout::{LineBreaking, PageBreaking, TextLayout},

View File

@ -3,48 +3,61 @@ use crate::ui::{
text::layout::{LayoutFit, TextNoOp}, text::layout::{LayoutFit, TextNoOp},
Component, ComponentExt, Event, EventCtx, FormattedText, Pad, Component, ComponentExt, Event, EventCtx, FormattedText, Pad,
}, },
display, display::Color,
geometry::Rect, geometry::Rect,
}; };
use super::{ pub trait Page {
page::{Page, PageMsg}, type Content;
theme,
};
pub struct Paginated<T> { fn new(area: Rect, page: Self::Content, page_count: usize, active_page: usize) -> Self;
page: Page<T>,
pad: Pad, fn inner_mut(&mut self) -> &mut Self::Content;
fade_after_next_paint: Option<i32>, fn page_count(&self) -> usize;
fn active_page(&self) -> usize;
fn fade_after_next_paint(&mut self);
} }
impl<T> Paginated<T> pub enum PageMsg<T> {
Content(T),
ChangePage(usize),
}
pub struct Paginated<P> {
page: P,
pad: Pad,
}
impl<P> Paginated<P>
where where
T: Paginate, P: Page,
P::Content: Paginate,
{ {
pub fn new(area: Rect, mut content: T) -> Self { pub fn new(area: Rect, content: impl FnOnce(Rect) -> P::Content, background: Color) -> Self {
let active_page = 0; let active_page = 0;
let mut content = content(area);
let page_count = content.page_count(); let page_count = content.page_count();
Self { Self {
page: Page::new(area, content, page_count, active_page), page: P::new(area, content, page_count, active_page),
pad: Pad::with_background(area, theme::BG), pad: Pad::with_background(area, background),
fade_after_next_paint: None,
} }
} }
} }
impl<T> Component for Paginated<T> impl<P> Component for Paginated<P>
where where
T: Paginate, P: Page,
T: Component, P: Component<Msg = PageMsg<<<P as Page>::Content as Component>::Msg>>,
P::Content: Paginate,
P::Content: Component,
{ {
type Msg = T::Msg; type Msg = <<P as Page>::Content as Component>::Msg;
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> { fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
self.page.event(ctx, event).and_then(|msg| match msg { self.page.event(ctx, event).and_then(|msg| match msg {
PageMsg::Content(c) => Some(c), PageMsg::Content(c) => Some(c),
PageMsg::ChangePage(page) => { PageMsg::ChangePage(page) => {
self.fade_after_next_paint = Some(theme::BACKLIGHT_NORMAL); self.page.fade_after_next_paint();
self.page.inner_mut().change_page(page); self.page.inner_mut().change_page(page);
self.page.inner_mut().request_complete_repaint(ctx); self.page.inner_mut().request_complete_repaint(ctx);
self.pad.clear(); self.pad.clear();
@ -56,16 +69,14 @@ where
fn paint(&mut self) { fn paint(&mut self) {
self.pad.paint(); self.pad.paint();
self.page.paint(); self.page.paint();
if let Some(val) = self.fade_after_next_paint.take() {
display::fade_backlight(val);
}
} }
} }
#[cfg(feature = "ui_debug")] #[cfg(feature = "ui_debug")]
impl<T> crate::trace::Trace for Paginated<T> impl<P> crate::trace::Trace for Paginated<P>
where where
T: crate::trace::Trace, P: Page + crate::trace::Trace,
P::Content: crate::trace::Trace,
{ {
fn trace(&self, t: &mut dyn crate::trace::Tracer) { fn trace(&self, t: &mut dyn crate::trace::Tracer) {
self.page.trace(t); self.page.trace(t);

View File

@ -3,7 +3,6 @@ mod confirm;
mod dialog; mod dialog;
mod loader; mod loader;
mod page; mod page;
mod paginated;
mod passphrase; mod passphrase;
mod pin; mod pin;
mod swipe; mod swipe;
@ -12,7 +11,7 @@ pub use button::{Button, ButtonContent, ButtonMsg, ButtonStyle, ButtonStyleSheet
pub use confirm::{HoldToConfirm, HoldToConfirmMsg}; pub use confirm::{HoldToConfirm, HoldToConfirmMsg};
pub use dialog::{Dialog, DialogLayout, DialogMsg}; pub use dialog::{Dialog, DialogLayout, DialogMsg};
pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet}; pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet};
pub use paginated::{Paginate, Paginated}; pub use page::SwipePage;
pub use swipe::{Swipe, SwipeDirection}; pub use swipe::{Swipe, SwipeDirection};
use super::{event, theme}; use super::{event, theme};

View File

@ -1,24 +1,32 @@
use crate::ui::{ use crate::ui::{
component::{Component, Event, EventCtx, Never}, component::{
paginated::{Page, PageMsg},
Component, Event, EventCtx, Never,
},
display, display,
geometry::{Offset, Point, Rect}, geometry::{Offset, Point, Rect},
}; };
use super::{theme, Swipe, SwipeDirection}; use super::{theme, Swipe, SwipeDirection};
pub enum PageMsg<T> { pub struct SwipePage<T> {
Content(T),
ChangePage(usize),
}
pub struct Page<T> {
swipe: Swipe, swipe: Swipe,
scrollbar: ScrollBar, scrollbar: ScrollBar,
page: T, page: T,
fade: Option<i32>,
} }
impl<T> Page<T> { impl<T> SwipePage<T> {
pub fn new(area: Rect, page: T, page_count: usize, active_page: usize) -> Self { fn setup_swipe(scrollbar: &ScrollBar, swipe: &mut Swipe) {
swipe.allow_up = scrollbar.has_next_page();
swipe.allow_down = scrollbar.has_previous_page();
}
}
impl<T> Page for SwipePage<T> {
type Content = T;
fn new(area: Rect, page: T, page_count: usize, active_page: usize) -> Self {
let scrollbar = ScrollBar::vertical_right(area, page_count, active_page); let scrollbar = ScrollBar::vertical_right(area, page_count, active_page);
let mut swipe = Swipe::new(area); let mut swipe = Swipe::new(area);
Self::setup_swipe(&scrollbar, &mut swipe); Self::setup_swipe(&scrollbar, &mut swipe);
@ -26,28 +34,28 @@ impl<T> Page<T> {
swipe, swipe,
scrollbar, scrollbar,
page, page,
fade: None,
} }
} }
fn setup_swipe(scrollbar: &ScrollBar, swipe: &mut Swipe) { fn inner_mut(&mut self) -> &mut T {
swipe.allow_up = scrollbar.has_next_page();
swipe.allow_down = scrollbar.has_previous_page();
}
pub fn inner_mut(&mut self) -> &mut T {
&mut self.page &mut self.page
} }
pub fn page_count(&self) -> usize { fn page_count(&self) -> usize {
self.scrollbar.page_count self.scrollbar.page_count
} }
pub fn active_page(&self) -> usize { fn active_page(&self) -> usize {
self.scrollbar.active_page self.scrollbar.active_page
} }
fn fade_after_next_paint(&mut self) {
self.fade = Some(theme::BACKLIGHT_NORMAL);
}
} }
impl<T: Component> Component for Page<T> { impl<T: Component> Component for SwipePage<T> {
type Msg = PageMsg<T::Msg>; type Msg = PageMsg<T::Msg>;
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> { fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
@ -79,16 +87,19 @@ impl<T: Component> Component for Page<T> {
fn paint(&mut self) { fn paint(&mut self) {
self.page.paint(); self.page.paint();
self.scrollbar.paint(); self.scrollbar.paint();
if let Some(val) = self.fade.take() {
display::fade_backlight(val);
}
} }
} }
#[cfg(feature = "ui_debug")] #[cfg(feature = "ui_debug")]
impl<T> crate::trace::Trace for Page<T> impl<T> crate::trace::Trace for SwipePage<T>
where where
T: crate::trace::Trace, T: crate::trace::Trace,
{ {
fn trace(&self, t: &mut dyn crate::trace::Tracer) { fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.open("Page"); t.open("SwipePage");
t.field("active_page", &self.active_page()); t.field("active_page", &self.active_page());
t.field("page_count", &self.page_count()); t.field("page_count", &self.page_count());
t.field("content", &self.page); t.field("content", &self.page);