mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-10 15:30:55 +00:00
refactor(core/rust): pass around &str instead of [u8] in most places
This commit is contained in:
parent
785dc7f4d7
commit
32c3320f07
@ -67,7 +67,7 @@ pub fn backlight(val: i32) -> i32 {
|
||||
unsafe { display_backlight(val) }
|
||||
}
|
||||
|
||||
pub fn text(baseline_x: i32, baseline_y: i32, text: &[u8], font: i32, fgcolor: u16, bgcolor: u16) {
|
||||
pub fn text(baseline_x: i32, baseline_y: i32, text: &str, font: i32, fgcolor: u16, bgcolor: u16) {
|
||||
unsafe {
|
||||
display_text(
|
||||
baseline_x,
|
||||
@ -81,10 +81,16 @@ pub fn text(baseline_x: i32, baseline_y: i32, text: &[u8], font: i32, fgcolor: u
|
||||
}
|
||||
}
|
||||
|
||||
pub fn text_width(text: &[u8], font: i32) -> i32 {
|
||||
pub fn text_width(text: &str, font: i32) -> i32 {
|
||||
unsafe { display_text_width(text.as_ptr() as _, text.len() as _, font) }
|
||||
}
|
||||
|
||||
pub fn char_width(ch: char, font: i32) -> i32 {
|
||||
let mut buf = [0u8; 4];
|
||||
let encoding = ch.encode_utf8(&mut buf);
|
||||
text_width(encoding, font)
|
||||
}
|
||||
|
||||
pub fn text_height(font: i32) -> i32 {
|
||||
unsafe { display_text_height(font) }
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ pub struct Label<T> {
|
||||
|
||||
impl<T> Label<T>
|
||||
where
|
||||
T: Deref<Target = [u8]>,
|
||||
T: Deref<Target = str>,
|
||||
{
|
||||
pub fn new(text: T, align: Alignment, style: LabelStyle) -> Self {
|
||||
Self {
|
||||
@ -58,7 +58,7 @@ where
|
||||
|
||||
impl<T> Component for Label<T>
|
||||
where
|
||||
T: Deref<Target = [u8]>,
|
||||
T: Deref<Target = str>,
|
||||
{
|
||||
type Msg = Never;
|
||||
|
||||
|
@ -20,8 +20,8 @@ pub trait Paginate {
|
||||
|
||||
impl<F, T> Paginate for FormattedText<F, T>
|
||||
where
|
||||
F: AsRef<[u8]>,
|
||||
T: AsRef<[u8]>,
|
||||
F: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn page_count(&mut self) -> usize {
|
||||
let mut page_count = 1; // There's always at least one page.
|
||||
|
@ -21,7 +21,7 @@ pub const MAX_ARGUMENTS: usize = 6;
|
||||
pub struct FormattedText<F, T> {
|
||||
layout: TextLayout,
|
||||
format: F,
|
||||
args: LinearMap<&'static [u8], T, MAX_ARGUMENTS>,
|
||||
args: LinearMap<&'static str, T, MAX_ARGUMENTS>,
|
||||
char_offset: usize,
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ impl<F, T> FormattedText<F, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(mut self, key: &'static [u8], value: T) -> Self {
|
||||
pub fn with(mut self, key: &'static str, value: T) -> Self {
|
||||
if self.args.insert(key, value).is_err() {
|
||||
#[cfg(feature = "ui_debug")]
|
||||
panic!("text args map is full");
|
||||
@ -83,18 +83,18 @@ impl<F, T> FormattedText<F, T> {
|
||||
|
||||
impl<F, T> FormattedText<F, T>
|
||||
where
|
||||
F: AsRef<[u8]>,
|
||||
T: AsRef<[u8]>,
|
||||
F: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn layout_content(&self, sink: &mut dyn LayoutSink) -> LayoutFit {
|
||||
let mut cursor = self.layout.initial_cursor();
|
||||
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(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(b"medium") => Some(Op::Font(self.layout.medium_font)),
|
||||
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(argument) => self
|
||||
.args
|
||||
.get(argument)
|
||||
@ -108,8 +108,8 @@ where
|
||||
|
||||
impl<F, T> Component for FormattedText<F, T>
|
||||
where
|
||||
F: AsRef<[u8]>,
|
||||
T: AsRef<[u8]>,
|
||||
F: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
type Msg = Never;
|
||||
|
||||
@ -141,8 +141,8 @@ pub mod trace {
|
||||
|
||||
impl<'a, F, T> crate::trace::Trace for TraceText<'a, F, T>
|
||||
where
|
||||
F: AsRef<[u8]>,
|
||||
T: AsRef<[u8]>,
|
||||
F: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn trace(&self, d: &mut dyn crate::trace::Tracer) {
|
||||
self.0.layout_content(&mut TraceSink(d));
|
||||
@ -153,8 +153,8 @@ pub mod trace {
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<F, T> crate::trace::Trace for FormattedText<F, T>
|
||||
where
|
||||
F: AsRef<[u8]>,
|
||||
T: AsRef<[u8]>,
|
||||
F: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Text");
|
||||
@ -166,9 +166,9 @@ where
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Token<'a> {
|
||||
/// Process literal text content.
|
||||
Literal(&'a [u8]),
|
||||
Literal(&'a str),
|
||||
/// Process argument with specified descriptor.
|
||||
Argument(&'a [u8]),
|
||||
Argument(&'a str),
|
||||
}
|
||||
|
||||
/// Processes a format string into an iterator of `Token`s.
|
||||
@ -182,17 +182,18 @@ pub enum Token<'a> {
|
||||
/// assert!(matches!(parser.next(), Some(Token::Literal(", where you been?"))));
|
||||
/// ```
|
||||
pub struct Tokenizer<'a> {
|
||||
input: &'a [u8],
|
||||
input: &'a str,
|
||||
inner: Peekable<Enumerate<slice::Iter<'a, u8>>>,
|
||||
}
|
||||
|
||||
impl<'a> Tokenizer<'a> {
|
||||
/// Create a new tokenizer for bytes of a formatting string `input`,
|
||||
/// returning an iterator.
|
||||
pub fn new(input: &'a [u8]) -> Self {
|
||||
pub fn new(input: &'a str) -> Self {
|
||||
assert!(input.is_ascii());
|
||||
Self {
|
||||
input,
|
||||
inner: input.iter().enumerate().peekable(),
|
||||
inner: input.as_bytes().iter().enumerate().peekable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -246,26 +247,26 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn tokenizer_yields_expected_tokens() {
|
||||
assert!(Tokenizer::new(b"").eq([]));
|
||||
assert!(Tokenizer::new(b"x").eq([Token::Literal(b"x")]));
|
||||
assert!(Tokenizer::new(b"x\0y").eq([Token::Literal("x\0y".as_bytes())]));
|
||||
assert!(Tokenizer::new(b"{").eq([]));
|
||||
assert!(Tokenizer::new(b"x{").eq([Token::Literal(b"x")]));
|
||||
assert!(Tokenizer::new(b"x{y").eq([Token::Literal(b"x")]));
|
||||
assert!(Tokenizer::new(b"{}").eq([Token::Argument(b"")]));
|
||||
assert!(Tokenizer::new(b"x{}y{").eq([
|
||||
Token::Literal(b"x"),
|
||||
Token::Argument(b""),
|
||||
Token::Literal(b"y"),
|
||||
assert!(Tokenizer::new("").eq([]));
|
||||
assert!(Tokenizer::new("x").eq([Token::Literal("x")]));
|
||||
assert!(Tokenizer::new("x\0y").eq([Token::Literal("x\0y")]));
|
||||
assert!(Tokenizer::new("{").eq([]));
|
||||
assert!(Tokenizer::new("x{").eq([Token::Literal("x")]));
|
||||
assert!(Tokenizer::new("x{y").eq([Token::Literal("x")]));
|
||||
assert!(Tokenizer::new("{}").eq([Token::Argument("")]));
|
||||
assert!(Tokenizer::new("x{}y{").eq([
|
||||
Token::Literal("x"),
|
||||
Token::Argument(""),
|
||||
Token::Literal("y"),
|
||||
]));
|
||||
assert!(Tokenizer::new(b"{\0}").eq([Token::Argument("\0".as_bytes()),]));
|
||||
assert!(Tokenizer::new(b"{{y}").eq([Token::Argument(b"{y"),]));
|
||||
assert!(Tokenizer::new(b"{{{{xyz").eq([]));
|
||||
assert!(Tokenizer::new(b"x{}{{}}}}").eq([
|
||||
Token::Literal(b"x"),
|
||||
Token::Argument(b""),
|
||||
Token::Argument(b"{"),
|
||||
Token::Literal(b"}}}"),
|
||||
assert!(Tokenizer::new("{\0}").eq([Token::Argument("\0"),]));
|
||||
assert!(Tokenizer::new("{{y}").eq([Token::Argument("{y"),]));
|
||||
assert!(Tokenizer::new("{{{{xyz").eq([]));
|
||||
assert!(Tokenizer::new("x{}{{}}}}").eq([
|
||||
Token::Literal("x"),
|
||||
Token::Argument(""),
|
||||
Token::Argument("{"),
|
||||
Token::Literal("}}}"),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ trait GlyphMetrics {
|
||||
|
||||
impl GlyphMetrics for Font {
|
||||
fn char_width(&self, ch: char) -> i32 {
|
||||
self.text_width(&[ch as u8])
|
||||
Font::char_width(*self, ch)
|
||||
}
|
||||
|
||||
fn line_height(&self) -> i32 {
|
||||
|
@ -114,11 +114,11 @@ impl TextLayout {
|
||||
self.bounds.top_left() + Offset::y(self.text_font.text_height() + self.padding_top)
|
||||
}
|
||||
|
||||
pub fn fit_text(&self, text: &[u8]) -> LayoutFit {
|
||||
pub fn fit_text(&self, text: &str) -> LayoutFit {
|
||||
self.layout_text(text, &mut self.initial_cursor(), &mut TextNoOp)
|
||||
}
|
||||
|
||||
pub fn render_text(&self, text: &[u8]) {
|
||||
pub fn render_text(&self, text: &str) {
|
||||
self.layout_text(text, &mut self.initial_cursor(), &mut TextRenderer);
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ impl TextLayout {
|
||||
|
||||
pub fn layout_text(
|
||||
&self,
|
||||
text: &[u8],
|
||||
text: &str,
|
||||
cursor: &mut Point,
|
||||
sink: &mut dyn LayoutSink,
|
||||
) -> LayoutFit {
|
||||
@ -276,7 +276,7 @@ impl LayoutFit {
|
||||
|
||||
/// Visitor for text segment operations.
|
||||
pub trait LayoutSink {
|
||||
fn text(&mut self, _cursor: Point, _layout: &TextLayout, _text: &[u8]) {}
|
||||
fn text(&mut self, _cursor: Point, _layout: &TextLayout, _text: &str) {}
|
||||
fn hyphen(&mut self, _cursor: Point, _layout: &TextLayout) {}
|
||||
fn ellipsis(&mut self, _cursor: Point, _layout: &TextLayout) {}
|
||||
fn line_break(&mut self, _cursor: Point) {}
|
||||
@ -290,7 +290,7 @@ impl LayoutSink for TextNoOp {}
|
||||
pub struct TextRenderer;
|
||||
|
||||
impl LayoutSink for TextRenderer {
|
||||
fn text(&mut self, cursor: Point, layout: &TextLayout, text: &[u8]) {
|
||||
fn text(&mut self, cursor: Point, layout: &TextLayout, text: &str) {
|
||||
display::text(
|
||||
cursor,
|
||||
text,
|
||||
@ -303,7 +303,7 @@ impl LayoutSink for TextRenderer {
|
||||
fn hyphen(&mut self, cursor: Point, layout: &TextLayout) {
|
||||
display::text(
|
||||
cursor,
|
||||
b"-",
|
||||
"-",
|
||||
layout.hyphen_font,
|
||||
layout.hyphen_color,
|
||||
layout.background_color,
|
||||
@ -313,7 +313,7 @@ impl LayoutSink for TextRenderer {
|
||||
fn ellipsis(&mut self, cursor: Point, layout: &TextLayout) {
|
||||
display::text(
|
||||
cursor,
|
||||
b"...",
|
||||
"...",
|
||||
layout.ellipsis_font,
|
||||
layout.ellipsis_color,
|
||||
layout.background_color,
|
||||
@ -330,8 +330,8 @@ pub mod trace {
|
||||
pub struct TraceSink<'a>(pub &'a mut dyn crate::trace::Tracer);
|
||||
|
||||
impl<'a> LayoutSink for TraceSink<'a> {
|
||||
fn text(&mut self, _cursor: Point, _layout: &TextLayout, text: &[u8]) {
|
||||
self.0.bytes(text);
|
||||
fn text(&mut self, _cursor: Point, _layout: &TextLayout, text: &str) {
|
||||
self.0.string(text);
|
||||
}
|
||||
|
||||
fn hyphen(&mut self, _cursor: Point, _layout: &TextLayout) {
|
||||
@ -351,7 +351,7 @@ pub mod trace {
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Op<'a> {
|
||||
/// Render text with current color and font.
|
||||
Text(&'a [u8]),
|
||||
Text(&'a str),
|
||||
/// Set current text color.
|
||||
Color(Color),
|
||||
/// Set currently used font.
|
||||
@ -396,22 +396,22 @@ struct Span {
|
||||
|
||||
impl Span {
|
||||
fn fit_horizontally(
|
||||
text: &[u8],
|
||||
text: &str,
|
||||
max_width: i32,
|
||||
text_font: Font,
|
||||
hyphen_font: Font,
|
||||
breaking: LineBreaking,
|
||||
) -> Self {
|
||||
const ASCII_LF: u8 = b'\n';
|
||||
const ASCII_CR: u8 = b'\r';
|
||||
const ASCII_SPACE: u8 = b' ';
|
||||
const ASCII_HYPHEN: u8 = b'-';
|
||||
const ASCII_LF: char = '\n';
|
||||
const ASCII_CR: char = '\r';
|
||||
const ASCII_SPACE: char = ' ';
|
||||
const ASCII_HYPHEN: char = '-';
|
||||
|
||||
fn is_whitespace(ch: u8) -> bool {
|
||||
fn is_whitespace(ch: char) -> bool {
|
||||
ch == ASCII_SPACE || ch == ASCII_LF || ch == ASCII_CR
|
||||
}
|
||||
|
||||
let hyphen_width = hyphen_font.text_width(&[ASCII_HYPHEN]);
|
||||
let hyphen_width = hyphen_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
|
||||
@ -427,8 +427,8 @@ impl Span {
|
||||
let mut span_width = 0;
|
||||
let mut found_any_whitespace = false;
|
||||
|
||||
for (i, &ch) in text.iter().enumerate() {
|
||||
let char_width = text_font.text_width(&[ch]);
|
||||
for (i, ch) in text.char_indices() {
|
||||
let char_width = text_font.char_width(ch);
|
||||
|
||||
// Consider if we could be breaking the line at this position.
|
||||
if is_whitespace(ch) {
|
||||
|
@ -29,7 +29,7 @@ pub struct Paragraphs<T> {
|
||||
|
||||
impl<T> Paragraphs<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@ -114,7 +114,7 @@ where
|
||||
|
||||
impl<T> Component for Paragraphs<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
type Msg = Never;
|
||||
|
||||
@ -146,7 +146,7 @@ where
|
||||
|
||||
impl<T> Paginate for Paragraphs<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn page_count(&mut self) -> usize {
|
||||
// There's always at least one page.
|
||||
@ -175,7 +175,7 @@ pub mod trace {
|
||||
|
||||
impl<T> crate::trace::Trace for Paragraphs<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Paragraphs");
|
||||
@ -201,20 +201,20 @@ pub struct Paragraph<T> {
|
||||
|
||||
impl<T> Paragraph<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
pub fn new(content: T, layout: TextLayout) -> Self {
|
||||
Self { content, layout }
|
||||
}
|
||||
|
||||
pub fn content(&self, char_offset: usize) -> &[u8] {
|
||||
pub fn content(&self, char_offset: usize) -> &str {
|
||||
&self.content.as_ref()[char_offset..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Dimensions for Paragraph<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn fit(&mut self, area: Rect) {
|
||||
self.layout.bounds = area;
|
||||
@ -246,7 +246,7 @@ struct PageBreakIterator<'a, T> {
|
||||
/// `PageOffset { 0, 0 }` even if the paragraph vector is empty.
|
||||
impl<'a, T> Iterator for PageBreakIterator<'a, T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
/// `PageOffset` denotes the first paragraph that is rendered and a
|
||||
/// character offset in that paragraph.
|
||||
|
@ -152,7 +152,7 @@ pub fn loader_indeterminate(
|
||||
);
|
||||
}
|
||||
|
||||
pub fn text(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: Color) {
|
||||
pub fn text(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) {
|
||||
display::text(
|
||||
baseline.x,
|
||||
baseline.y,
|
||||
@ -163,7 +163,7 @@ pub fn text(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color:
|
||||
);
|
||||
}
|
||||
|
||||
pub fn text_center(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: Color) {
|
||||
pub fn text_center(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) {
|
||||
let w = font.text_width(text);
|
||||
display::text(
|
||||
baseline.x - w / 2,
|
||||
@ -183,10 +183,14 @@ impl Font {
|
||||
Self(id)
|
||||
}
|
||||
|
||||
pub fn text_width(self, text: &[u8]) -> i32 {
|
||||
pub fn text_width(self, text: &str) -> i32 {
|
||||
display::text_width(text, self.0)
|
||||
}
|
||||
|
||||
pub fn char_width(self, ch: char) -> i32 {
|
||||
display::char_width(ch, self.0)
|
||||
}
|
||||
|
||||
pub fn text_height(self) -> i32 {
|
||||
display::text_height(self.0)
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ pub struct Button<T> {
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl<T: AsRef<[u8]>> Button<T> {
|
||||
impl<T: AsRef<str>> Button<T> {
|
||||
pub fn new(pos: ButtonPos, content: ButtonContent<T>, styles: ButtonStyleSheet) -> Self {
|
||||
Self {
|
||||
pos,
|
||||
@ -100,7 +100,7 @@ impl<T: AsRef<[u8]>> Button<T> {
|
||||
|
||||
impl<T> Component for Button<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
type Msg = ButtonMsg;
|
||||
|
||||
@ -157,7 +157,7 @@ where
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<T> crate::trace::Trace for Button<T>
|
||||
where
|
||||
T: AsRef<[u8]> + crate::trace::Trace,
|
||||
T: AsRef<str> + crate::trace::Trace,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Button");
|
||||
|
@ -22,7 +22,7 @@ pub struct Dialog<T, U> {
|
||||
impl<T, U> Dialog<T, U>
|
||||
where
|
||||
T: Component,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
pub fn new(content: T, left: Option<Button<U>>, right: Option<Button<U>>) -> Self {
|
||||
Self {
|
||||
@ -40,7 +40,7 @@ where
|
||||
impl<T, U> Component for Dialog<T, U>
|
||||
where
|
||||
T: Component,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
type Msg = DialogMsg<T::Msg>;
|
||||
|
||||
@ -80,7 +80,7 @@ where
|
||||
impl<T, U> crate::trace::Trace for Dialog<T, U>
|
||||
where
|
||||
T: crate::trace::Trace,
|
||||
U: crate::trace::Trace + AsRef<[u8]>,
|
||||
U: crate::trace::Trace + AsRef<str>,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Dialog");
|
||||
|
@ -14,7 +14,7 @@ pub struct Frame<T, U> {
|
||||
impl<T, U> Frame<T, U>
|
||||
where
|
||||
T: Component,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
pub fn new(title: U, content: T) -> Self {
|
||||
Self {
|
||||
@ -32,7 +32,7 @@ where
|
||||
impl<T, U> Component for Frame<T, U>
|
||||
where
|
||||
T: Component,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
type Msg = T::Msg;
|
||||
|
||||
@ -68,7 +68,7 @@ where
|
||||
impl<T, U> crate::trace::Trace for Frame<T, U>
|
||||
where
|
||||
T: crate::trace::Trace,
|
||||
U: crate::trace::Trace + AsRef<[u8]>,
|
||||
U: crate::trace::Trace + AsRef<str>,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Frame");
|
||||
|
@ -2,7 +2,7 @@ use core::convert::TryInto;
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::{buffer::Buffer, map::Map, module::Module, obj::Obj, qstr::Qstr},
|
||||
micropython::{buffer::StrBuffer, map::Map, module::Module, obj::Obj, qstr::Qstr},
|
||||
ui::{
|
||||
component::{
|
||||
base::Component,
|
||||
@ -39,7 +39,7 @@ where
|
||||
impl<T, U> ComponentMsgObj for Frame<T, U>
|
||||
where
|
||||
T: ComponentMsgObj,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
self.inner().msg_try_into_obj(msg)
|
||||
@ -48,12 +48,12 @@ where
|
||||
|
||||
extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = |_args: &[Obj], kwargs: &Map| {
|
||||
let title: Buffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let action: Option<Buffer> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
|
||||
let description: Option<Buffer> =
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let action: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
|
||||
let description: Option<StrBuffer> =
|
||||
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
|
||||
let verb: Option<Buffer> = kwargs.get(Qstr::MP_QSTR_verb)?.try_into_option()?;
|
||||
let verb_cancel: Option<Buffer> =
|
||||
let verb: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_verb)?.try_into_option()?;
|
||||
let verb_cancel: Option<StrBuffer> =
|
||||
kwargs.get(Qstr::MP_QSTR_verb_cancel)?.try_into_option()?;
|
||||
let reverse: bool = kwargs.get(Qstr::MP_QSTR_reverse)?.try_into()?;
|
||||
|
||||
@ -74,8 +74,8 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
|
||||
title,
|
||||
ButtonPage::new(
|
||||
FormattedText::new::<theme::T1DefaultText>(format)
|
||||
.with(b"action", action.unwrap_or_default())
|
||||
.with(b"description", description.unwrap_or_default()),
|
||||
.with("action", action.unwrap_or_default())
|
||||
.with("description", description.unwrap_or_default()),
|
||||
theme::BG,
|
||||
),
|
||||
))?;
|
||||
@ -86,9 +86,9 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
|
||||
|
||||
extern "C" fn new_confirm_text(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = |_args: &[Obj], kwargs: &Map| {
|
||||
let title: Buffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let data: Buffer = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?;
|
||||
let description: Option<Buffer> =
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let data: StrBuffer = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?;
|
||||
let description: Option<StrBuffer> =
|
||||
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
|
||||
|
||||
let obj = LayoutObj::new(Frame::new(
|
||||
@ -165,7 +165,7 @@ mod tests {
|
||||
impl<T, U> ComponentMsgObj for Dialog<T, U>
|
||||
where
|
||||
T: ComponentMsgObj,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
@ -182,7 +182,7 @@ mod tests {
|
||||
FormattedText::new::<theme::T1DefaultText>(
|
||||
"Testing text layout, with some text, and some more text. And {param}",
|
||||
)
|
||||
.with(b"param", b"parameters!"),
|
||||
.with("param", "parameters!"),
|
||||
Some(Button::with_text(
|
||||
ButtonPos::Left,
|
||||
"Left",
|
||||
@ -212,7 +212,7 @@ arameters! > left:<Button text:Left > right:<Button text:Right > >"#
|
||||
FormattedText::new::<theme::T1DefaultText>(
|
||||
"Testing text layout, with some text, and some more text. And {param}",
|
||||
)
|
||||
.with(b"param", b"parameters!"),
|
||||
.with("param", "parameters!"),
|
||||
Some(Button::with_text(
|
||||
ButtonPos::Left,
|
||||
"Left",
|
||||
|
@ -156,7 +156,7 @@ impl<T> Button<T> {
|
||||
|
||||
pub fn paint_content(&self, style: &ButtonStyle)
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
match &self.content {
|
||||
ButtonContent::Empty => {}
|
||||
@ -189,7 +189,7 @@ impl<T> Button<T> {
|
||||
|
||||
impl<T> Component for Button<T>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
type Msg = ButtonMsg;
|
||||
|
||||
@ -266,7 +266,7 @@ where
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<T> crate::trace::Trace for Button<T>
|
||||
where
|
||||
T: AsRef<[u8]> + crate::trace::Trace,
|
||||
T: AsRef<str> + crate::trace::Trace,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Button");
|
||||
@ -322,7 +322,7 @@ impl<T> Button<T> {
|
||||
where
|
||||
F0: Fn(ButtonMsg) -> Option<R>,
|
||||
F1: Fn(ButtonMsg) -> Option<R>,
|
||||
T: AsRef<[u8]>,
|
||||
T: AsRef<str>,
|
||||
{
|
||||
const BUTTON_SPACING: i32 = 6;
|
||||
(
|
||||
|
@ -14,7 +14,7 @@ pub struct Frame<T, U> {
|
||||
impl<T, U> Frame<T, U>
|
||||
where
|
||||
T: Component,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
pub fn new(title: U, content: T) -> Self {
|
||||
Self {
|
||||
@ -32,7 +32,7 @@ where
|
||||
impl<T, U> Component for Frame<T, U>
|
||||
where
|
||||
T: Component,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
type Msg = T::Msg;
|
||||
|
||||
@ -76,7 +76,7 @@ where
|
||||
impl<T, U> crate::trace::Trace for Frame<T, U>
|
||||
where
|
||||
T: crate::trace::Trace,
|
||||
U: crate::trace::Trace + AsRef<[u8]>,
|
||||
U: crate::trace::Trace + AsRef<str>,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("Frame");
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
const MAX_LENGTH: usize = 8;
|
||||
|
||||
pub struct Bip39Input {
|
||||
button: Button<&'static [u8]>,
|
||||
button: Button<&'static str>,
|
||||
textbox: TextBox<MAX_LENGTH>,
|
||||
multi_tap: MultiTapKeyboard,
|
||||
suggested_word: Option<&'static str>,
|
||||
@ -95,7 +95,7 @@ impl Component for Bip39Input {
|
||||
self.button.paint_background(&style);
|
||||
|
||||
// Paint the entered content (the prefix of the suggested word).
|
||||
let text = self.textbox.content().as_bytes();
|
||||
let text = self.textbox.content();
|
||||
let width = style.font.text_width(text);
|
||||
// Content starts in the left-center point, offset by 16px to the right and 8px
|
||||
// to the bottom.
|
||||
@ -113,7 +113,7 @@ impl Component for Bip39Input {
|
||||
let word_baseline = text_baseline + Offset::new(width, 0);
|
||||
display::text(
|
||||
word_baseline,
|
||||
word.as_bytes(),
|
||||
word,
|
||||
style.font,
|
||||
theme::GREY_LIGHT,
|
||||
style.button_color,
|
||||
@ -211,7 +211,7 @@ impl Bip39Input {
|
||||
// Disabled button.
|
||||
self.button.disable(ctx);
|
||||
self.button.set_stylesheet(ctx, theme::button_default());
|
||||
self.button.set_content(ctx, ButtonContent::Text(b""));
|
||||
self.button.set_content(ctx, ButtonContent::Text(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,9 +79,6 @@ impl MultiTapKeyboard {
|
||||
/// the pending state. Caller is required to handle the timer event and
|
||||
/// call `Self::clear_pending_state` when the timer hits.
|
||||
pub fn click_key(&mut self, ctx: &mut EventCtx, key: usize, key_text: &str) -> TextEdit {
|
||||
// To simplify things, we assume the key text is ASCII-only.
|
||||
let ascii_text = key_text.as_bytes();
|
||||
|
||||
let (is_pending, press) = match &self.pending {
|
||||
Some(pending) if pending.key == key => {
|
||||
// This key is pending. Cycle the last inserted character through the
|
||||
@ -102,7 +99,7 @@ impl MultiTapKeyboard {
|
||||
// progress into a pending state (to display the pending marker), but such
|
||||
// transition only happens as a result of an append op, so the painting should
|
||||
// be requested by handling the `TextEdit`.
|
||||
self.pending = if ascii_text.len() > 1 {
|
||||
self.pending = if key_text.len() > 1 {
|
||||
Some(Pending {
|
||||
key,
|
||||
press,
|
||||
@ -112,7 +109,9 @@ impl MultiTapKeyboard {
|
||||
None
|
||||
};
|
||||
|
||||
let ch = ascii_text[press % ascii_text.len()] as char;
|
||||
assert!(!key_text.is_empty());
|
||||
// Now we can be sure that a looped iterator will return a value
|
||||
let ch = key_text.chars().cycle().nth(press).unwrap();
|
||||
if is_pending {
|
||||
TextEdit::ReplaceLast(ch)
|
||||
} else {
|
||||
@ -208,11 +207,11 @@ impl<const L: usize> TextBox<L> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn paint_pending_marker(text_baseline: Point, text: &[u8], font: Font, color: Color) {
|
||||
pub fn paint_pending_marker(text_baseline: Point, text: &str, font: Font, color: Color) {
|
||||
// Measure the width of the last character of input.
|
||||
if let Some(last) = text.last().copied() {
|
||||
if let Some(last) = text.chars().last() {
|
||||
let width = font.text_width(text);
|
||||
let last_width = font.text_width(&[last]);
|
||||
let last_width = font.char_width(last);
|
||||
// Draw the marker 2px under the start of the baseline of the last character.
|
||||
let marker_origin = text_baseline + Offset::new(width - last_width, 2);
|
||||
// Draw the marker 1px longer than the last character, and 3px thick.
|
||||
|
@ -19,17 +19,17 @@ pub struct MnemonicKeyboard<T, U> {
|
||||
/// Initial prompt, displayed on empty input.
|
||||
prompt: Child<Maybe<Label<U>>>,
|
||||
/// Backspace button.
|
||||
back: Child<Maybe<Button<&'static [u8]>>>,
|
||||
back: Child<Maybe<Button<&'static str>>>,
|
||||
/// Input area, acting as the auto-complete and confirm button.
|
||||
input: Child<Maybe<T>>,
|
||||
/// Key buttons.
|
||||
keys: [Child<Button<&'static [u8]>>; MNEMONIC_KEY_COUNT],
|
||||
keys: [Child<Button<&'static str>>; MNEMONIC_KEY_COUNT],
|
||||
}
|
||||
|
||||
impl<T, U> MnemonicKeyboard<T, U>
|
||||
where
|
||||
T: MnemonicInput,
|
||||
U: Deref<Target = [u8]>,
|
||||
U: Deref<Target = str>,
|
||||
{
|
||||
pub fn new(input: T, prompt: U) -> Self {
|
||||
Self {
|
||||
@ -42,10 +42,7 @@ where
|
||||
Button::with_icon(theme::ICON_BACK).styled(theme::button_clear()),
|
||||
)),
|
||||
input: Child::new(Maybe::hidden(theme::BG, input)),
|
||||
keys: T::keys()
|
||||
.map(str::as_bytes)
|
||||
.map(Button::with_text)
|
||||
.map(Child::new),
|
||||
keys: T::keys().map(Button::with_text).map(Child::new),
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +84,7 @@ where
|
||||
impl<T, U> Component for MnemonicKeyboard<T, U>
|
||||
where
|
||||
T: MnemonicInput,
|
||||
U: Deref<Target = [u8]>,
|
||||
U: Deref<Target = str>,
|
||||
{
|
||||
type Msg = MnemonicKeyboardMsg;
|
||||
|
||||
|
@ -250,7 +250,7 @@ impl Component for Input {
|
||||
|
||||
let style = theme::label_default();
|
||||
let text_baseline = self.area.bottom_left() - TEXT_OFFSET;
|
||||
let text = self.textbox.content().as_bytes();
|
||||
let text = self.textbox.content();
|
||||
|
||||
// Possible optimization is to redraw the background only when pending character
|
||||
// is replaced, or only draw rectangle over the pending character and
|
||||
|
@ -1,5 +1,5 @@
|
||||
use core::ops::Deref;
|
||||
use heapless::Vec;
|
||||
use heapless::String;
|
||||
|
||||
use crate::{
|
||||
trezorhal::random,
|
||||
@ -26,7 +26,7 @@ const MAX_LENGTH: usize = 9;
|
||||
const DIGIT_COUNT: usize = 10; // 0..10
|
||||
|
||||
pub struct PinKeyboard<T> {
|
||||
digits: Vec<u8, MAX_LENGTH>,
|
||||
digits: String<MAX_LENGTH>,
|
||||
allow_cancel: bool,
|
||||
major_prompt: Label<T>,
|
||||
minor_prompt: Label<T>,
|
||||
@ -40,7 +40,7 @@ pub struct PinKeyboard<T> {
|
||||
|
||||
impl<T> PinKeyboard<T>
|
||||
where
|
||||
T: Deref<Target = [u8]>,
|
||||
T: Deref<Target = str>,
|
||||
{
|
||||
const HEADER_HEIGHT: i32 = 25;
|
||||
const HEADER_PADDING_SIDE: i32 = 5;
|
||||
@ -56,7 +56,7 @@ where
|
||||
major_warning: Option<T>,
|
||||
allow_cancel: bool,
|
||||
) -> Self {
|
||||
let digits = Vec::new();
|
||||
let digits = String::new();
|
||||
|
||||
// Control buttons.
|
||||
let reset_btn = Button::with_icon(theme::ICON_BACK)
|
||||
@ -97,7 +97,7 @@ where
|
||||
}
|
||||
|
||||
fn pin_modified(&mut self, ctx: &mut EventCtx) {
|
||||
let is_full = self.digits.is_full();
|
||||
let is_full = self.digits.len() == self.digits.capacity();
|
||||
for btn in &mut self.digit_btns {
|
||||
btn.mutate(ctx, |ctx, btn| btn.enable_if(ctx, !is_full));
|
||||
}
|
||||
@ -118,14 +118,14 @@ where
|
||||
.mutate(ctx, |ctx, dots| dots.update(ctx, digit_count));
|
||||
}
|
||||
|
||||
pub fn pin(&self) -> &[u8] {
|
||||
pub fn pin(&self) -> &str {
|
||||
&self.digits
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Component for PinKeyboard<T>
|
||||
where
|
||||
T: Deref<Target = [u8]>,
|
||||
T: Deref<Target = str>,
|
||||
{
|
||||
type Msg = PinKeyboardMsg;
|
||||
|
||||
@ -188,7 +188,7 @@ where
|
||||
for btn in &mut self.digit_btns {
|
||||
if let Some(Clicked) = btn.event(ctx, event) {
|
||||
if let ButtonContent::Text(text) = btn.inner().content() {
|
||||
if self.digits.extend_from_slice(text.as_ref()).is_err() {
|
||||
if self.digits.push_str(text).is_err() {
|
||||
// `self.pin` is full and wasn't able to accept all of
|
||||
// `text`. Should not happen.
|
||||
}
|
||||
@ -309,7 +309,7 @@ impl Component for PinDots {
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<T> crate::trace::Trace for PinKeyboard<T>
|
||||
where
|
||||
T: Deref<Target = [u8]>,
|
||||
T: Deref<Target = str>,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.open("PinKeyboard");
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
const MAX_LENGTH: usize = 8;
|
||||
|
||||
pub struct Slip39Input {
|
||||
button: Button<&'static [u8]>,
|
||||
button: Button<&'static str>,
|
||||
textbox: TextBox<MAX_LENGTH>,
|
||||
multi_tap: MultiTapKeyboard,
|
||||
final_word: Option<&'static str>,
|
||||
@ -139,8 +139,9 @@ impl Component for Slip39Input {
|
||||
if let (Some(key), Some(press)) =
|
||||
(self.multi_tap.pending_key(), self.multi_tap.pending_press())
|
||||
{
|
||||
let ascii_text = Self::keys()[key].as_bytes();
|
||||
let ch = ascii_text[press % ascii_text.len()] as char;
|
||||
assert!(!Self::keys()[key].is_empty());
|
||||
// Now we can be sure that the looped iterator will return a value.
|
||||
let ch = Self::keys()[key].chars().cycle().nth(press).unwrap();
|
||||
text.pop();
|
||||
text.push(ch)
|
||||
.assert_if_debugging_ui("Text buffer is too small");
|
||||
@ -148,7 +149,7 @@ impl Component for Slip39Input {
|
||||
}
|
||||
display::text(
|
||||
text_baseline,
|
||||
text.as_bytes(),
|
||||
text.as_str(),
|
||||
style.font,
|
||||
style.text_color,
|
||||
style.button_color,
|
||||
@ -156,7 +157,7 @@ impl Component for Slip39Input {
|
||||
|
||||
// Paint the pending marker.
|
||||
if self.multi_tap.pending_key().is_some() && self.final_word.is_none() {
|
||||
paint_pending_marker(text_baseline, text.as_bytes(), style.font, style.text_color);
|
||||
paint_pending_marker(text_baseline, text.as_str(), style.font, style.text_color);
|
||||
}
|
||||
|
||||
// Paint the icon.
|
||||
@ -221,7 +222,7 @@ impl Slip39Input {
|
||||
// Disabled button.
|
||||
self.button.disable(ctx);
|
||||
self.button.set_stylesheet(ctx, theme::button_default());
|
||||
self.button.set_content(ctx, ButtonContent::Text(b""));
|
||||
self.button.set_content(ctx, ButtonContent::Text(""));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ where
|
||||
fn paint_hint(&mut self) {
|
||||
display::text_center(
|
||||
self.pad.area.bottom_center() - Offset::y(3),
|
||||
b"SWIPE TO CONTINUE",
|
||||
"SWIPE TO CONTINUE",
|
||||
theme::FONT_BOLD, // FIXME: Figma has this as 14px but bold is 16px
|
||||
theme::GREY_LIGHT,
|
||||
theme::BG,
|
||||
|
@ -2,7 +2,7 @@ use core::{convert::TryInto, ops::Deref};
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::{buffer::Buffer, map::Map, module::Module, obj::Obj, qstr::Qstr},
|
||||
micropython::{buffer::StrBuffer, map::Map, module::Module, obj::Obj, qstr::Qstr},
|
||||
ui::{
|
||||
component::{
|
||||
base::ComponentExt,
|
||||
@ -30,7 +30,7 @@ use super::{
|
||||
impl<T, U> ComponentMsgObj for Dialog<T, Button<U>, Button<U>>
|
||||
where
|
||||
T: ComponentMsgObj,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
@ -57,7 +57,7 @@ where
|
||||
|
||||
impl<T> ComponentMsgObj for PinKeyboard<T>
|
||||
where
|
||||
T: Deref<Target = [u8]>,
|
||||
T: Deref<Target = str>,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
@ -79,7 +79,7 @@ impl ComponentMsgObj for PassphraseKeyboard {
|
||||
impl<T, U> ComponentMsgObj for MnemonicKeyboard<T, U>
|
||||
where
|
||||
T: MnemonicInput,
|
||||
U: Deref<Target = [u8]>,
|
||||
U: Deref<Target = str>,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
@ -97,7 +97,7 @@ where
|
||||
impl<T, U> ComponentMsgObj for Frame<T, U>
|
||||
where
|
||||
T: ComponentMsgObj,
|
||||
U: AsRef<[u8]>,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
self.inner().msg_try_into_obj(msg)
|
||||
@ -120,11 +120,11 @@ where
|
||||
|
||||
extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let title: Buffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let action: Option<Buffer> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
|
||||
let description: Option<Buffer> =
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let action: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
|
||||
let description: Option<StrBuffer> =
|
||||
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
|
||||
let verb: Option<Buffer> = kwargs.get(Qstr::MP_QSTR_verb)?.try_into_option()?;
|
||||
let verb: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_verb)?.try_into_option()?;
|
||||
let reverse: bool = kwargs.get(Qstr::MP_QSTR_reverse)?.try_into()?;
|
||||
|
||||
let paragraphs = {
|
||||
@ -161,11 +161,11 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
|
||||
|
||||
extern "C" fn new_request_pin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let prompt: Buffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let subprompt: Buffer = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
|
||||
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let subprompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
|
||||
let allow_cancel: Option<bool> =
|
||||
kwargs.get(Qstr::MP_QSTR_allow_cancel)?.try_into_option()?;
|
||||
let warning: Option<Buffer> = kwargs.get(Qstr::MP_QSTR_warning)?.try_into_option()?;
|
||||
let warning: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_warning)?.try_into_option()?;
|
||||
let obj = LayoutObj::new(
|
||||
PinKeyboard::new(prompt, subprompt, warning, allow_cancel.unwrap_or(true)).into_child(),
|
||||
)?;
|
||||
@ -176,7 +176,7 @@ extern "C" fn new_request_pin(n_args: usize, args: *const Obj, kwargs: *mut Map)
|
||||
|
||||
extern "C" fn new_request_passphrase(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let _prompt: Buffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let _prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let _max_len: u32 = kwargs.get(Qstr::MP_QSTR_max_len)?.try_into()?;
|
||||
let obj = LayoutObj::new(PassphraseKeyboard::new().into_child())?;
|
||||
Ok(obj.into())
|
||||
@ -186,7 +186,7 @@ extern "C" fn new_request_passphrase(n_args: usize, args: *const Obj, kwargs: *m
|
||||
|
||||
extern "C" fn new_request_bip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let prompt: Buffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let obj = LayoutObj::new(MnemonicKeyboard::new(Bip39Input::new(), prompt).into_child())?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
@ -195,7 +195,7 @@ extern "C" fn new_request_bip39(n_args: usize, args: *const Obj, kwargs: *mut Ma
|
||||
|
||||
extern "C" fn new_request_slip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let prompt: Buffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let obj = LayoutObj::new(MnemonicKeyboard::new(Slip39Input::new(), prompt).into_child())?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
@ -288,9 +288,9 @@ mod tests {
|
||||
FormattedText::new::<theme::TTDefaultText>(
|
||||
"Testing text layout, with some text, and some more text. And {param}",
|
||||
)
|
||||
.with(b"param", b"parameters!"),
|
||||
Button::with_text(b"Left"),
|
||||
Button::with_text(b"Right"),
|
||||
.with("param", "parameters!"),
|
||||
Button::with_text("Left"),
|
||||
Button::with_text("Right"),
|
||||
);
|
||||
layout.place(SCREEN);
|
||||
assert_eq!(
|
||||
|
Loading…
Reference in New Issue
Block a user