1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-02-03 11:20:59 +00:00

feat(core/bootloader): new style for result screens (fixes #2910)

This commit is contained in:
matejcik 2023-03-29 16:22:45 +02:00
parent 6d434122f7
commit 839a940990
7 changed files with 188 additions and 273 deletions

View File

@ -30,14 +30,13 @@ use crate::{
connect::Connect,
theme::{
button_bld, button_confirm, button_wipe_cancel, button_wipe_confirm, BLD_BG,
BLD_BTN_COLOR, BLD_FG, BLD_WIPE_CANCEL_BTN_COLOR, BLD_WIPE_COLOR, CHECK24,
CHECK40, DOWNLOAD32, FIRE32, FIRE40, LOGO_EMPTY, TEXT_WIPE_BOLD,
TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, WELCOME_HIGHLIGHT_COLOR, X24,
BLD_FG, BLD_WIPE_COLOR, CHECK24, CHECK40, DOWNLOAD32, FIRE32, FIRE40,
LOGO_EMPTY, TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24,
},
welcome::Welcome,
},
component::{Button, ResultScreen},
theme::{BACKLIGHT_DIM, BACKLIGHT_NORMAL, BLACK, FG, TEXT_ERROR_HIGHLIGHT, WHITE},
theme::{BACKLIGHT_DIM, BACKLIGHT_NORMAL, BLACK, FG, WHITE},
},
util::{from_c_array, from_c_str},
},
@ -46,6 +45,10 @@ use confirm::Confirm;
use intro::Intro;
use menu::Menu;
use self::theme::{RESULT_FW_INSTALL, RESULT_INITIAL, RESULT_WIPE};
const RECONNECT_MESSAGE: &str = "PLEASE RECONNECT\nTHE DEVICE";
pub trait ReturnToC {
fn return_to_c(self) -> u32;
}
@ -333,28 +336,11 @@ extern "C" fn screen_connect() {
#[no_mangle]
extern "C" fn screen_wipe_success() {
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&TEXT_WIPE_NORMAL, "Trezor reset").centered());
messages.add(Paragraph::new(&TEXT_WIPE_NORMAL, "successfully").centered());
let m_top =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&TEXT_ERROR_HIGHLIGHT, "PLEASE RECONNECT").centered());
messages.add(Paragraph::new(&TEXT_ERROR_HIGHLIGHT, "THE DEVICE").centered());
let m_bottom =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut frame = ResultScreen::new(
WHITE,
BLD_WIPE_COLOR,
BLD_WIPE_CANCEL_BTN_COLOR,
&RESULT_WIPE,
Icon::new(CHECK40),
m_top,
Some(m_bottom),
"Trezor reset\nsuccessfully.",
RECONNECT_MESSAGE,
true,
);
show(&mut frame, true);
@ -362,27 +348,11 @@ extern "C" fn screen_wipe_success() {
#[no_mangle]
extern "C" fn screen_wipe_fail() {
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&TEXT_WIPE_NORMAL, "Trezor reset was").centered());
messages.add(Paragraph::new(&TEXT_WIPE_NORMAL, "not successful.").centered());
let m_top =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&TEXT_ERROR_HIGHLIGHT, "PLEASE RECONNECT").centered());
messages.add(Paragraph::new(&TEXT_ERROR_HIGHLIGHT, "THE DEVICE").centered());
let m_bottom =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut frame = ResultScreen::new(
WHITE,
BLD_WIPE_COLOR,
BLD_WIPE_CANCEL_BTN_COLOR,
&RESULT_WIPE,
Icon::new(WARNING40),
m_top,
Some(m_bottom),
"Trezor reset was\nnot successful.",
RECONNECT_MESSAGE,
true,
);
show(&mut frame, true);
@ -410,76 +380,33 @@ extern "C" fn screen_boot_empty(fading: bool) {
#[no_mangle]
extern "C" fn screen_install_fail() {
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&theme::TEXT_NORMAL, "Firmware installation was").centered());
messages.add(Paragraph::new(&theme::TEXT_NORMAL, "not successful.").centered());
let m_top =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&theme::TEXT_SUBMSG, "PLEASE RECONNECT").centered());
messages.add(Paragraph::new(&theme::TEXT_SUBMSG, "THE DEVICE").centered());
let m_bottom =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut frame = ResultScreen::new(
WHITE,
BLD_BG,
BLD_BTN_COLOR,
&RESULT_FW_INSTALL,
Icon::new(WARNING40),
m_top,
Some(m_bottom),
"Firmware installation was\nnot successful.",
RECONNECT_MESSAGE,
true,
);
show(&mut frame, true);
}
fn screen_install_success_bld(msg: &'static str, complete_draw: bool) {
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&theme::TEXT_NORMAL, "Firmware installed").centered());
messages.add(Paragraph::new(&theme::TEXT_NORMAL, "successfully").centered());
let m_top =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&theme::TEXT_SUBMSG, msg).centered());
let m_bottom =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut frame = ResultScreen::new(
WHITE,
BLD_BG,
BLD_BTN_COLOR,
&RESULT_FW_INSTALL,
Icon::new(CHECK40),
m_top,
Some(m_bottom),
"Firmware installed\nsuccessfully.",
msg,
complete_draw,
);
show(&mut frame, complete_draw);
}
fn screen_install_success_initial(msg: &'static str, complete_draw: bool) {
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&theme::TEXT_WELCOME_URL, "Firmware installed").centered());
messages.add(Paragraph::new(&theme::TEXT_WELCOME_URL, "successfully").centered());
let m_top =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&theme::TEXT_SUBMSG_INITIAL, msg).centered());
let m_bottom =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut frame = ResultScreen::new(
FG,
WELCOME_COLOR,
WELCOME_HIGHLIGHT_COLOR,
&RESULT_INITIAL,
Icon::new(CHECK40),
m_top,
Some(m_bottom),
"Firmware installed\nsuccessfully.",
msg,
complete_draw,
);
show(&mut frame, complete_draw);

View File

@ -4,8 +4,8 @@ use crate::ui::{
display::{Color, Font},
geometry::{Offset, Point, Rect},
model_tt::{
component::{ButtonStyle, ButtonStyleSheet},
theme::{BLACK, FG, GREY_DARK, GREY_LIGHT, GREY_MEDIUM, WHITE},
component::{ButtonStyle, ButtonStyleSheet, ResultStyle},
theme::{BLACK, FG, GREY_DARK, GREY_LIGHT, WHITE},
},
};
@ -232,14 +232,7 @@ pub fn button_bld() -> ButtonStyleSheet {
},
}
}
pub const TEXT_WELCOME: TextStyle = TextStyle::new(
Font::NORMAL,
GREY_MEDIUM,
WELCOME_COLOR,
GREY_MEDIUM,
GREY_MEDIUM,
);
pub const TEXT_WELCOME_URL: TextStyle = TextStyle::new(Font::NORMAL, FG, WELCOME_COLOR, FG, FG);
pub const TEXT_TITLE: TextStyle = TextStyle::new(
Font::BOLD,
BLD_TITLE_COLOR,
@ -247,13 +240,6 @@ pub const TEXT_TITLE: TextStyle = TextStyle::new(
BLD_TITLE_COLOR,
BLD_TITLE_COLOR,
);
pub const TEXT_SUBMSG_INITIAL: TextStyle = TextStyle::new(
Font::BOLD,
WHITE,
WELCOME_HIGHLIGHT_COLOR,
GREY_MEDIUM,
GREY_MEDIUM,
);
pub const TEXT_NORMAL: TextStyle = TextStyle::new(Font::NORMAL, BLD_FG, BLD_BG, BLD_FG, BLD_FG);
pub const TEXT_FINGERPRINT: TextStyle =
@ -274,4 +260,14 @@ pub const TEXT_WIPE_NORMAL: TextStyle = TextStyle::new(
BLD_WIPE_TEXT_COLOR,
BLD_WIPE_TEXT_COLOR,
);
pub const TEXT_SUBMSG: TextStyle = TextStyle::new(Font::BOLD, WHITE, BLD_BTN_COLOR, WHITE, WHITE);
pub const RESULT_WIPE: ResultStyle = ResultStyle::new(
BLD_WIPE_TEXT_COLOR,
BLD_WIPE_COLOR,
BLD_WIPE_CANCEL_BTN_COLOR,
);
pub const RESULT_FW_INSTALL: ResultStyle = ResultStyle::new(BLD_FG, BLD_BG, BLD_BTN_COLOR);
pub const RESULT_INITIAL: ResultStyle =
ResultStyle::new(FG, WELCOME_COLOR, WELCOME_HIGHLIGHT_COLOR);

View File

@ -1,38 +1,38 @@
use crate::ui::{
component::{
text::paragraphs::{ParagraphStrType, ParagraphVecShort, Paragraphs},
Child, Component, Event, EventCtx, Label, Never, Pad,
},
component::{Child, Component, Event, EventCtx, Label, Never, Pad},
constant::screen,
display::{self, Icon},
display::Icon,
geometry::{Alignment::Center, Point, Rect, TOP_CENTER},
};
use crate::ui::model_tt::{
component::{ResultFooter, ResultStyle},
constant::WIDTH,
theme::{
FATAL_ERROR_COLOR, FATAL_ERROR_HIGHLIGHT_COLOR, ICON_WARNING40, RESULT_FOOTER_HEIGHT,
RESULT_FOOTER_START, RESULT_PADDING, TEXT_ERROR_BOLD, WHITE,
},
theme::{FATAL_ERROR_COLOR, ICON_WARNING40, RESULT_FOOTER_START, RESULT_PADDING, WHITE},
};
const ICON_TOP: i16 = 23;
const TITLE_AREA_START: i16 = 70;
const ICON_TOP: i16 = 27;
const MESSAGE_AREA_START: i16 = 116;
pub struct ErrorScreen<T> {
#[cfg(feature = "bootloader")]
const STYLE: &ResultStyle = &crate::ui::model_tt::bootloader::theme::RESULT_WIPE;
#[cfg(not(feature = "bootloader"))]
const STYLE: &ResultStyle = &super::theme::RESULT_ERROR;
pub struct ErrorScreen<'a, T> {
bg: Pad,
title: Child<Label<T>>,
message: Child<Paragraphs<ParagraphVecShort<T>>>,
footer: Child<Paragraphs<ParagraphVecShort<T>>>,
message: Child<Label<T>>,
footer: Child<ResultFooter<'a, T>>,
}
impl<T: ParagraphStrType> ErrorScreen<T> {
pub fn new(
title: T,
message: Paragraphs<ParagraphVecShort<T>>,
footer: Paragraphs<ParagraphVecShort<T>>,
) -> Self {
let title = Label::new(title, Center, TEXT_ERROR_BOLD);
impl<T: AsRef<str>> ErrorScreen<'_, T> {
pub fn new(title: T, message: T, footer: T) -> Self {
let title = Label::new(title, Center, STYLE.title_style());
let message = Label::new(message, Center, STYLE.message_style());
let footer = ResultFooter::new(footer, STYLE);
Self {
bg: Pad::with_background(FATAL_ERROR_COLOR).with_clear(),
title: Child::new(title),
@ -42,33 +42,28 @@ impl<T: ParagraphStrType> ErrorScreen<T> {
}
}
impl<T: ParagraphStrType> Component for ErrorScreen<T> {
impl<T: AsRef<str>> Component for ErrorScreen<'_, T> {
type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect {
fn place(&mut self, _bounds: Rect) -> Rect {
self.bg.place(screen());
let title_area = Rect::new(
Point::new(RESULT_PADDING, TITLE_AREA_START),
Point::new(WIDTH - RESULT_PADDING, RESULT_FOOTER_START),
Point::new(WIDTH - RESULT_PADDING, MESSAGE_AREA_START),
);
self.title.place(title_area);
let (_, message_area) = title_area.split_top(self.title.inner().area().height());
let message_area = Rect::new(
Point::new(RESULT_PADDING, MESSAGE_AREA_START),
Point::new(WIDTH - RESULT_PADDING, RESULT_FOOTER_START),
);
self.message.place(message_area);
let bottom_area = Rect::new(
Point::new(RESULT_PADDING, RESULT_FOOTER_START),
Point::new(
WIDTH - RESULT_PADDING,
RESULT_FOOTER_START + RESULT_FOOTER_HEIGHT,
),
);
let (_, bottom_area) = ResultFooter::<T>::split_bounds();
self.footer.place(bottom_area);
bounds
screen()
}
fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> {
@ -87,19 +82,6 @@ impl<T: ParagraphStrType> Component for ErrorScreen<T> {
);
self.title.paint();
self.message.paint();
display::rect_fill_rounded(
Rect::new(
Point::new(RESULT_PADDING, RESULT_FOOTER_START),
Point::new(
WIDTH - RESULT_PADDING,
RESULT_FOOTER_START + RESULT_FOOTER_HEIGHT,
),
),
FATAL_ERROR_HIGHLIGHT_COLOR,
FATAL_ERROR_COLOR,
2,
);
self.footer.paint();
}
}

View File

@ -47,7 +47,7 @@ pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet};
pub use number_input::{NumberInputDialog, NumberInputDialogMsg};
pub use page::{SwipeHoldPage, SwipePage};
pub use progress::Progress;
pub use result::ResultScreen;
pub use result::{ResultFooter, ResultScreen, ResultStyle};
pub use scroll::ScrollBar;
pub use swipe::{Swipe, SwipeDirection};
pub use welcome_screen::WelcomeScreen;

View File

@ -1,51 +1,124 @@
use crate::ui::{
component::{
text::paragraphs::{ParagraphStrType, ParagraphVecShort, Paragraphs},
Child, Component, Event, EventCtx, Never, Pad,
text::{paragraphs::ParagraphStrType, TextStyle},
Child, Component, Event, EventCtx, Label, Never, Pad,
},
constant::screen,
display::{self, Color, Icon},
geometry::{Point, Rect, CENTER},
display::{self, Color, Font, Icon},
geometry::{Alignment::Center, Insets, Offset, Point, Rect, CENTER},
model_tt::theme::FG,
};
use crate::ui::model_tt::{
constant::WIDTH,
theme::{RESULT_FOOTER_HEIGHT, RESULT_FOOTER_START, RESULT_PADDING},
theme::{RESULT_FOOTER_START, RESULT_PADDING},
};
const MESSAGE_AREA_START: i16 = 82;
const MESSAGE_AREA_START: i16 = 97;
const ICON_CENTER_Y: i16 = 62;
pub struct ResultScreen<T> {
bg: Pad,
footer_pad: Pad,
fg_color: Color,
bg_color: Color,
msg_area_color: Color,
icon: Icon,
message: Child<Paragraphs<ParagraphVecShort<T>>>,
footer: Option<Child<Paragraphs<ParagraphVecShort<T>>>>,
pub struct ResultStyle {
pub fg_color: Color,
pub bg_color: Color,
pub divider_color: Color,
}
impl<T: ParagraphStrType> ResultScreen<T> {
pub fn new(
fg_color: Color,
bg_color: Color,
msg_area_color: Color,
impl ResultStyle {
pub const fn new(fg_color: Color, bg_color: Color, divider_color: Color) -> Self {
Self {
fg_color,
bg_color,
divider_color,
}
}
pub const fn message_style(&self) -> TextStyle {
TextStyle::new(Font::NORMAL, self.fg_color, self.bg_color, FG, FG)
}
pub const fn title_style(&self) -> TextStyle {
TextStyle::new(Font::BOLD, self.fg_color, self.bg_color, FG, FG)
}
}
pub struct ResultFooter<'a, T> {
style: &'a ResultStyle,
text: Label<T>,
area: Rect,
}
impl<'a, T: AsRef<str>> ResultFooter<'a, T> {
pub fn new(text: T, style: &'a ResultStyle) -> Self {
Self {
style,
text: Label::new(text, Center, style.title_style()).vertically_aligned(Center),
area: Rect::zero(),
}
}
pub const fn split_bounds() -> (Rect, Rect) {
let main_area = Rect::new(
Point::new(RESULT_PADDING, 0),
Point::new(WIDTH - RESULT_PADDING, RESULT_FOOTER_START),
);
let footer_area = Rect::new(
Point::new(RESULT_PADDING, RESULT_FOOTER_START),
Point::new(WIDTH - RESULT_PADDING, screen().height()),
);
(main_area, footer_area)
}
}
impl<T: AsRef<str>> Component for ResultFooter<'_, T> {
type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
self.text.place(bounds);
bounds
}
fn paint(&mut self) {
// divider line
let bar = Rect::from_center_and_size(
Point::new(self.area.center().x, self.area.y0),
Offset::new(self.area.width(), 1),
);
display::rect_fill(bar, self.style.divider_color);
// footer text
self.text.paint();
}
fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> {
None
}
}
pub struct ResultScreen<'a, T> {
bg: Pad,
footer_pad: Pad,
style: &'a ResultStyle,
icon: Icon,
message: Paragraphs<ParagraphVecShort<T>>,
footer: Option<Paragraphs<ParagraphVecShort<T>>>,
message: Child<Label<T>>,
footer: Child<ResultFooter<'a, T>>,
}
impl<'a, T: ParagraphStrType> ResultScreen<'a, T> {
pub fn new(
style: &'a ResultStyle,
icon: Icon,
message: T,
footer: T,
complete_draw: bool,
) -> Self {
let mut instance = Self {
bg: Pad::with_background(bg_color),
footer_pad: Pad::with_background(bg_color),
fg_color,
bg_color,
msg_area_color,
bg: Pad::with_background(style.bg_color),
footer_pad: Pad::with_background(style.bg_color),
style,
icon,
message: Child::new(message),
footer: footer.map(Child::new),
message: Child::new(Label::new(message, Center, style.message_style())),
footer: Child::new(ResultFooter::new(footer, style)),
};
if complete_draw {
@ -57,39 +130,21 @@ impl<T: ParagraphStrType> ResultScreen<T> {
}
}
impl<T: ParagraphStrType> Component for ResultScreen<T> {
impl<T: ParagraphStrType> Component for ResultScreen<'_, T> {
type Msg = Never;
fn place(&mut self, bounds: Rect) -> Rect {
fn place(&mut self, _bounds: Rect) -> Rect {
self.bg.place(screen());
let message_arae = if let Some(footer) = &mut self.footer {
let footer_area = Rect::new(
Point::new(RESULT_PADDING, RESULT_FOOTER_START),
Point::new(
WIDTH - RESULT_PADDING,
RESULT_FOOTER_START + RESULT_FOOTER_HEIGHT,
),
);
let (main_area, footer_area) = ResultFooter::<T>::split_bounds();
self.footer_pad.place(footer_area);
footer.place(footer_area);
Rect::new(
Point::new(RESULT_PADDING, MESSAGE_AREA_START),
Point::new(WIDTH - RESULT_PADDING, RESULT_FOOTER_START),
)
} else {
Rect::new(
Point::new(RESULT_PADDING, MESSAGE_AREA_START),
Point::new(
WIDTH - RESULT_PADDING,
RESULT_FOOTER_START + RESULT_FOOTER_HEIGHT,
),
)
};
self.footer.place(footer_area);
self.message.place(message_arae);
let message_area = main_area.inset(Insets::top(MESSAGE_AREA_START));
self.message.place(message_area);
bounds
screen()
}
fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> {
@ -103,25 +158,10 @@ impl<T: ParagraphStrType> Component for ResultScreen<T> {
self.icon.draw(
Point::new(screen().center().x, ICON_CENTER_Y),
CENTER,
self.fg_color,
self.bg_color,
self.style.fg_color,
self.style.bg_color,
);
self.message.paint();
if let Some(bottom) = &mut self.footer {
display::rect_fill_rounded(
Rect::new(
Point::new(RESULT_PADDING, RESULT_FOOTER_START),
Point::new(
WIDTH - RESULT_PADDING,
RESULT_FOOTER_START + RESULT_FOOTER_HEIGHT,
),
),
self.msg_area_color,
self.bg_color,
2,
);
bottom.paint();
}
self.footer.paint();
}
}

View File

@ -1,16 +1,8 @@
#[cfg(feature = "micropython")]
use crate::micropython::buffer::StrBuffer;
use crate::ui::{
component::{
text::paragraphs::{Paragraph, ParagraphVecShort, Paragraphs, VecExt},
Component,
},
geometry::LinearPlacement,
model_tt::{
component::ErrorScreen,
constant,
theme::{TEXT_ERROR_HIGHLIGHT, TEXT_ERROR_NORMAL},
},
component::Component,
model_tt::{component::ErrorScreen, constant},
};
#[cfg(not(feature = "micropython"))]
@ -32,21 +24,7 @@ pub fn screen_fatal_error(title: &str, msg: &str, footer: &str) {
let msg = unsafe { get_str(msg) };
let footer = unsafe { get_str(footer) };
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&TEXT_ERROR_NORMAL, msg).centered());
let m_top =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut messages = ParagraphVecShort::new();
messages.add(Paragraph::new(&TEXT_ERROR_HIGHLIGHT, footer).centered());
let m_bottom =
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
let mut frame = ErrorScreen::new(title, m_top, m_bottom);
let mut frame = ErrorScreen::new(title, msg, footer);
frame.place(constant::screen());
frame.paint();
}

View File

@ -10,7 +10,7 @@ use crate::{
},
};
use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet};
use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet, ResultStyle};
use num_traits::FromPrimitive;
@ -516,17 +516,6 @@ pub fn textstyle_number(num: i32) -> &'static TextStyle {
_ => &TEXT_NORMAL,
}
}
pub const TEXT_ERROR_NORMAL: TextStyle =
TextStyle::new(Font::NORMAL, FG, FATAL_ERROR_COLOR, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_ERROR_BOLD: TextStyle =
TextStyle::new(Font::BOLD, FG, FATAL_ERROR_COLOR, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_ERROR_HIGHLIGHT: TextStyle = TextStyle::new(
Font::BOLD,
FG,
FATAL_ERROR_HIGHLIGHT_COLOR,
GREY_LIGHT,
GREY_LIGHT,
);
pub const TEXT_NORMAL_OFF_WHITE: TextStyle =
TextStyle::new(Font::NORMAL, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT);
@ -557,8 +546,8 @@ pub const INFO_BUTTON_HEIGHT: i16 = 44;
pub const PIN_BUTTON_HEIGHT: i16 = 40;
pub const MNEMONIC_BUTTON_HEIGHT: i16 = 52;
pub const RESULT_PADDING: i16 = 6;
pub const RESULT_FOOTER_START: i16 = 178;
pub const RESULT_FOOTER_HEIGHT: i16 = 56;
pub const RESULT_FOOTER_START: i16 = 171;
pub const RESULT_FOOTER_HEIGHT: i16 = 62;
pub const fn button_bar<T>(inner: T) -> FixedHeightBar<T> {
FixedHeightBar::bottom(inner, BUTTON_HEIGHT)
@ -582,3 +571,6 @@ pub const fn borders_horizontal_scroll() -> Insets {
pub const fn borders_notification() -> Insets {
Insets::new(48, 6, 6, 6)
}
pub const RESULT_ERROR: ResultStyle =
ResultStyle::new(FG, FATAL_ERROR_COLOR, FATAL_ERROR_HIGHLIGHT_COLOR);