From e358b2c97a5406458e4c36ba525e9ea9a313cb51 Mon Sep 17 00:00:00 2001 From: obrusvit Date: Tue, 16 Apr 2024 15:37:51 +0200 Subject: [PATCH] feat(core/ui): add Footer to T3T1 Frame --- .../src/ui/model_mercury/component/footer.rs | 13 +++++++ .../src/ui/model_mercury/component/frame.rs | 38 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/core/embed/rust/src/ui/model_mercury/component/footer.rs b/core/embed/rust/src/ui/model_mercury/component/footer.rs index 18d557a59..91038a1cd 100644 --- a/core/embed/rust/src/ui/model_mercury/component/footer.rs +++ b/core/embed/rust/src/ui/model_mercury/component/footer.rs @@ -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); + } } diff --git a/core/embed/rust/src/ui/model_mercury/component/frame.rs b/core/embed/rust/src/ui/model_mercury/component/frame.rs index 55a005f17..16a6f0dd7 100644 --- a/core/embed/rust/src/ui/model_mercury/component/frame.rs +++ b/core/embed/rust/src/ui/model_mercury/component/frame.rs @@ -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 { button: Option>, button_msg: CancelInfoConfirmMsg, content: Child, + footer: Option>, } pub enum FrameMsg { @@ -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>, + ) -> 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; 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>(&'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); + } } }