refactor(core/rust/ui): use TString instead of StrBuffer when constructing layouts

[no changelog]
pull/3677/head
Martin Milata 1 month ago
parent 827b421394
commit c7832c39ab

@ -8,6 +8,7 @@ use crate::{
util::{iter_into_array, try_or_raise},
},
storage::{get_avatar_len, load_avatar},
strutil::TString,
ui::{
component::text::{
paragraphs::{Paragraph, ParagraphSource},
@ -24,16 +25,17 @@ use crate::{
pub const MAX_HEX_CHARS_ON_SCREEN: usize = 256;
pub enum StrOrBytes {
Str(StrBuffer),
Str(TString<'static>),
Bytes(Obj),
}
impl StrOrBytes {
pub fn as_str_offset(&self, offset: usize) -> StrBuffer {
pub fn as_str_offset(&self, offset: usize) -> TString<'static> {
match self {
StrOrBytes::Str(x) => x.skip_prefix(offset),
StrOrBytes::Bytes(x) => hexlify_bytes(*x, offset, MAX_HEX_CHARS_ON_SCREEN)
.unwrap_or_else(|_| StrBuffer::from("ERROR")),
.unwrap_or_else(|_| StrBuffer::from("ERROR"))
.into(),
}
}
}
@ -53,8 +55,8 @@ impl TryFrom<Obj> for StrOrBytes {
}
pub struct ConfirmBlob {
pub description: StrBuffer,
pub extra: StrBuffer,
pub description: TString<'static>,
pub extra: TString<'static>,
pub data: StrOrBytes,
pub description_font: &'static TextStyle,
pub extra_font: &'static TextStyle,

@ -2,7 +2,7 @@ use heapless::Vec;
use crate::{
error::Error,
micropython::buffer::StrBuffer,
strutil::TString,
translations::TR,
ui::{
component::{
@ -24,7 +24,7 @@ pub struct AddressDetails {
qr_code: Qr,
details_view: Paragraphs<ParagraphVecShort<'static>>,
xpub_view: Frame<Paragraphs<Paragraph<'static>>>,
xpubs: Vec<(StrBuffer, StrBuffer), MAX_XPUBS>,
xpubs: Vec<(TString<'static>, TString<'static>), MAX_XPUBS>,
current_page: usize,
current_subpage: usize,
area: Rect,
@ -34,12 +34,14 @@ pub struct AddressDetails {
impl AddressDetails {
pub fn new(
qr_address: StrBuffer,
qr_address: TString<'static>,
case_sensitive: bool,
account: Option<StrBuffer>,
path: Option<StrBuffer>,
account: Option<TString<'static>>,
path: Option<TString<'static>>,
) -> Result<Self, Error> {
let qr_code = Qr::new(qr_address, case_sensitive)?.with_border(QR_BORDER);
let qr_code = qr_address
.map(|s| Qr::new(s, case_sensitive))?
.with_border(QR_BORDER);
let details_view = {
let mut para = ParagraphVecShort::new();
if let Some(account) = account {
@ -74,7 +76,11 @@ impl AddressDetails {
Ok(result)
}
pub fn add_xpub(&mut self, title: StrBuffer, xpub: StrBuffer) -> 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)
@ -149,7 +155,7 @@ impl AddressDetails {
fn fill_xpub_page(&mut self, ctx: &mut EventCtx) {
let i = self.current_page - 2;
self.xpub_view.update_title(ctx, self.xpubs[i].0.into());
self.xpub_view.update_title(ctx, self.xpubs[i].0);
self.xpub_view.update_content(ctx, |p| {
p.inner_mut().update(self.xpubs[i].1);
p.change_page(0)

@ -1,7 +1,7 @@
use core::mem;
use crate::{
strutil::StringType,
strutil::TString,
translations::TR,
ui::{
component::{
@ -21,19 +21,16 @@ const FOOTER_TEXT_MARGIN: i16 = 8;
const LOADER_OFFSET: i16 = -15;
const LOADER_SPEED: u16 = 10;
pub struct CoinJoinProgress<T> {
pub struct CoinJoinProgress {
value: u16,
loader_y_offset: i16,
text: T,
text: TString<'static>,
area: Rect,
indeterminate: bool,
}
impl<T> CoinJoinProgress<T>
where
T: StringType,
{
pub fn new(text: T, indeterminate: bool) -> Self {
impl CoinJoinProgress {
pub fn new(text: TString<'static>, indeterminate: bool) -> Self {
Self {
value: 0,
loader_y_offset: LOADER_OFFSET,
@ -44,10 +41,7 @@ where
}
}
impl<T> Component for CoinJoinProgress<T>
where
T: StringType,
{
impl Component for CoinJoinProgress {
type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect {
@ -122,7 +116,7 @@ where
if let Some(rest) = top_rest {
text_multiline_bottom(
rest.inset(Insets::bottom(FOOTER_TEXT_MARGIN)),
self.text.as_ref().into(),
self.text,
Font::NORMAL,
theme::FG,
theme::BG,
@ -133,14 +127,11 @@ where
}
#[cfg(feature = "ui_debug")]
impl<T> crate::trace::Trace for CoinJoinProgress<T>
where
T: StringType,
{
impl crate::trace::Trace for CoinJoinProgress {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("CoinJoinProgress");
t.string("header", TR::coinjoin__title_progress.into());
t.string("text", self.text.as_ref().into());
t.string("text", self.text);
t.string("footer", TR::coinjoin__do_not_disconnect.into());
}
}

@ -16,7 +16,7 @@ use crate::{
qstr::Qstr,
util,
},
strutil::{StringType, TString},
strutil::TString,
translations::TR,
trezorhal::model,
ui::{
@ -142,10 +142,7 @@ impl ComponentMsgObj for AddressDetails {
}
}
impl<T> ComponentMsgObj for CoinJoinProgress<T>
where
T: StringType,
{
impl ComponentMsgObj for CoinJoinProgress {
fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> {
unreachable!();
}
@ -242,10 +239,10 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
/// Function to create and call a `ButtonPage` dialog based on paginable content
/// (e.g. `Paragraphs` or `FormattedText`).
/// Has optional title (supply empty `StrBuffer` for that) and hold-to-confirm
/// Has optional title (supply empty `TString` for that) and hold-to-confirm
/// functionality.
fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
title: StrBuffer,
title: TString<'static>,
content: T,
verb: TString<'static>,
verb_cancel: Option<TString<'static>>,
@ -270,8 +267,8 @@ fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
.with_confirm_btn(confirm_btn);
let mut frame = ScrollableFrame::new(content);
if !title.as_ref().is_empty() {
frame = frame.with_title(title.into());
if !title.is_empty() {
frame = frame.with_title(title);
}
let obj = LayoutObj::new(frame)?;
@ -280,9 +277,9 @@ fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
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> =
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let action: Option<TString> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let verb: TString<'static> =
kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.into())?;
@ -294,8 +291,8 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let paragraphs = {
let action = action.unwrap_or_default();
let description = description.unwrap_or_default();
let action = action.unwrap_or("".into());
let description = description.unwrap_or("".into());
let mut paragraphs = ParagraphVecShort::new();
if !reverse {
paragraphs
@ -316,11 +313,11 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let description: Option<StrBuffer> =
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let extra: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let extra: Option<TString> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let verb: TString<'static> =
kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.into())?;
let verb_cancel: Option<TString<'static>> = kwargs
@ -338,8 +335,8 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
};
let paragraphs = ConfirmBlob {
description: description.unwrap_or_else(StrBuffer::empty),
extra: extra.unwrap_or_else(StrBuffer::empty),
description: description.unwrap_or("".into()),
extra: extra.unwrap_or("".into()),
data: data.try_into()?,
description_font: &theme::TEXT_BOLD,
extra_font: &theme::TEXT_NORMAL,
@ -354,7 +351,7 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
@ -362,8 +359,8 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
for para in IterBuf::new().try_iterate(items)? {
let [key, value, is_data]: [Obj; 3] = util::iter_into_array(para)?;
let key = key.try_into_option::<StrBuffer>()?;
let value = value.try_into_option::<StrBuffer>()?;
let key = key.try_into_option::<TString>()?;
let value = value.try_into_option::<TString>()?;
let is_data: bool = is_data.try_into()?;
if let Some(key) = key {
@ -402,7 +399,7 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
// Layout needs to hold the Obj to play nice with GC. Obj is resolved to &[u8]
@ -411,7 +408,7 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
// discarded before returning to micropython.
let buffer_func = move || unsafe { unwrap!(get_buffer(data)) };
let obj = LayoutObj::new(ConfirmHomescreen::new(title.into(), buffer_func))?;
let obj = LayoutObj::new(ConfirmHomescreen::new(title, buffer_func))?;
Ok(obj.into())
};
@ -420,7 +417,7 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let ops = OpTextLayout::new(theme::TEXT_NORMAL)
@ -471,17 +468,17 @@ extern "C" fn new_confirm_backup(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let address: StrBuffer = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let address: TString = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let case_sensitive: bool = kwargs.get(Qstr::MP_QSTR_case_sensitive)?.try_into()?;
let account: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let path: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let path: Option<TString> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
let xpubs: Obj = kwargs.get(Qstr::MP_QSTR_xpubs)?;
let mut ad = AddressDetails::new(address, case_sensitive, account, path)?;
for i in IterBuf::new().try_iterate(xpubs)? {
let [xtitle, text]: [StrBuffer; 2] = util::iter_into_array(i)?;
let [xtitle, text]: [TString; 2] = util::iter_into_array(i)?;
ad.add_xpub(xtitle, text)?;
}
@ -493,9 +490,9 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let value: StrBuffer = kwargs.get(Qstr::MP_QSTR_value)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let value: TString = kwargs.get(Qstr::MP_QSTR_value)?.try_into()?;
let verb: Option<TString<'static>> = kwargs
.get(Qstr::MP_QSTR_verb)
@ -521,8 +518,8 @@ extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_confirm_joint_total(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let spending_amount: StrBuffer = kwargs.get(Qstr::MP_QSTR_spending_amount)?.try_into()?;
let total_amount: StrBuffer = kwargs.get(Qstr::MP_QSTR_total_amount)?.try_into()?;
let spending_amount: TString = kwargs.get(Qstr::MP_QSTR_spending_amount)?.try_into()?;
let total_amount: TString = kwargs.get(Qstr::MP_QSTR_total_amount)?.try_into()?;
let paragraphs = Paragraphs::new([
Paragraph::new(&theme::TEXT_BOLD, TR::joint__you_are_contributing),
@ -545,8 +542,8 @@ extern "C" fn new_confirm_joint_total(n_args: usize, args: *const Obj, kwargs: *
extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let sign: i32 = kwargs.get(Qstr::MP_QSTR_sign)?.try_into()?;
let amount_change: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_change)?.try_into()?;
let amount_new: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_new)?.try_into()?;
let amount_change: TString = kwargs.get(Qstr::MP_QSTR_amount_change)?.try_into()?;
let amount_new: TString = kwargs.get(Qstr::MP_QSTR_amount_new)?.try_into()?;
let description = if sign < 0 {
TR::modify_amount__decrease_amount
@ -574,9 +571,9 @@ extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_confirm_output_address(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let address: StrBuffer = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let address_label: StrBuffer = kwargs.get(Qstr::MP_QSTR_address_label)?.try_into()?;
let address_title: StrBuffer = kwargs.get(Qstr::MP_QSTR_address_title)?.try_into()?;
let address: TString = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let address_label: TString = kwargs.get(Qstr::MP_QSTR_address_label)?.try_into()?;
let address_title: TString = kwargs.get(Qstr::MP_QSTR_address_title)?.try_into()?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let get_page = move |page_index| {
@ -602,7 +599,7 @@ extern "C" fn new_confirm_output_address(n_args: usize, args: *const Obj, kwargs
}
ops = ops.text_mono(address);
let formatted = FormattedText::new(ops).vertically_centered();
Page::new(btn_layout, btn_actions, formatted).with_title(address_title.into())
Page::new(btn_layout, btn_actions, formatted).with_title(address_title)
};
let pages = FlowPages::new(get_page, 1);
@ -614,8 +611,8 @@ extern "C" fn new_confirm_output_address(n_args: usize, args: *const Obj, kwargs
extern "C" fn new_confirm_output_amount(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let amount: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount)?.try_into()?;
let amount_title: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_title)?.try_into()?;
let amount: TString = kwargs.get(Qstr::MP_QSTR_amount)?.try_into()?;
let amount_title: TString = kwargs.get(Qstr::MP_QSTR_amount_title)?.try_into()?;
let get_page = move |page_index| {
assert!(page_index == 0);
@ -624,7 +621,7 @@ extern "C" fn new_confirm_output_amount(n_args: usize, args: *const Obj, kwargs:
let btn_actions = ButtonActions::cancel_none_confirm();
let ops = OpTextLayout::new(theme::TEXT_MONO).text_mono(amount);
let formatted = FormattedText::new(ops).vertically_centered();
Page::new(btn_layout, btn_actions, formatted).with_title(amount_title.into())
Page::new(btn_layout, btn_actions, formatted).with_title(amount_title)
};
let pages = FlowPages::new(get_page, 1);
@ -636,15 +633,15 @@ extern "C" fn new_confirm_output_amount(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let total_amount: StrBuffer = kwargs.get(Qstr::MP_QSTR_total_amount)?.try_into()?;
let fee_amount: StrBuffer = kwargs.get(Qstr::MP_QSTR_fee_amount)?.try_into()?;
let fee_rate_amount: Option<StrBuffer> = kwargs
let total_amount: TString = kwargs.get(Qstr::MP_QSTR_total_amount)?.try_into()?;
let fee_amount: TString = kwargs.get(Qstr::MP_QSTR_fee_amount)?.try_into()?;
let fee_rate_amount: Option<TString> = kwargs
.get(Qstr::MP_QSTR_fee_rate_amount)?
.try_into_option()?;
let account_label: Option<StrBuffer> =
let account_label: Option<TString> =
kwargs.get(Qstr::MP_QSTR_account_label)?.try_into_option()?;
let total_label: StrBuffer = kwargs.get(Qstr::MP_QSTR_total_label)?.try_into()?;
let fee_label: StrBuffer = kwargs.get(Qstr::MP_QSTR_fee_label)?.try_into()?;
let total_label: TString = kwargs.get(Qstr::MP_QSTR_total_label)?.try_into()?;
let fee_label: TString = kwargs.get(Qstr::MP_QSTR_fee_label)?.try_into()?;
let get_page = move |page_index| {
match page_index {
@ -671,7 +668,7 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
let btn_layout = ButtonLayout::arrow_none_arrow();
let btn_actions = ButtonActions::prev_none_next();
let fee_rate_amount = fee_rate_amount.unwrap_or_default();
let fee_rate_amount = fee_rate_amount.unwrap_or("".into());
let ops = OpTextLayout::new(theme::TEXT_MONO)
.text_bold(TR::confirm_total__title_fee)
@ -690,7 +687,7 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
let btn_layout = ButtonLayout::arrow_none_none();
let btn_actions = ButtonActions::prev_none_none();
let account_label = account_label.unwrap_or_default();
let account_label = account_label.unwrap_or("".into());
// TODO: include wallet info when available
@ -719,10 +716,10 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_altcoin_tx_summary(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let amount_title: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_title)?.try_into()?;
let amount_value: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_value)?.try_into()?;
let fee_title: StrBuffer = kwargs.get(Qstr::MP_QSTR_fee_title)?.try_into()?;
let fee_value: StrBuffer = kwargs.get(Qstr::MP_QSTR_fee_value)?.try_into()?;
let amount_title: TString = kwargs.get(Qstr::MP_QSTR_amount_title)?.try_into()?;
let amount_value: TString = kwargs.get(Qstr::MP_QSTR_amount_value)?.try_into()?;
let fee_title: TString = kwargs.get(Qstr::MP_QSTR_fee_title)?.try_into()?;
let fee_value: TString = kwargs.get(Qstr::MP_QSTR_fee_value)?.try_into()?;
let cancel_cross: bool = kwargs.get_or(Qstr::MP_QSTR_cancel_cross, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
@ -746,7 +743,7 @@ extern "C" fn new_altcoin_tx_summary(n_args: usize, args: *const Obj, kwargs: *m
.text_mono(fee_value);
let formatted = FormattedText::new(ops);
Page::new(btn_layout, btn_actions, formatted).with_title(amount_title.into())
Page::new(btn_layout, btn_actions, formatted).with_title(amount_title)
}
1 => {
// Other information
@ -785,8 +782,8 @@ extern "C" fn new_altcoin_tx_summary(n_args: usize, args: *const Obj, kwargs: *m
extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let address: StrBuffer = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let address: TString = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?;
let verb: TString<'static> =
kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.into())?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
@ -804,7 +801,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
};
let ops = OpTextLayout::new(style).text_mono(address);
let formatted = FormattedText::new(ops).vertically_centered();
Page::new(btn_layout, btn_actions, formatted).with_title(title.into())
Page::new(btn_layout, btn_actions, formatted).with_title(title)
};
let pages = FlowPages::new(get_page, 1);
@ -906,16 +903,16 @@ extern "C" fn tutorial(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj
extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let sign: i32 = kwargs.get(Qstr::MP_QSTR_sign)?.try_into()?;
let user_fee_change: StrBuffer = kwargs.get(Qstr::MP_QSTR_user_fee_change)?.try_into()?;
let total_fee_new: StrBuffer = kwargs.get(Qstr::MP_QSTR_total_fee_new)?.try_into()?;
let fee_rate_amount: Option<StrBuffer> = kwargs
let user_fee_change: TString = kwargs.get(Qstr::MP_QSTR_user_fee_change)?.try_into()?;
let total_fee_new: TString = kwargs.get(Qstr::MP_QSTR_total_fee_new)?.try_into()?;
let fee_rate_amount: Option<TString> = kwargs
.get(Qstr::MP_QSTR_fee_rate_amount)?
.try_into_option()?;
let (description, change) = match sign {
s if s < 0 => (TR::modify_fee__decrease_fee, user_fee_change),
s if s > 0 => (TR::modify_fee__increase_fee, user_fee_change),
_ => (TR::modify_fee__no_change, StrBuffer::empty()),
_ => (TR::modify_fee__no_change, "".into()),
};
let mut paragraphs_vec = ParagraphVecShort::new();
@ -944,7 +941,7 @@ extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *m
extern "C" fn new_multiple_pages_texts(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let verb: TString = kwargs.get(Qstr::MP_QSTR_verb)?.try_into()?;
let items: Gc<List> = kwargs.get(Qstr::MP_QSTR_items)?.try_into()?;
@ -991,7 +988,7 @@ extern "C" fn new_multiple_pages_texts(n_args: usize, args: *const Obj, kwargs:
};
let pages = FlowPages::new(get_page, page_count);
let obj = LayoutObj::new(Flow::new(pages).with_common_title(title.into()))?;
let obj = LayoutObj::new(Flow::new(pages).with_common_title(title))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -999,8 +996,8 @@ extern "C" fn new_multiple_pages_texts(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let app_name: StrBuffer = kwargs.get(Qstr::MP_QSTR_app_name)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let app_name: TString = kwargs.get(Qstr::MP_QSTR_app_name)?.try_into()?;
let accounts: Gc<List> = kwargs.get(Qstr::MP_QSTR_accounts)?.try_into()?;
// Cache the page count so that we can move `accounts` into the closure.
@ -1053,7 +1050,7 @@ extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map
// Returning the page index in case of confirmation.
let obj = LayoutObj::new(
Flow::new(pages)
.with_common_title(title.into())
.with_common_title(title)
.with_return_confirmed_index(),
)?;
Ok(obj.into())
@ -1064,8 +1061,8 @@ extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map
extern "C" fn new_show_warning(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let warning: StrBuffer = kwargs.get(Qstr::MP_QSTR_warning)?.try_into()?;
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let warning: TString = kwargs.get(Qstr::MP_QSTR_warning)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let get_page = move |page_index| {
assert!(page_index == 0);
@ -1092,13 +1089,12 @@ extern "C" fn new_show_warning(n_args: usize, args: *const Obj, kwargs: *mut Map
extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: TString = kwargs.get_or(Qstr::MP_QSTR_description, "".into())?;
let time_ms: u32 = kwargs.get_or(Qstr::MP_QSTR_time_ms, 0)?;
let content = Frame::new(
title.into(),
title,
Paragraphs::new([Paragraph::new(&theme::TEXT_NORMAL, description)]),
);
let obj = if time_ms == 0 {
@ -1118,7 +1114,7 @@ extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -
extern "C" fn new_show_passphrase() -> Obj {
let block = move || {
let text: StrBuffer = TR::passphrase__please_enter.try_into()?;
let text: TString = TR::passphrase__please_enter.try_into()?;
let paragraph = Paragraph::new(&theme::TEXT_NORMAL, text).centered();
let content = Paragraphs::new([paragraph]);
let obj = LayoutObj::new(content)?;
@ -1129,7 +1125,7 @@ extern "C" fn new_show_passphrase() -> Obj {
extern "C" fn new_show_waiting_text(message: Obj) -> Obj {
let block = || {
let text: StrBuffer = message.try_into()?;
let text: TString = message.try_into()?;
let paragraph = Paragraph::new(&theme::TEXT_NORMAL, text).centered();
let content = Paragraphs::new([paragraph]);
let obj = LayoutObj::new(content)?;
@ -1140,7 +1136,7 @@ extern "C" fn new_show_waiting_text(message: Obj) -> Obj {
extern "C" fn new_show_mismatch(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let get_page = move |page_index| {
assert!(page_index == 0);
@ -1167,7 +1163,7 @@ extern "C" fn new_show_mismatch(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let verb_cancel: Option<TString<'static>> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
@ -1180,7 +1176,7 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: StrBuffer = text.try_into()?;
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
@ -1188,7 +1184,7 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
}
let obj = LayoutObj::new(Frame::new(
title.into(),
title,
ShowMore::<Paragraphs<ParagraphVecShort>>::new(
paragraphs.into_paragraphs(),
verb_cancel,
@ -1202,7 +1198,7 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
@ -1211,7 +1207,7 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: StrBuffer = text.try_into()?;
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
}
@ -1228,8 +1224,8 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map
extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let max_rounds: StrBuffer = kwargs.get(Qstr::MP_QSTR_max_rounds)?.try_into()?;
let max_feerate: StrBuffer = kwargs.get(Qstr::MP_QSTR_max_feerate)?.try_into()?;
let max_rounds: TString = kwargs.get(Qstr::MP_QSTR_max_rounds)?.try_into()?;
let max_feerate: TString = kwargs.get(Qstr::MP_QSTR_max_feerate)?.try_into()?;
// Decreasing bottom padding between paragraphs to fit one screen
let paragraphs = Paragraphs::new([
@ -1254,10 +1250,10 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_request_pin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let subprompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let subprompt: TString = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let obj = LayoutObj::new(PinEntry::new(prompt.into(), subprompt.into()))?;
let obj = LayoutObj::new(PinEntry::new(prompt, subprompt))?;
Ok(obj.into())
};
@ -1266,11 +1262,9 @@ 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 = |_args: &[Obj], kwargs: &Map| {
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(prompt.into(), PassphraseEntry::new()).with_title_centered(),
)?;
let obj = LayoutObj::new(Frame::new(prompt, PassphraseEntry::new()).with_title_centered())?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -1279,17 +1273,14 @@ 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 = |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: StrBuffer = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(
prompt.into(),
WordlistEntry::prefilled_word(
prefill_word.as_ref(),
WordlistType::Bip39,
can_go_back,
),
prompt,
prefill_word
.map(|s| WordlistEntry::prefilled_word(s, WordlistType::Bip39, can_go_back)),
)
.with_title_centered(),
)?;
@ -1300,18 +1291,15 @@ 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 = |_args: &[Obj], kwargs: &Map| {
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: StrBuffer = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(
prompt.into(),
WordlistEntry::prefilled_word(
prefill_word.as_ref(),
WordlistType::Slip39,
can_go_back,
),
prompt,
prefill_word
.map(|s| WordlistEntry::prefilled_word(s, WordlistType::Slip39, can_go_back)),
)
.with_title_centered(),
)?;
@ -1323,7 +1311,7 @@ extern "C" fn new_request_slip39(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], kwargs: &Map| {
// we ignore passed in `title` and use `description` in its place
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let words_iterable: Obj = kwargs.get(Qstr::MP_QSTR_words)?;
// There are only 3 words, but SimpleChoice requires 5 elements
let words: Vec<TString<'static>, 5> = util::iter_into_vec(words_iterable)?;
@ -1331,7 +1319,7 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
// Returning the index of the selected word, not the word itself
let obj = LayoutObj::new(
Frame::new(
description.into(),
description,
SimpleChoice::new(words, false)
.with_show_incomplete()
.with_return_index(),
@ -1364,14 +1352,13 @@ extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let min_count: u32 = kwargs.get(Qstr::MP_QSTR_min_count)?.try_into()?;
let max_count: u32 = kwargs.get(Qstr::MP_QSTR_max_count)?.try_into()?;
let count: u32 = kwargs.get(Qstr::MP_QSTR_count)?.try_into()?;
let obj = LayoutObj::new(
Frame::new(title.into(), NumberInput::new(min_count, max_count, count))
.with_title_centered(),
Frame::new(title, NumberInput::new(min_count, max_count, count)).with_title_centered(),
)?;
Ok(obj.into())
};
@ -1391,7 +1378,7 @@ extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut M
Ordering::Equal => &theme::TEXT_BOLD,
Ordering::Greater => &theme::TEXT_NORMAL,
};
let text: StrBuffer = item.try_into()?;
let text: TString = item.try_into()?;
paragraphs.add(Paragraph::new(style, text));
}
@ -1420,7 +1407,7 @@ extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let dry_run: bool = kwargs.get(Qstr::MP_QSTR_dry_run)?.try_into()?;
let show_info: bool = kwargs.get(Qstr::MP_QSTR_show_info)?.try_into()?;
@ -1458,7 +1445,7 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_select_word_count(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = |_args: &[Obj], _kwargs: &Map| {
let title: StrBuffer = TR::word_count__title.try_into()?;
let title: TString = TR::word_count__title.try_into()?;
let choices: Vec<TString<'static>, 5> = ["12", "18", "20", "24", "33"]
.map(|num| num.into())
@ -1466,7 +1453,7 @@ extern "C" fn new_select_word_count(n_args: usize, args: *const Obj, kwargs: *mu
.collect();
let obj = LayoutObj::new(
Frame::new(title.into(), SimpleChoice::new(choices, false)).with_title_centered(),
Frame::new(title, SimpleChoice::new(choices, false)).with_title_centered(),
)?;
Ok(obj.into())
};
@ -1480,7 +1467,7 @@ extern "C" fn new_show_group_share_success(
) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let lines_iterable: Obj = kwargs.get(Qstr::MP_QSTR_lines)?;
let lines: [StrBuffer; 4] = util::iter_into_array(lines_iterable)?;
let lines: [TString; 4] = util::iter_into_array(lines_iterable)?;
let [l0, l1, l2, l3] = lines;
@ -1504,20 +1491,18 @@ extern "C" fn new_show_group_share_success(
extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
let title: Option<StrBuffer> = kwargs
let title: Option<TString> = kwargs
.get(Qstr::MP_QSTR_title)
.and_then(Obj::try_into_option)
.unwrap_or(None);
let mut progress = Progress::new(indeterminate, description.into());
let mut progress = Progress::new(indeterminate, description);
if let Some(title) = title {
progress = progress.with_title(title.into());
progress = progress.with_title(title);
};
// Description updates are received as &str and we need to provide a way to
// convert them to StrBuffer.
let obj = LayoutObj::new(progress)?;
Ok(obj.into())
};
@ -1526,7 +1511,7 @@ extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_show_progress_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
let time_ms: u32 = kwargs.get_or(Qstr::MP_QSTR_time_ms, 0)?;
let skip_first_paint: bool = kwargs.get_or(Qstr::MP_QSTR_skip_first_paint, false)?;
@ -1549,23 +1534,19 @@ extern "C" fn new_show_progress_coinjoin(n_args: usize, args: *const Obj, kwargs
}
extern "C" fn new_show_homescreen(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let label: StrBuffer = kwargs
let label: TString = kwargs
.get(Qstr::MP_QSTR_label)?
.try_into_option()?
.unwrap_or_else(|| model::FULL_NAME.into());
let notification: Option<StrBuffer> =
let notification: Option<TString> =
kwargs.get(Qstr::MP_QSTR_notification)?.try_into_option()?;
let notification_level: u8 = kwargs.get_or(Qstr::MP_QSTR_notification_level, 0)?;
let skip_first_paint: bool = kwargs.get(Qstr::MP_QSTR_skip_first_paint)?.try_into()?;
let hold: bool = kwargs.get(Qstr::MP_QSTR_hold)?.try_into()?;
let notification = notification.map(|w| (w.into(), notification_level));
let notification = notification.map(|w| (w, notification_level));
let loader_description = hold.then_some("Locking the device...".into());
let obj = LayoutObj::new(Homescreen::new(
label.into(),
notification,
loader_description,
))?;
let obj = LayoutObj::new(Homescreen::new(label, notification, loader_description))?;
if skip_first_paint {
obj.skip_first_paint();
}
@ -1576,7 +1557,7 @@ extern "C" fn new_show_homescreen(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_show_lockscreen(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let label: StrBuffer = kwargs
let label: TString = kwargs
.get(Qstr::MP_QSTR_label)?
.try_into_option()?
.unwrap_or_else(|| model::FULL_NAME.into());
@ -1584,11 +1565,7 @@ extern "C" fn new_show_lockscreen(n_args: usize, args: *const Obj, kwargs: *mut
let coinjoin_authorized: bool = kwargs.get_or(Qstr::MP_QSTR_coinjoin_authorized, false)?;
let skip_first_paint: bool = kwargs.get(Qstr::MP_QSTR_skip_first_paint)?.try_into()?;
let obj = LayoutObj::new(Lockscreen::new(
label.into(),
bootscreen,
coinjoin_authorized,
))?;
let obj = LayoutObj::new(Lockscreen::new(label, bootscreen, coinjoin_authorized))?;
if skip_first_paint {
obj.skip_first_paint();
}
@ -1604,14 +1581,13 @@ extern "C" fn new_confirm_firmware_update(
) -> Obj {
use super::component::bl_confirm::Confirm;
let block = move |_args: &[Obj], kwargs: &Map| {
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let fingerprint: StrBuffer = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let fingerprint: TString = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?;
let title = TR::firmware_update__title;
let message =
Label::left_aligned(description.into(), theme::TEXT_NORMAL).vertically_centered();
let message = Label::left_aligned(description, theme::TEXT_NORMAL).vertically_centered();
let fingerprint = Label::left_aligned(
fingerprint.into(),
fingerprint,
theme::TEXT_NORMAL.with_line_breaking(LineBreaking::BreakWordsNoHyphen),
)
.vertically_centered();

@ -2,8 +2,7 @@ use heapless::Vec;
use crate::{
error::Error,
micropython::buffer::StrBuffer,
strutil::StringType,
strutil::TString,
translations::TR,
ui::{
component::{
@ -18,30 +17,24 @@ use super::{theme, Frame, FrameMsg};
const MAX_XPUBS: usize = 16;
pub struct AddressDetails<T> {
pub struct AddressDetails {
qr_code: Frame<Qr>,
details: Frame<Paragraphs<ParagraphVecShort<'static>>>,
xpub_view: Frame<Paragraphs<Paragraph<'static>>>,
xpubs: Vec<(T, T), MAX_XPUBS>,
xpubs: Vec<(TString<'static>, TString<'static>), MAX_XPUBS>,
xpub_page_count: Vec<u8, MAX_XPUBS>,
current_page: usize,
}
impl<T> AddressDetails<T>
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<StrBuffer>,
path: Option<StrBuffer>,
) -> Result<Self, Error>
where
T: From<&'static str>,
{
details_title: TString<'static>,
account: Option<TString<'static>>,
path: Option<TString<'static>>,
) -> Result<Self, Error> {
let mut para = ParagraphVecShort::new();
if let Some(a) = account {
para.add(Paragraph::new(
@ -60,14 +53,16 @@ where
let result = Self {
qr_code: Frame::left_aligned(
theme::label_title(),
qr_title.into(),
Qr::new(qr_address, case_sensitive)?.with_border(7),
qr_title,
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(
theme::label_title(),
details_title.into(),
details_title,
para.into_paragraphs(),
)
.with_cancel_button()
@ -86,24 +81,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().into());
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
@ -128,10 +123,7 @@ where
}
}
impl<T> Paginate for AddressDetails<T>
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())
@ -147,10 +139,7 @@ where
}
}
impl<T> Component for AddressDetails<T>
where
T: StringType + Clone,
{
impl Component for AddressDetails {
type Msg = ();
fn place(&mut self, bounds: Rect) -> Rect {
@ -198,10 +187,7 @@ where
}
#[cfg(feature = "ui_debug")]
impl<T> crate::trace::Trace for AddressDetails<T>
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 {

@ -1,6 +1,6 @@
use crate::{
error::Error,
strutil::{self, StringType},
strutil::{self, TString},
translations::TR,
ui::{
component::{
@ -21,9 +21,9 @@ pub enum NumberInputDialogMsg {
InfoRequested,
}
pub struct NumberInputDialog<T, F>
pub struct NumberInputDialog<F>
where
F: Fn(u32) -> T,
F: Fn(u32) -> TString<'static>,
{
area: Rect,
description_func: F,
@ -34,10 +34,9 @@ where
confirm_button: Child<Button>,
}
impl<T, F> NumberInputDialog<T, F>
impl<F> NumberInputDialog<F>
where
F: Fn(u32) -> T,
T: StringType,
F: Fn(u32) -> TString<'static>,
{
pub fn new(min: u32, max: u32, init_value: u32, description_func: F) -> Result<Self, Error> {
let text = description_func(init_value);
@ -71,10 +70,9 @@ where
}
}
impl<T, F> Component for NumberInputDialog<T, F>
impl<F> Component for NumberInputDialog<F>
where
T: StringType,
F: Fn(u32) -> T,
F: Fn(u32) -> TString<'static>,
{
type Msg = NumberInputDialogMsg;
@ -133,10 +131,9 @@ where
}
#[cfg(feature = "ui_debug")]
impl<T, F> crate::trace::Trace for NumberInputDialog<T, F>
impl<F> crate::trace::Trace for NumberInputDialog<F>
where
T: StringType,
F: Fn(u32) -> T,
F: Fn(u32) -> TString<'static>,
{
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("NumberInputDialog");

@ -3,17 +3,10 @@ use core::{cmp::Ordering, convert::TryInto};
use crate::{
error::Error,
micropython::{
buffer::{get_buffer, StrBuffer},
gc::Gc,
iter::IterBuf,
list::List,
map::Map,
module::Module,
obj::Obj,
qstr::Qstr,
util,
buffer::get_buffer, gc::Gc, iter::IterBuf, list::List, map::Map, module::Module, obj::Obj,
qstr::Qstr, util,
},
strutil::{StringType, TString},
strutil::TString,
translations::TR,
trezorhal::model,
ui::{
@ -239,10 +232,9 @@ where
}
}
impl<T, F> ComponentMsgObj for NumberInputDialog<T, F>
impl<F> ComponentMsgObj for NumberInputDialog<F>
where
T: StringType,
F: Fn(u32) -> T,
F: Fn(u32) -> TString<'static>,
{
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
let value = self.value().try_into()?;
@ -323,10 +315,7 @@ where
}
}
impl<T> ComponentMsgObj for AddressDetails<T>
where
T: StringType + Clone,
{
impl ComponentMsgObj for AddressDetails {
fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> {
Ok(CANCELLED.as_obj())
}
@ -352,15 +341,15 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
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: 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> =
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let action: Option<TString> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let verb: Option<StrBuffer> = kwargs
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<StrBuffer> = kwargs
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
@ -369,8 +358,8 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let hold_danger: bool = kwargs.get_or(Qstr::MP_QSTR_hold_danger, false)?;
let paragraphs = {
let action = action.unwrap_or_default();
let description = description.unwrap_or_default();
let action = action.unwrap_or("".into());
let description = description.unwrap_or("".into());
let mut paragraphs = ParagraphVecShort::new();
if !reverse {
paragraphs
@ -387,17 +376,12 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let mut page = if hold {
ButtonPage::new(paragraphs, theme::BG).with_hold()?
} else {
ButtonPage::new(paragraphs, theme::BG)
.with_cancel_confirm(verb_cancel.map(|c| c.into()), verb.map(|c| c.into()))
ButtonPage::new(paragraphs, theme::BG).with_cancel_confirm(verb_cancel, verb)
};
if hold && hold_danger {
page = page.with_confirm_style(theme::button_danger())
}
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
page,
))?;
let obj = LayoutObj::new(Frame::left_aligned(theme::label_title(), title, page))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -405,8 +389,8 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let verb: Option<StrBuffer> = kwargs
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
@ -415,10 +399,10 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
let mut ops = OpTextLayout::new(theme::TEXT_NORMAL);
for item in IterBuf::new().try_iterate(items)? {
if item.is_str() {
ops = ops.text_normal(StrBuffer::try_from(item)?)
ops = ops.text_normal(TString::try_from(item)?)
} else {
let [emphasis, text]: [Obj; 2] = util::iter_into_array(item)?;
let text: StrBuffer = text.try_into()?;
let text: TString = text.try_into()?;
if emphasis.try_into()? {
ops = ops.text_demibold(text);
} else {
@ -429,9 +413,9 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
ButtonPage::new(FormattedText::new(ops).vertically_centered(), theme::BG)
.with_cancel_confirm(None, verb.map(|v| v.into())),
.with_cancel_confirm(None, verb),
))?;
Ok(obj.into())
};
@ -439,13 +423,13 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
}
struct ConfirmBlobParams {
title: StrBuffer,
subtitle: Option<StrBuffer>,
title: TString<'static>,
subtitle: Option<TString<'static>>,
data: Obj,
description: Option<StrBuffer>,
extra: Option<StrBuffer>,
verb: Option<StrBuffer>,
verb_cancel: Option<StrBuffer>,
description: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
info_button: bool,
hold: bool,
chunkify: bool,
@ -454,11 +438,11 @@ struct ConfirmBlobParams {
impl ConfirmBlobParams {
fn new(
title: StrBuffer,
title: TString<'static>,
data: Obj,
description: Option<StrBuffer>,
verb: Option<StrBuffer>,
verb_cancel: Option<StrBuffer>,
description: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
hold: bool,
) -> Self {
Self {
@ -476,12 +460,12 @@ impl ConfirmBlobParams {
}
}
fn with_extra(mut self, extra: Option<StrBuffer>) -> Self {
fn with_extra(mut self, extra: Option<TString<'static>>) -> Self {
self.extra = extra;
self
}
fn with_subtitle(mut self, subtitle: Option<StrBuffer>) -> Self {
fn with_subtitle(mut self, subtitle: Option<TString<'static>>) -> Self {
self.subtitle = subtitle;
self
}
@ -503,13 +487,13 @@ impl ConfirmBlobParams {
fn into_layout(self) -> Result<Obj, Error> {
let paragraphs = ConfirmBlob {
description: self.description.unwrap_or_else(StrBuffer::empty),
extra: self.extra.unwrap_or_else(StrBuffer::empty),
description: self.description.unwrap_or("".into()),
extra: self.extra.unwrap_or("".into()),
data: self.data.try_into()?,
description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD,
data_font: if self.chunkify {
let data: StrBuffer = self.data.try_into()?;
let data: TString = self.data.try_into()?;
theme::get_chunkified_text_style(data.len())
} else if self.text_mono {
&theme::TEXT_MONO
@ -521,14 +505,14 @@ impl ConfirmBlobParams {
let mut page = ButtonPage::new(paragraphs, theme::BG);
if let Some(verb) = self.verb {
page = page.with_cancel_confirm(self.verb_cancel.map(|v| v.into()), Some(verb.into()))
page = page.with_cancel_confirm(self.verb_cancel, Some(verb))
}
if self.hold {
page = page.with_hold()?
}
let mut frame = Frame::left_aligned(theme::label_title(), self.title.into(), page);
let mut frame = Frame::left_aligned(theme::label_title(), self.title, page);
if let Some(subtitle) = self.subtitle {
frame = frame.with_subtitle(theme::label_subtitle(), subtitle.into());
frame = frame.with_subtitle(theme::label_subtitle(), subtitle);
}
if self.info_button {
frame = frame.with_info_button();
@ -540,16 +524,16 @@ impl ConfirmBlobParams {
extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let description: Option<StrBuffer> =
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let extra: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let verb: Option<StrBuffer> = kwargs
let extra: Option<TString> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<StrBuffer> = kwargs
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
@ -566,25 +550,24 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: Option<StrBuffer> =
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let verb: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.try_into()?)?;
let extra: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let verb: TString = kwargs.get_or(Qstr::MP_QSTR_verb, TR::buttons__confirm.try_into()?)?;
let extra: Option<TString> = kwargs.get(Qstr::MP_QSTR_extra)?.try_into_option()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let data_style = if chunkify {
let address: StrBuffer = data.try_into()?;
let address: TString = data.try_into()?;
theme::get_chunkified_text_style(address.len())
} else {
&theme::TEXT_MONO
};
let paragraphs = ConfirmBlob {
description: description.unwrap_or_else(StrBuffer::empty),
extra: extra.unwrap_or_else(StrBuffer::empty),
description: description.unwrap_or("".into()),
extra: extra.unwrap_or("".into()),
data: data.try_into()?,
description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD,
@ -595,10 +578,10 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
let obj = LayoutObj::new(
Frame::left_aligned(
theme::label_title(),
title.into(),
title,
ButtonPage::new(paragraphs, theme::BG)
.with_swipe_left()
.with_cancel_confirm(None, Some(verb.into())),
.with_cancel_confirm(None, Some(verb)),
)
.with_info_button(),
)?;
@ -609,7 +592,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
@ -625,11 +608,7 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG)
.with_cancel_confirm(None, Some(TR::buttons__confirm.into()))
};
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
page,
))?;
let obj = LayoutObj::new(Frame::left_aligned(theme::label_title(), title, page))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -637,7 +616,7 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
// Layout needs to hold the Obj to play nice with GC. Obj is resolved to &[u8]
@ -663,7 +642,7 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
let buttons = Button::cancel_confirm_text(None, Some(TR::buttons__change.into()));
let obj = LayoutObj::new(Frame::centered(
theme::label_title(),
title.into(),
title,
Dialog::new(painter::jpeg_painter(buffer_func, size, 1), buttons),
))?;
Ok(obj.into())
@ -674,8 +653,8 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let par_array: [Paragraph<'static>; 3] = [
Paragraph::new(&theme::TEXT_NORMAL, TR::reset__by_continuing).with_bottom_padding(17), /* simulating a carriage return */
@ -685,12 +664,12 @@ extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs:
let paragraphs = Paragraphs::new(par_array);
let buttons = Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL),
Button::with_text(button.into()).styled(theme::button_confirm()),
Button::with_text(button).styled(theme::button_confirm()),
true,
);
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
Dialog::new(paragraphs, buttons),
))?;
Ok(obj.into())
@ -700,12 +679,12 @@ extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let qr_title: StrBuffer = kwargs.get(Qstr::MP_QSTR_qr_title)?.try_into()?;
let details_title: StrBuffer = kwargs.get(Qstr::MP_QSTR_details_title)?.try_into()?;
let address: StrBuffer = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let qr_title: TString<'static> = kwargs.get(Qstr::MP_QSTR_qr_title)?.try_into()?;
let details_title: TString = kwargs.get(Qstr::MP_QSTR_details_title)?.try_into()?;
let address: TString = kwargs.get(Qstr::MP_QSTR_address)?.try_into()?;
let case_sensitive: bool = kwargs.get(Qstr::MP_QSTR_case_sensitive)?.try_into()?;
let account: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let path: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
let account: Option<TString> = kwargs.get(Qstr::MP_QSTR_account)?.try_into_option()?;
let path: Option<TString> = kwargs.get(Qstr::MP_QSTR_path)?.try_into_option()?;
let xpubs: Obj = kwargs.get(Qstr::MP_QSTR_xpubs)?;
@ -719,7 +698,7 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
)?;
for i in IterBuf::new().try_iterate(xpubs)? {
let [xtitle, text]: [StrBuffer; 2] = util::iter_into_array(i)?;
let [xtitle, text]: [TString; 2] = util::iter_into_array(i)?;
ad.add_xpub(xtitle, text)?;
}
@ -732,7 +711,7 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let horizontal: bool = kwargs.get_or(Qstr::MP_QSTR_horizontal, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
@ -741,8 +720,8 @@ extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs:
for para in IterBuf::new().try_iterate(items)? {
let [key, value]: [Obj; 2] = util::iter_into_array(para)?;
let key: StrBuffer = key.try_into()?;
let value: StrBuffer = value.try_into()?;
let key: TString = key.try_into()?;
let value: TString = value.try_into()?;
paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, key).no_break());
if chunkify {
paragraphs.add(Paragraph::new(
@ -762,7 +741,7 @@ extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs:
let obj = LayoutObj::new(
Frame::left_aligned(
theme::label_title(),
title.into(),
title,
SimplePage::new(paragraphs.into_paragraphs(), axis, theme::BG)
.with_swipe_right_to_go_back(),
)
@ -775,18 +754,18 @@ extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let subtitle: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_subtitle)?.try_into_option()?;
let description: Option<StrBuffer> =
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let subtitle: Option<TString> = kwargs.get(Qstr::MP_QSTR_subtitle)?.try_into_option()?;
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let value: Obj = kwargs.get(Qstr::MP_QSTR_value)?;
let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?;
let verb: Option<StrBuffer> = kwargs
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<StrBuffer> = kwargs
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
@ -806,7 +785,7 @@ extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?;
let cancel_arrow: bool = kwargs.get_or(Qstr::MP_QSTR_cancel_arrow, false)?;
@ -814,7 +793,7 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
let mut paragraphs = ParagraphVecShort::new();
for pair in IterBuf::new().try_iterate(items)? {
let [label, value]: [StrBuffer; 2] = util::iter_into_array(pair)?;
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, label).no_break());
paragraphs.add(Paragraph::new(&theme::TEXT_MONO, value));
}
@ -825,7 +804,7 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
if info_button {
page = page.with_swipe_left();
}
let mut frame = Frame::left_aligned(theme::label_title(), title.into(), page);
let mut frame = Frame::left_aligned(theme::label_title(), title, page);
if info_button {
frame = frame.with_info_button();
}
@ -838,8 +817,8 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let sign: i32 = kwargs.get(Qstr::MP_QSTR_sign)?.try_into()?;
let amount_change: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_change)?.try_into()?;
let amount_new: StrBuffer = kwargs.get(Qstr::MP_QSTR_amount_new)?.try_into()?;
let amount_change: TString = kwargs.get(Qstr::MP_QSTR_amount_change)?.try_into()?;
let amount_new: TString = kwargs.get(Qstr::MP_QSTR_amount_new)?.try_into()?;
let description = if sign < 0 {
TR::modify_amount__decrease_amount
@ -867,10 +846,10 @@ extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let sign: i32 = kwargs.get(Qstr::MP_QSTR_sign)?.try_into()?;
let user_fee_change: StrBuffer = kwargs.get(Qstr::MP_QSTR_user_fee_change)?.try_into()?;
let total_fee_new: StrBuffer = kwargs.get(Qstr::MP_QSTR_total_fee_new)?.try_into()?;
let user_fee_change: TString = kwargs.get(Qstr::MP_QSTR_user_fee_change)?.try_into()?;
let total_fee_new: TString = kwargs.get(Qstr::MP_QSTR_total_fee_new)?.try_into()?;
let (description, change, total_label) = match sign {
s if s < 0 => (
@ -885,7 +864,7 @@ extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *m
),
_ => (
TR::modify_fee__no_change,
StrBuffer::empty(),
"".into(),
TR::modify_fee__transaction_fee,
),
};
@ -900,7 +879,7 @@ extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *m
let obj = LayoutObj::new(
Frame::left_aligned(
theme::label_title(),
title.into(),
title,
ButtonPage::new(paragraphs, theme::BG)
.with_hold()?
.with_swipe_left(),
@ -917,15 +896,14 @@ fn new_show_modal(
icon: BlendedImage,
button_style: ButtonStyleSheet,
) -> Result<Obj, Error> {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let value: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_value, StrBuffer::empty())?;
let description: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let button: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_button, TR::buttons__continue.try_into()?)?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let value: TString = kwargs.get_or(Qstr::MP_QSTR_value, "".into())?;
let description: TString = kwargs.get_or(Qstr::MP_QSTR_description, "".into())?;
let button: TString = kwargs.get_or(Qstr::MP_QSTR_button, TR::buttons__continue.try_into()?)?;
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
let time_ms: u32 = kwargs.get_or(Qstr::MP_QSTR_time_ms, 0)?;
let no_buttons = button.as_ref().is_empty();
let no_buttons = button.is_empty();
let obj = if no_buttons && time_ms == 0 {
// No buttons and no timer, used when we only want to draw the dialog once and
// then throw away the layout object.
@ -955,7 +933,7 @@ fn new_show_modal(
title,
Button::cancel_confirm(
Button::with_icon(theme::ICON_CANCEL),
Button::with_text(button.into()).styled(button_style),
Button::with_text(button).styled(button_style),
false,
),
)
@ -969,9 +947,9 @@ fn new_show_modal(
IconDialog::new(
icon,
title,
theme::button_bar(Button::with_text(button.into()).styled(button_style).map(
|msg| (matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed),
)),
theme::button_bar(Button::with_text(button).styled(button_style).map(|msg| {
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
})),
)
.with_value(value)
.with_description(description),
@ -998,8 +976,8 @@ extern "C" fn new_show_error(n_args: usize, args: *const Obj, kwargs: *mut Map)
extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let app_name: StrBuffer = kwargs.get(Qstr::MP_QSTR_app_name)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let app_name: TString = kwargs.get(Qstr::MP_QSTR_app_name)?.try_into()?;
let icon: Option<TString> = kwargs.get(Qstr::MP_QSTR_icon_name)?.try_into_option()?;
let accounts: Gc<List> = kwargs.get(Qstr::MP_QSTR_accounts)?.try_into()?;
@ -1019,13 +997,9 @@ extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map
true,
);
let fido_page = FidoConfirm::new(app_name.into(), get_page, page_count, icon, controls);
let fido_page = FidoConfirm::new(app_name, get_page, page_count, icon, controls);
let obj = LayoutObj::new(Frame::centered(
theme::label_title(),
title.into(),
fido_page,
))?;
let obj = LayoutObj::new(Frame::centered(theme::label_title(), title, fido_page))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -1075,10 +1049,10 @@ extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -
extern "C" fn new_show_mismatch(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = TR::addr_mismatch__contact_support_at.try_into()?;
let url: StrBuffer = TR::addr_mismatch__support_url.try_into()?;
let button: StrBuffer = TR::buttons__quit.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: TString = TR::addr_mismatch__contact_support_at.try_into()?;
let url: TString = TR::addr_mismatch__support_url.try_into()?;
let button: TString = TR::buttons__quit.try_into()?;
let icon = BlendedImage::new(
theme::IMAGE_BG_OCTAGON,
@ -1093,7 +1067,7 @@ extern "C" fn new_show_mismatch(n_args: usize, args: *const Obj, kwargs: *mut Ma
title,
Button::cancel_confirm(
Button::with_icon(theme::ICON_BACK),
Button::with_text(button.into()).styled(theme::button_reset()),
Button::with_text(button).styled(theme::button_reset()),
true,
),
)
@ -1115,18 +1089,17 @@ extern "C" fn new_show_mismatch(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_show_simple(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_title)?.try_into_option()?;
let description: StrBuffer =
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
let button: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_button, StrBuffer::empty())?;
let title: Option<TString> = kwargs.get(Qstr::MP_QSTR_title)?.try_into_option()?;
let description: TString = kwargs.get_or(Qstr::MP_QSTR_description, "".into())?;
let button: TString = kwargs.get_or(Qstr::MP_QSTR_button, "".into())?;
let obj = if let Some(t) = title {
LayoutObj::new(Frame::left_aligned(
theme::label_title(),
t.into(),
t,
Dialog::new(
Paragraphs::new([Paragraph::new(&theme::TEXT_NORMAL, description)]),
theme::button_bar(Button::with_text(button.into()).map(|msg| {
theme::button_bar(Button::with_text(button).map(|msg| {
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
})),
),
@ -1137,7 +1110,7 @@ extern "C" fn new_show_simple(n_args: usize, args: *const Obj, kwargs: *mut Map)
theme::borders(),
Dialog::new(
Paragraphs::new([Paragraph::new(&theme::TEXT_NORMAL, description)]),
theme::button_bar(Button::with_text(button.into()).map(|msg| {
theme::button_bar(Button::with_text(button).map(|msg| {
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
})),
),
@ -1163,9 +1136,9 @@ extern "C" fn new_show_simple(n_args: usize, args: *const Obj, kwargs: *mut Map)
extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let info_button: StrBuffer = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let info_button: TString = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut paragraphs = ParagraphVecShort::new();
@ -1173,18 +1146,18 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: StrBuffer = text.try_into()?;
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let buttons = Button::cancel_info_confirm(button.into(), info_button.into());
let buttons = Button::cancel_info_confirm(button, info_button);
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
Dialog::new(paragraphs.into_paragraphs(), buttons),
))?;
Ok(obj.into())
@ -1194,8 +1167,8 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut paragraphs = ParagraphVecLong::new();
@ -1203,15 +1176,15 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: StrBuffer = text.try_into()?;
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
}
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG)
.with_cancel_confirm(None, Some(button.into()))
.with_cancel_confirm(None, Some(button))
.with_confirm_style(theme::button_default())
.with_back_button(),
))?;
@ -1222,8 +1195,8 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map
extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let max_rounds: StrBuffer = kwargs.get(Qstr::MP_QSTR_max_rounds)?.try_into()?;
let max_feerate: StrBuffer = kwargs.get(Qstr::MP_QSTR_max_feerate)?.try_into()?;
let max_rounds: TString = kwargs.get(Qstr::MP_QSTR_max_rounds)?.try_into()?;
let max_feerate: TString = kwargs.get(Qstr::MP_QSTR_max_feerate)?.try_into()?;
let paragraphs = Paragraphs::new([
Paragraph::new(&theme::TEXT_NORMAL, TR::coinjoin__max_rounds),
@ -1244,8 +1217,8 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
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: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let subprompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let subprompt: TString = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
let warning: bool = kwargs.get_or(Qstr::MP_QSTR_wrong_pin, false)?;
let warning = if warning {
@ -1253,12 +1226,7 @@ extern "C" fn new_request_pin(n_args: usize, args: *const Obj, kwargs: *mut Map)
} else {
None
};
let obj = LayoutObj::new(PinKeyboard::new(
prompt.into(),
subprompt.into(),
warning,
allow_cancel,
))?;
let obj = LayoutObj::new(PinKeyboard::new(prompt, subprompt, warning, allow_cancel))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -1266,7 +1234,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: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let _prompt: TString = 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())?;
Ok(obj.into())
@ -1276,12 +1244,12 @@ 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: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: StrBuffer = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(MnemonicKeyboard::new(
Bip39Input::prefilled_word(prefill_word.as_ref()),
prompt.into(),
prefill_word.map(Bip39Input::prefilled_word),
prompt,
can_go_back,
))?;
Ok(obj.into())
@ -1291,12 +1259,12 @@ 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: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: StrBuffer = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
let prefill_word: TString = kwargs.get(Qstr::MP_QSTR_prefill_word)?.try_into()?;
let can_go_back: bool = kwargs.get(Qstr::MP_QSTR_can_go_back)?.try_into()?;
let obj = LayoutObj::new(MnemonicKeyboard::new(
Slip39Input::prefilled_word(prefill_word.as_ref()),
prompt.into(),
prefill_word.map(Slip39Input::prefilled_word),
prompt,
can_go_back,
))?;
Ok(obj.into())
@ -1306,15 +1274,15 @@ extern "C" fn new_request_slip39(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let words_iterable: Obj = kwargs.get(Qstr::MP_QSTR_words)?;
let words: [TString<'static>; 3] = util::iter_into_array(words_iterable)?;
let paragraphs = Paragraphs::new([Paragraph::new(&theme::TEXT_DEMIBOLD, description)]);
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
Dialog::new(paragraphs, Button::select_word(words)),
))?;
Ok(obj.into())
@ -1324,18 +1292,18 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let pages: Obj = kwargs.get(Qstr::MP_QSTR_pages)?;
let mut paragraphs = ParagraphVecLong::new();
for page in IterBuf::new().try_iterate(pages)? {
let text: StrBuffer = page.try_into()?;
let text: TString = page.try_into()?;
paragraphs.add(Paragraph::new(&theme::TEXT_MONO, text).break_after());
}
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG)
.with_hold()?
.without_cancel(),
@ -1347,7 +1315,7 @@ extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let min_count: u32 = kwargs.get(Qstr::MP_QSTR_min_count)?.try_into()?;
let max_count: u32 = kwargs.get(Qstr::MP_QSTR_max_count)?.try_into()?;
let count: u32 = kwargs.get(Qstr::MP_QSTR_count)?.try_into()?;
@ -1355,7 +1323,7 @@ extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut M
assert!(description_callback != Obj::const_none());
let callback = move |i: u32| {
StrBuffer::try_from(
TString::try_from(
description_callback
.call_with_n_args(&[i.try_into().unwrap()])
.unwrap(),
@ -1365,7 +1333,7 @@ extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut M
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
NumberInputDialog::new(min_count, max_count, count, callback)?,
))?;
Ok(obj.into())
@ -1375,8 +1343,8 @@ extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let active: usize = kwargs.get(Qstr::MP_QSTR_active)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
@ -1387,13 +1355,13 @@ extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut M
Ordering::Equal => &theme::TEXT_CHECKLIST_SELECTED,
Ordering::Greater => &theme::TEXT_CHECKLIST_DEFAULT,
};
let text: StrBuffer = item.try_into()?;
let text: TString = item.try_into()?;
paragraphs.add(Paragraph::new(style, text));
}
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
Dialog::new(
Checklist::from_paragraphs(
theme::ICON_LIST_CURRENT,
@ -1406,7 +1374,7 @@ extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut M
.with_check_width(theme::CHECKLIST_CHECK_WIDTH)
.with_current_offset(theme::CHECKLIST_CURRENT_OFFSET)
.with_done_offset(theme::CHECKLIST_DONE_OFFSET),
theme::button_bar(Button::with_text(button.into()).map(|msg| {
theme::button_bar(Button::with_text(button).map(|msg| {
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
})),
),
@ -1418,9 +1386,9 @@ extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let button: StrBuffer = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let dry_run: bool = kwargs.get(Qstr::MP_QSTR_dry_run)?.try_into()?;
let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?;
@ -1430,7 +1398,7 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut
])
.with_spacing(theme::RECOVERY_SPACING);
let notification: StrBuffer = if dry_run {
let notification: TString = if dry_run {
TR::recovery__title_dry_run.try_into()?
} else {
TR::recovery__title.try_into()?
@ -1439,7 +1407,7 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut
let obj = if info_button {
LayoutObj::new(Frame::left_aligned(
theme::label_title(),
notification.into(),
notification,
Dialog::new(
paragraphs,
Button::cancel_info_confirm(
@ -1451,11 +1419,8 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut
} else {
LayoutObj::new(Frame::left_aligned(
theme::label_title(),
notification.into(),
Dialog::new(
paragraphs,
Button::cancel_confirm_text(None, Some(button.into())),
),
notification,
Dialog::new(paragraphs, Button::cancel_confirm_text(None, Some(button))),
))?
};
Ok(obj.into())
@ -1466,7 +1431,7 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_select_word_count(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let dry_run: bool = kwargs.get(Qstr::MP_QSTR_dry_run)?.try_into()?;
let title: StrBuffer = if dry_run {
let title: TString = if dry_run {
TR::recovery__title_dry_run.try_into()?
} else {
TR::recovery__title.try_into()?
@ -1479,7 +1444,7 @@ extern "C" fn new_select_word_count(n_args: usize, args: *const Obj, kwargs: *mu
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title.into(),
title,
Dialog::new(paragraphs, SelectWordCount::new()),
))?;
Ok(obj.into())
@ -1494,7 +1459,7 @@ extern "C" fn new_show_group_share_success(
) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let lines_iterable: Obj = kwargs.get(Qstr::MP_QSTR_lines)?;
let lines: [StrBuffer; 4] = util::iter_into_array(lines_iterable)?;
let lines: [TString; 4] = util::iter_into_array(lines_iterable)?;
let obj = LayoutObj::new(IconDialog::new_shares(
lines,
@ -1513,7 +1478,7 @@ extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs:
let mut paragraphs = ParagraphVecLong::new();
for page in IterBuf::new().try_iterate(pages_iterable)? {
let [title, description]: [StrBuffer; 2] = util::iter_into_array(page)?;
let [title, description]: [TString; 2] = util::iter_into_array(page)?;
paragraphs
.add(Paragraph::new(&theme::TEXT_DEMIBOLD, title))
.add(Paragraph::new(&theme::TEXT_NORMAL, description).break_after());
@ -1534,9 +1499,9 @@ extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs:
extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
let title: Option<StrBuffer> = kwargs
let title: Option<TString> = kwargs
.get(Qstr::MP_QSTR_title)
.and_then(Obj::try_into_option)
.unwrap_or(None);
@ -1544,16 +1509,10 @@ extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Ma
let (title, description) = if let Some(title) = title {
(title, description)
} else {
(description, StrBuffer::empty())
(description, "".into())
};
// Description updates are received as &str and we need to provide a way to
// convert them to StrBuffer.
let obj = LayoutObj::new(Progress::new(
title.into(),
indeterminate,
description.into(),
))?;
let obj = LayoutObj::new(Progress::new(title, indeterminate, description))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -1561,14 +1520,14 @@ extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Ma
extern "C" fn new_show_progress_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
let time_ms: u32 = kwargs.get_or(Qstr::MP_QSTR_time_ms, 0)?;
let skip_first_paint: bool = kwargs.get_or(Qstr::MP_QSTR_skip_first_paint, false)?;
// The second type parameter is actually not used in `new()` but we need to
// provide it.
let progress = CoinJoinProgress::<Never>::new(title.into(), indeterminate)?;
let progress = CoinJoinProgress::<Never>::new(title, indeterminate)?;
let obj = if time_ms > 0 && indeterminate {
let timeout = Timeout::new(time_ms);
LayoutObj::new((timeout, progress.map(|_msg| None)))?
@ -1642,12 +1601,12 @@ extern "C" fn new_confirm_firmware_update(
) -> Obj {
use super::component::bl_confirm::{Confirm, ConfirmTitle};
let block = move |_args: &[Obj], kwargs: &Map| {
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let fingerprint: StrBuffer = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?;
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
let fingerprint: TString = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?;
let title_str = TR::firmware_update__title.into();
let title = Label::left_aligned(title_str, theme::TEXT_BOLD).vertically_centered();
let msg = Label::left_aligned(description.into(), theme::TEXT_NORMAL);
let msg = Label::left_aligned(description, theme::TEXT_NORMAL);
let left = Button::with_text(TR::buttons__cancel.into()).styled(theme::button_default());
let right = Button::with_text(TR::buttons__install.into()).styled(theme::button_confirm());
@ -1655,7 +1614,7 @@ extern "C" fn new_confirm_firmware_update(
let obj = LayoutObj::new(
Confirm::new(theme::BG, left, right, ConfirmTitle::Text(title), msg).with_info(
TR::firmware_update__title_fingerprint.into(),
fingerprint.into(),
fingerprint,
theme::button_moreinfo(),
),
)?;

Loading…
Cancel
Save