mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-26 09:52:34 +00:00
chore(eckhart): simplify updatable info screen
[no changelog]
This commit is contained in:
parent
13a020202e
commit
468ddaab9d
@ -42,7 +42,7 @@ pub use qr_screen::{QrMsg, QrScreen};
|
|||||||
pub use select_word_screen::{SelectWordMsg, SelectWordScreen};
|
pub use select_word_screen::{SelectWordMsg, SelectWordScreen};
|
||||||
pub use share_words::{ShareWordsScreen, ShareWordsScreenMsg};
|
pub use share_words::{ShareWordsScreen, ShareWordsScreenMsg};
|
||||||
pub use text_screen::{AllowedTextContent, TextScreen, TextScreenMsg};
|
pub use text_screen::{AllowedTextContent, TextScreen, TextScreenMsg};
|
||||||
pub use updatable_info_screen::UpdatableInfoScreen;
|
pub use updatable_info_screen::{UpdatableInfoScreen, UpdatableInfoScreenMsg};
|
||||||
pub use value_input_screen::{
|
pub use value_input_screen::{
|
||||||
DurationInput, NumberInput, ValueInput, ValueInputScreen, ValueInputScreenMsg,
|
DurationInput, NumberInput, ValueInput, ValueInputScreen, ValueInputScreenMsg,
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
component::{
|
component::{
|
||||||
swipe_detect::SwipeConfig,
|
swipe_detect::SwipeConfig,
|
||||||
text::paragraphs::{Paragraph, ParagraphSource, Paragraphs},
|
text::paragraphs::{Paragraph, ParagraphSource, Paragraphs},
|
||||||
Component, Event, EventCtx,
|
Component, Event, EventCtx, PaginateFull,
|
||||||
},
|
},
|
||||||
flow::Swipable,
|
flow::Swipable,
|
||||||
geometry::{LinearPlacement, Rect},
|
geometry::{LinearPlacement, Rect},
|
||||||
@ -14,16 +14,20 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{theme, Header, TextScreen, TextScreenMsg};
|
use super::{constant::SCREEN, theme, ActionBar, ActionBarMsg, Header};
|
||||||
|
|
||||||
|
pub enum UpdatableInfoScreenMsg {
|
||||||
|
Close,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UpdatableInfoScreen<F>
|
pub struct UpdatableInfoScreen<F>
|
||||||
where
|
where
|
||||||
F: Fn() -> TString<'static>,
|
F: Fn() -> TString<'static>,
|
||||||
{
|
{
|
||||||
|
header: Header,
|
||||||
info_func: F,
|
info_func: F,
|
||||||
paragraphs: Paragraphs<Paragraph<'static>>,
|
paragraph: Paragraphs<Paragraph<'static>>,
|
||||||
area: Rect,
|
action_bar: ActionBar,
|
||||||
text_screen: TextScreen<Paragraphs<Paragraph<'static>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> UpdatableInfoScreen<F>
|
impl<F> UpdatableInfoScreen<F>
|
||||||
@ -31,59 +35,97 @@ where
|
|||||||
F: Fn() -> TString<'static>,
|
F: Fn() -> TString<'static>,
|
||||||
{
|
{
|
||||||
pub fn new(info_func: F) -> Self {
|
pub fn new(info_func: F) -> Self {
|
||||||
let paragraphs = Paragraph::new(&theme::TEXT_REGULAR, TString::empty())
|
let paragraph = Paragraph::new(&theme::TEXT_REGULAR, TString::empty())
|
||||||
.into_paragraphs()
|
.into_paragraphs()
|
||||||
.with_placement(LinearPlacement::vertical());
|
.with_placement(LinearPlacement::vertical());
|
||||||
let text_screen = create_text_screen(paragraphs.clone());
|
|
||||||
Self {
|
Self {
|
||||||
|
header: Header::new(TR::buttons__more_info.into()).with_close_button(),
|
||||||
info_func,
|
info_func,
|
||||||
paragraphs,
|
paragraph,
|
||||||
area: Rect::zero(),
|
action_bar: ActionBar::new_paginate_only(),
|
||||||
text_screen,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_header(mut self, header: Header) -> Self {
|
||||||
|
self.header = header;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn update_text(&mut self, ctx: &mut EventCtx) {
|
fn update_text(&mut self, ctx: &mut EventCtx) {
|
||||||
let text = (self.info_func)();
|
let text = (self.info_func)();
|
||||||
self.paragraphs.update(text);
|
self.paragraph.update(text);
|
||||||
self.text_screen = create_text_screen(self.paragraphs.clone());
|
|
||||||
self.text_screen.place(self.area);
|
self.update_page(0);
|
||||||
ctx.request_paint();
|
ctx.request_paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_page(&mut self, page_idx: u16) {
|
||||||
|
self.paragraph.change_page(page_idx);
|
||||||
|
self.action_bar.update(self.paragraph.pager());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> Component for UpdatableInfoScreen<F>
|
impl<F> Component for UpdatableInfoScreen<F>
|
||||||
where
|
where
|
||||||
F: Fn() -> TString<'static>,
|
F: Fn() -> TString<'static>,
|
||||||
{
|
{
|
||||||
type Msg = TextScreenMsg;
|
type Msg = UpdatableInfoScreenMsg;
|
||||||
|
|
||||||
fn place(&mut self, bounds: Rect) -> Rect {
|
fn place(&mut self, bounds: Rect) -> Rect {
|
||||||
self.text_screen.place(bounds);
|
// assert full screen
|
||||||
self.area = bounds;
|
debug_assert_eq!(bounds.height(), SCREEN.height());
|
||||||
|
debug_assert_eq!(bounds.width(), SCREEN.width());
|
||||||
|
|
||||||
|
let (header_area, rest) = bounds.split_top(Header::HEADER_HEIGHT);
|
||||||
|
let (info_area, action_bar_area) = rest.split_bottom(ActionBar::ACTION_BAR_HEIGHT);
|
||||||
|
|
||||||
|
self.header.place(header_area);
|
||||||
|
self.paragraph.place(info_area.inset(theme::SIDE_INSETS));
|
||||||
|
self.action_bar.place(action_bar_area);
|
||||||
|
|
||||||
|
self.update_page(0);
|
||||||
|
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||||
|
// Update page count of the screen
|
||||||
|
ctx.set_page_count(self.paragraph.pager().total() as usize);
|
||||||
|
|
||||||
if let Event::Attach(_) = event {
|
if let Event::Attach(_) = event {
|
||||||
self.update_text(ctx);
|
self.update_text(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.text_screen.event(ctx, event)
|
self.paragraph.event(ctx, event);
|
||||||
|
|
||||||
|
if self.header.event(ctx, event).is_some() {
|
||||||
|
return Some(UpdatableInfoScreenMsg::Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(msg) = self.action_bar.event(ctx, event) {
|
||||||
|
match msg {
|
||||||
|
ActionBarMsg::Prev => {
|
||||||
|
self.update_page(self.paragraph.pager().prev());
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
ActionBarMsg::Next => {
|
||||||
|
self.update_page(self.paragraph.pager().next());
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
self.text_screen.render(target);
|
self.header.render(target);
|
||||||
|
self.paragraph.render(target);
|
||||||
|
self.action_bar.render(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_text_screen(
|
|
||||||
paragraphs: Paragraphs<Paragraph<'static>>,
|
|
||||||
) -> TextScreen<Paragraphs<Paragraph<'static>>> {
|
|
||||||
TextScreen::new(paragraphs)
|
|
||||||
.with_header(Header::new(TR::buttons__more_info.into()).with_close_button())
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F: Fn() -> TString<'static>> Swipable for UpdatableInfoScreen<F> {
|
impl<F: Fn() -> TString<'static>> Swipable for UpdatableInfoScreen<F> {
|
||||||
fn get_pager(&self) -> Pager {
|
fn get_pager(&self) -> Pager {
|
||||||
Pager::single_page()
|
Pager::single_page()
|
||||||
@ -93,6 +135,9 @@ impl<F: Fn() -> TString<'static>> Swipable for UpdatableInfoScreen<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait UpdatableTextContent: Component + PaginateFull {}
|
||||||
|
impl<'a, T> UpdatableTextContent for Paragraphs<T> where T: ParagraphSource<'a> {}
|
||||||
|
|
||||||
#[cfg(feature = "ui_debug")]
|
#[cfg(feature = "ui_debug")]
|
||||||
impl<F> crate::trace::Trace for UpdatableInfoScreen<F>
|
impl<F> crate::trace::Trace for UpdatableInfoScreen<F>
|
||||||
where
|
where
|
||||||
@ -100,6 +145,8 @@ where
|
|||||||
{
|
{
|
||||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||||
t.component("UpdatableInfoScreen");
|
t.component("UpdatableInfoScreen");
|
||||||
t.child("screen", &self.text_screen);
|
t.child("Header", &self.header);
|
||||||
|
t.child("Content", &self.paragraph);
|
||||||
|
t.child("ActionBar", &self.action_bar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,8 @@ use core::sync::atomic::{AtomicU16, Ordering};
|
|||||||
use super::super::{
|
use super::super::{
|
||||||
component::Button,
|
component::Button,
|
||||||
firmware::{
|
firmware::{
|
||||||
ActionBar, Header, NumberInput, ShortMenuVec, TextScreenMsg, UpdatableInfoScreen,
|
ActionBar, Header, NumberInput, ShortMenuVec, UpdatableInfoScreen, ValueInputScreen,
|
||||||
ValueInputScreen, ValueInputScreenMsg, VerticalMenu, VerticalMenuScreen,
|
ValueInputScreenMsg, VerticalMenu, VerticalMenuScreen, VerticalMenuScreenMsg,
|
||||||
VerticalMenuScreenMsg,
|
|
||||||
},
|
},
|
||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
@ -104,17 +103,16 @@ pub fn new_request_number(
|
|||||||
));
|
));
|
||||||
|
|
||||||
let content_menu = VerticalMenuScreen::new(menu_items)
|
let content_menu = VerticalMenuScreen::new(menu_items)
|
||||||
.with_header(Header::new(TString::empty()).with_close_button())
|
.with_header(Header::new(title).with_close_button())
|
||||||
.map(move |msg| match msg {
|
.map(move |msg| match msg {
|
||||||
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
|
VerticalMenuScreenMsg::Selected(i) => Some(FlowMsg::Choice(i)),
|
||||||
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
|
VerticalMenuScreenMsg::Close => Some(FlowMsg::Cancelled),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let content_info = UpdatableInfoScreen::new(info_closure).map(|msg| match msg {
|
let content_info = UpdatableInfoScreen::new(info_closure)
|
||||||
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
|
.with_header(Header::new(title).with_close_button())
|
||||||
_ => None,
|
.map(|_| Some(FlowMsg::Cancelled));
|
||||||
});
|
|
||||||
|
|
||||||
let mut res = SwipeFlow::new(&RequestNumber::Number)?;
|
let mut res = SwipeFlow::new(&RequestNumber::Number)?;
|
||||||
res.add_page(&RequestNumber::Number, content_input)?
|
res.add_page(&RequestNumber::Number, content_input)?
|
||||||
|
Loading…
Reference in New Issue
Block a user