1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-26 17:38:39 +00:00

feat(core/ui): add Footer to T3T1 Frame

This commit is contained in:
obrusvit 2024-04-16 15:37:51 +02:00 committed by Martin Milata
parent 683ea6ed26
commit b87048e265
2 changed files with 47 additions and 4 deletions

View File

@ -64,6 +64,14 @@ impl<'a> Footer<'a> {
self.style_description = style;
ctx.request_paint();
}
pub fn height(&self) -> i16 {
if self.text_description.is_some() {
Footer::HEIGHT_DEFAULT
} else {
Footer::HEIGHT_SIMPLE
}
}
}
impl<'a> Component for Footer<'a> {
@ -124,4 +132,9 @@ impl<'a> Component for Footer<'a> {
.render(target);
});
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.area);
}
}

View File

@ -11,7 +11,7 @@ use crate::{
},
};
use super::{constant::SPACING, Button, ButtonMsg, CancelInfoConfirmMsg};
use super::{constant::SPACING, Button, ButtonMsg, CancelInfoConfirmMsg, Footer};
const TITLE_HEIGHT: i16 = 42;
@ -23,6 +23,7 @@ pub struct Frame<T> {
button: Option<Child<Button>>,
button_msg: CancelInfoConfirmMsg,
content: Child<T>,
footer: Option<Footer<'static>>,
}
pub enum FrameMsg<T> {
@ -43,6 +44,7 @@ where
button: None,
button_msg: CancelInfoConfirmMsg::Cancelled,
content: Child::new(content),
footer: None,
}
}
@ -97,6 +99,19 @@ where
self.with_button(theme::ICON_MENU, CancelInfoConfirmMsg::Info)
}
pub fn with_footer(
mut self,
instruction: TString<'static>,
description: Option<TString<'static>>,
) -> Self {
let mut footer = Footer::new(instruction);
if let Some(description_text) = description {
footer = footer.with_description(description_text);
}
self.footer = Some(footer);
self
}
pub fn inner(&self) -> &T {
self.content.inner()
}
@ -127,10 +142,10 @@ where
type Msg = FrameMsg<T::Msg>;
fn place(&mut self, bounds: Rect) -> Rect {
let (mut header_area, content_area) = bounds.split_top(TITLE_HEIGHT);
let content_area = content_area.inset(Insets::top(SPACING));
let (mut header_area, mut content_area) = bounds.split_top(TITLE_HEIGHT);
content_area = content_area.inset(Insets::top(SPACING));
header_area = header_area.inset(Insets::sides(SPACING));
if let Some(b) = &mut self.button {
let (rest, button_area) = header_area.split_right(TITLE_HEIGHT);
header_area = rest;
@ -144,6 +159,15 @@ where
} else {
self.title.place(header_area);
}
if let Some(footer) = &mut self.footer {
// FIXME: spacer at the bottom might be applied also for usage without footer
// but not for VerticalMenu
content_area = content_area.inset(Insets::bottom(SPACING));
let (remaining, footer_area) = content_area.split_bottom(footer.height());
footer.place(footer_area);
content_area = remaining;
}
self.content.place(content_area);
bounds
}
@ -162,12 +186,14 @@ where
self.subtitle.paint();
self.button.paint();
self.content.paint();
self.footer.paint();
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
self.title.render(target);
self.subtitle.render(target);
self.button.render(target);
self.content.render(target);
self.footer.render(target);
}
#[cfg(feature = "ui_bounds")]
@ -176,6 +202,7 @@ where
self.subtitle.bounds(sink);
self.button.bounds(sink);
self.content.bounds(sink);
self.footer.bounds(sink);
}
}
@ -194,6 +221,9 @@ where
if let Some(button) = &self.button {
t.child("button", button);
}
if let Some(footer) = &self.footer {
t.child("footer", footer);
}
}
}