diff --git a/core/embed/rust/src/ui/constant.rs b/core/embed/rust/src/ui/constant.rs index c47ea35064..3237db67aa 100644 --- a/core/embed/rust/src/ui/constant.rs +++ b/core/embed/rust/src/ui/constant.rs @@ -9,5 +9,5 @@ pub use super::model_mercury::constant::*; #[cfg(all(feature = "model_tr", not(feature = "model_tt")))] pub use super::model_tr::constant::*; -#[cfg(all(feature = "model_tt", not(feature = "model_mercury")))] +#[cfg(feature = "model_tt")] pub use super::model_tt::constant::*; diff --git a/core/embed/rust/src/ui/model_mercury/component/address_details.rs b/core/embed/rust/src/ui/model_mercury/component/address_details.rs index 01c08df034..f79276dfd6 100644 --- a/core/embed/rust/src/ui/model_mercury/component/address_details.rs +++ b/core/embed/rust/src/ui/model_mercury/component/address_details.rs @@ -2,8 +2,7 @@ use heapless::Vec; use crate::{ error::Error, - micropython::buffer::StrBuffer, - strutil::StringType, + strutil::TString, translations::TR, ui::{ component::{ @@ -19,58 +18,57 @@ use super::{theme, Frame, FrameMsg}; const MAX_XPUBS: usize = 16; -pub struct AddressDetails { - qr_code: Frame, - details: Frame>, T>, - xpub_view: Frame>, T>, - xpubs: Vec<(T, T), MAX_XPUBS>, +pub struct AddressDetails { + qr_code: Frame, + details: Frame>>, + xpub_view: Frame>>, + xpubs: Vec<(TString<'static>, TString<'static>), MAX_XPUBS>, xpub_page_count: Vec, current_page: usize, } -impl AddressDetails -where - T: StringType, -{ +impl AddressDetails { pub fn new( - qr_title: T, - qr_address: T, + qr_title: TString<'static>, + qr_address: TString<'static>, case_sensitive: bool, - details_title: T, - account: Option, - path: Option, - ) -> Result - where - T: From<&'static str>, - { + details_title: TString<'static>, + account: Option>, + path: Option>, + ) -> Result { let mut para = ParagraphVecShort::new(); if let Some(a) = account { para.add(Paragraph::new( &theme::TEXT_NORMAL, - TR::words__account_colon.try_into()?, + TR::words__account_colon, )); para.add(Paragraph::new(&theme::TEXT_MONO, a)); } if let Some(p) = path { para.add(Paragraph::new( &theme::TEXT_NORMAL, - TR::address_details__derivation_path.try_into()?, + TR::address_details__derivation_path, )); para.add(Paragraph::new(&theme::TEXT_MONO, p)); } let result = Self { qr_code: Frame::left_aligned( qr_title, - Qr::new(qr_address, case_sensitive)?.with_border(7), + qr_address + .map(|s| Qr::new(s, case_sensitive))? + .with_border(7), + ) + .with_cancel_button() + .with_border(theme::borders_horizontal_scroll()), + details: Frame::left_aligned( + details_title, + para.into_paragraphs(), ) .with_cancel_button() .with_border(theme::borders_horizontal_scroll()), - details: Frame::left_aligned(details_title, para.into_paragraphs()) - .with_cancel_button() - .with_border(theme::borders_horizontal_scroll()), xpub_view: Frame::left_aligned( " \n ".into(), - Paragraph::new(&theme::TEXT_MONO, "".into()).into_paragraphs(), + Paragraph::new(&theme::TEXT_MONO, "").into_paragraphs(), ) .with_cancel_button() .with_border(theme::borders_horizontal_scroll()), @@ -81,24 +79,24 @@ where Ok(result) } - pub fn add_xpub(&mut self, title: T, xpub: T) -> Result<(), Error> { + pub fn add_xpub( + &mut self, + title: TString<'static>, + xpub: TString<'static>, + ) -> Result<(), Error> { self.xpubs .push((title, xpub)) .map_err(|_| Error::OutOfRange) } - fn switch_xpub(&mut self, i: usize, page: usize) -> usize - where - T: Clone, - { + fn switch_xpub(&mut self, i: usize, page: usize) -> usize { // Context is needed for updating child so that it can request repaint. In this // case the parent component that handles paging always requests complete // repaint after page change so we can use a dummy context here. let mut dummy_ctx = EventCtx::new(); - self.xpub_view - .update_title(&mut dummy_ctx, self.xpubs[i].0.clone()); + self.xpub_view.update_title(&mut dummy_ctx, self.xpubs[i].0); self.xpub_view.update_content(&mut dummy_ctx, |p| { - p.inner_mut().update(self.xpubs[i].1.clone()); + p.inner_mut().update(self.xpubs[i].1); let npages = p.page_count(); p.change_page(page); npages @@ -123,10 +121,7 @@ where } } -impl Paginate for AddressDetails -where - T: StringType + Clone, -{ +impl Paginate for AddressDetails { fn page_count(&mut self) -> usize { let total_xpub_pages: u8 = self.xpub_page_count.iter().copied().sum(); 2usize.saturating_add(total_xpub_pages.into()) @@ -142,10 +137,7 @@ where } } -impl Component for AddressDetails -where - T: StringType + Clone, -{ +impl Component for AddressDetails { type Msg = (); fn place(&mut self, bounds: Rect) -> Rect { @@ -201,10 +193,7 @@ where } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for AddressDetails -where - T: StringType, -{ +impl crate::trace::Trace for AddressDetails { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.component("AddressDetails"); match self.current_page { diff --git a/core/embed/rust/src/ui/model_mercury/component/button.rs b/core/embed/rust/src/ui/model_mercury/component/button.rs index dbb513aa0a..037aa38294 100644 --- a/core/embed/rust/src/ui/model_mercury/component/button.rs +++ b/core/embed/rust/src/ui/model_mercury/component/button.rs @@ -32,7 +32,7 @@ pub struct Button { long_timer: Option, } -impl Button { +impl Button { /// Offsets the baseline of the button text /// -x/+x => left/right /// -y/+y => up/down @@ -58,8 +58,8 @@ impl Button { Self::new(ButtonContent::Icon(icon)) } - pub const fn with_icon_and_text(content: IconText) -> Self { - Self::new(ButtonContent::IconAndText::(content)) + pub const fn with_icon_and_text(content: IconText) -> Self { + Self::new(ButtonContent::IconAndText(content)) } pub const fn with_icon_blend(bg: Icon, fg: Icon, fg_offset: Offset) -> Self { @@ -204,15 +204,16 @@ impl Button { match &self.content { ButtonContent::Empty => {} ButtonContent::Text(text) => { - let text = text.as_ref(); let start_of_baseline = self.area.center() + Self::BASELINE_OFFSET; - display::text_left( - start_of_baseline, - text, - style.font, - style.text_color, - style.button_color, - ); + text.map(|text| { + display::text_left( + start_of_baseline, + text, + style.font, + style.text_color, + style.button_color, + ); + }); } ButtonContent::Icon(icon) => { icon.draw( @@ -238,12 +239,13 @@ impl Button { match &self.content { ButtonContent::Empty => {} ButtonContent::Text(text) => { - let text = text.as_ref(); let start_of_baseline = self.area.left_center() + Self::BASELINE_OFFSET; - shape::Text::new(start_of_baseline, text) - .with_font(style.font) - .with_fg(style.text_color) - .render(target); + text.map(|text| { + shape::Text::new(start_of_baseline, text) + .with_font(style.font) + .with_fg(style.text_color) + .render(target); + }); } ButtonContent::Icon(icon) => { shape::ToifImage::new(self.area.center(), icon.toif) @@ -376,7 +378,7 @@ impl crate::trace::Trace for Button { ButtonContent::Text(text) => t.string("text", *text), ButtonContent::Icon(_) => t.bool("icon", true), ButtonContent::IconAndText(content) => { - t.string("text", content.text.as_ref().into()); + t.string("text", content.text.into()); t.bool("icon", true); } ButtonContent::IconBlend(_, _, _) => t.bool("icon", true), @@ -397,7 +399,7 @@ pub enum ButtonContent { Empty, Text(TString<'static>), Icon(Icon), - IconAndText(IconText), + IconAndText(IconText), IconBlend(Icon, Icon, Offset), } @@ -419,18 +421,15 @@ pub struct ButtonStyle { pub border_width: i16, } -impl Button { +impl Button { pub fn cancel_confirm( - left: Button, - right: Button, + left: Button, + right: Button, left_is_small: bool, ) -> CancelConfirm< - T, impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, > - where - T: AsRef, { let width = if left_is_small { theme::BUTTON_WIDTH @@ -450,21 +449,18 @@ impl Button { } pub fn cancel_confirm_text( - left: Option, - right: Option, + left: Option>, + right: Option>, ) -> CancelConfirm< - T, impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, > - where - T: AsRef, { let left_is_small: bool; let left = if let Some(verb) = left { - left_is_small = verb.as_ref().len() <= 4; - if verb.as_ref() == "^" { + left_is_small = verb.len() <= 4; + if verb == "^".into() { Button::with_icon(theme::ICON_UP) } else { Button::with_text(verb) @@ -482,16 +478,13 @@ impl Button { } pub fn cancel_info_confirm( - confirm: T, - info: T, + confirm: TString<'static>, + info: TString<'static>, ) -> CancelInfoConfirm< - T, impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, > - where - T: AsRef, { let right = Button::with_text(confirm) .styled(theme::button_confirm()) @@ -522,11 +515,10 @@ pub enum CancelConfirmMsg { Confirmed, } -type CancelInfoConfirm = FixedHeightBar< - Split, F0>, Split, F1>, MsgMap, F2>>>, ->; +type CancelInfoConfirm = + FixedHeightBar, Split, MsgMap>>>; -type CancelConfirm = FixedHeightBar, F0>, MsgMap, F1>>>; +type CancelConfirm = FixedHeightBar, MsgMap>>; #[derive(Clone, Copy)] pub enum CancelInfoConfirmMsg { @@ -536,25 +528,23 @@ pub enum CancelInfoConfirmMsg { } #[derive(PartialEq, Eq)] -pub struct IconText { - text: T, +pub struct IconText { + text: &'static str, icon: Icon, } -impl IconText -where - T: AsRef, -{ +impl IconText { const ICON_SPACE: i16 = 46; const ICON_MARGIN: i16 = 4; const TEXT_MARGIN: i16 = 6; - pub fn new(text: T, icon: Icon) -> Self { + pub fn new(text: &'static str, icon: Icon) -> Self { Self { text, icon } } pub fn paint(&self, area: Rect, style: &ButtonStyle, baseline_offset: Offset) { - let width = style.font.text_width(self.text.as_ref()); + let width = style.font.text_width(self.text); + let height = style.font.text_height(); let mut use_icon = false; let mut use_text = false; @@ -563,7 +553,8 @@ where area.top_left().x + ((Self::ICON_SPACE + Self::ICON_MARGIN) / 2), area.center().y, ); - let mut text_pos = area.left_center() + baseline_offset; + let mut text_pos = + area.center() + Offset::new(-width / 2, height / 2) + baseline_offset; if area.width() > (Self::ICON_SPACE + Self::TEXT_MARGIN + width) { //display both icon and text @@ -581,7 +572,7 @@ where if use_text { display::text_left( text_pos, - self.text.as_ref(), + self.text, style.font, style.text_color, style.button_color, @@ -629,7 +620,7 @@ where } if use_text { - shape::Text::new(text_pos, self.text.as_ref()) + shape::Text::new(text_pos, self.text) .with_fg(style.text_color) .render(target); } diff --git a/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs b/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs index 506b3d5633..eabb074037 100644 --- a/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs +++ b/core/embed/rust/src/ui/model_mercury/component/coinjoin_progress.rs @@ -3,15 +3,15 @@ use core::mem; use crate::{ error::Error, maybe_trace::MaybeTrace, - micropython::buffer::StrBuffer, + strutil::TString, translations::TR, ui::{ component::{ base::Never, Bar, Child, Component, ComponentExt, Empty, Event, EventCtx, Label, Split, }, - constant, display::loader::{loader_circular_uncompress, LoaderDimensions}, geometry::{Insets, Offset, Rect}, + model_mercury::constant, shape, shape::Renderer, util::animation_disabled, @@ -27,49 +27,43 @@ const LOADER_INNER: i16 = 28; const LOADER_OFFSET: i16 = -34; const LOADER_SPEED: u16 = 5; -pub struct CoinJoinProgress { +pub struct CoinJoinProgress { value: u16, indeterminate: bool, - content: Child, StrBuffer>>, + content: Child>>, // Label is not a child since circular loader paints large black rectangle which overlaps it. // To work around this, draw label every time loader is drawn. - label: Label, + label: Label<'static>, } -impl CoinJoinProgress -where - T: AsRef, -{ +impl CoinJoinProgress { pub fn new( - text: T, + text: TString<'static>, indeterminate: bool, - ) -> Result + MaybeTrace>, Error> - where - T: AsRef, - { + ) -> Result + MaybeTrace>, Error> { let style = theme::label_coinjoin_progress(); - let label = Label::centered( - TryInto::::try_into(TR::coinjoin__title_do_not_disconnect)?, - style, - ) - .vertically_centered(); + let label = Label::centered(TR::coinjoin__title_do_not_disconnect.into(), style) + .vertically_centered(); let bg = Bar::new(style.background_color, theme::BG, 2); let inner = (bg, label); CoinJoinProgress::with_background(text, inner, indeterminate) } } -impl CoinJoinProgress +impl CoinJoinProgress where - T: AsRef, U: Component, { - pub fn with_background(text: T, inner: U, indeterminate: bool) -> Result { + pub fn with_background( + text: TString<'static>, + inner: U, + indeterminate: bool, + ) -> Result { Ok(Self { value: 0, indeterminate, content: Frame::centered( - TR::coinjoin__title_progress.try_into()?, + TR::coinjoin__title_progress.into(), Split::bottom(RECTANGLE_HEIGHT, 0, Empty, inner), ) .into_child(), @@ -78,9 +72,8 @@ where } } -impl Component for CoinJoinProgress +impl Component for CoinJoinProgress where - T: AsRef, U: Component, { type Msg = Never; @@ -167,9 +160,8 @@ where } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for CoinJoinProgress +impl crate::trace::Trace for CoinJoinProgress where - T: AsRef, U: Component + crate::trace::Trace, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { diff --git a/core/embed/rust/src/ui/model_mercury/component/dialog.rs b/core/embed/rust/src/ui/model_mercury/component/dialog.rs index 49c344ca85..c66d37a91f 100644 --- a/core/embed/rust/src/ui/model_mercury/component/dialog.rs +++ b/core/embed/rust/src/ui/model_mercury/component/dialog.rs @@ -1,5 +1,5 @@ use crate::{ - strutil::StringType, + strutil::TString, ui::{ component::{ image::BlendedImage, @@ -97,18 +97,17 @@ where } } -pub struct IconDialog { +pub struct IconDialog { image: Child, - paragraphs: Paragraphs>, + paragraphs: Paragraphs>, controls: Child, } -impl IconDialog +impl IconDialog where - T: StringType, U: Component, { - pub fn new(icon: BlendedImage, title: T, controls: U) -> Self { + pub fn new(icon: BlendedImage, title: impl Into>, controls: U) -> Self { Self { image: Child::new(icon), paragraphs: Paragraphs::new(ParagraphVecShort::from_iter([Paragraph::new( @@ -125,26 +124,26 @@ where } } - pub fn with_paragraph(mut self, para: Paragraph) -> Self { - if !para.content().as_ref().is_empty() { + pub fn with_paragraph(mut self, para: Paragraph<'static>) -> Self { + if !para.content().is_empty() { self.paragraphs.inner_mut().add(para); } self } - pub fn with_text(self, style: &'static TextStyle, text: T) -> Self { + pub fn with_text(self, style: &'static TextStyle, text: impl Into>) -> Self { self.with_paragraph(Paragraph::new(style, text).centered()) } - pub fn with_description(self, description: T) -> Self { + pub fn with_description(self, description: impl Into>) -> Self { self.with_text(&theme::TEXT_NORMAL_OFF_WHITE, description) } - pub fn with_value(self, value: T) -> Self { + pub fn with_value(self, value: impl Into>) -> Self { self.with_text(&theme::TEXT_MONO, value) } - pub fn new_shares(lines: [T; 4], controls: U) -> Self { + pub fn new_shares(lines: [impl Into>; 4], controls: U) -> Self { let [l0, l1, l2, l3] = lines; Self { image: Child::new(BlendedImage::new( @@ -171,9 +170,8 @@ where pub const VALUE_SPACE: i16 = 5; } -impl Component for IconDialog +impl Component for IconDialog where - T: StringType, U: Component, { type Msg = DialogMsg; @@ -219,9 +217,8 @@ where } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for IconDialog +impl crate::trace::Trace for IconDialog where - T: StringType, U: crate::trace::Trace, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { diff --git a/core/embed/rust/src/ui/model_mercury/component/fido.rs b/core/embed/rust/src/ui/model_mercury/component/fido.rs index 4da615068e..93c279ec9b 100644 --- a/core/embed/rust/src/ui/model_mercury/component/fido.rs +++ b/core/embed/rust/src/ui/model_mercury/component/fido.rs @@ -1,14 +1,17 @@ -use crate::ui::{ - component::{image::Image, Child, Component, Event, EventCtx, Label}, - display, - geometry::{Insets, Rect}, - model_mercury::component::{ - fido_icons::get_fido_icon_data, - swipe::{Swipe, SwipeDirection}, - theme, ScrollBar, +use crate::{ + strutil::TString, + ui::{ + component::{image::Image, Child, Component, Event, EventCtx, Label}, + display, + geometry::{Insets, Rect}, + model_mercury::component::{ + fido_icons::get_fido_icon_data, + swipe::{Swipe, SwipeDirection}, + theme, ScrollBar, + }, + shape, + shape::Renderer, }, - shape, - shape::Renderer, }; use super::CancelConfirmMsg; @@ -25,10 +28,10 @@ pub enum FidoMsg { Cancelled, } -pub struct FidoConfirm T, T, U> { +pub struct FidoConfirm TString<'static>, U> { page_swipe: Swipe, - app_name: Label, - account_name: Label, + app_name: Label<'static>, + account_name: Label<'static>, icon: Child, /// Function/closure that will return appropriate page on demand. get_account: F, @@ -37,20 +40,19 @@ pub struct FidoConfirm T, T, U> { controls: U, } -impl FidoConfirm +impl FidoConfirm where - F: Fn(usize) -> T, - T: AsRef + From<&'static str>, + F: Fn(usize) -> TString<'static>, U: Component, { pub fn new( - app_name: T, + app_name: TString<'static>, get_account: F, page_count: usize, - icon_name: Option, + icon_name: Option>, controls: U, ) -> Self { - let icon_data = get_fido_icon_data(icon_name.as_ref()); + let icon_data = get_fido_icon_data(icon_name); // Preparing scrollbar and setting its page-count. let mut scrollbar = ScrollBar::horizontal(); @@ -118,10 +120,9 @@ where } } -impl Component for FidoConfirm +impl Component for FidoConfirm where - F: Fn(usize) -> T, - T: AsRef + From<&'static str>, + F: Fn(usize) -> TString<'static>, U: Component, { type Msg = FidoMsg; @@ -200,8 +201,8 @@ where // Account name is optional. // Showing it only if it differs from app name. // (Dummy requests usually have some text as both app_name and account_name.) - let account_name = self.account_name.text().as_ref(); - let app_name = self.app_name.text().as_ref(); + let account_name = self.account_name.text(); + let app_name = self.app_name.text(); if !account_name.is_empty() && account_name != app_name { self.account_name.paint(); } @@ -230,8 +231,8 @@ where // Account name is optional. // Showing it only if it differs from app name. // (Dummy requests usually have some text as both app_name and account_name.) - let account_name = self.account_name.text().as_ref(); - let app_name = self.app_name.text().as_ref(); + let account_name = self.account_name.text(); + let app_name = self.app_name.text(); if !account_name.is_empty() && account_name != app_name { self.account_name.render(target); } @@ -251,9 +252,9 @@ where } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for FidoConfirm +impl crate::trace::Trace for FidoConfirm where - F: Fn(usize) -> T, + F: Fn(usize) -> TString<'static>, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.component("FidoConfirm"); diff --git a/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs b/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs index 5a3d675757..730232cf4d 100644 --- a/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs +++ b/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs @@ -3,6 +3,9 @@ //! do not edit manually! +use crate::strutil::TString; + + const ICON_APPLE: &[u8] = include_res!("model_mercury/res/fido/icon_apple.toif"); const ICON_AWS: &[u8] = include_res!("model_mercury/res/fido/icon_aws.toif"); const ICON_BINANCE: &[u8] = include_res!("model_mercury/res/fido/icon_binance.toif"); @@ -39,9 +42,9 @@ const ICON_WEBAUTHN: &[u8] = include_res!("model_mercury/res/fido/icon_webauthn. /// Translates icon name into its data. /// Returns default `ICON_WEBAUTHN` when the icon is not found or name not /// supplied. -pub fn get_fido_icon_data>(icon_name: Option) -> &'static [u8] { +pub fn get_fido_icon_data(icon_name: Option>) -> &'static [u8] { if let Some(icon_name) = icon_name { - match icon_name.as_ref() { + icon_name.map(|c| match c { "apple" => ICON_APPLE, "aws" => ICON_AWS, "binance" => ICON_BINANCE, @@ -73,7 +76,7 @@ pub fn get_fido_icon_data>(icon_name: Option) -> &'static [u8] "stripe" => ICON_STRIPE, "tutanota" => ICON_TUTANOTA, _ => ICON_WEBAUTHN, - } + }) } else { ICON_WEBAUTHN } diff --git a/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs.mako b/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs.mako index 068360df56..5b832e9a27 100644 --- a/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs.mako +++ b/core/embed/rust/src/ui/model_mercury/component/fido_icons.rs.mako @@ -2,6 +2,9 @@ //! (by running `make templates` in `core`) //! do not edit manually! + +use crate::strutil::TString; + <% icons: list[tuple[str, str]] = [] for app in fido: @@ -21,14 +24,14 @@ const ICON_WEBAUTHN: &[u8] = include_res!("model_mercury/res/fido/icon_webauthn. /// Translates icon name into its data. /// Returns default `ICON_WEBAUTHN` when the icon is not found or name not /// supplied. -pub fn get_fido_icon_data>(icon_name: Option) -> &'static [u8] { +pub fn get_fido_icon_data(icon_name: Option>) -> &'static [u8] { if let Some(icon_name) = icon_name { - match icon_name.as_ref() { + icon_name.map(|c| match c { % for icon_name, var_name in icons: "${icon_name}" => ICON_${var_name}, % endfor _ => ICON_WEBAUTHN, - } + }) } else { ICON_WEBAUTHN } 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 aa8adf7062..bd74351e01 100644 --- a/core/embed/rust/src/ui/model_mercury/component/frame.rs +++ b/core/embed/rust/src/ui/model_mercury/component/frame.rs @@ -62,7 +62,7 @@ where self } - pub fn with_subtitle(mut self, subtitle: U) -> Self { + pub fn with_subtitle(mut self, subtitle: TString<'static>) -> Self { let style = theme::TEXT_SUB; self.title = Child::new(self.title.into_inner().top_aligned()); self.subtitle = Some(Child::new(Label::new( diff --git a/core/embed/rust/src/ui/model_mercury/component/homescreen/mod.rs b/core/embed/rust/src/ui/model_mercury/component/homescreen/mod.rs index da7418633a..62e95cc0f2 100644 --- a/core/embed/rust/src/ui/model_mercury/component/homescreen/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/component/homescreen/mod.rs @@ -288,6 +288,13 @@ impl Component for Homescreen { } self.label.map(|t| { + let r = Rect::new(Point::new(6, 198), Point::new(234, 233)); + shape::Bar::new(r) + .with_bg(Color::black()) + .with_alpha(89) + .with_radius(3) + .render(target); + let style = theme::TEXT_DEMIBOLD; let pos = Point::new(self.pad.area.center().x, LABEL_Y); shape::Text::new(pos, t) @@ -355,15 +362,15 @@ impl crate::trace::Trace for Homescreen { } } -pub struct Lockscreen { - label: TString<'static>, +pub struct Lockscreen<'a> { + label: TString<'a>, custom_image: Option>, bootscreen: bool, coinjoin_authorized: bool, } -impl Lockscreen { - pub fn new(label: TString<'static>, bootscreen: bool, coinjoin_authorized: bool) -> Self { +impl<'a> Lockscreen<'a> { + pub fn new(label: TString<'a>, bootscreen: bool, coinjoin_authorized: bool) -> Self { Lockscreen { label, custom_image: get_user_custom_image().ok(), @@ -373,7 +380,7 @@ impl Lockscreen { } } -impl Component for Lockscreen { +impl Component for Lockscreen<'_> { type Msg = HomescreenMsg; fn place(&mut self, bounds: Rect) -> Rect { @@ -470,7 +477,7 @@ impl Component for Lockscreen { shape::JpegImage::new(center, img_data) .with_align(Alignment2D::CENTER) .with_blur(4) - .with_dim(130) + .with_dim(140) .render(target); } else if is_image_toif(img_data) { shape::ToifImage::new(center, unwrap!(Toif::new(img_data))) @@ -591,7 +598,7 @@ fn is_image_toif(buffer: &[u8]) -> bool { } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for Lockscreen { +impl crate::trace::Trace for Lockscreen<'_> { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.component("Lockscreen"); } diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs index d4716494c7..8697af3683 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/bip39.rs @@ -23,9 +23,9 @@ use heapless::String; const MAX_LENGTH: usize = 8; pub struct Bip39Input { - button: Button<&'static str>, + button: Button<>, // used only to keep track of suggestion text color - button_suggestion: Button<&'static str>, + button_suggestion: Button<>, textbox: TextBox, multi_tap: MultiTapKeyboard, options_num: Option, @@ -228,7 +228,7 @@ impl Bip39Input { // Styling the input to reflect already filled word Self { button: Button::with_icon(theme::ICON_LIST_CHECK).styled(theme::button_pin_confirm()), - textbox: TextBox::new(String::from(word)), + textbox: TextBox::new(unwrap!(String::try_from(word))), multi_tap: MultiTapKeyboard::new(), options_num: bip39::options_num(word), suggested_word: bip39::complete_word(word), @@ -310,7 +310,7 @@ impl Bip39Input { // Disabled button. self.button.disable(ctx); self.button.set_stylesheet(ctx, theme::button_pin()); - self.button.set_content(ctx, ButtonContent::Text("")); + self.button.set_content(ctx, ButtonContent::Text("".into())); } } } diff --git a/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs b/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs index ed8bd2c84c..def0f6897b 100644 --- a/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs +++ b/core/embed/rust/src/ui/model_mercury/component/keyboard/mnemonic.rs @@ -1,11 +1,14 @@ -use crate::ui::{ - component::{maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe}, - geometry::{Alignment2D, Grid, Offset, Rect}, - model_mercury::{ - component::{Button, ButtonMsg, Swipe, SwipeDirection}, - theme, +use crate::{ + strutil::TString, + ui::{ + component::{maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe}, + geometry::{Alignment2D, Grid, Offset, Rect}, + model_mercury::{ + component::{Button, ButtonMsg, Swipe, SwipeDirection}, + theme, + }, + shape::Renderer, }, - shape::Renderer, }; pub const MNEMONIC_KEY_COUNT: usize = 9; @@ -15,27 +18,26 @@ pub enum MnemonicKeyboardMsg { Previous, } -pub struct MnemonicKeyboard { +pub struct MnemonicKeyboard { /// Initial prompt, displayed on empty input. - prompt: Child>>, + prompt: Child>>, /// Backspace button. - back: Child>>, + back: Child>, /// Input area, acting as the auto-complete and confirm button. input: Child>, /// Key buttons. - keys: [Child>; MNEMONIC_KEY_COUNT], + keys: [Child