refactor(core/rust/ui): text theme struct

[no changelog]
pull/2470/head
Martin Milata 2 years ago
parent 20ac679651
commit 005e4203a7

@ -12,24 +12,36 @@ use crate::ui::{
};
use super::layout::{
DefaultTextTheme, LayoutFit, LayoutSink, LineBreaking, Op, PageBreaking, TextLayout,
TextRenderer,
LayoutFit, LayoutSink, LineBreaking, Op, PageBreaking, TextLayout, TextRenderer, TextStyle,
};
pub const MAX_ARGUMENTS: usize = 6;
pub struct FormattedText<F, T> {
layout: TextLayout,
fonts: FormattedFonts,
format: F,
args: LinearMap<&'static str, T, MAX_ARGUMENTS>,
char_offset: usize,
}
pub struct FormattedFonts {
/// Font used to format `{normal}`.
pub normal: Font,
/// Font used to format `{medium}`.
pub medium: Font,
/// Font used to format `{bold}`.
pub bold: Font,
/// Font used to format `{mono}`.
pub mono: Font,
}
impl<F, T> FormattedText<F, T> {
pub fn new<D: DefaultTextTheme>(format: F) -> Self {
pub fn new(style: TextStyle, fonts: FormattedFonts, format: F) -> Self {
Self {
format,
layout: TextLayout::new::<D>(),
fonts,
layout: TextLayout::new(style),
args: LinearMap::new(),
char_offset: 0,
}
@ -49,22 +61,22 @@ impl<F, T> FormattedText<F, T> {
}
pub fn with_text_font(mut self, text_font: Font) -> Self {
self.layout.text_font = text_font;
self.layout.style.text_font = text_font;
self
}
pub fn with_text_color(mut self, text_color: Color) -> Self {
self.layout.text_color = text_color;
self.layout.style.text_color = text_color;
self
}
pub fn with_line_breaking(mut self, line_breaking: LineBreaking) -> Self {
self.layout.line_breaking = line_breaking;
self.layout.style.line_breaking = line_breaking;
self
}
pub fn with_page_breaking(mut self, page_breaking: PageBreaking) -> Self {
self.layout.page_breaking = page_breaking;
self.layout.style.page_breaking = page_breaking;
self
}
@ -91,10 +103,10 @@ where
let mut ops = Op::skip_n_text_bytes(
Tokenizer::new(self.format.as_ref()).flat_map(|arg| match arg {
Token::Literal(literal) => Some(Op::Text(literal)),
Token::Argument("mono") => Some(Op::Font(self.layout.mono_font)),
Token::Argument("bold") => Some(Op::Font(self.layout.bold_font)),
Token::Argument("normal") => Some(Op::Font(self.layout.normal_font)),
Token::Argument("medium") => Some(Op::Font(self.layout.medium_font)),
Token::Argument("mono") => Some(Op::Font(self.fonts.mono)),
Token::Argument("bold") => Some(Op::Font(self.fonts.bold)),
Token::Argument("normal") => Some(Op::Font(self.fonts.normal)),
Token::Argument("medium") => Some(Op::Font(self.fonts.medium)),
Token::Argument(argument) => self
.args
.get(argument)

@ -37,72 +37,59 @@ pub struct TextLayout {
/// negative.
pub padding_bottom: i32,
/// Background color.
pub background_color: Color,
/// Text color. Can be overridden by `Op::Color`.
pub text_color: Color,
/// Fonts, colors, line/page breaking behavior.
pub style: TextStyle,
}
#[derive(Copy, Clone)]
pub struct TextStyle {
/// Text font ID. Can be overridden by `Op::Font`.
pub text_font: Font,
/// Text color. Can be overridden by `Op::Color`.
pub text_color: Color,
/// Background color.
pub background_color: Color,
/// Specifies which line-breaking strategy to use.
pub line_breaking: LineBreaking,
/// Font used for drawing the word-breaking hyphen.
pub hyphen_font: Font,
/// Foreground color used for drawing the hyphen.
pub hyphen_color: Color,
/// Specifies what to do at the end of the page.
pub page_breaking: PageBreaking,
/// Font used for drawing the ellipsis.
pub ellipsis_font: Font,
/// Foreground color used for drawing the ellipsis.
pub ellipsis_color: Color,
/// Font used to format `{normal}`.
pub normal_font: Font,
/// Font used to format `{medium}`.
pub medium_font: Font,
/// Font used to format `{bold}`.
pub bold_font: Font,
/// Font used to format `{mono}`.
pub mono_font: Font,
/// Specifies which line-breaking strategy to use.
pub line_breaking: LineBreaking,
/// Specifies what to do at the end of the page.
pub page_breaking: PageBreaking,
}
pub trait DefaultTextTheme {
const BACKGROUND_COLOR: Color;
const TEXT_FONT: Font;
const TEXT_COLOR: Color;
const HYPHEN_FONT: Font;
const HYPHEN_COLOR: Color;
const ELLIPSIS_FONT: Font;
const ELLIPSIS_COLOR: Color;
const NORMAL_FONT: Font;
const MEDIUM_FONT: Font;
const BOLD_FONT: Font;
const MONO_FONT: Font;
impl TextStyle {
pub const fn new(
text_font: Font,
text_color: Color,
background_color: Color,
hyphen_color: Color,
ellipsis_color: Color,
) -> Self {
TextStyle {
text_font,
text_color,
background_color,
hyphen_color,
ellipsis_color,
line_breaking: LineBreaking::BreakAtWhitespace,
page_breaking: PageBreaking::CutAndInsertEllipsis,
}
}
}
impl TextLayout {
/// Create a new text layout, with empty size and default text parameters
/// filled from `T`.
pub fn new<T: DefaultTextTheme>() -> Self {
pub fn new(style: TextStyle) -> Self {
Self {
bounds: Rect::zero(),
padding_top: 0,
padding_bottom: 0,
background_color: T::BACKGROUND_COLOR,
text_color: T::TEXT_COLOR,
text_font: T::TEXT_FONT,
line_breaking: LineBreaking::BreakAtWhitespace,
hyphen_font: T::HYPHEN_FONT,
hyphen_color: T::HYPHEN_COLOR,
page_breaking: PageBreaking::CutAndInsertEllipsis,
ellipsis_font: T::ELLIPSIS_FONT,
ellipsis_color: T::ELLIPSIS_COLOR,
normal_font: T::NORMAL_FONT,
medium_font: T::MEDIUM_FONT,
bold_font: T::BOLD_FONT,
mono_font: T::MONO_FONT,
style,
}
}
@ -112,7 +99,7 @@ impl TextLayout {
}
pub fn initial_cursor(&self) -> Point {
self.bounds.top_left() + Offset::y(self.text_font.text_height() + self.padding_top)
self.bounds.top_left() + Offset::y(self.style.text_font.text_height() + self.padding_top)
}
pub fn fit_text(&self, text: &str) -> LayoutFit {
@ -135,10 +122,10 @@ impl TextLayout {
for op in ops {
match op {
Op::Color(color) => {
self.text_color = color;
self.style.text_color = color;
}
Op::Font(font) => {
self.text_font = font;
self.style.text_font = font;
}
Op::Text(text) => match self.layout_text(text, cursor, sink) {
LayoutFit::Fitting {
@ -189,9 +176,8 @@ impl TextLayout {
let span = Span::fit_horizontally(
remaining_text,
self.bounds.x1 - cursor.x,
self.text_font,
self.hyphen_font,
self.line_breaking,
self.style.text_font,
self.style.line_breaking,
);
// Report the span at the cursor position.
@ -216,7 +202,7 @@ impl TextLayout {
// Append ellipsis to indicate more content is available, but only if we
// haven't already appended a hyphen.
let should_append_ellipsis =
matches!(self.page_breaking, PageBreaking::CutAndInsertEllipsis)
matches!(self.style.page_breaking, PageBreaking::CutAndInsertEllipsis)
&& !span.insert_hyphen_before_line_break;
if should_append_ellipsis {
sink.ellipsis(*cursor, self);
@ -253,7 +239,7 @@ impl TextLayout {
fn layout_height(&self, init_cursor: Point, end_cursor: Point) -> i32 {
self.padding_top
+ self.text_font.text_height()
+ self.style.text_font.text_height()
+ (end_cursor.y - init_cursor.y)
+ self.padding_bottom
}
@ -295,9 +281,9 @@ impl LayoutSink for TextRenderer {
display::text(
cursor,
text,
layout.text_font,
layout.text_color,
layout.background_color,
layout.style.text_font,
layout.style.text_color,
layout.style.background_color,
);
}
@ -305,9 +291,9 @@ impl LayoutSink for TextRenderer {
display::text(
cursor,
"-",
layout.hyphen_font,
layout.hyphen_color,
layout.background_color,
layout.style.text_font,
layout.style.hyphen_color,
layout.style.background_color,
);
}
@ -315,9 +301,9 @@ impl LayoutSink for TextRenderer {
display::text(
cursor,
"...",
layout.ellipsis_font,
layout.ellipsis_color,
layout.background_color,
layout.style.text_font,
layout.style.ellipsis_color,
layout.style.background_color,
);
}
}
@ -401,7 +387,6 @@ impl Span {
text: &str,
max_width: i32,
text_font: impl GlyphMetrics,
hyphen_font: impl GlyphMetrics,
breaking: LineBreaking,
) -> Self {
const ASCII_LF: char = '\n';
@ -413,7 +398,7 @@ impl Span {
ch == ASCII_SPACE || ch == ASCII_LF || ch == ASCII_CR
}
let hyphen_width = hyphen_font.char_width(ASCII_HYPHEN);
let hyphen_width = text_font.char_width(ASCII_HYPHEN);
// The span we return in case the line has to break. We mutate it in the
// possible break points, and its initial value is returned in case no text
@ -563,7 +548,6 @@ mod tests {
remaining_text,
max_width,
FIXED_FONT,
FIXED_FONT,
LineBreaking::BreakAtWhitespace,
);
spans.push((

@ -2,3 +2,5 @@ pub mod formatted;
mod iter;
pub mod layout;
pub mod paragraphs;
pub use layout::TextStyle;

@ -2,11 +2,10 @@ use heapless::Vec;
use crate::ui::{
component::{Component, Event, EventCtx, Never, Paginate},
display::Font,
geometry::{Dimensions, Insets, LinearPlacement, Rect},
};
use super::layout::{DefaultTextTheme, LayoutFit, TextLayout};
use super::layout::{LayoutFit, TextLayout, TextStyle};
pub const MAX_PARAGRAPHS: usize = 6;
/// Maximum space between paragraphs. Actual result may be smaller (even 0) if
@ -53,17 +52,16 @@ where
self
}
pub fn add<D: DefaultTextTheme>(mut self, text_font: Font, content: T) -> Self {
pub fn add(mut self, style: TextStyle, content: T) -> Self {
if content.as_ref().is_empty() {
return self;
}
let paragraph = Paragraph::new(
content,
TextLayout {
text_font,
padding_top: PARAGRAPH_TOP_SPACE,
padding_bottom: PARAGRAPH_BOTTOM_SPACE,
..TextLayout::new::<D>()
..TextLayout::new(style)
},
);
if self.list.push(paragraph).is_err() {

@ -72,7 +72,7 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let obj = LayoutObj::new(Frame::new(
title,
ButtonPage::new(
FormattedText::new::<theme::T1DefaultText>(format)
FormattedText::new(theme::TEXT_NORMAL, theme::FORMATTED, format)
.with("action", action.unwrap_or_default())
.with("description", description.unwrap_or_default()),
theme::BG,
@ -94,11 +94,8 @@ extern "C" fn new_confirm_text(n_args: usize, args: *const Obj, kwargs: *mut Map
title,
ButtonPage::new(
Paragraphs::new()
.add::<theme::T1DefaultText>(
theme::FONT_NORMAL,
description.unwrap_or_default(),
)
.add::<theme::T1DefaultText>(theme::FONT_BOLD, data),
.add(theme::TEXT_NORMAL, description.unwrap_or_default())
.add(theme::TEXT_BOLD, data),
theme::BG,
),
))?;
@ -178,7 +175,9 @@ mod tests {
#[test]
fn trace_example_layout() {
let mut layout = Dialog::new(
FormattedText::new::<theme::T1DefaultText>(
FormattedText::new(
theme::TEXT_NORMAL,
theme::FORMATTED,
"Testing text layout, with some text, and some more text. And {param}",
)
.with("param", "parameters!"),
@ -208,7 +207,9 @@ arameters! > left:<Button text:Left > right:<Button text:Right > >"#
let mut layout = Frame::new(
"Please confirm",
Dialog::new(
FormattedText::new::<theme::T1DefaultText>(
FormattedText::new(
theme::TEXT_NORMAL,
theme::FORMATTED,
"Testing text layout, with some text, and some more text. And {param}",
)
.with("param", "parameters!"),

@ -1,5 +1,5 @@
use crate::ui::{
component::text::layout::DefaultTextTheme,
component::text::{formatted::FormattedFonts, TextStyle},
display::{Color, Font},
};
@ -48,19 +48,14 @@ pub fn button_cancel() -> ButtonStyleSheet {
}
}
pub struct T1DefaultText;
pub const TEXT_NORMAL: TextStyle = TextStyle::new(FONT_NORMAL, FG, BG, FG, FG);
pub const TEXT_MEDIUM: TextStyle = TextStyle::new(FONT_MEDIUM, FG, BG, FG, FG);
pub const TEXT_BOLD: TextStyle = TextStyle::new(FONT_BOLD, FG, BG, FG, FG);
pub const TEXT_MONO: TextStyle = TextStyle::new(FONT_MONO, FG, BG, FG, FG);
impl DefaultTextTheme for T1DefaultText {
const BACKGROUND_COLOR: Color = BG;
const TEXT_FONT: Font = FONT_NORMAL;
const TEXT_COLOR: Color = FG;
const HYPHEN_FONT: Font = FONT_NORMAL;
const HYPHEN_COLOR: Color = FG;
const ELLIPSIS_FONT: Font = FONT_NORMAL;
const ELLIPSIS_COLOR: Color = FG;
const NORMAL_FONT: Font = FONT_NORMAL;
const MEDIUM_FONT: Font = FONT_MEDIUM;
const BOLD_FONT: Font = FONT_BOLD;
const MONO_FONT: Font = FONT_MONO;
}
pub const FORMATTED: FormattedFonts = FormattedFonts {
normal: FONT_NORMAL,
medium: FONT_MEDIUM,
bold: FONT_BOLD,
mono: FONT_MONO,
};

@ -2,16 +2,14 @@ use crate::{
time::Instant,
ui::{
component::{
text::{layout::DefaultTextTheme, paragraphs::Paragraphs},
Child, Component, ComponentExt, Event, EventCtx, Label, LabelStyle, Pad,
text::paragraphs::Paragraphs, Child, Component, ComponentExt, Event, EventCtx, Label,
LabelStyle, Pad,
},
constant::screen,
display::{Color, Font},
geometry::{Alignment, Insets, LinearPlacement, Point, Rect},
model_tr::{
component::{Button, ButtonMsg, ButtonPos, ResultAnim, ResultAnimMsg},
theme,
theme::{TRDefaultText, FONT_BOLD, FONT_MEDIUM},
theme::{self, FONT_BOLD},
},
},
};
@ -31,23 +29,6 @@ pub struct ResultPopup {
autoclose: bool,
}
pub struct MessageText;
impl DefaultTextTheme for MessageText {
const BACKGROUND_COLOR: Color = theme::BG;
const TEXT_FONT: Font = FONT_MEDIUM;
const TEXT_COLOR: Color = theme::FG;
const HYPHEN_FONT: Font = FONT_MEDIUM;
const HYPHEN_COLOR: Color = theme::FG;
const ELLIPSIS_FONT: Font = FONT_MEDIUM;
const ELLIPSIS_COLOR: Color = theme::FG;
const NORMAL_FONT: Font = FONT_MEDIUM;
const MEDIUM_FONT: Font = theme::FONT_MEDIUM;
const BOLD_FONT: Font = theme::FONT_BOLD;
const MONO_FONT: Font = theme::FONT_MONO;
}
const ANIM_SIZE: i32 = 18;
const BUTTON_HEIGHT: i32 = 13;
const ANIM_SPACE: i32 = 11;
@ -63,7 +44,7 @@ impl ResultPopup {
button_text: Option<&'static str>,
) -> Self {
let p1 = Paragraphs::new()
.add::<TRDefaultText>(FONT_MEDIUM, text)
.add(theme::TEXT_MEDIUM, text)
.with_placement(LinearPlacement::vertical().align_at_center());
let button = button_text.map(|t| {

@ -72,7 +72,7 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let obj = LayoutObj::new(Frame::new(
title,
ButtonPage::new(
FormattedText::new::<theme::TRDefaultText>(format)
FormattedText::new(theme::TEXT_NORMAL, theme::FORMATTED, format)
.with("action", action.unwrap_or_default())
.with("description", description.unwrap_or_default()),
theme::BG,
@ -94,11 +94,8 @@ extern "C" fn new_confirm_text(n_args: usize, args: *const Obj, kwargs: *mut Map
title,
ButtonPage::new(
Paragraphs::new()
.add::<theme::TRDefaultText>(
theme::FONT_NORMAL,
description.unwrap_or_default(),
)
.add::<theme::TRDefaultText>(theme::FONT_BOLD, data),
.add(theme::TEXT_NORMAL, description.unwrap_or_default())
.add(theme::TEXT_BOLD, data),
theme::BG,
),
))?;
@ -178,7 +175,9 @@ mod tests {
#[test]
fn trace_example_layout() {
let mut layout = Dialog::new(
FormattedText::new::<theme::TRDefaultText>(
FormattedText::new(
theme::TEXT_NORMAL,
theme::FORMATTED,
"Testing text layout, with some text, and some more text. And {param}",
)
.with("param", "parameters!"),
@ -208,7 +207,9 @@ arameters! > left:<Button text:Left > right:<Button text:Right > >"#
let mut layout = Frame::new(
"Please confirm",
Dialog::new(
FormattedText::new::<theme::TRDefaultText>(
FormattedText::new(
theme::TEXT_NORMAL,
theme::FORMATTED,
"Testing text layout, with some text, and some more text. And {param}",
)
.with("param", "parameters!"),

@ -1,5 +1,5 @@
use crate::ui::{
component::text::layout::DefaultTextTheme,
component::text::{formatted::FormattedFonts, TextStyle},
display::{Color, Font},
model_tr::component::{LoaderStyle, LoaderStyleSheet},
};
@ -62,19 +62,14 @@ pub fn loader_default() -> LoaderStyleSheet {
}
}
pub struct TRDefaultText;
pub const TEXT_NORMAL: TextStyle = TextStyle::new(FONT_NORMAL, FG, BG, FG, FG);
pub const TEXT_MEDIUM: TextStyle = TextStyle::new(FONT_MEDIUM, FG, BG, FG, FG);
pub const TEXT_BOLD: TextStyle = TextStyle::new(FONT_BOLD, FG, BG, FG, FG);
pub const TEXT_MONO: TextStyle = TextStyle::new(FONT_MONO, FG, BG, FG, FG);
impl DefaultTextTheme for TRDefaultText {
const BACKGROUND_COLOR: Color = BG;
const TEXT_FONT: Font = FONT_NORMAL;
const TEXT_COLOR: Color = FG;
const HYPHEN_FONT: Font = FONT_NORMAL;
const HYPHEN_COLOR: Color = FG;
const ELLIPSIS_FONT: Font = FONT_NORMAL;
const ELLIPSIS_COLOR: Color = FG;
const NORMAL_FONT: Font = FONT_NORMAL;
const MEDIUM_FONT: Font = FONT_MEDIUM;
const BOLD_FONT: Font = FONT_BOLD;
const MONO_FONT: Font = FONT_MONO;
}
pub const FORMATTED: FormattedFonts = FormattedFonts {
normal: FONT_NORMAL,
medium: FONT_MEDIUM,
bold: FONT_BOLD,
mono: FONT_MONO,
};

@ -380,12 +380,12 @@ mod tests {
fn paragraphs_single() {
let mut page = SwipePage::new(
Paragraphs::new()
.add::<theme::TTDefaultText>(
theme::FONT_NORMAL,
.add(
theme::TEXT_NORMAL,
"This is the first paragraph and it should fit on the screen entirely.",
)
.add::<theme::TTDefaultText>(
theme::FONT_BOLD,
.add(
theme::TEXT_BOLD,
"Second, bold, paragraph should also fit on the screen whole I think.",
),
Empty,
@ -406,8 +406,8 @@ mod tests {
fn paragraphs_one_long() {
let mut page = SwipePage::new(
Paragraphs::new()
.add::<theme::TTDefaultText>(
theme::FONT_BOLD,
.add(
theme::TEXT_BOLD,
"This is somewhat long paragraph that goes on and on and on and on and on and will definitely not fit on just a single screen. You have to swipe a bit to see all the text it contains I guess. There's just so much letters in it.",
),
Empty,
@ -433,16 +433,16 @@ mod tests {
fn paragraphs_three_long() {
let mut page = SwipePage::new(
Paragraphs::new()
.add::<theme::TTDefaultText>(
theme::FONT_BOLD,
.add(
theme::TEXT_BOLD,
"This paragraph is using a bold font. It doesn't need to be all that long.",
)
.add::<theme::TTDefaultText>(
theme::FONT_MONO,
.add(
theme::TEXT_MONO,
"And this one is using MONO. Monospace is nice for numbers, they have the same width and can be scanned quickly. Even if they span several pages or something.",
)
.add::<theme::TTDefaultText>(
theme::FONT_BOLD,
.add(
theme::TEXT_BOLD,
"Let's add another one for a good measure. This one should overflow all the way to the third page with a bit of luck.",
),
Empty,

@ -206,12 +206,12 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let mut paragraphs = Paragraphs::new();
if !reverse {
paragraphs = paragraphs
.add::<theme::TTDefaultText>(theme::FONT_BOLD, action)
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description);
.add(theme::TEXT_BOLD, action)
.add(theme::TEXT_NORMAL, description);
} else {
paragraphs = paragraphs
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description)
.add::<theme::TTDefaultText>(theme::FONT_BOLD, action);
.add(theme::TEXT_NORMAL, description)
.add(theme::TEXT_BOLD, action);
}
paragraphs
};
@ -246,9 +246,9 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description)
.add::<theme::TTDefaultText>(theme::FONT_BOLD, extra)
.add::<theme::TTDefaultText>(theme::FONT_MONO, data);
.add(theme::TEXT_NORMAL, description)
.add(theme::TEXT_BOLD, extra)
.add(theme::TEXT_MONO, data);
let obj = if hold {
LayoutObj::new(
@ -302,8 +302,8 @@ extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut M
let verb = "NEXT";
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description)
.add::<theme::TTDefaultText>(theme::FONT_MONO, value);
.add(theme::TEXT_NORMAL, description)
.add(theme::TEXT_MONO, value);
let buttons = Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL),
@ -326,8 +326,8 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
let value: StrBuffer = kwargs.get(Qstr::MP_QSTR_value)?.try_into()?;
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description)
.add::<theme::TTDefaultText>(theme::FONT_MONO, value);
.add(theme::TEXT_NORMAL, description)
.add(theme::TEXT_MONO, value);
let obj = LayoutObj::new(
Frame::new(title, SwipeHoldPage::new(paragraphs, theme::BG)).into_child(),
@ -343,10 +343,10 @@ extern "C" fn new_confirm_joint_total(n_args: usize, args: *const Obj, kwargs: *
let total_amount: StrBuffer = kwargs.get(Qstr::MP_QSTR_total_amount)?.try_into()?;
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "You are contributing:".into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, spending_amount)
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "To the total amount:".into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, total_amount);
.add(theme::TEXT_NORMAL, "You are contributing:".into())
.add(theme::TEXT_MONO, spending_amount)
.add(theme::TEXT_NORMAL, "To the total amount:".into())
.add(theme::TEXT_MONO, total_amount);
let obj = LayoutObj::new(
Frame::new(
@ -374,13 +374,13 @@ extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs:
};
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "Address:".into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, address)
.add(theme::TEXT_NORMAL, "Address:".into())
.add(theme::TEXT_MONO, address)
// FIXME pagebreak
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description.into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, amount_change)
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "New amount:".into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, amount_new);
.add(theme::TEXT_NORMAL, description.into())
.add(theme::TEXT_MONO, amount_change)
.add(theme::TEXT_NORMAL, "New amount:".into())
.add(theme::TEXT_MONO, amount_new);
let buttons = Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL),
@ -413,10 +413,10 @@ extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *m
};
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, description.into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, change)
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "\nTransaction fee:".into())
.add::<theme::TTDefaultText>(theme::FONT_MONO, total_fee_new);
.add(theme::TEXT_NORMAL, description.into())
.add(theme::TEXT_MONO, change)
.add(theme::TEXT_NORMAL, "\nTransaction fee:".into())
.add(theme::TEXT_MONO, total_fee_new);
let buttons = Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL),
@ -481,14 +481,13 @@ extern "C" fn new_confirm_payment_request(
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let memos: Obj = kwargs.get(Qstr::MP_QSTR_memos)?;
let mut paragraphs =
Paragraphs::new().add::<theme::TTDefaultText>(theme::FONT_NORMAL, description);
let mut paragraphs = Paragraphs::new().add(theme::TEXT_NORMAL, description);
let mut iter_buf = IterBuf::new();
let iter = Iter::try_from_obj_with_buf(memos, &mut iter_buf)?;
for memo in iter {
let text: StrBuffer = memo.try_into()?;
paragraphs = paragraphs.add::<theme::TTDefaultText>(theme::FONT_NORMAL, text);
paragraphs = paragraphs.add(theme::TEXT_NORMAL, text);
}
let buttons = Button::cancel_info_confirm("CONFIRM", "DETAILS");
@ -512,12 +511,12 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
let max_feerate: StrBuffer = kwargs.get(Qstr::MP_QSTR_max_feerate)?.try_into()?;
let paragraphs = Paragraphs::new()
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "Coin name:".into())
.add::<theme::TTDefaultText>(theme::FONT_BOLD, coin_name)
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "Maximum rounds:".into())
.add::<theme::TTDefaultText>(theme::FONT_BOLD, max_rounds)
.add::<theme::TTDefaultText>(theme::FONT_NORMAL, "Maximum mining fee:".into())
.add::<theme::TTDefaultText>(theme::FONT_BOLD, max_feerate);
.add(theme::TEXT_NORMAL, "Coin name:".into())
.add(theme::TEXT_BOLD, coin_name)
.add(theme::TEXT_NORMAL, "Maximum rounds:".into())
.add(theme::TEXT_BOLD, max_rounds)
.add(theme::TEXT_NORMAL, "Maximum mining fee:".into())
.add(theme::TEXT_BOLD, max_feerate);
let obj = LayoutObj::new(
Frame::new(
@ -761,7 +760,9 @@ mod tests {
let buttons =
Button::cancel_confirm(Button::with_text("Left"), Button::with_text("Right"), 1);
let mut layout = Dialog::new(
FormattedText::new::<theme::TTDefaultText>(
FormattedText::new(
theme::TEXT_NORMAL,
theme::FORMATTED,
"Testing text layout, with some text, and some more text. And {param}",
)
.with("param", "parameters!"),

@ -1,5 +1,8 @@
use crate::ui::{
component::{label::LabelStyle, text::layout::DefaultTextTheme},
component::{
label::LabelStyle,
text::{formatted::FormattedFonts, TextStyle},
},
display::{Color, Font},
geometry::Insets,
};
@ -298,22 +301,17 @@ pub fn loader_default() -> LoaderStyleSheet {
}
}
pub struct TTDefaultText;
pub const TEXT_NORMAL: TextStyle = TextStyle::new(FONT_NORMAL, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_MEDIUM: TextStyle = TextStyle::new(FONT_MEDIUM, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_BOLD: TextStyle = TextStyle::new(FONT_BOLD, FG, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_MONO: TextStyle = TextStyle::new(FONT_MONO, FG, BG, GREY_LIGHT, GREY_LIGHT);
impl DefaultTextTheme for TTDefaultText {
const BACKGROUND_COLOR: Color = BG;
const TEXT_FONT: Font = FONT_NORMAL;
const TEXT_COLOR: Color = FG;
const HYPHEN_FONT: Font = FONT_BOLD;
const HYPHEN_COLOR: Color = GREY_LIGHT;
const ELLIPSIS_FONT: Font = FONT_BOLD;
const ELLIPSIS_COLOR: Color = GREY_LIGHT;
const NORMAL_FONT: Font = FONT_NORMAL;
const MEDIUM_FONT: Font = FONT_MEDIUM;
const BOLD_FONT: Font = FONT_BOLD;
const MONO_FONT: Font = FONT_MONO;
}
pub const FORMATTED: FormattedFonts = FormattedFonts {
normal: FONT_NORMAL,
medium: FONT_MEDIUM,
bold: FONT_BOLD,
mono: FONT_MONO,
};
pub const CONTENT_BORDER: i32 = 5;
pub const KEYBOARD_SPACING: i32 = 8;

@ -6,8 +6,6 @@ from trezor.enums import ButtonRequestType
import trezorui2
from ...components.tt.confirm import Confirm
from ...constants.tt import MONO_ADDR_PER_LINE
from ..common import button_request, interact
if TYPE_CHECKING:
@ -419,8 +417,8 @@ async def confirm_output(
color_to: int = ui.FG, # TODO cleanup @ redesign
to_str: str = " to\n", # TODO cleanup @ redesign
to_paginated: bool = False, # TODO cleanup @ redesign
width: int = MONO_ADDR_PER_LINE,
width_paginated: int = MONO_ADDR_PER_LINE - 1,
width: int = 0, # TODO cleanup @ redesign
width_paginated: int = 0, # TODO cleanup @ redesign
br_code: ButtonRequestType = ButtonRequestType.ConfirmOutput,
icon: str = ui.ICON_SEND,
) -> None:
@ -495,7 +493,7 @@ async def should_show_more(
br_code: ButtonRequestType = ButtonRequestType.Other,
icon: str = ui.ICON_DEFAULT,
icon_color: int = ui.ORANGE_ICON,
confirm: ButtonContent = Confirm.DEFAULT_CONFIRM,
confirm: ButtonContent = None,
major_confirm: bool = False,
) -> bool:
raise NotImplementedError

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save