mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 12:28:09 +00:00
refactor(core/ui): VerticalMenu flexibility
This commit is contained in:
parent
cf53876292
commit
b05b54dfd8
@ -536,7 +536,6 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_show_share_words;
|
MP_QSTR_show_share_words;
|
||||||
MP_QSTR_show_simple;
|
MP_QSTR_show_simple;
|
||||||
MP_QSTR_show_success;
|
MP_QSTR_show_success;
|
||||||
MP_QSTR_show_tx_context_menu;
|
|
||||||
MP_QSTR_show_wait_text;
|
MP_QSTR_show_wait_text;
|
||||||
MP_QSTR_show_warning;
|
MP_QSTR_show_warning;
|
||||||
MP_QSTR_sign;
|
MP_QSTR_sign;
|
||||||
|
@ -503,7 +503,7 @@ pub enum CancelInfoConfirmMsg {
|
|||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct IconText {
|
pub struct IconText {
|
||||||
text: &'static str,
|
text: TString<'static>,
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,12 +512,15 @@ impl IconText {
|
|||||||
const ICON_MARGIN: i16 = 4;
|
const ICON_MARGIN: i16 = 4;
|
||||||
const TEXT_MARGIN: i16 = 6;
|
const TEXT_MARGIN: i16 = 6;
|
||||||
|
|
||||||
pub fn new(text: &'static str, icon: Icon) -> Self {
|
pub fn new(text: impl Into<TString<'static>>, icon: Icon) -> Self {
|
||||||
Self { text, icon }
|
Self {
|
||||||
|
text: text.into(),
|
||||||
|
icon,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint(&self, area: Rect, style: &ButtonStyle, baseline_offset: Offset) {
|
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 height = style.font.text_height();
|
||||||
|
|
||||||
let mut use_icon = false;
|
let mut use_icon = false;
|
||||||
@ -543,13 +546,15 @@ impl IconText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if use_text {
|
if use_text {
|
||||||
display::text_left(
|
self.text.map(|t| {
|
||||||
text_pos,
|
display::text_left(
|
||||||
self.text,
|
text_pos,
|
||||||
style.font,
|
t,
|
||||||
style.text_color,
|
style.font,
|
||||||
style.button_color,
|
style.text_color,
|
||||||
);
|
style.button_color,
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if use_icon {
|
if use_icon {
|
||||||
@ -568,7 +573,7 @@ impl IconText {
|
|||||||
style: &ButtonStyle,
|
style: &ButtonStyle,
|
||||||
baseline_offset: Offset,
|
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_icon = false;
|
||||||
let mut use_text = false;
|
let mut use_text = false;
|
||||||
@ -593,10 +598,12 @@ impl IconText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if use_text {
|
if use_text {
|
||||||
shape::Text::new(text_pos, self.text)
|
self.text.map(|t| {
|
||||||
.with_font(style.font)
|
shape::Text::new(text_pos, t)
|
||||||
.with_fg(style.text_color)
|
.with_font(style.font)
|
||||||
.render(target);
|
.with_fg(style.text_color)
|
||||||
|
.render(target)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if use_icon {
|
if use_icon {
|
||||||
|
@ -59,25 +59,23 @@ impl VerticalMenu {
|
|||||||
Self::new(buttons_vec)
|
Self::new(buttons_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_menu(options: Vec<(&'static str, Icon), N_ITEMS>) -> Self {
|
pub fn empty() -> Self {
|
||||||
// FIXME: args should be TString when IconText has TString
|
Self::new(VerticalMenuButtons::new())
|
||||||
let mut buttons_vec = VerticalMenuButtons::new();
|
}
|
||||||
for opt in options {
|
|
||||||
let button_theme;
|
pub fn item(mut self, icon: Icon, text: TString<'static>) -> Self {
|
||||||
match opt.1 {
|
unwrap!(self.buttons.push(
|
||||||
// FIXME: might not be applicable everywhere
|
Button::with_icon_and_text(IconText::new(text, icon)).styled(theme::button_default())
|
||||||
theme::ICON_CANCEL => {
|
));
|
||||||
button_theme = theme::button_warning_high();
|
self
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
button_theme = theme::button_default();
|
pub fn danger(mut self, icon: Icon, text: TString<'static>) -> Self {
|
||||||
}
|
unwrap!(self.buttons.push(
|
||||||
}
|
Button::with_icon_and_text(IconText::new(text, icon))
|
||||||
unwrap!(buttons_vec.push(
|
.styled(theme::button_warning_high())
|
||||||
Button::with_icon_and_text(IconText::new(opt.0, opt.1)).styled(button_theme)
|
));
|
||||||
));
|
self
|
||||||
}
|
|
||||||
Self::new(buttons_vec)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ use crate::{
|
|||||||
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow, SwipePage},
|
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow, SwipePage},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use heapless::Vec;
|
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
component::{Frame, FrameMsg, PromptScreen, VerticalMenu, VerticalMenuChoiceMsg},
|
component::{Frame, FrameMsg, PromptScreen, VerticalMenu, VerticalMenuChoiceMsg},
|
||||||
@ -91,10 +90,7 @@ impl ConfirmResetDevice {
|
|||||||
|
|
||||||
let content_menu = Frame::left_aligned(
|
let content_menu = Frame::left_aligned(
|
||||||
"".into(),
|
"".into(),
|
||||||
VerticalMenu::context_menu(unwrap!(Vec::from_slice(&[(
|
VerticalMenu::empty().danger(theme::ICON_CANCEL, "Cancel".into()),
|
||||||
"Cancel", // FIXME: use TString
|
|
||||||
theme::ICON_CANCEL
|
|
||||||
)]))),
|
|
||||||
)
|
)
|
||||||
.with_cancel_button()
|
.with_cancel_button()
|
||||||
.map(|msg| match msg {
|
.map(|msg| match msg {
|
||||||
|
@ -10,7 +10,6 @@ use crate::{
|
|||||||
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow, SwipePage},
|
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow, SwipePage},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use heapless::Vec;
|
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
component::{
|
component::{
|
||||||
@ -95,10 +94,7 @@ impl CreateBackup {
|
|||||||
|
|
||||||
let content_menu = Frame::left_aligned(
|
let content_menu = Frame::left_aligned(
|
||||||
"".into(),
|
"".into(),
|
||||||
VerticalMenu::context_menu(unwrap!(Vec::from_slice(&[(
|
VerticalMenu::empty().danger(theme::ICON_CANCEL, "Skip backup".into()),
|
||||||
"Skip backup", // FIXME: use TString
|
|
||||||
theme::ICON_CANCEL
|
|
||||||
)]))),
|
|
||||||
)
|
)
|
||||||
.with_cancel_button()
|
.with_cancel_button()
|
||||||
.map(|msg| match msg {
|
.map(|msg| match msg {
|
||||||
|
@ -12,7 +12,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use heapless::Vec;
|
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
component::{Frame, FrameMsg, IconDialog, VerticalMenu, VerticalMenuChoiceMsg},
|
component::{Frame, FrameMsg, IconDialog, VerticalMenu, VerticalMenuChoiceMsg},
|
||||||
@ -121,11 +120,10 @@ impl GetAddress {
|
|||||||
.add(
|
.add(
|
||||||
Frame::left_aligned(
|
Frame::left_aligned(
|
||||||
"".into(),
|
"".into(),
|
||||||
VerticalMenu::context_menu(unwrap!(Vec::from_slice(&[
|
VerticalMenu::empty()
|
||||||
("Address QR code", theme::ICON_QR_CODE),
|
.item(theme::ICON_QR_CODE, "Address QR code".into())
|
||||||
("Account info", theme::ICON_CHEVRON_RIGHT),
|
.item(theme::ICON_CHEVRON_RIGHT, "Account info".into())
|
||||||
("Cancel trans.", theme::ICON_CANCEL),
|
.danger(theme::ICON_CANCEL, "Cancel operation".into()),
|
||||||
]))),
|
|
||||||
)
|
)
|
||||||
.with_cancel_button()
|
.with_cancel_button()
|
||||||
.map(|msg| match msg {
|
.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) }
|
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 {
|
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 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()?;
|
||||||
@ -2040,11 +2023,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
|||||||
/// iterable must be of exact size. Returns index in range `0..3`."""
|
/// 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(),
|
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
|
// TODO: This is just POC
|
||||||
/// def create_backup_flow() -> LayoutObj[UiResult]
|
/// def create_backup_flow() -> LayoutObj[UiResult]
|
||||||
/// """Start create backup or skip flow."""
|
/// """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`."""
|
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
|
# rust/src/ui/model_mercury/layout.rs
|
||||||
def create_backup_flow() -> LayoutObj[UiResult]
|
def create_backup_flow() -> LayoutObj[UiResult]
|
||||||
"""Start create backup or skip flow."""
|
"""Start create backup or skip flow."""
|
||||||
|
Loading…
Reference in New Issue
Block a user