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:
parent
6d434122f7
commit
839a940990
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
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: Child<Label<T>>,
|
||||
footer: Child<ResultFooter<'a, T>>,
|
||||
}
|
||||
|
||||
impl<'a, T: ParagraphStrType> ResultScreen<'a, T> {
|
||||
pub fn new(
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
msg_area_color: Color,
|
||||
style: &'a ResultStyle,
|
||||
icon: Icon,
|
||||
message: Paragraphs<ParagraphVecShort<T>>,
|
||||
footer: Option<Paragraphs<ParagraphVecShort<T>>>,
|
||||
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,
|
||||
),
|
||||
);
|
||||
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,
|
||||
),
|
||||
)
|
||||
};
|
||||
let (main_area, footer_area) = ResultFooter::<T>::split_bounds();
|
||||
|
||||
self.message.place(message_arae);
|
||||
self.footer_pad.place(footer_area);
|
||||
self.footer.place(footer_area);
|
||||
|
||||
bounds
|
||||
let message_area = main_area.inset(Insets::top(MESSAGE_AREA_START));
|
||||
self.message.place(message_area);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user