mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-12 00:10:58 +00:00
WIP: core(rust): format translated strings
This commit is contained in:
parent
c9b50f3cde
commit
2a18a6fb3e
@ -136,6 +136,33 @@ impl<'a> OpTextLayout<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Op::TextFmt(tmpl, arg) => {
|
||||
// Split the template on {0}
|
||||
tmpl.map(|t| {
|
||||
let mut parts = heapless::Vec::<&str, 3>::new();
|
||||
let mut start = 0;
|
||||
while let Some(pos) = t[start..].find("{0}") {
|
||||
let abs_pos = start + pos;
|
||||
// Add the part before {0}
|
||||
unwrap!(parts.push(&t[start..abs_pos]));
|
||||
// Skip the {0}
|
||||
start = abs_pos + 3;
|
||||
}
|
||||
// Add remaining text after last {0}
|
||||
if start < t.len() {
|
||||
unwrap!(parts.push(&t[start..]));
|
||||
}
|
||||
|
||||
for (i, part) in parts.iter().enumerate() {
|
||||
if i > 0 {
|
||||
// Insert the argument between parts
|
||||
arg.map(|t| layout.layout_text(t, cursor, sink));
|
||||
}
|
||||
// Layout the template part
|
||||
layout.layout_text(part, cursor, sink);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,6 +229,10 @@ impl<'a> OpTextLayout<'a> {
|
||||
self.with_new_item(Op::Text(text, false))
|
||||
}
|
||||
|
||||
pub fn text_fmt(self, text_tmpl: TString<'a>, arg1: TString<'a>) -> Self {
|
||||
self.with_new_item(Op::TextFmt(text_tmpl, arg1))
|
||||
}
|
||||
|
||||
pub fn newline(self) -> Self {
|
||||
self.text("\n".into())
|
||||
}
|
||||
@ -276,6 +307,7 @@ pub enum Op<'a> {
|
||||
/// Bool signifies whether this is a split Text Op continued from previous
|
||||
/// page. If true, a leading ellipsis will be rendered.
|
||||
Text(TString<'a>, bool),
|
||||
TextFmt(TString<'a>, TString<'a>),
|
||||
/// Set current text color.
|
||||
Color(Color),
|
||||
/// Set currently used font.
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
error::{value_error, Error},
|
||||
io::BinaryData,
|
||||
micropython::{gc::Gc, iter::IterBuf, list::List, obj::Obj, util},
|
||||
strutil::TString,
|
||||
strutil::{format_i64, TString},
|
||||
translations::TR,
|
||||
ui::{
|
||||
component::{
|
||||
@ -20,7 +20,8 @@ use crate::{
|
||||
},
|
||||
Border, ComponentExt, Empty, FormattedText, Jpeg, Label, Never, Timeout,
|
||||
},
|
||||
geometry,
|
||||
display::Font,
|
||||
geometry::{self, Offset},
|
||||
layout::{
|
||||
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||
util::{ConfirmBlob, PropsList, RecoveryType},
|
||||
@ -57,30 +58,42 @@ impl FirmwareUI for UIBolt {
|
||||
_prompt_screen: bool,
|
||||
_prompt_title: Option<TString<'static>>,
|
||||
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||
let paragraphs = {
|
||||
let formatted = {
|
||||
let action = action.unwrap_or("".into());
|
||||
let description = description.unwrap_or("".into());
|
||||
let mut paragraphs = ParagraphVecShort::new();
|
||||
if !reverse {
|
||||
paragraphs
|
||||
.add(Paragraph::new(&theme::TEXT_DEMIBOLD, action))
|
||||
.add(Paragraph::new(&theme::TEXT_NORMAL, description));
|
||||
|
||||
let action_tmpl: TString = TR::reset__select_word_template.into();
|
||||
let arg1: TString = TString::from("3rd");
|
||||
|
||||
let ops = if !reverse {
|
||||
let mut ops_text = OpTextLayout::new(theme::TEXT_NORMAL);
|
||||
OpTextLayout::new(theme::TEXT_NORMAL)
|
||||
// .text_demibold(action)
|
||||
.text_fmt(action_tmpl, arg1)
|
||||
.newline()
|
||||
.text_normal(description)
|
||||
.offset(Offset::x(Font::NORMAL.text_width(" ")))
|
||||
.text_demibold(description)
|
||||
} else {
|
||||
paragraphs
|
||||
.add(Paragraph::new(&theme::TEXT_NORMAL, description))
|
||||
.add(Paragraph::new(&theme::TEXT_DEMIBOLD, action));
|
||||
}
|
||||
paragraphs.into_paragraphs()
|
||||
OpTextLayout::new(theme::TEXT_NORMAL)
|
||||
.text_normal(description)
|
||||
.newline()
|
||||
.text_demibold(action)
|
||||
};
|
||||
|
||||
FormattedText::new(ops).vertically_centered()
|
||||
};
|
||||
|
||||
let mut page = if hold {
|
||||
ButtonPage::new(paragraphs, theme::BG).with_hold()?
|
||||
ButtonPage::new(formatted, theme::BG).with_hold()?
|
||||
} else {
|
||||
ButtonPage::new(paragraphs, theme::BG).with_cancel_confirm(verb_cancel, verb)
|
||||
ButtonPage::new(formatted, theme::BG).with_cancel_confirm(verb_cancel, verb)
|
||||
};
|
||||
|
||||
if hold && hold_danger {
|
||||
page = page.with_confirm_style(theme::button_danger())
|
||||
}
|
||||
|
||||
let layout = RootComponent::new(Frame::left_aligned(theme::label_title(), title, page));
|
||||
Ok(layout)
|
||||
}
|
||||
|
@ -274,7 +274,13 @@ async def handle_Ping(msg: Ping) -> Success:
|
||||
from trezor.enums import ButtonRequestType as B
|
||||
from trezor.ui.layouts import confirm_action
|
||||
|
||||
await confirm_action("ping", TR.words__confirm, "ping", br_code=B.ProtectCall)
|
||||
await confirm_action(
|
||||
"ping",
|
||||
TR.words__confirm,
|
||||
"action",
|
||||
description="description",
|
||||
br_code=B.ProtectCall,
|
||||
)
|
||||
return Success(message=msg.message)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user