mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-01 03:18:12 +00:00
fix(core/ui): style update: buttons
[no changelog]
This commit is contained in:
parent
a8e7ad97b4
commit
f64fe18ad5
@ -26,7 +26,7 @@ pub use maybe::Maybe;
|
||||
pub use pad::Pad;
|
||||
pub use paginated::{AuxPageMsg, PageMsg, Paginate};
|
||||
pub use painter::Painter;
|
||||
pub use placed::{FixedHeightBar, Floating, GridPlaced, VSplit};
|
||||
pub use placed::{FixedHeightBar, Floating, GridPlaced, Split};
|
||||
pub use qr_code::Qr;
|
||||
pub use text::{
|
||||
formatted::FormattedText,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::ui::{
|
||||
component::{Component, Event, EventCtx},
|
||||
geometry::{Alignment, Alignment2D, Grid, GridCellSpan, Insets, Offset, Rect, TOP_RIGHT},
|
||||
geometry::{Alignment, Alignment2D, Axis, Grid, GridCellSpan, Insets, Offset, Rect, TOP_RIGHT},
|
||||
};
|
||||
|
||||
pub struct GridPlaced<T> {
|
||||
@ -195,25 +195,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VSplit<T, U> {
|
||||
pub struct Split<T, U> {
|
||||
first: T,
|
||||
second: U,
|
||||
width: i16,
|
||||
axis: Axis,
|
||||
size: i16,
|
||||
spacing: i16,
|
||||
}
|
||||
|
||||
impl<T, U> VSplit<T, U> {
|
||||
pub const fn new(width: i16, spacing: i16, first: T, second: U) -> Self {
|
||||
impl<T, U> Split<T, U> {
|
||||
pub const fn new(axis: Axis, size: i16, spacing: i16, first: T, second: U) -> Self {
|
||||
Self {
|
||||
first,
|
||||
second,
|
||||
width,
|
||||
axis,
|
||||
size,
|
||||
spacing,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn vertical(size: i16, spacing: i16, first: T, second: U) -> Self {
|
||||
Self::new(Axis::Vertical, size, spacing, first, second)
|
||||
}
|
||||
|
||||
pub const fn horizontal(size: i16, spacing: i16, first: T, second: U) -> Self {
|
||||
Self::new(Axis::Horizontal, size, spacing, first, second)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M, T, U> Component for VSplit<T, U>
|
||||
impl<M, T, U> Component for Split<T, U>
|
||||
where
|
||||
T: Component<Msg = M>,
|
||||
U: Component<Msg = M>,
|
||||
@ -221,10 +231,26 @@ where
|
||||
type Msg = M;
|
||||
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
let (left, right) = bounds.split_left(self.width);
|
||||
let right = right.inset(Insets::left(self.spacing));
|
||||
self.first.place(left);
|
||||
self.second.place(right);
|
||||
let size = if self.size == 0 {
|
||||
(bounds.size().axis(self.axis.cross()) - self.spacing) / 2
|
||||
} else {
|
||||
self.size
|
||||
};
|
||||
let (first, second) = match self.axis {
|
||||
Axis::Vertical if size > 0 => bounds.split_left(size),
|
||||
Axis::Vertical => bounds.split_right(-size),
|
||||
Axis::Horizontal if size > 0 => bounds.split_top(size),
|
||||
Axis::Horizontal => bounds.split_bottom(-size),
|
||||
};
|
||||
let (first, second) = match self.axis {
|
||||
Axis::Vertical if size > 0 => (first, second.inset(Insets::left(self.spacing))),
|
||||
Axis::Vertical => (first.inset(Insets::right(self.spacing)), second),
|
||||
Axis::Horizontal if size > 0 => (first, second.inset(Insets::top(self.spacing))),
|
||||
Axis::Horizontal => (first.inset(Insets::bottom(self.spacing)), second),
|
||||
};
|
||||
|
||||
self.first.place(first);
|
||||
self.second.place(second);
|
||||
bounds
|
||||
}
|
||||
|
||||
@ -241,13 +267,13 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<T, U> crate::trace::Trace for VSplit<T, U>
|
||||
impl<T, U> crate::trace::Trace for Split<T, U>
|
||||
where
|
||||
T: Component + crate::trace::Trace,
|
||||
U: Component + crate::trace::Trace,
|
||||
{
|
||||
fn trace(&self, d: &mut dyn crate::trace::Tracer) {
|
||||
d.open("VSplit");
|
||||
d.open("Split");
|
||||
d.field("first", &self.first);
|
||||
d.field("second", &self.second);
|
||||
d.close();
|
||||
|
@ -2,8 +2,8 @@ use crate::{
|
||||
time::Duration,
|
||||
ui::{
|
||||
component::{
|
||||
Component, ComponentExt, Event, EventCtx, FixedHeightBar, Floating, GridPlaced, Map,
|
||||
Paginate, TimerToken, VSplit,
|
||||
Component, ComponentExt, Event, EventCtx, FixedHeightBar, Floating, Map, Paginate,
|
||||
Split, TimerToken,
|
||||
},
|
||||
display::{self, toif::Icon, Color, Font},
|
||||
event::TouchEvent,
|
||||
@ -63,16 +63,16 @@ impl<T> Button<T> {
|
||||
Self::new(ButtonContent::IconBlend(bg, fg, fg_offset))
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
pub const fn empty() -> Self {
|
||||
Self::new(ButtonContent::Empty)
|
||||
}
|
||||
|
||||
pub fn styled(mut self, styles: ButtonStyleSheet) -> Self {
|
||||
pub const fn styled(mut self, styles: ButtonStyleSheet) -> Self {
|
||||
self.styles = styles;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_expanded_touch_area(mut self, expand: Insets) -> Self {
|
||||
pub const fn with_expanded_touch_area(mut self, expand: Insets) -> Self {
|
||||
self.touch_expand = Some(expand);
|
||||
self
|
||||
}
|
||||
@ -377,7 +377,7 @@ impl<T> Button<T> {
|
||||
pub fn cancel_confirm(
|
||||
left: Button<T>,
|
||||
right: Button<T>,
|
||||
right_size_factor: usize,
|
||||
left_is_small: bool,
|
||||
) -> CancelConfirm<
|
||||
T,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
@ -386,59 +386,13 @@ impl<T> Button<T> {
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let columns = 1 + right_size_factor;
|
||||
theme::button_bar((
|
||||
GridPlaced::new(left)
|
||||
.with_grid(1, columns)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_row_col(0, 0)
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Cancelled)
|
||||
}),
|
||||
GridPlaced::new(right)
|
||||
.with_grid(1, columns)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_from_to((0, 1), (0, right_size_factor))
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn cancel_confirm_text(
|
||||
left: Option<T>,
|
||||
right: T,
|
||||
) -> CancelConfirm<
|
||||
T,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let (left, right_size_factor) = if let Some(verb) = left {
|
||||
(Button::with_text(verb), 1)
|
||||
let width = if left_is_small {
|
||||
theme::BUTTON_WIDTH
|
||||
} else {
|
||||
(Button::with_icon(Icon::new(theme::ICON_CANCEL)), 2)
|
||||
0
|
||||
};
|
||||
let right = Button::with_text(right).styled(theme::button_confirm());
|
||||
|
||||
Self::cancel_confirm(left, right, right_size_factor)
|
||||
}
|
||||
|
||||
pub fn cancel_confirm_square(
|
||||
left: Button<T>,
|
||||
right: Button<T>,
|
||||
) -> CancelConfirmSquare<
|
||||
T,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
theme::button_bar(VSplit::new(
|
||||
theme::BUTTON_HEIGHT,
|
||||
theme::button_bar(Split::vertical(
|
||||
width,
|
||||
theme::BUTTON_SPACING,
|
||||
left.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Cancelled)
|
||||
@ -449,6 +403,34 @@ impl<T> Button<T> {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn cancel_confirm_text(
|
||||
left: Option<T>,
|
||||
right: Option<T>,
|
||||
) -> CancelConfirm<
|
||||
T,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
|
||||
>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let left_is_small: bool;
|
||||
|
||||
let left = if let Some(verb) = left {
|
||||
left_is_small = verb.as_ref().len() <= 4;
|
||||
Button::with_text(verb)
|
||||
} else {
|
||||
left_is_small = right.is_some();
|
||||
Button::with_icon(Icon::new(theme::ICON_CANCEL))
|
||||
};
|
||||
let right = if let Some(verb) = right {
|
||||
Button::with_text(verb).styled(theme::button_confirm())
|
||||
} else {
|
||||
Button::with_icon(Icon::new(theme::ICON_CONFIRM)).styled(theme::button_confirm())
|
||||
};
|
||||
Self::cancel_confirm(left, right, left_is_small)
|
||||
}
|
||||
|
||||
pub fn cancel_info_confirm(
|
||||
confirm: T,
|
||||
info: T,
|
||||
@ -461,69 +443,29 @@ impl<T> Button<T> {
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let right = Button::with_text(confirm).styled(theme::button_confirm());
|
||||
let top = Button::with_text(info);
|
||||
let left = Button::with_icon(Icon::new(theme::ICON_CANCEL));
|
||||
theme::button_bar_rows(
|
||||
2,
|
||||
(
|
||||
GridPlaced::new(left)
|
||||
.with_grid(2, 3)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_row_col(1, 0)
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Cancelled)
|
||||
}),
|
||||
GridPlaced::new(top)
|
||||
.with_grid(2, 3)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_from_to((0, 0), (0, 2))
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Info)
|
||||
}),
|
||||
GridPlaced::new(right)
|
||||
.with_grid(2, 3)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_from_to((1, 1), (1, 2))
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Confirmed)
|
||||
}),
|
||||
let right = Button::with_text(confirm)
|
||||
.styled(theme::button_confirm())
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Confirmed)
|
||||
});
|
||||
let top = Button::with_text(info)
|
||||
.styled(theme::button_moreinfo())
|
||||
.map(|msg| (matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Info));
|
||||
let left = Button::with_icon(Icon::new(theme::ICON_CANCEL)).map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Cancelled)
|
||||
});
|
||||
let total_height = theme::BUTTON_HEIGHT + theme::BUTTON_SPACING + theme::INFO_BUTTON_HEIGHT;
|
||||
FixedHeightBar::bottom(
|
||||
Split::horizontal(
|
||||
theme::INFO_BUTTON_HEIGHT,
|
||||
theme::BUTTON_SPACING,
|
||||
top,
|
||||
Split::vertical(theme::BUTTON_WIDTH, theme::BUTTON_SPACING, left, right),
|
||||
),
|
||||
total_height,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn abort_info_enter() -> CancelInfoConfirm<
|
||||
&'static str,
|
||||
impl Fn(ButtonMsg) -> Option<CancelInfoConfirmMsg>,
|
||||
impl Fn(ButtonMsg) -> Option<CancelInfoConfirmMsg>,
|
||||
impl Fn(ButtonMsg) -> Option<CancelInfoConfirmMsg>,
|
||||
> {
|
||||
let left = Button::with_text("ABORT").styled(theme::button_cancel());
|
||||
let middle = Button::with_text("INFO");
|
||||
let right = Button::with_text("ENTER").styled(theme::button_confirm());
|
||||
theme::button_bar((
|
||||
GridPlaced::new(left)
|
||||
.with_grid(1, 3)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_row_col(0, 0)
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Cancelled)
|
||||
}),
|
||||
GridPlaced::new(middle)
|
||||
.with_grid(1, 3)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_row_col(0, 1)
|
||||
.map(|msg| (matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Info)),
|
||||
GridPlaced::new(right)
|
||||
.with_grid(1, 3)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_row_col(0, 2)
|
||||
.map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelInfoConfirmMsg::Confirmed)
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn select_word(
|
||||
words: [T; 3],
|
||||
) -> CancelInfoConfirm<
|
||||
@ -536,38 +478,41 @@ impl<T> Button<T> {
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let btn = move |i, word| {
|
||||
GridPlaced::new(Button::with_text(word))
|
||||
.with_grid(3, 1)
|
||||
.with_spacing(theme::BUTTON_SPACING)
|
||||
.with_row_col(i, 0)
|
||||
Button::with_text(word)
|
||||
.styled(theme::button_pin())
|
||||
.map(move |msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| SelectWordMsg::Selected(i))
|
||||
})
|
||||
};
|
||||
|
||||
let [top, middle, bottom] = words;
|
||||
theme::button_bar_rows(3, (btn(0, top), btn(1, middle), btn(2, bottom)))
|
||||
let total_height = 3 * theme::BUTTON_HEIGHT + 2 * theme::BUTTON_SPACING;
|
||||
FixedHeightBar::bottom(
|
||||
Split::horizontal(
|
||||
theme::BUTTON_HEIGHT,
|
||||
theme::BUTTON_SPACING,
|
||||
btn(0, top),
|
||||
Split::horizontal(
|
||||
theme::BUTTON_HEIGHT,
|
||||
theme::BUTTON_SPACING,
|
||||
btn(1, middle),
|
||||
btn(2, bottom),
|
||||
),
|
||||
),
|
||||
total_height,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
type CancelConfirm<T, F0, F1> = FixedHeightBar<(
|
||||
Map<GridPlaced<Button<T>>, F0>,
|
||||
Map<GridPlaced<Button<T>>, F1>,
|
||||
)>;
|
||||
|
||||
pub enum CancelConfirmMsg {
|
||||
Cancelled,
|
||||
Confirmed,
|
||||
}
|
||||
|
||||
type CancelInfoConfirm<T, F0, F1, F2> = FixedHeightBar<(
|
||||
Map<GridPlaced<Button<T>>, F0>,
|
||||
Map<GridPlaced<Button<T>>, F1>,
|
||||
Map<GridPlaced<Button<T>>, F2>,
|
||||
)>;
|
||||
type CancelInfoConfirm<T, F0, F1, F2> =
|
||||
FixedHeightBar<Split<Map<Button<T>, F0>, Split<Map<Button<T>, F1>, Map<Button<T>, F2>>>>;
|
||||
|
||||
type CancelConfirmSquare<T, F0, F1> =
|
||||
FixedHeightBar<VSplit<Map<Button<T>, F0>, Map<Button<T>, F1>>>;
|
||||
type CancelConfirm<T, F0, F1> = FixedHeightBar<Split<Map<Button<T>, F0>, Map<Button<T>, F1>>>;
|
||||
|
||||
pub enum CancelInfoConfirmMsg {
|
||||
Cancelled,
|
||||
@ -658,7 +603,9 @@ where
|
||||
button: Floating::top_right(
|
||||
theme::CORNER_BUTTON_SIDE,
|
||||
theme::CORNER_BUTTON_SPACING,
|
||||
Button::with_icon(icon),
|
||||
Button::with_icon(icon)
|
||||
.with_expanded_touch_area(Insets::uniform(theme::CORNER_BUTTON_SPACING))
|
||||
.styled(theme::button_moreinfo()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -126,11 +126,11 @@ where
|
||||
T: Component,
|
||||
U: AsRef<str>,
|
||||
{
|
||||
const HEIGHT: i16 = 32;
|
||||
const HEIGHT: i16 = 36;
|
||||
const COLOR: Color = theme::YELLOW;
|
||||
const TEXT_OFFSET: Offset = Offset::new(1, -2);
|
||||
const ICON_SPACE: i16 = 8;
|
||||
const BORDER: i16 = 8;
|
||||
const BORDER: i16 = 6;
|
||||
|
||||
pub fn new(icon: Icon, title: U, content: T) -> Self {
|
||||
Self {
|
||||
|
@ -47,7 +47,9 @@ where
|
||||
.with_long_press(theme::ERASE_HOLD_DURATION),
|
||||
)),
|
||||
input: Child::new(Maybe::hidden(theme::BG, input)),
|
||||
keys: T::keys().map(Button::with_text).map(Child::new),
|
||||
keys: T::keys()
|
||||
.map(|t| Button::with_text(t).styled(theme::button_pin()))
|
||||
.map(Child::new),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,7 +381,10 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
|
||||
let action: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?;
|
||||
let description: Option<StrBuffer> =
|
||||
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
|
||||
let verb: StrBuffer = kwargs.get_or(Qstr::MP_QSTR_verb, "CONFIRM".into())?;
|
||||
let verb: Option<StrBuffer> = kwargs
|
||||
.get(Qstr::MP_QSTR_verb)
|
||||
.unwrap_or_else(|_| Obj::const_none())
|
||||
.try_into_option()?;
|
||||
let verb_cancel: Option<StrBuffer> = kwargs
|
||||
.get(Qstr::MP_QSTR_verb_cancel)
|
||||
.unwrap_or_else(|_| Obj::const_none())
|
||||
@ -452,7 +455,7 @@ fn confirm_blob(
|
||||
SwipeHoldPage::new(paragraphs, theme::BG),
|
||||
))?
|
||||
} else if let Some(verb) = verb {
|
||||
let buttons = Button::cancel_confirm_text(verb_cancel, verb);
|
||||
let buttons = Button::cancel_confirm_text(verb_cancel, Some(verb));
|
||||
LayoutObj::new(Frame::left_aligned(
|
||||
theme::label_title(),
|
||||
title,
|
||||
@ -504,12 +507,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
|
||||
}
|
||||
.into_paragraphs();
|
||||
|
||||
let buttons = Button::cancel_confirm(
|
||||
Button::<&'static str>::with_icon(Icon::new(theme::ICON_CANCEL)),
|
||||
Button::<&'static str>::with_icon(Icon::new(theme::ICON_CONFIRM))
|
||||
.styled(theme::button_confirm()),
|
||||
1,
|
||||
);
|
||||
let buttons = Button::cancel_confirm_text(None, Some("CONFIRM"));
|
||||
let obj = LayoutObj::new(FloatingButton::top_right_corner(
|
||||
Icon::new(theme::ICON_CORNER_INFO),
|
||||
Frame::left_aligned(
|
||||
@ -542,7 +540,7 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
|
||||
SwipeHoldPage::new(paragraphs.into_paragraphs(), theme::BG),
|
||||
))?
|
||||
} else {
|
||||
let buttons = Button::cancel_confirm_text(None, "CONFIRM");
|
||||
let buttons = Button::cancel_confirm_text(None, Some("CONFIRM"));
|
||||
LayoutObj::new(Frame::left_aligned(
|
||||
theme::label_title(),
|
||||
title,
|
||||
@ -570,7 +568,7 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
|
||||
_ => return Err(Error::ValueError(cstr!("Invalid image."))),
|
||||
};
|
||||
|
||||
let buttons = Button::cancel_confirm_text(None, "CONFIRM");
|
||||
let buttons = Button::cancel_confirm_text(None, Some("CONFIRM"));
|
||||
let obj = LayoutObj::new(
|
||||
Frame::centered(
|
||||
theme::label_title(),
|
||||
@ -602,7 +600,7 @@ extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs:
|
||||
let buttons = Button::cancel_confirm(
|
||||
Button::with_icon(Icon::new(theme::ICON_CANCEL)),
|
||||
Button::with_text(button).styled(theme::button_confirm()),
|
||||
3,
|
||||
true,
|
||||
);
|
||||
let obj = LayoutObj::new(
|
||||
Frame::left_aligned(
|
||||
@ -635,7 +633,7 @@ extern "C" fn new_show_qr(n_args: usize, args: *const Obj, kwargs: *mut Map) ->
|
||||
let buttons = Button::cancel_confirm(
|
||||
Button::with_text(verb_cancel),
|
||||
Button::with_text("CONFIRM".into()).styled(theme::button_confirm()),
|
||||
1,
|
||||
false,
|
||||
);
|
||||
|
||||
let obj = LayoutObj::new(
|
||||
@ -746,7 +744,7 @@ extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs:
|
||||
let buttons = Button::cancel_confirm(
|
||||
Button::with_icon(Icon::new(theme::ICON_CANCEL)),
|
||||
Button::with_text("NEXT").styled(theme::button_confirm()),
|
||||
2,
|
||||
true,
|
||||
);
|
||||
|
||||
let obj = LayoutObj::new(Frame::left_aligned(
|
||||
@ -781,7 +779,7 @@ extern "C" fn new_confirm_modify_fee(n_args: usize, args: *const Obj, kwargs: *m
|
||||
let buttons = Button::cancel_confirm(
|
||||
Button::with_icon(Icon::new(theme::ICON_CANCEL)),
|
||||
Button::with_text("NEXT").styled(theme::button_confirm()),
|
||||
2,
|
||||
true,
|
||||
);
|
||||
|
||||
let obj = LayoutObj::new(Frame::left_aligned(
|
||||
@ -832,7 +830,7 @@ fn new_show_modal(
|
||||
Button::cancel_confirm(
|
||||
Button::with_icon(Icon::new(theme::ICON_CANCEL)).styled(theme::button_cancel()),
|
||||
Button::with_text(button).styled(button_style),
|
||||
2,
|
||||
true,
|
||||
),
|
||||
)
|
||||
.with_description(description),
|
||||
@ -890,7 +888,7 @@ extern "C" fn new_confirm_fido(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
let controls = Button::cancel_confirm(
|
||||
Button::with_icon(Icon::new(theme::ICON_CANCEL)),
|
||||
Button::with_text("CONFIRM").styled(theme::button_confirm()),
|
||||
2,
|
||||
true,
|
||||
);
|
||||
|
||||
let fido_page = FidoConfirm::new(app_name, get_page, page_count, icon, controls);
|
||||
@ -963,9 +961,10 @@ extern "C" fn new_show_mismatch() -> Obj {
|
||||
IconDialog::new(
|
||||
icon,
|
||||
title,
|
||||
Button::cancel_confirm_square(
|
||||
Button::cancel_confirm(
|
||||
Button::with_icon(Icon::new(theme::ICON_BACK)),
|
||||
Button::with_text(button).styled(theme::button_reset()),
|
||||
true,
|
||||
),
|
||||
)
|
||||
.with_description(description)
|
||||
@ -1167,7 +1166,7 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
|
||||
let words_iterable: Obj = kwargs.get(Qstr::MP_QSTR_words)?;
|
||||
let words: [StrBuffer; 3] = iter_into_array(words_iterable)?;
|
||||
|
||||
let paragraphs = Paragraphs::new([Paragraph::new(&theme::TEXT_NORMAL, description)]);
|
||||
let paragraphs = Paragraphs::new([Paragraph::new(&theme::TEXT_DEMIBOLD, description)]);
|
||||
let buttons = Button::select_word(words);
|
||||
|
||||
let obj = LayoutObj::new(Frame::left_aligned(
|
||||
@ -1315,13 +1314,16 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut
|
||||
LayoutObj::new(NotificationFrame::new(
|
||||
Icon::new(theme::ICON_WARN),
|
||||
notification,
|
||||
Dialog::new(paragraphs, Button::<&'static str>::abort_info_enter()),
|
||||
Dialog::new(
|
||||
paragraphs,
|
||||
Button::cancel_info_confirm("CONTINUE", "MORE INFO"),
|
||||
),
|
||||
))?
|
||||
} else {
|
||||
LayoutObj::new(NotificationFrame::new(
|
||||
Icon::new(theme::ICON_WARN),
|
||||
notification,
|
||||
Dialog::new(paragraphs, Button::cancel_confirm_text(None, button)),
|
||||
Dialog::new(paragraphs, Button::cancel_confirm_text(None, Some(button))),
|
||||
))?
|
||||
};
|
||||
Ok(obj.into())
|
||||
@ -1920,7 +1922,7 @@ mod tests {
|
||||
#[test]
|
||||
fn trace_example_layout() {
|
||||
let buttons =
|
||||
Button::cancel_confirm(Button::with_text("Left"), Button::with_text("Right"), 1);
|
||||
Button::cancel_confirm(Button::with_text("Left"), Button::with_text("Right"), false);
|
||||
let mut layout = Dialog::new(
|
||||
FormattedText::new(
|
||||
theme::TEXT_NORMAL,
|
||||
|
@ -288,6 +288,38 @@ pub const fn button_reset() -> ButtonStyleSheet {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn button_moreinfo() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: FG,
|
||||
button_color: BG,
|
||||
background_color: BG,
|
||||
border_color: GREY_DARK,
|
||||
border_radius: RADIUS,
|
||||
border_width: 2,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: FG,
|
||||
button_color: BG,
|
||||
background_color: BG,
|
||||
border_color: FG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 2,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: GREY_LIGHT,
|
||||
button_color: BG,
|
||||
background_color: BG,
|
||||
border_color: GREY_DARK,
|
||||
border_radius: RADIUS,
|
||||
border_width: 2,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn button_info() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
@ -444,27 +476,21 @@ pub const FORMATTED: FormattedFonts = FormattedFonts {
|
||||
mono: Font::MONO,
|
||||
};
|
||||
|
||||
pub const CONTENT_BORDER: i16 = 5;
|
||||
pub const KEYBOARD_SPACING: i16 = 8;
|
||||
pub const BUTTON_HEIGHT: i16 = 38;
|
||||
pub const CONTENT_BORDER: i16 = 0;
|
||||
pub const BUTTON_HEIGHT: i16 = 50;
|
||||
pub const BUTTON_WIDTH: i16 = 56;
|
||||
pub const BUTTON_SPACING: i16 = 6;
|
||||
pub const KEYBOARD_SPACING: i16 = BUTTON_SPACING;
|
||||
pub const CHECKLIST_SPACING: i16 = 10;
|
||||
pub const RECOVERY_SPACING: i16 = 18;
|
||||
pub const CORNER_BUTTON_SIDE: i16 = 32;
|
||||
pub const CORNER_BUTTON_SPACING: i16 = 8;
|
||||
|
||||
/// Standard button height in pixels.
|
||||
pub const fn button_rows(count: usize) -> i16 {
|
||||
let count = count as i16;
|
||||
BUTTON_HEIGHT * count + BUTTON_SPACING * count.saturating_sub(1)
|
||||
}
|
||||
|
||||
pub const fn button_bar_rows<T>(rows: usize, inner: T) -> FixedHeightBar<T> {
|
||||
FixedHeightBar::bottom(inner, button_rows(rows))
|
||||
}
|
||||
pub const CORNER_BUTTON_SIDE: i16 = 44;
|
||||
pub const CORNER_BUTTON_SPACING: i16 = BUTTON_SPACING;
|
||||
pub const INFO_BUTTON_HEIGHT: i16 = 44;
|
||||
pub const PIN_BUTTON_HEIGHT: i16 = 40;
|
||||
pub const MNEMONIC_BUTTON_HEIGHT: i16 = 52;
|
||||
|
||||
pub const fn button_bar<T>(inner: T) -> FixedHeightBar<T> {
|
||||
button_bar_rows(1, inner)
|
||||
FixedHeightBar::bottom(inner, BUTTON_HEIGHT)
|
||||
}
|
||||
|
||||
/// +----------+
|
||||
|
@ -213,7 +213,7 @@ async def confirm_action(
|
||||
description: str | None = None,
|
||||
description_param: str | None = None,
|
||||
description_param_font: int = ui.BOLD,
|
||||
verb: str = "CONFIRM",
|
||||
verb: str | None = None,
|
||||
verb_cancel: str | None = None,
|
||||
hold: bool = False,
|
||||
hold_danger: bool = False,
|
||||
@ -221,6 +221,8 @@ async def confirm_action(
|
||||
exc: ExceptionType = ActionCancelled,
|
||||
br_code: ButtonRequestType = BR_TYPE_OTHER,
|
||||
) -> None:
|
||||
if verb is not None:
|
||||
verb = verb.upper()
|
||||
if verb_cancel is not None:
|
||||
verb_cancel = verb_cancel.upper()
|
||||
|
||||
@ -237,7 +239,7 @@ async def confirm_action(
|
||||
title=title.upper(),
|
||||
action=action,
|
||||
description=description,
|
||||
verb=verb.upper(),
|
||||
verb=verb,
|
||||
verb_cancel=verb_cancel,
|
||||
hold=hold,
|
||||
hold_danger=hold_danger,
|
||||
|
@ -109,7 +109,7 @@ async def select_word(
|
||||
trezorui2.select_word(
|
||||
title=title,
|
||||
description=f"Select word {checked_index + 1} of {count}:",
|
||||
words=(words[0].upper(), words[1].upper(), words[2].upper()),
|
||||
words=(words[0], words[1], words[2]),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user