diff --git a/core/embed/rust/src/ui/component/mod.rs b/core/embed/rust/src/ui/component/mod.rs index cabc4c5ba..db9218b41 100644 --- a/core/embed/rust/src/ui/component/mod.rs +++ b/core/embed/rust/src/ui/component/mod.rs @@ -8,4 +8,4 @@ pub mod tuple; pub use base::{Child, Component, Event, EventCtx, Never, TimerToken}; pub use empty::Empty; pub use label::{Label, LabelStyle}; -pub use text::{LineBreaking, PageBreaking, Text, TextLayout}; +pub use text::{FormattedText, LineBreaking, PageBreaking, TextLayout}; diff --git a/core/embed/rust/src/ui/component/text.rs b/core/embed/rust/src/ui/component/text.rs index 05cd71387..209bb1987 100644 --- a/core/embed/rust/src/ui/component/text.rs +++ b/core/embed/rust/src/ui/component/text.rs @@ -14,13 +14,13 @@ use crate::ui::{ pub const MAX_ARGUMENTS: usize = 6; -pub struct Text { +pub struct FormattedText { layout: TextLayout, format: F, args: LinearMap<&'static [u8], T, MAX_ARGUMENTS>, } -impl Text { +impl FormattedText { pub fn new(area: Rect, format: F) -> Self { Self { layout: TextLayout::new::(area), @@ -29,11 +29,6 @@ impl Text { } } - pub fn format(mut self, format: F) -> Self { - self.format = format; - self - } - pub fn with(mut self, key: &'static [u8], value: T) -> Self { if self.args.insert(key, value).is_err() { // Map is full, ignore. @@ -43,6 +38,11 @@ impl Text { self } + pub fn with_format(mut self, format: F) -> Self { + self.format = format; + self + } + pub fn with_text_font(mut self, text_font: Font) -> Self { self.layout.text_font = text_font; self @@ -68,30 +68,28 @@ impl Text { } } -impl Text +impl FormattedText where F: AsRef<[u8]>, T: AsRef<[u8]>, { fn layout_content(&self, sink: &mut dyn LayoutSink) { - self.layout.layout_formatted( - self.format.as_ref(), - |arg| match arg { - Token::Literal(literal) => Some(Op::Text(literal)), - Token::Argument(b"mono") => Some(Op::Font(self.layout.mono_font)), - Token::Argument(b"bold") => Some(Op::Font(self.layout.bold_font)), - Token::Argument(b"normal") => Some(Op::Font(self.layout.normal_font)), - Token::Argument(argument) => self - .args - .get(argument) - .map(|value| Op::Text(value.as_ref())), - }, - sink, - ); + let mut cursor = self.layout.initial_cursor(); + let mut ops = Tokenizer::new(self.format.as_ref()).flat_map(|arg| match arg { + Token::Literal(literal) => Some(Op::Text(literal)), + Token::Argument(b"mono") => Some(Op::Font(self.layout.mono_font)), + Token::Argument(b"bold") => Some(Op::Font(self.layout.bold_font)), + Token::Argument(b"normal") => Some(Op::Font(self.layout.normal_font)), + Token::Argument(argument) => self + .args + .get(argument) + .map(|value| Op::Text(value.as_ref())), + }); + self.layout.layout_ops(&mut ops, &mut cursor, sink); } } -impl Component for Text +impl Component for FormattedText where F: AsRef<[u8]>, T: AsRef<[u8]>, @@ -131,7 +129,7 @@ mod trace { } } - pub struct TraceText<'a, F, T>(pub &'a Text); + pub struct TraceText<'a, F, T>(pub &'a FormattedText); impl<'a, F, T> crate::trace::Trace for TraceText<'a, F, T> where @@ -145,7 +143,7 @@ mod trace { } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for Text +impl crate::trace::Trace for FormattedText where F: AsRef<[u8]>, T: AsRef<[u8]>, @@ -250,26 +248,7 @@ impl TextLayout { ) } - pub fn layout_formatted<'f, 'o, F, I>( - self, - format: &'f [u8], - resolve: F, - sink: &mut dyn LayoutSink, - ) -> LayoutFit - where - F: Fn(Token<'f>) -> I, - I: IntoIterator>, - { - let mut cursor = self.initial_cursor(); - - self.layout_op_stream( - &mut Tokenizer::new(format).flat_map(resolve), - &mut cursor, - sink, - ) - } - - pub fn layout_op_stream<'o>( + pub fn layout_ops<'o>( mut self, ops: &mut dyn Iterator>, cursor: &mut Point, diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index 0f7c9e841..5b3dcf817 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -4,7 +4,7 @@ use crate::{ error::Error, micropython::{buffer::Buffer, obj::Obj}, ui::{ - component::{Child, Text}, + component::{Child, FormattedText}, display, layout::obj::LayoutObj, }, @@ -40,7 +40,7 @@ extern "C" fn ui_layout_new_example(param: Obj) -> Obj { let layout = LayoutObj::new(Child::new(Dialog::new( display::screen(), |area| { - Text::new::(area, param) + FormattedText::new::(area, param) .with(b"some", "a few") .with(b"param", "xx") }, @@ -100,7 +100,7 @@ mod tests { let layout = Child::new(Dialog::new( display::screen(), |area| { - Text::new::( + FormattedText::new::( area, "Testing text layout, with some text, and some more text. And {param}", )