refactor(core/ui): VerticalMenu flexibility

mmilata/ui-t3t1-verticalmenu
Martin Milata 2 weeks ago
parent 0eeb8b68bb
commit 9127874fd7

@ -533,7 +533,6 @@ static void _librust_qstrs(void) {
MP_QSTR_show_share_words;
MP_QSTR_show_simple;
MP_QSTR_show_success;
MP_QSTR_show_tx_context_menu;
MP_QSTR_show_wait_text;
MP_QSTR_show_warning;
MP_QSTR_sign;

@ -503,7 +503,7 @@ pub enum CancelInfoConfirmMsg {
#[derive(PartialEq, Eq, Clone)]
pub struct IconText {
text: &'static str,
text: TString<'static>,
icon: Icon,
}
@ -512,12 +512,15 @@ impl IconText {
const ICON_MARGIN: i16 = 4;
const TEXT_MARGIN: i16 = 6;
pub fn new(text: &'static str, icon: Icon) -> Self {
Self { text, icon }
pub fn new(text: impl Into<TString<'static>>, icon: Icon) -> Self {
Self {
text: text.into(),
icon,
}
}
pub fn paint(&self, area: Rect, style: &ButtonStyle, baseline_offset: Offset) {
let width = style.font.text_width(self.text);
let width = self.text.map(|t| style.font.text_width(t));
let height = style.font.text_height();
let mut use_icon = false;
@ -543,13 +546,15 @@ impl IconText {
}
if use_text {
display::text_left(
text_pos,
self.text,
style.font,
style.text_color,
style.button_color,
);
self.text.map(|t| {
display::text_left(
text_pos,
t,
style.font,
style.text_color,
style.button_color,
)
});
}
if use_icon {
@ -568,7 +573,7 @@ impl IconText {
style: &ButtonStyle,
baseline_offset: Offset,
) {
let width = style.font.text_width(self.text.as_ref());
let width = self.text.map(|t| style.font.text_width(t));
let mut use_icon = false;
let mut use_text = false;
@ -593,10 +598,12 @@ impl IconText {
}
if use_text {
shape::Text::new(text_pos, self.text)
.with_font(style.font)
.with_fg(style.text_color)
.render(target);
self.text.map(|t| {
shape::Text::new(text_pos, t)
.with_font(style.font)
.with_fg(style.text_color)
.render(target)
});
}
if use_icon {

@ -59,25 +59,23 @@ impl VerticalMenu {
Self::new(buttons_vec)
}
pub fn context_menu(options: Vec<(&'static str, Icon), N_ITEMS>) -> Self {
// FIXME: args should be TString when IconText has TString
let mut buttons_vec = VerticalMenuButtons::new();
for opt in options {
let button_theme;
match opt.1 {
// FIXME: might not be applicable everywhere
theme::ICON_CANCEL => {
button_theme = theme::button_warning_high();
}
_ => {
button_theme = theme::button_default();
}
}
unwrap!(buttons_vec.push(
Button::with_icon_and_text(IconText::new(opt.0, opt.1)).styled(button_theme)
));
}
Self::new(buttons_vec)
pub fn empty() -> Self {
Self::new(VerticalMenuButtons::new())
}
pub fn item(mut self, icon: Icon, text: TString<'static>) -> Self {
unwrap!(self.buttons.push(
Button::with_icon_and_text(IconText::new(text, icon)).styled(theme::button_default())
));
self
}
pub fn danger(mut self, icon: Icon, text: TString<'static>) -> Self {
unwrap!(self.buttons.push(
Button::with_icon_and_text(IconText::new(text, icon))
.styled(theme::button_warning_high())
));
self
}
}

@ -11,7 +11,6 @@ use crate::{
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow, SwipePage},
},
};
use heapless::Vec;
use super::super::{
component::{Frame, FrameMsg, PromptScreen, VerticalMenu, VerticalMenuChoiceMsg},
@ -91,10 +90,7 @@ impl ConfirmResetDevice {
let content_menu = Frame::left_aligned(
"".into(),
VerticalMenu::context_menu(unwrap!(Vec::from_slice(&[(
"Cancel", // FIXME: use TString
theme::ICON_CANCEL
)]))),
VerticalMenu::empty().danger(theme::ICON_CANCEL, "Cancel".into()),
)
.with_cancel_button()
.map(|msg| match msg {

@ -10,7 +10,6 @@ use crate::{
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow, SwipePage},
},
};
use heapless::Vec;
use super::super::{
component::{
@ -95,10 +94,7 @@ impl CreateBackup {
let content_menu = Frame::left_aligned(
"".into(),
VerticalMenu::context_menu(unwrap!(Vec::from_slice(&[(
"Skip backup", // FIXME: use TString
theme::ICON_CANCEL
)]))),
VerticalMenu::empty().danger(theme::ICON_CANCEL, "Skip backup".into()),
)
.with_cancel_button()
.map(|msg| match msg {

@ -12,7 +12,6 @@ use crate::{
},
},
};
use heapless::Vec;
use super::super::{
component::{Frame, FrameMsg, IconDialog, VerticalMenu, VerticalMenuChoiceMsg},
@ -121,11 +120,10 @@ impl GetAddress {
.add(
Frame::left_aligned(
"".into(),
VerticalMenu::context_menu(unwrap!(Vec::from_slice(&[
("Address QR code", theme::ICON_QR_CODE),
("Account info", theme::ICON_CHEVRON_RIGHT),
("Cancel trans.", theme::ICON_CANCEL),
]))),
VerticalMenu::empty()
.item(theme::ICON_QR_CODE, "Address QR code".into())
.item(theme::ICON_CHEVRON_RIGHT, "Account info".into())
.danger(theme::ICON_CANCEL, "Cancel operation".into()),
)
.with_cancel_button()
.map(|msg| match msg {

@ -1295,23 +1295,6 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_show_tx_context_menu(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], _kwargs: &Map| {
// TODO: this is just POC
let title: TString = "".into();
let options = unwrap!(Vec::from_slice(&[
("Address QR code", theme::ICON_QR_CODE),
("Fee info", theme::ICON_CHEVRON_RIGHT),
("Cancel transaction", theme::ICON_CANCEL),
]));
let content = VerticalMenu::context_menu(options);
let frame_with_menu = Frame::left_aligned(title, content).with_cancel_button();
let obj = LayoutObj::new(frame_with_menu)?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
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: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
@ -2040,11 +2023,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// iterable must be of exact size. Returns index in range `0..3`."""
Qstr::MP_QSTR_select_word => obj_fn_kw!(0, new_select_word).as_obj(),
/// def show_tx_context_menu() -> LayoutObj[int]:
/// """Show transaction context menu with the options for 1) Address QR code, 2) Fee
/// information, 3) Cancel transaction"""
Qstr::MP_QSTR_show_tx_context_menu => obj_fn_kw!(0, new_show_tx_context_menu).as_obj(),
// TODO: This is just POC
/// def create_backup_flow() -> LayoutObj[UiResult]
/// """Start create backup or skip flow."""

@ -389,12 +389,6 @@ def select_word(
iterable must be of exact size. Returns index in range `0..3`."""
# rust/src/ui/model_mercury/layout.rs
def show_tx_context_menu() -> LayoutObj[int]:
"""Show transaction context menu with the options for 1) Address QR code, 2) Fee
information, 3) Cancel transaction"""
# rust/src/ui/model_mercury/layout.rs
def create_backup_flow() -> LayoutObj[UiResult]
"""Start create backup or skip flow."""

Loading…
Cancel
Save