mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-01 20:08:26 +00:00
refactor(core): move show_checklist to UiFeatures
- checklist is now fixed to 3 items as they are not used in other way, it can be switched to use heapless::Vec if the need for more items appears.
This commit is contained in:
parent
466d9a796e
commit
f8fec86dab
@ -227,6 +227,21 @@ extern "C" fn new_set_brightness(n_args: usize, args: *const Obj, kwargs: *mut M
|
|||||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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: 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)?;
|
||||||
|
|
||||||
|
let items: [TString<'static>; 3] = util::iter_into_array(items)?;
|
||||||
|
|
||||||
|
let layout = ModelUI::show_checklist(title, button, active, items)?;
|
||||||
|
Ok(LayoutObj::new_root(layout)?.into())
|
||||||
|
};
|
||||||
|
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn new_show_homescreen(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
extern "C" fn new_show_homescreen(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||||
let label: TString<'static> = kwargs
|
let label: TString<'static> = kwargs
|
||||||
@ -543,6 +558,17 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
|||||||
/// """Show the brightness configuration dialog."""
|
/// """Show the brightness configuration dialog."""
|
||||||
Qstr::MP_QSTR_set_brightness => obj_fn_kw!(0, new_set_brightness).as_obj(),
|
Qstr::MP_QSTR_set_brightness => obj_fn_kw!(0, new_set_brightness).as_obj(),
|
||||||
|
|
||||||
|
/// def show_checklist(
|
||||||
|
/// *,
|
||||||
|
/// title: str,
|
||||||
|
/// items: Iterable[str],
|
||||||
|
/// active: int,
|
||||||
|
/// button: str,
|
||||||
|
/// ) -> LayoutObj[UiResult]:
|
||||||
|
/// """Checklist of backup steps. Active index is highlighted, previous items have check
|
||||||
|
/// mark next to them. Limited to 3 items."""
|
||||||
|
Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(),
|
||||||
|
|
||||||
/// def show_homescreen(
|
/// def show_homescreen(
|
||||||
/// *,
|
/// *,
|
||||||
/// label: str | None,
|
/// label: str | None,
|
||||||
|
@ -1063,47 +1063,6 @@ extern "C" fn new_prompt_backup() -> Obj {
|
|||||||
unsafe { util::try_or_raise(block) }
|
unsafe { util::try_or_raise(block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
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: 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)?;
|
|
||||||
|
|
||||||
let mut paragraphs = ParagraphVecLong::new();
|
|
||||||
for (i, item) in IterBuf::new().try_iterate(items)?.enumerate() {
|
|
||||||
let style = match i.cmp(&active) {
|
|
||||||
Ordering::Less => &theme::TEXT_CHECKLIST_DONE,
|
|
||||||
Ordering::Equal => &theme::TEXT_CHECKLIST_SELECTED,
|
|
||||||
Ordering::Greater => &theme::TEXT_CHECKLIST_DEFAULT,
|
|
||||||
};
|
|
||||||
let text: TString = item.try_into()?;
|
|
||||||
paragraphs.add(Paragraph::new(style, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
let checklist_content = Checklist::from_paragraphs(
|
|
||||||
theme::ICON_CHEVRON_RIGHT,
|
|
||||||
theme::ICON_BULLET_CHECKMARK,
|
|
||||||
active,
|
|
||||||
paragraphs
|
|
||||||
.into_paragraphs()
|
|
||||||
.with_spacing(theme::CHECKLIST_SPACING),
|
|
||||||
)
|
|
||||||
.with_check_width(theme::CHECKLIST_CHECK_WIDTH)
|
|
||||||
.with_numerals()
|
|
||||||
.with_icon_done_color(theme::GREEN)
|
|
||||||
.with_done_offset(theme::CHECKLIST_DONE_OFFSET);
|
|
||||||
|
|
||||||
let obj = LayoutObj::new(SwipeUpScreen::new(
|
|
||||||
Frame::left_aligned(title, SwipeContent::new(checklist_content))
|
|
||||||
.with_footer(TR::instructions__swipe_up.into(), None)
|
|
||||||
.with_swipe(Direction::Up, SwipeSettings::default()),
|
|
||||||
))?;
|
|
||||||
Ok(obj.into())
|
|
||||||
};
|
|
||||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" fn new_show_tutorial() -> Obj {
|
extern "C" fn new_show_tutorial() -> Obj {
|
||||||
let block = || {
|
let block = || {
|
||||||
let flow = flow::show_tutorial::new_show_tutorial()?;
|
let flow = flow::show_tutorial::new_show_tutorial()?;
|
||||||
@ -1407,17 +1366,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
|||||||
/// confirmation."""
|
/// confirmation."""
|
||||||
Qstr::MP_QSTR_flow_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
|
Qstr::MP_QSTR_flow_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
|
||||||
|
|
||||||
/// def show_checklist(
|
|
||||||
/// *,
|
|
||||||
/// title: str,
|
|
||||||
/// items: Iterable[str],
|
|
||||||
/// active: int,
|
|
||||||
/// button: str,
|
|
||||||
/// ) -> LayoutObj[UiResult]:
|
|
||||||
/// """Checklist of backup steps. Active index is highlighted, previous items have check
|
|
||||||
/// mark next to them."""
|
|
||||||
Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(),
|
|
||||||
|
|
||||||
/// def flow_continue_recovery(
|
/// def flow_continue_recovery(
|
||||||
/// *,
|
/// *,
|
||||||
/// first_screen: bool,
|
/// first_screen: bool,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{value_error, Error},
|
error::{value_error, Error},
|
||||||
io::BinaryData,
|
io::BinaryData,
|
||||||
@ -8,7 +10,10 @@ use crate::{
|
|||||||
component::{
|
component::{
|
||||||
connect::Connect,
|
connect::Connect,
|
||||||
swipe_detect::SwipeSettings,
|
swipe_detect::SwipeSettings,
|
||||||
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs},
|
text::paragraphs::{
|
||||||
|
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
|
||||||
|
Paragraphs, VecExt,
|
||||||
|
},
|
||||||
CachedJpeg, ComponentExt, Never, Timeout,
|
CachedJpeg, ComponentExt, Never, Timeout,
|
||||||
},
|
},
|
||||||
geometry::Direction,
|
geometry::Direction,
|
||||||
@ -218,6 +223,43 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
|
|||||||
Ok(flow)
|
Ok(flow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_checklist(
|
||||||
|
title: TString<'static>,
|
||||||
|
button: TString<'static>,
|
||||||
|
active: usize,
|
||||||
|
items: [TString<'static>; 3],
|
||||||
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
|
let mut paragraphs = ParagraphVecLong::new();
|
||||||
|
for (i, item) in items.into_iter().enumerate() {
|
||||||
|
let style = match i.cmp(&active) {
|
||||||
|
Ordering::Less => &theme::TEXT_CHECKLIST_DONE,
|
||||||
|
Ordering::Equal => &theme::TEXT_CHECKLIST_SELECTED,
|
||||||
|
Ordering::Greater => &theme::TEXT_CHECKLIST_DEFAULT,
|
||||||
|
};
|
||||||
|
paragraphs.add(Paragraph::new(style, item));
|
||||||
|
}
|
||||||
|
|
||||||
|
let checklist_content = Checklist::from_paragraphs(
|
||||||
|
theme::ICON_CHEVRON_RIGHT,
|
||||||
|
theme::ICON_BULLET_CHECKMARK,
|
||||||
|
active,
|
||||||
|
paragraphs
|
||||||
|
.into_paragraphs()
|
||||||
|
.with_spacing(theme::CHECKLIST_SPACING),
|
||||||
|
)
|
||||||
|
.with_check_width(theme::CHECKLIST_CHECK_WIDTH)
|
||||||
|
.with_numerals()
|
||||||
|
.with_icon_done_color(theme::GREEN)
|
||||||
|
.with_done_offset(theme::CHECKLIST_DONE_OFFSET);
|
||||||
|
|
||||||
|
let layout = RootComponent::new(SwipeUpScreen::new(
|
||||||
|
Frame::left_aligned(title, SwipeContent::new(checklist_content))
|
||||||
|
.with_footer(TR::instructions__swipe_up.into(), None)
|
||||||
|
.with_swipe(Direction::Up, SwipeSettings::default()),
|
||||||
|
));
|
||||||
|
Ok(layout)
|
||||||
|
}
|
||||||
|
|
||||||
fn show_homescreen(
|
fn show_homescreen(
|
||||||
label: TString<'static>,
|
label: TString<'static>,
|
||||||
hold: bool,
|
hold: bool,
|
||||||
|
@ -1205,46 +1205,6 @@ extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut
|
|||||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn new_show_checklist(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 active: usize = kwargs.get(Qstr::MP_QSTR_active)?.try_into()?;
|
|
||||||
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
|
|
||||||
|
|
||||||
let mut paragraphs = ParagraphVecLong::new();
|
|
||||||
for (i, item) in IterBuf::new().try_iterate(items)?.enumerate() {
|
|
||||||
let style = match i.cmp(&active) {
|
|
||||||
Ordering::Less => &theme::TEXT_NORMAL,
|
|
||||||
Ordering::Equal => &theme::TEXT_BOLD,
|
|
||||||
Ordering::Greater => &theme::TEXT_NORMAL,
|
|
||||||
};
|
|
||||||
let text: TString = item.try_into()?;
|
|
||||||
paragraphs.add(Paragraph::new(style, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
let confirm_btn = Some(ButtonDetails::text(button));
|
|
||||||
|
|
||||||
let obj = LayoutObj::new(
|
|
||||||
ButtonPage::new(
|
|
||||||
Checklist::from_paragraphs(
|
|
||||||
theme::ICON_ARROW_RIGHT_FAT,
|
|
||||||
theme::ICON_TICK_FAT,
|
|
||||||
active,
|
|
||||||
paragraphs
|
|
||||||
.into_paragraphs()
|
|
||||||
.with_spacing(theme::CHECKLIST_SPACING),
|
|
||||||
)
|
|
||||||
.with_check_width(theme::CHECKLIST_CHECK_WIDTH)
|
|
||||||
.with_current_offset(theme::CHECKLIST_CURRENT_OFFSET),
|
|
||||||
theme::BG,
|
|
||||||
)
|
|
||||||
.with_confirm_btn(confirm_btn),
|
|
||||||
)?;
|
|
||||||
Ok(obj.into())
|
|
||||||
};
|
|
||||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||||
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||||
@ -1549,17 +1509,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
|||||||
/// """Shows a backup seed."""
|
/// """Shows a backup seed."""
|
||||||
Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
|
Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
|
||||||
|
|
||||||
/// def show_checklist(
|
|
||||||
/// *,
|
|
||||||
/// title: str, # unused on TR
|
|
||||||
/// items: Iterable[str],
|
|
||||||
/// active: int,
|
|
||||||
/// button: str,
|
|
||||||
/// ) -> LayoutObj[UiResult]:
|
|
||||||
/// """Checklist of backup steps. Active index is highlighted, previous items have check
|
|
||||||
/// mark next to them."""
|
|
||||||
Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(),
|
|
||||||
|
|
||||||
/// def confirm_recovery(
|
/// def confirm_recovery(
|
||||||
/// *,
|
/// *,
|
||||||
/// title: str, # unused on TR
|
/// title: str, # unused on TR
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::Error,
|
||||||
io::BinaryData,
|
io::BinaryData,
|
||||||
@ -8,7 +10,10 @@ use crate::{
|
|||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{
|
||||||
connect::Connect,
|
connect::Connect,
|
||||||
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt},
|
text::paragraphs::{
|
||||||
|
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
|
||||||
|
Paragraphs, VecExt,
|
||||||
|
},
|
||||||
Component, ComponentExt, Empty, Label, LineBreaking, Paginate, Timeout,
|
Component, ComponentExt, Empty, Label, LineBreaking, Paginate, Timeout,
|
||||||
},
|
},
|
||||||
layout::{
|
layout::{
|
||||||
@ -219,6 +224,42 @@ impl UIFeaturesFirmware for ModelTRFeatures {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_checklist(
|
||||||
|
title: TString<'static>,
|
||||||
|
button: TString<'static>,
|
||||||
|
active: usize,
|
||||||
|
items: [TString<'static>; 3],
|
||||||
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
|
let mut paragraphs = ParagraphVecLong::new();
|
||||||
|
for (i, item) in items.into_iter().enumerate() {
|
||||||
|
let style = match i.cmp(&active) {
|
||||||
|
Ordering::Less => &theme::TEXT_NORMAL,
|
||||||
|
Ordering::Equal => &theme::TEXT_BOLD,
|
||||||
|
Ordering::Greater => &theme::TEXT_NORMAL,
|
||||||
|
};
|
||||||
|
paragraphs.add(Paragraph::new(style, item));
|
||||||
|
}
|
||||||
|
let confirm_btn = Some(ButtonDetails::text(button));
|
||||||
|
|
||||||
|
let layout = RootComponent::new(
|
||||||
|
ButtonPage::new(
|
||||||
|
Checklist::from_paragraphs(
|
||||||
|
theme::ICON_ARROW_RIGHT_FAT,
|
||||||
|
theme::ICON_TICK_FAT,
|
||||||
|
active,
|
||||||
|
paragraphs
|
||||||
|
.into_paragraphs()
|
||||||
|
.with_spacing(theme::CHECKLIST_SPACING),
|
||||||
|
)
|
||||||
|
.with_check_width(theme::CHECKLIST_CHECK_WIDTH)
|
||||||
|
.with_current_offset(theme::CHECKLIST_CURRENT_OFFSET),
|
||||||
|
theme::BG,
|
||||||
|
)
|
||||||
|
.with_confirm_btn(confirm_btn),
|
||||||
|
);
|
||||||
|
Ok(layout)
|
||||||
|
}
|
||||||
|
|
||||||
fn show_homescreen(
|
fn show_homescreen(
|
||||||
label: TString<'static>,
|
label: TString<'static>,
|
||||||
hold: bool,
|
hold: bool,
|
||||||
|
@ -1131,49 +1131,6 @@ extern "C" fn new_show_share_words(n_args: usize, args: *const Obj, kwargs: *mut
|
|||||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
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: 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)?;
|
|
||||||
|
|
||||||
let mut paragraphs = ParagraphVecLong::new();
|
|
||||||
for (i, item) in IterBuf::new().try_iterate(items)?.enumerate() {
|
|
||||||
let style = match i.cmp(&active) {
|
|
||||||
Ordering::Less => &theme::TEXT_CHECKLIST_DONE,
|
|
||||||
Ordering::Equal => &theme::TEXT_CHECKLIST_SELECTED,
|
|
||||||
Ordering::Greater => &theme::TEXT_CHECKLIST_DEFAULT,
|
|
||||||
};
|
|
||||||
let text: TString = item.try_into()?;
|
|
||||||
paragraphs.add(Paragraph::new(style, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
let obj = LayoutObj::new(Frame::left_aligned(
|
|
||||||
theme::label_title(),
|
|
||||||
title,
|
|
||||||
Dialog::new(
|
|
||||||
Checklist::from_paragraphs(
|
|
||||||
theme::ICON_LIST_CURRENT,
|
|
||||||
theme::ICON_LIST_CHECK,
|
|
||||||
active,
|
|
||||||
paragraphs
|
|
||||||
.into_paragraphs()
|
|
||||||
.with_spacing(theme::CHECKLIST_SPACING),
|
|
||||||
)
|
|
||||||
.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).map(|msg| {
|
|
||||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
))?;
|
|
||||||
Ok(obj.into())
|
|
||||||
};
|
|
||||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||||
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||||
@ -1499,17 +1456,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
|||||||
/// """Show mnemonic for backup. Expects the words pre-divided into individual pages."""
|
/// """Show mnemonic for backup. Expects the words pre-divided into individual pages."""
|
||||||
Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
|
Qstr::MP_QSTR_show_share_words => obj_fn_kw!(0, new_show_share_words).as_obj(),
|
||||||
|
|
||||||
/// def show_checklist(
|
|
||||||
/// *,
|
|
||||||
/// title: str,
|
|
||||||
/// items: Iterable[str],
|
|
||||||
/// active: int,
|
|
||||||
/// button: str,
|
|
||||||
/// ) -> LayoutObj[UiResult]:
|
|
||||||
/// """Checklist of backup steps. Active index is highlighted, previous items have check
|
|
||||||
/// mark next to them."""
|
|
||||||
Qstr::MP_QSTR_show_checklist => obj_fn_kw!(0, new_show_checklist).as_obj(),
|
|
||||||
|
|
||||||
/// def confirm_recovery(
|
/// def confirm_recovery(
|
||||||
/// *,
|
/// *,
|
||||||
/// title: str,
|
/// title: str,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{value_error, Error},
|
error::{value_error, Error},
|
||||||
io::BinaryData,
|
io::BinaryData,
|
||||||
@ -8,7 +10,10 @@ use crate::{
|
|||||||
component::{
|
component::{
|
||||||
connect::Connect,
|
connect::Connect,
|
||||||
image::BlendedImage,
|
image::BlendedImage,
|
||||||
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt},
|
text::paragraphs::{
|
||||||
|
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
|
||||||
|
Paragraphs, VecExt,
|
||||||
|
},
|
||||||
ComponentExt, Empty, Jpeg, Label, Never, Timeout,
|
ComponentExt, Empty, Jpeg, Label, Never, Timeout,
|
||||||
},
|
},
|
||||||
layout::{
|
layout::{
|
||||||
@ -240,6 +245,45 @@ impl UIFeaturesFirmware for ModelTTFeatures {
|
|||||||
Ok(layout)
|
Ok(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_checklist(
|
||||||
|
title: TString<'static>,
|
||||||
|
button: TString<'static>,
|
||||||
|
active: usize,
|
||||||
|
items: [TString<'static>; 3],
|
||||||
|
) -> Result<impl LayoutMaybeTrace, Error> {
|
||||||
|
let mut paragraphs = ParagraphVecLong::new();
|
||||||
|
for (i, item) in items.into_iter().enumerate() {
|
||||||
|
let style = match i.cmp(&active) {
|
||||||
|
Ordering::Less => &theme::TEXT_CHECKLIST_DONE,
|
||||||
|
Ordering::Equal => &theme::TEXT_CHECKLIST_SELECTED,
|
||||||
|
Ordering::Greater => &theme::TEXT_CHECKLIST_DEFAULT,
|
||||||
|
};
|
||||||
|
paragraphs.add(Paragraph::new(style, item));
|
||||||
|
}
|
||||||
|
|
||||||
|
let layout = RootComponent::new(Frame::left_aligned(
|
||||||
|
theme::label_title(),
|
||||||
|
title,
|
||||||
|
Dialog::new(
|
||||||
|
Checklist::from_paragraphs(
|
||||||
|
theme::ICON_LIST_CURRENT,
|
||||||
|
theme::ICON_LIST_CHECK,
|
||||||
|
active,
|
||||||
|
paragraphs
|
||||||
|
.into_paragraphs()
|
||||||
|
.with_spacing(theme::CHECKLIST_SPACING),
|
||||||
|
)
|
||||||
|
.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).map(|msg| {
|
||||||
|
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
Ok(layout)
|
||||||
|
}
|
||||||
|
|
||||||
fn show_homescreen(
|
fn show_homescreen(
|
||||||
label: TString<'static>,
|
label: TString<'static>,
|
||||||
hold: bool,
|
hold: bool,
|
||||||
|
@ -75,6 +75,13 @@ pub trait UIFeaturesFirmware {
|
|||||||
|
|
||||||
fn set_brightness(current_brightness: Option<u8>) -> Result<impl LayoutMaybeTrace, Error>;
|
fn set_brightness(current_brightness: Option<u8>) -> Result<impl LayoutMaybeTrace, Error>;
|
||||||
|
|
||||||
|
fn show_checklist(
|
||||||
|
title: TString<'static>,
|
||||||
|
button: TString<'static>,
|
||||||
|
active: usize,
|
||||||
|
items: [TString<'static>; 3],
|
||||||
|
) -> Result<impl LayoutMaybeTrace, Error>;
|
||||||
|
|
||||||
fn show_homescreen(
|
fn show_homescreen(
|
||||||
label: TString<'static>,
|
label: TString<'static>,
|
||||||
hold: bool,
|
hold: bool,
|
||||||
|
@ -257,18 +257,6 @@ def flow_show_share_words(
|
|||||||
confirmation."""
|
confirmation."""
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/model_mercury/layout.rs
|
|
||||||
def show_checklist(
|
|
||||||
*,
|
|
||||||
title: str,
|
|
||||||
items: Iterable[str],
|
|
||||||
active: int,
|
|
||||||
button: str,
|
|
||||||
) -> LayoutObj[UiResult]:
|
|
||||||
"""Checklist of backup steps. Active index is highlighted, previous items have check
|
|
||||||
mark next to them."""
|
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/model_mercury/layout.rs
|
# rust/src/ui/model_mercury/layout.rs
|
||||||
def flow_continue_recovery(
|
def flow_continue_recovery(
|
||||||
*,
|
*,
|
||||||
@ -619,18 +607,6 @@ def show_share_words(
|
|||||||
"""Shows a backup seed."""
|
"""Shows a backup seed."""
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/model_tr/layout.rs
|
|
||||||
def show_checklist(
|
|
||||||
*,
|
|
||||||
title: str, # unused on TR
|
|
||||||
items: Iterable[str],
|
|
||||||
active: int,
|
|
||||||
button: str,
|
|
||||||
) -> LayoutObj[UiResult]:
|
|
||||||
"""Checklist of backup steps. Active index is highlighted, previous items have check
|
|
||||||
mark next to them."""
|
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/model_tr/layout.rs
|
# rust/src/ui/model_tr/layout.rs
|
||||||
def confirm_recovery(
|
def confirm_recovery(
|
||||||
*,
|
*,
|
||||||
@ -933,18 +909,6 @@ def show_share_words(
|
|||||||
"""Show mnemonic for backup. Expects the words pre-divided into individual pages."""
|
"""Show mnemonic for backup. Expects the words pre-divided into individual pages."""
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/model_tt/layout.rs
|
|
||||||
def show_checklist(
|
|
||||||
*,
|
|
||||||
title: str,
|
|
||||||
items: Iterable[str],
|
|
||||||
active: int,
|
|
||||||
button: str,
|
|
||||||
) -> LayoutObj[UiResult]:
|
|
||||||
"""Checklist of backup steps. Active index is highlighted, previous items have check
|
|
||||||
mark next to them."""
|
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/model_tt/layout.rs
|
# rust/src/ui/model_tt/layout.rs
|
||||||
def confirm_recovery(
|
def confirm_recovery(
|
||||||
*,
|
*,
|
||||||
|
@ -196,6 +196,18 @@ def set_brightness(
|
|||||||
"""Show the brightness configuration dialog."""
|
"""Show the brightness configuration dialog."""
|
||||||
|
|
||||||
|
|
||||||
|
# rust/src/ui/api/firmware_upy.rs
|
||||||
|
def show_checklist(
|
||||||
|
*,
|
||||||
|
title: str,
|
||||||
|
items: Iterable[str],
|
||||||
|
active: int,
|
||||||
|
button: str,
|
||||||
|
) -> LayoutObj[UiResult]:
|
||||||
|
"""Checklist of backup steps. Active index is highlighted, previous items have check
|
||||||
|
mark next to them. Limited to 3 items."""
|
||||||
|
|
||||||
|
|
||||||
# rust/src/ui/api/firmware_upy.rs
|
# rust/src/ui/api/firmware_upy.rs
|
||||||
def show_homescreen(
|
def show_homescreen(
|
||||||
*,
|
*,
|
||||||
|
@ -98,7 +98,7 @@ async def slip39_show_checklist(
|
|||||||
) -> None:
|
) -> None:
|
||||||
items = _slip_39_checklist_items(step, advanced, count, threshold)
|
items = _slip_39_checklist_items(step, advanced, count, threshold)
|
||||||
result = await interact(
|
result = await interact(
|
||||||
trezorui2.show_checklist(
|
trezorui_api.show_checklist(
|
||||||
title=TR.reset__title_shamir_backup,
|
title=TR.reset__title_shamir_backup,
|
||||||
button=TR.buttons__continue,
|
button=TR.buttons__continue,
|
||||||
active=step,
|
active=step,
|
||||||
|
@ -122,7 +122,7 @@ def slip39_show_checklist(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return raise_if_not_confirmed(
|
return raise_if_not_confirmed(
|
||||||
trezorui2.show_checklist(
|
trezorui_api.show_checklist(
|
||||||
title=TR.reset__slip39_checklist_title,
|
title=TR.reset__slip39_checklist_title,
|
||||||
button=TR.buttons__continue,
|
button=TR.buttons__continue,
|
||||||
active=step,
|
active=step,
|
||||||
|
@ -120,7 +120,7 @@ def slip39_show_checklist(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return raise_if_not_confirmed(
|
return raise_if_not_confirmed(
|
||||||
trezorui2.show_checklist(
|
trezorui_api.show_checklist(
|
||||||
title=TR.reset__slip39_checklist_title,
|
title=TR.reset__slip39_checklist_title,
|
||||||
button=TR.buttons__continue,
|
button=TR.buttons__continue,
|
||||||
active=step,
|
active=step,
|
||||||
|
Loading…
Reference in New Issue
Block a user