From 229c81fa7ec8630024fe043f0b735e0319ecdf99 Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Thu, 30 Mar 2023 23:40:25 +0200 Subject: [PATCH] feat(core/ui): frames with title and subtitle [no changelog] --- core/embed/rust/src/ui/component/label.rs | 4 ++ .../rust/src/ui/model_tt/component/frame.rs | 37 ++++++++++++++++--- core/embed/rust/src/ui/model_tt/theme.rs | 4 ++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/core/embed/rust/src/ui/component/label.rs b/core/embed/rust/src/ui/component/label.rs index a1ab4baea7..d394c59ae8 100644 --- a/core/embed/rust/src/ui/component/label.rs +++ b/core/embed/rust/src/ui/component/label.rs @@ -57,6 +57,10 @@ where self.layout.bounds } + pub fn alignment(&self) -> Alignment { + self.layout.align + } + pub fn max_size(&self) -> Offset { let font = self.font(); Offset::new(font.text_width(self.text.as_ref()), font.text_max_height()) diff --git a/core/embed/rust/src/ui/model_tt/component/frame.rs b/core/embed/rust/src/ui/model_tt/component/frame.rs index b6f9fa9d11..9df7a7daaf 100644 --- a/core/embed/rust/src/ui/model_tt/component/frame.rs +++ b/core/embed/rust/src/ui/model_tt/component/frame.rs @@ -11,6 +11,7 @@ use crate::ui::{ pub struct Frame { border: Insets, title: Child>, + subtitle: Option>>, button: Option>>, button_msg: CancelInfoConfirmMsg, content: Child, @@ -29,6 +30,7 @@ where pub fn new(style: TextStyle, alignment: Alignment, title: U, content: T) -> Self { Self { title: Child::new(Label::new(title, alignment, style)), + subtitle: None, border: theme::borders(), button: None, button_msg: CancelInfoConfirmMsg::Cancelled, @@ -53,6 +55,15 @@ where self } + pub fn with_subtitle(mut self, style: TextStyle, subtitle: U) -> Self { + self.subtitle = Some(Child::new(Label::new( + subtitle, + self.title.inner().alignment(), + style, + ))); + self + } + fn with_button(mut self, icon: Icon, msg: CancelInfoConfirmMsg) -> Self { let touch_area = Insets { left: self.border.left * 4, @@ -118,21 +129,29 @@ where let bounds = bounds.inset(self.border); if let Some(b) = &mut self.button { let button_side = theme::CORNER_BUTTON_SIDE; - let (title_area, button_area) = bounds.split_right(button_side); + let (header_area, button_area) = bounds.split_right(button_side); let (button_area, _) = button_area.split_top(button_side); b.place(button_area); - let title_area = self.title.place(title_area); - let title_height = title_area.height(); - let height = title_area.height().max(button_side); + let title_area = self.title.place(header_area); + let remaining = header_area.inset(Insets::top(title_area.height())); + let subtitle_area = self.subtitle.place(remaining); + + let title_height = title_area.height() + subtitle_area.height(); + let header_height = title_height.max(button_side); if title_height < button_side { self.title .place(title_area.translate(Offset::y((button_side - title_height) / 2))); + self.subtitle + .place(subtitle_area.translate(Offset::y((button_side - title_height) / 2))); } - let content_area = bounds.inset(Insets::top(height + TITLE_SPACE)); + let content_area = bounds.inset(Insets::top(header_height + TITLE_SPACE)); self.content.place(content_area); } else { let title_area = self.title.place(bounds); - let content_area = bounds.inset(Insets::top(title_area.height() + TITLE_SPACE)); + let remaining = bounds.inset(Insets::top(title_area.height())); + let subtitle_area = self.subtitle.place(remaining); + let remaining = remaining.inset(Insets::top(subtitle_area.height())); + let content_area = remaining.inset(Insets::top(TITLE_SPACE)); self.content.place(content_area); } bounds @@ -140,6 +159,7 @@ where fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option { self.title.event(ctx, event); + self.subtitle.event(ctx, event); if let Some(ButtonMsg::Clicked) = self.button.event(ctx, event) { return Some(FrameMsg::Button(self.button_msg)); } @@ -148,6 +168,7 @@ where fn paint(&mut self) { self.title.paint(); + self.subtitle.paint(); self.button.paint(); self.content.paint(); } @@ -155,6 +176,7 @@ where #[cfg(feature = "ui_bounds")] fn bounds(&self, sink: &mut dyn FnMut(Rect)) { self.title.bounds(sink); + self.subtitle.bounds(sink); self.button.bounds(sink); self.content.bounds(sink); } @@ -169,6 +191,9 @@ where fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Frame"); t.field("title", &self.title); + if let Some(s) = &self.subtitle { + t.field("subtitle", s); + } if let Some(b) = &self.button { t.field("button", b); } diff --git a/core/embed/rust/src/ui/model_tt/theme.rs b/core/embed/rust/src/ui/model_tt/theme.rs index b5d6653d2c..f24af14473 100644 --- a/core/embed/rust/src/ui/model_tt/theme.rs +++ b/core/embed/rust/src/ui/model_tt/theme.rs @@ -150,6 +150,10 @@ pub const fn label_title() -> TextStyle { TextStyle::new(Font::BOLD, GREY_LIGHT, BG, GREY_LIGHT, GREY_LIGHT) } +pub const fn label_subtitle() -> TextStyle { + TextStyle::new(Font::NORMAL, GREY_LIGHT, BG, GREY_LIGHT, GREY_LIGHT) +} + pub const fn label_coinjoin_progress() -> TextStyle { TextStyle::new(Font::BOLD, FG, YELLOW, FG, FG) }