Skip to content

Commit

Permalink
feat(core/rust/ui): support ask_pagination flag in confirm_blob
Browse files Browse the repository at this point in the history
[no changelog]
  • Loading branch information
mmilata committed Dec 5, 2022
1 parent 58276a7 commit 4528577
Show file tree
Hide file tree
Showing 12 changed files with 435 additions and 256 deletions.
1 change: 1 addition & 0 deletions core/embed/rust/librust_qstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static void _librust_qstrs(void) {
MP_QSTR_confirm_text;
MP_QSTR_confirm_value;
MP_QSTR_confirm_with_info;
MP_QSTR_confirm_more;
MP_QSTR_confirm_recovery;
MP_QSTR_show_checklist;
MP_QSTR_show_error;
Expand Down
4 changes: 4 additions & 0 deletions core/embed/rust/src/ui/component/paginated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ pub enum PageMsg<T, U> {
/// Messages from page controls outside the paged component, like
/// "OK" and "Cancel" buttons.
Controls(U),

/// Page component was instantiated with BACK button on every page and it
/// was pressed.
GoBack,
}

pub trait Paginate {
Expand Down
2 changes: 1 addition & 1 deletion core/embed/rust/src/ui/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ impl Glyph {

/// Font constants. Keep in sync with FONT_ definitions in
/// `extmod/modtrezorui/fonts/fonts.h`.
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq, FromPrimitive)]
#[repr(u8)]
pub enum Font {
NORMAL = 1,
Expand Down
1 change: 1 addition & 0 deletions core/embed/rust/src/ui/model_t1/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ where
PageMsg::Content(_) => Err(Error::TypeError),
PageMsg::Controls(true) => Ok(CONFIRMED.as_obj()),
PageMsg::Controls(false) => Ok(CANCELLED.as_obj()),
PageMsg::GoBack => unreachable!(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/embed/rust/src/ui/model_tr/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ where
PageMsg::Content(_) => Err(Error::TypeError),
PageMsg::Controls(true) => Ok(CONFIRMED.as_obj()),
PageMsg::Controls(false) => Ok(CANCELLED.as_obj()),
PageMsg::GoBack => unreachable!(),
}
}
}
Expand Down
39 changes: 38 additions & 1 deletion core/embed/rust/src/ui/model_tt/component/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::ui::{
},
display::{self, Color},
geometry::{Insets, Rect},
model_tt::component::{Button, ButtonMsg},
};

use super::{
Expand All @@ -19,6 +20,7 @@ pub struct SwipePage<T, U> {
swipe: Swipe,
scrollbar: ScrollBar,
hint: Label<&'static str>,
button_back: Option<Button<&'static str>>,
fade: Option<i32>,
}

Expand All @@ -36,10 +38,16 @@ where
swipe: Swipe::new(),
pad: Pad::with_background(background),
hint: Label::centered("SWIPE TO CONTINUE", theme::label_page_hint()),
button_back: None,
fade: None,
}
}

pub fn with_back_button(mut self) -> Self {
self.button_back = Some(Button::with_icon(theme::ICON_BACK));
self
}

fn setup_swipe(&mut self) {
self.swipe.allow_up = self.scrollbar.has_next_page();
self.swipe.allow_down = self.scrollbar.has_previous_page();
Expand All @@ -66,7 +74,14 @@ where
let mut layout = PageLayout::new(bounds);
self.pad.place(bounds);
self.swipe.place(bounds);
self.hint.place(layout.hint);

if self.button_back.is_some() {
self.button_back.place(layout.hint_button);
self.hint.place(layout.hint_button_hint);
} else {
self.hint.place(layout.hint);
}

let buttons_area = self.buttons.place(layout.buttons);
layout.set_buttons_height(buttons_area.height());
self.scrollbar.place(layout.scrollbar);
Expand Down Expand Up @@ -136,6 +151,9 @@ where
return Some(PageMsg::Controls(msg));
}
} else {
if let Some(ButtonMsg::Clicked) = self.button_back.event(ctx, event) {
return Some(PageMsg::GoBack);
}
self.hint.event(ctx, event);
}
None
Expand All @@ -148,6 +166,7 @@ where
self.scrollbar.paint();
}
if self.scrollbar.has_next_page() {
self.button_back.paint();
self.hint.paint();
} else {
self.buttons.paint();
Expand All @@ -165,6 +184,7 @@ where
if !self.scrollbar.has_next_page() {
self.buttons.bounds(sink);
} else {
self.button_back.bounds(sink);
self.hint.bounds(sink);
}
}
Expand All @@ -187,11 +207,20 @@ where
}

pub struct PageLayout {
/// Content when it fits on single page (no scrollbar).
pub content_single_page: Rect,
/// Content when multiple pages.
pub content: Rect,
/// Scroll bar when multiple pages.
pub scrollbar: Rect,
/// Controls displayed on last page.
pub buttons: Rect,
/// Swipe to continue (unless back button enabled).
pub hint: Rect,
/// Optional back button on every page.
pub hint_button: Rect,
/// Hint area when back button is enabled.
pub hint_button_hint: Rect,
}

impl PageLayout {
Expand All @@ -208,12 +237,20 @@ impl PageLayout {
content.split_right(Self::SCROLLBAR_SPACE + Self::SCROLLBAR_WIDTH);
let (_space, scrollbar) = scrollbar.split_left(Self::SCROLLBAR_SPACE);

let (_, one_row_buttons) = area.split_bottom(theme::button_rows(1));
let (hint_button, hint_button_hint) = one_row_buttons.split_left(one_row_buttons.height());
let vertical_inset = (hint_button_hint.height() - Self::HINT_OFF) / 2;
let hint_button_hint =
hint_button_hint.inset(Insets::new(vertical_inset, 0, vertical_inset, 0));

Self {
content_single_page,
content,
scrollbar,
buttons,
hint,
hint_button,
hint_button_hint,
}
}

Expand Down
74 changes: 62 additions & 12 deletions core/embed/rust/src/ui/model_tt/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ use crate::{
image::BlendedImage,
paginated::{PageMsg, Paginate},
painter,
text::paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
text::{
paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
Border, Component, Timeout, TimeoutMsg,
},
geometry,
layout::{
obj::{ComponentMsgObj, LayoutObj},
result::{CANCELLED, CONFIRMED, INFO},
util::{iter_into_array, ConfirmBlob, PropsList},
util::{iter_into_array, iter_into_objs, ConfirmBlob, PropsList},
},
},
};
Expand Down Expand Up @@ -213,6 +216,7 @@ where
match msg {
PageMsg::Content(_) => Err(Error::TypeError),
PageMsg::Controls(msg) => msg.try_into(),
PageMsg::GoBack => Ok(CANCELLED.as_obj()),
}
}
}
Expand All @@ -225,6 +229,7 @@ where
match msg {
PageMsg::Content(_) => Err(Error::TypeError),
PageMsg::Controls(msg) => msg.try_into(),
PageMsg::GoBack => unreachable!(),
}
}
}
Expand Down Expand Up @@ -373,7 +378,6 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let _ask_pagination: bool = kwargs.get_or(Qstr::MP_QSTR_ask_pagination, false)?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;

let verb: StrBuffer = "CONFIRM".into();
Expand Down Expand Up @@ -763,20 +767,56 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
let info_button: StrBuffer = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;

let mut paragraphs = ParagraphVecLong::new();
let mut paragraphs = ParagraphVecShort::new();

let mut iter_buf = IterBuf::new();
let iter = Iter::try_from_obj_with_buf(items, &mut iter_buf)?;
for text in iter {
for para in iter {
let [font, text]: [Obj; 2] = iter_into_objs(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: StrBuffer = text.try_into()?;
paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, text));
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}

let buttons = Button::cancel_info_confirm(button, info_button);

let obj = LayoutObj::new(
Frame::new(title, Dialog::new(paragraphs.into_paragraphs(), buttons))
.with_border(theme::borders()),
)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}

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 items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;

let mut paragraphs = ParagraphVecLong::new();

let mut iter_buf = IterBuf::new();
let iter = Iter::try_from_obj_with_buf(items, &mut iter_buf)?;
for para in iter {
let [font, text]: [Obj; 2] = iter_into_objs(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: StrBuffer = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
}

let button =
theme::button_bar(Button::with_text(button).map(|msg| {
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
}));

let obj = LayoutObj::new(Frame::new(
title,
SwipePage::new(paragraphs.into_paragraphs(), buttons, theme::BG),
SwipePage::new(paragraphs.into_paragraphs(), button, theme::BG).with_back_button(),
))?;
Ok(obj.into())
};
Expand Down Expand Up @@ -1116,7 +1156,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// description: str | None,
/// extra: str | None,
/// verb_cancel: str | None = None,
/// ask_pagination: bool = False,
/// hold: bool = False,
/// ) -> object:
/// """Confirm byte sequence data."""
Expand Down Expand Up @@ -1259,11 +1298,22 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// title: str,
/// button: str,
/// info_button: str,
/// items: Iterable[str],
/// items: Iterable[Tuple[int, str]],
/// ) -> object:
/// """Confirm action but with third button."""
/// """Confirm given items but with third button. Always single page
/// without scrolling."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),

/// def confirm_more(
/// *,
/// title: str,
/// button: str,
/// items: Iterable[Tuple[int, str]],
/// ) -> object:
/// """Confirm long content with the possibility to go back from any page.
/// Meant to be used with confirm_with_info."""
Qstr::MP_QSTR_confirm_more => obj_fn_kw!(0, new_confirm_more).as_obj(),

/// def confirm_coinjoin(
/// *,
/// max_rounds: str,
Expand Down
13 changes: 13 additions & 0 deletions core/embed/rust/src/ui/model_tt/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::ui::{

use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet};

use num_traits::FromPrimitive;

// Typical backlight values.
pub const BACKLIGHT_NORMAL: i32 = 150;
pub const BACKLIGHT_LOW: i32 = 45;
Expand Down Expand Up @@ -363,6 +365,17 @@ pub const TEXT_MONO: TextStyle = TextStyle::new(Font::MONO, FG, BG, GREY_LIGHT,
.with_line_breaking(LineBreaking::BreakWordsNoHyphen)
.with_page_breaking(PageBreaking::Cut);

/// Convert Python-side numeric id to a `TextStyle`.
pub fn textstyle_number(num: i32) -> &'static TextStyle {
let font = Font::from_i32(-num);
match font {
Some(Font::DEMIBOLD) => &TEXT_DEMIBOLD,
Some(Font::BOLD) => &TEXT_BOLD,
Some(Font::MONO) => &TEXT_MONO,
_ => &TEXT_NORMAL,
}
}

pub const TEXT_NORMAL_OFF_WHITE: TextStyle =
TextStyle::new(Font::NORMAL, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_CHECKLIST_DEFAULT: TextStyle =
Expand Down
17 changes: 14 additions & 3 deletions core/mocks/generated/trezorui2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ def confirm_blob(
description: str | None,
extra: str | None,
verb_cancel: str | None = None,
ask_pagination: bool = False,
hold: bool = False,
) -> object:
"""Confirm byte sequence data."""
Expand Down Expand Up @@ -235,9 +234,21 @@ def confirm_with_info(
title: str,
button: str,
info_button: str,
items: Iterable[str],
items: Iterable[Tuple[int, str]],
) -> object:
"""Confirm given items but with third button. Always single page
without scrolling."""


# rust/src/ui/model_tt/layout.rs
def confirm_more(
*,
title: str,
button: str,
items: Iterable[Tuple[int, str]],
) -> object:
"""Confirm action but with third button."""
"""Confirm long content with the possibility to go back from any page.
Meant to be used with confirm_with_info."""


# rust/src/ui/model_tt/layout.rs
Expand Down
Loading

0 comments on commit 4528577

Please sign in to comment.