feat(core): update bootloader style
[no changelog]
BIN
core/assets/check40.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 9.3 KiB |
BIN
core/assets/fire24.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
core/assets/fire32.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
core/assets/fire40.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.6 KiB |
BIN
core/assets/refresh24.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
core/assets/warning40.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
@ -190,11 +190,11 @@ void ui_screen_done(int restart_seconds, secbool full_redraw) {
|
||||
const char *str;
|
||||
char count_str[24];
|
||||
if (restart_seconds >= 1) {
|
||||
mini_snprintf(count_str, sizeof(count_str), "Done! Restarting in %d s",
|
||||
mini_snprintf(count_str, sizeof(count_str), "DONE! RESTARTING IN %d",
|
||||
restart_seconds);
|
||||
str = count_str;
|
||||
} else {
|
||||
str = "Done! Unplug the device.";
|
||||
str = "DONE! RECONNECT THE DEVICE";
|
||||
}
|
||||
|
||||
screen_install_success(str, initial_setup, full_redraw);
|
||||
|
@ -146,11 +146,13 @@ static usb_result_t bootloader_usb_loop(const vendor_header *const vhdr,
|
||||
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
|
||||
if (r < 0) { // error
|
||||
screen_wipe_fail();
|
||||
hal_delay(100);
|
||||
usb_stop();
|
||||
usb_deinit();
|
||||
return SHUTDOWN;
|
||||
} else { // success
|
||||
screen_wipe_success();
|
||||
hal_delay(100);
|
||||
usb_stop();
|
||||
usb_deinit();
|
||||
return SHUTDOWN;
|
||||
|
@ -18,6 +18,13 @@ impl Pad {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_clear(self) -> Self {
|
||||
Self {
|
||||
clear: true,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn place(&mut self, area: Rect) {
|
||||
self.area = area;
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ use crate::ui::{
|
||||
geometry::{Alignment, Insets, Offset, Point, Rect, TOP_CENTER},
|
||||
model_tt::{
|
||||
bootloader::theme::{
|
||||
button_bld_menu, BUTTON_AREA_START, CLOSE, CONTENT_PADDING, CORNER_BUTTON_AREA,
|
||||
INFO_SMALL, TEXT_TITLE, TITLE_AREA,
|
||||
button_bld_menu, BUTTON_AREA_START, BUTTON_HEIGHT, CONTENT_PADDING, CORNER_BUTTON_AREA,
|
||||
CORNER_BUTTON_TOUCH_EXPANSION, INFO32, TEXT_TITLE, TITLE_AREA, TITLE_Y_ADJUSTMENT, X32,
|
||||
},
|
||||
component::{Button, ButtonMsg::Clicked},
|
||||
constant::WIDTH,
|
||||
@ -18,6 +18,10 @@ use crate::ui::{
|
||||
},
|
||||
};
|
||||
|
||||
const ICON_TOP: i16 = 17;
|
||||
const CONTENT_START_WITH_ICON: i16 = 40 + CONTENT_PADDING;
|
||||
const CONTENT_START: i16 = 58;
|
||||
|
||||
#[derive(Copy, Clone, ToPrimitive)]
|
||||
pub enum ConfirmMsg {
|
||||
Cancel = 1,
|
||||
@ -29,27 +33,28 @@ pub struct Confirm<'a> {
|
||||
content_pad: Pad,
|
||||
bg_color: Color,
|
||||
icon: Option<Icon>,
|
||||
title: Option<Child<Label<&'static str>>>,
|
||||
message: Child<Paragraphs<ParagraphVecShort<&'a str>>>,
|
||||
left: Child<Button<&'static str>>,
|
||||
right: Child<Button<&'static str>>,
|
||||
title: Option<Child<Label<&'a str>>>,
|
||||
message: Child<Label<&'a str>>,
|
||||
alert: Option<Child<Label<&'a str>>>,
|
||||
left_button: Child<Button<&'static str>>,
|
||||
right_button: Child<Button<&'static str>>,
|
||||
info_button: Option<Button<&'static str>>,
|
||||
close_button: Option<Button<&'static str>>,
|
||||
info_title: Option<Child<Label<&'static str>>>,
|
||||
info_text: Option<Paragraphs<ParagraphVecShort<&'a str>>>,
|
||||
info_text: Option<Child<Paragraphs<ParagraphVecShort<&'a str>>>>,
|
||||
show_info: bool,
|
||||
|
||||
confirm_left: bool,
|
||||
}
|
||||
|
||||
impl<'a> Confirm<'a> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
bg_color: Color,
|
||||
icon: Option<Icon>,
|
||||
left: Button<&'static str>,
|
||||
right: Button<&'static str>,
|
||||
confirm_left: bool,
|
||||
confirm: (Option<&'static str>, Paragraphs<ParagraphVecShort<&'a str>>),
|
||||
left_button: Button<&'static str>,
|
||||
right_button: Button<&'static str>,
|
||||
title: Option<Label<&'a str>>,
|
||||
msg: Label<&'a str>,
|
||||
alert: Option<Label<&'a str>>,
|
||||
info: Option<(&'static str, Paragraphs<ParagraphVecShort<&'a str>>)>,
|
||||
) -> Self {
|
||||
let mut instance = Self {
|
||||
@ -57,31 +62,29 @@ impl<'a> Confirm<'a> {
|
||||
content_pad: Pad::with_background(bg_color),
|
||||
bg_color,
|
||||
icon,
|
||||
message: Child::new(confirm.1),
|
||||
left: Child::new(left),
|
||||
right: Child::new(right),
|
||||
title: title.map(Child::new),
|
||||
message: Child::new(msg),
|
||||
alert: alert.map(Child::new),
|
||||
left_button: Child::new(left_button),
|
||||
right_button: Child::new(right_button),
|
||||
close_button: None,
|
||||
info_button: None,
|
||||
info_title: None,
|
||||
info_text: None,
|
||||
confirm_left,
|
||||
show_info: false,
|
||||
title: confirm
|
||||
.0
|
||||
.map(|title| Child::new(Label::new(title, Alignment::Start, TEXT_TITLE))),
|
||||
};
|
||||
if let Some((title, text)) = info {
|
||||
instance.info_title = Some(Child::new(Label::new(title, Alignment::Start, TEXT_TITLE)));
|
||||
instance.info_text = Some(text);
|
||||
instance.info_text = Some(text.into_child());
|
||||
instance.info_button = Some(
|
||||
Button::with_icon(Icon::new(INFO_SMALL))
|
||||
Button::with_icon(Icon::new(INFO32))
|
||||
.styled(button_bld_menu())
|
||||
.with_expanded_touch_area(Insets::uniform(13)),
|
||||
.with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)),
|
||||
);
|
||||
instance.close_button = Some(
|
||||
Button::with_icon(Icon::new(CLOSE))
|
||||
Button::with_icon(Icon::new(X32))
|
||||
.styled(button_bld_menu())
|
||||
.with_expanded_touch_area(Insets::uniform(13)),
|
||||
.with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)),
|
||||
);
|
||||
}
|
||||
instance.bg.clear();
|
||||
@ -98,29 +101,86 @@ impl<'a> Component for Confirm<'a> {
|
||||
Point::zero(),
|
||||
Point::new(WIDTH, BUTTON_AREA_START),
|
||||
));
|
||||
let icon_height = if let Some(icon) = self.icon {
|
||||
icon.toif.height()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.message.place(Rect::new(
|
||||
Point::new(CONTENT_PADDING, 32 + icon_height),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START),
|
||||
));
|
||||
|
||||
let button_size = Offset::new(106, 38);
|
||||
self.left.place(Rect::from_top_left_and_size(
|
||||
let content_area_start = if self.icon.is_some() {
|
||||
CONTENT_START_WITH_ICON
|
||||
} else {
|
||||
CONTENT_START
|
||||
};
|
||||
|
||||
let content_area = Rect::new(
|
||||
Point::new(CONTENT_PADDING, content_area_start),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START - CONTENT_PADDING),
|
||||
);
|
||||
|
||||
self.message.place(content_area);
|
||||
let message_height = self.message.inner().area().height();
|
||||
|
||||
if let Some(alert) = &mut self.alert {
|
||||
alert.place(content_area);
|
||||
let alert_height = alert.inner().area().height();
|
||||
|
||||
let space_height = (content_area.height() - message_height - alert_height) / 3;
|
||||
|
||||
self.message.place(Rect::new(
|
||||
Point::new(CONTENT_PADDING, content_area_start + space_height),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START),
|
||||
));
|
||||
self.alert.place(Rect::new(
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
content_area_start + 2 * space_height + message_height,
|
||||
),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START),
|
||||
));
|
||||
} else {
|
||||
self.message.place(Rect::new(
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
content_area.center().y - (message_height / 2),
|
||||
),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START - CONTENT_PADDING),
|
||||
));
|
||||
}
|
||||
|
||||
let button_size = Offset::new((WIDTH - 3 * CONTENT_PADDING) / 2, BUTTON_HEIGHT);
|
||||
self.left_button.place(Rect::from_top_left_and_size(
|
||||
Point::new(CONTENT_PADDING, BUTTON_AREA_START),
|
||||
button_size,
|
||||
));
|
||||
self.right.place(Rect::from_top_left_and_size(
|
||||
Point::new(124, BUTTON_AREA_START),
|
||||
self.right_button.place(Rect::from_top_left_and_size(
|
||||
Point::new(2 * CONTENT_PADDING + button_size.x, BUTTON_AREA_START),
|
||||
button_size,
|
||||
));
|
||||
self.info_button.place(CORNER_BUTTON_AREA);
|
||||
self.close_button.place(CORNER_BUTTON_AREA);
|
||||
self.info_title.place(TITLE_AREA);
|
||||
self.title.place(TITLE_AREA);
|
||||
|
||||
if let Some(title) = self.info_title.as_mut() {
|
||||
title.place(TITLE_AREA);
|
||||
let title_height = title.inner().area().height();
|
||||
|
||||
title.place(Rect::new(
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
TITLE_AREA.center().y - (title_height / 2) - TITLE_Y_ADJUSTMENT,
|
||||
),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START - CONTENT_PADDING),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(title) = self.title.as_mut() {
|
||||
title.place(TITLE_AREA);
|
||||
let title_height = title.inner().area().height();
|
||||
|
||||
title.place(Rect::new(
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
TITLE_AREA.center().y - (title_height / 2) - TITLE_Y_ADJUSTMENT,
|
||||
),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START - CONTENT_PADDING),
|
||||
));
|
||||
}
|
||||
|
||||
self.info_text.place(Rect::new(
|
||||
Point::new(CONTENT_PADDING, TITLE_AREA.y1),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START),
|
||||
@ -144,19 +204,11 @@ impl<'a> Component for Confirm<'a> {
|
||||
self.content_pad.clear();
|
||||
return None;
|
||||
}
|
||||
if let Some(Clicked) = self.left.event(ctx, event) {
|
||||
return if self.confirm_left {
|
||||
Some(Self::Msg::Confirm)
|
||||
} else {
|
||||
Some(Self::Msg::Cancel)
|
||||
};
|
||||
if let Some(Clicked) = self.left_button.event(ctx, event) {
|
||||
return Some(Self::Msg::Cancel);
|
||||
};
|
||||
if let Some(Clicked) = self.right.event(ctx, event) {
|
||||
return if self.confirm_left {
|
||||
Some(Self::Msg::Cancel)
|
||||
} else {
|
||||
Some(Self::Msg::Confirm)
|
||||
};
|
||||
if let Some(Clicked) = self.right_button.event(ctx, event) {
|
||||
return Some(Self::Msg::Confirm);
|
||||
};
|
||||
None
|
||||
}
|
||||
@ -169,17 +221,18 @@ impl<'a> Component for Confirm<'a> {
|
||||
self.close_button.paint();
|
||||
self.info_title.paint();
|
||||
self.info_text.paint();
|
||||
self.left.paint();
|
||||
self.right.paint();
|
||||
self.left_button.paint();
|
||||
self.right_button.paint();
|
||||
} else {
|
||||
self.info_button.paint();
|
||||
self.title.paint();
|
||||
self.message.paint();
|
||||
self.left.paint();
|
||||
self.right.paint();
|
||||
self.alert.paint();
|
||||
self.left_button.paint();
|
||||
self.right_button.paint();
|
||||
if let Some(icon) = self.icon {
|
||||
icon.draw(
|
||||
Point::new(screen().center().x, 32),
|
||||
Point::new(screen().center().x, ICON_TOP),
|
||||
TOP_CENTER,
|
||||
WHITE,
|
||||
self.bg_color,
|
||||
@ -190,7 +243,7 @@ impl<'a> Component for Confirm<'a> {
|
||||
|
||||
#[cfg(feature = "ui_bounds")]
|
||||
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
|
||||
self.left.bounds(sink);
|
||||
self.right.bounds(sink);
|
||||
self.left_button.bounds(sink);
|
||||
self.right_button.bounds(sink);
|
||||
}
|
||||
}
|
||||
|
@ -7,14 +7,17 @@ use crate::ui::{
|
||||
display::Icon,
|
||||
geometry::{Alignment, Insets, Point, Rect},
|
||||
model_tt::{
|
||||
bootloader::theme::{button_bld_menu, button_bld_menu_item, BLD_BG, MENU},
|
||||
bootloader::theme::{button_bld, button_bld_menu, BLD_BG, MENU32},
|
||||
component::ButtonMsg::Clicked,
|
||||
},
|
||||
};
|
||||
use heapless::String;
|
||||
|
||||
use crate::ui::model_tt::{
|
||||
bootloader::theme::{CONTENT_PADDING, CORNER_BUTTON_AREA, TEXT_TITLE, TITLE_AREA},
|
||||
bootloader::theme::{
|
||||
BUTTON_AREA_START, BUTTON_HEIGHT, CONTENT_PADDING, CORNER_BUTTON_AREA, TEXT_TITLE,
|
||||
TITLE_AREA, TITLE_Y_ADJUSTMENT,
|
||||
},
|
||||
component::Button,
|
||||
constant::WIDTH,
|
||||
};
|
||||
@ -40,20 +43,17 @@ impl<'a> Intro<'a> {
|
||||
unwrap!(title.push_str("BOOTLOADER "));
|
||||
unwrap!(title.push_str(bld_version));
|
||||
|
||||
let mut instance = Self {
|
||||
bg: Pad::with_background(BLD_BG),
|
||||
Self {
|
||||
bg: Pad::with_background(BLD_BG).with_clear(),
|
||||
title: Child::new(Label::new(title, Alignment::Start, TEXT_TITLE)),
|
||||
menu: Child::new(
|
||||
Button::with_icon(Icon::new(MENU))
|
||||
Button::with_icon(Icon::new(MENU32))
|
||||
.styled(button_bld_menu())
|
||||
.with_expanded_touch_area(Insets::uniform(13)),
|
||||
),
|
||||
host: Child::new(Button::with_text("INSTALL FIRMWARE").styled(button_bld_menu_item())),
|
||||
host: Child::new(Button::with_text("INSTALL FIRMWARE").styled(button_bld())),
|
||||
text: Child::new(content),
|
||||
};
|
||||
|
||||
instance.bg.clear();
|
||||
instance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,17 +61,26 @@ impl<'a> Component for Intro<'a> {
|
||||
type Msg = IntroMsg;
|
||||
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
const BUTTON_AREA_START: i16 = 188;
|
||||
self.bg.place(screen());
|
||||
|
||||
self.title.place(TITLE_AREA);
|
||||
let title_height = self.title.inner().area().height();
|
||||
self.title.place(Rect::new(
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
TITLE_AREA.center().y - (title_height / 2) - TITLE_Y_ADJUSTMENT,
|
||||
),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START - CONTENT_PADDING),
|
||||
));
|
||||
|
||||
self.menu.place(CORNER_BUTTON_AREA);
|
||||
self.host.place(Rect::new(
|
||||
Point::new(10, BUTTON_AREA_START),
|
||||
Point::new(10 + 220, BUTTON_AREA_START + 38),
|
||||
Point::new(CONTENT_PADDING, BUTTON_AREA_START),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START + BUTTON_HEIGHT),
|
||||
));
|
||||
self.text.place(Rect::new(
|
||||
Point::new(CONTENT_PADDING, 75),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START),
|
||||
Point::new(CONTENT_PADDING, TITLE_AREA.y1 + CONTENT_PADDING),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START - CONTENT_PADDING),
|
||||
));
|
||||
bounds
|
||||
}
|
||||
|
@ -1,18 +1,22 @@
|
||||
use crate::ui::{
|
||||
component::{Child, Component, Event, EventCtx, Label, Pad},
|
||||
constant::{screen, WIDTH},
|
||||
constant::{screen, HEIGHT, WIDTH},
|
||||
display::Icon,
|
||||
geometry::{Alignment, Insets, Point, Rect},
|
||||
model_tt::{
|
||||
bootloader::theme::{
|
||||
button_bld_menu, button_bld_menu_item, BLD_BG, CLOSE, CONTENT_PADDING,
|
||||
CORNER_BUTTON_AREA, ERASE, REBOOT, TEXT_TITLE, TITLE_AREA,
|
||||
button_bld, button_bld_menu, BLD_BG, BUTTON_HEIGHT, CONTENT_PADDING,
|
||||
CORNER_BUTTON_AREA, CORNER_BUTTON_TOUCH_EXPANSION, FIRE24, REFRESH24, TEXT_TITLE,
|
||||
TITLE_AREA, TITLE_Y_ADJUSTMENT, X32,
|
||||
},
|
||||
component::{Button, ButtonMsg::Clicked, IconText},
|
||||
},
|
||||
};
|
||||
use heapless::String;
|
||||
|
||||
const BUTTON_AREA_START: i16 = 56;
|
||||
const BUTTON_SPACING: i16 = 8;
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone, ToPrimitive)]
|
||||
pub enum MenuMsg {
|
||||
@ -30,28 +34,23 @@ pub struct Menu {
|
||||
}
|
||||
|
||||
impl Menu {
|
||||
pub fn new(bld_version: &'static str) -> Self {
|
||||
let content_reboot = IconText::new("REBOOT TREZOR", Icon::new(REBOOT));
|
||||
let content_reset = IconText::new("FACTORY RESET", Icon::new(ERASE));
|
||||
pub fn new(_bld_version: &'static str) -> Self {
|
||||
let content_reboot = IconText::new("REBOOT TREZOR", Icon::new(REFRESH24));
|
||||
let content_reset = IconText::new("FACTORY RESET", Icon::new(FIRE24));
|
||||
|
||||
let mut title: String<32> = String::new();
|
||||
unwrap!(title.push_str("BOOTLOADER "));
|
||||
unwrap!(title.push_str(bld_version));
|
||||
|
||||
let mut instance = Self {
|
||||
bg: Pad::with_background(BLD_BG),
|
||||
title: Child::new(Label::new(title, Alignment::Start, TEXT_TITLE)),
|
||||
close: Child::new(
|
||||
Button::with_icon(Icon::new(CLOSE))
|
||||
Button::with_icon(Icon::new(X32))
|
||||
.styled(button_bld_menu())
|
||||
.with_expanded_touch_area(Insets::uniform(13)),
|
||||
),
|
||||
reboot: Child::new(
|
||||
Button::with_icon_and_text(content_reboot).styled(button_bld_menu_item()),
|
||||
),
|
||||
reset: Child::new(
|
||||
Button::with_icon_and_text(content_reset).styled(button_bld_menu_item()),
|
||||
.with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)),
|
||||
),
|
||||
reboot: Child::new(Button::with_icon_and_text(content_reboot).styled(button_bld())),
|
||||
reset: Child::new(Button::with_icon_and_text(content_reset).styled(button_bld())),
|
||||
};
|
||||
instance.bg.clear();
|
||||
instance
|
||||
@ -64,14 +63,28 @@ impl Component for Menu {
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
self.bg.place(screen());
|
||||
self.title.place(TITLE_AREA);
|
||||
let title_height = self.title.inner().area().height();
|
||||
self.title.place(Rect::new(
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
TITLE_AREA.center().y - (title_height / 2) - TITLE_Y_ADJUSTMENT,
|
||||
),
|
||||
Point::new(WIDTH - CONTENT_PADDING, HEIGHT),
|
||||
));
|
||||
self.close.place(CORNER_BUTTON_AREA);
|
||||
self.reboot.place(Rect::new(
|
||||
Point::new(CONTENT_PADDING, 64),
|
||||
Point::new(WIDTH - CONTENT_PADDING, 64 + 38),
|
||||
Point::new(CONTENT_PADDING, BUTTON_AREA_START),
|
||||
Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START + BUTTON_HEIGHT),
|
||||
));
|
||||
self.reset.place(Rect::new(
|
||||
Point::new(CONTENT_PADDING, 110),
|
||||
Point::new(WIDTH - CONTENT_PADDING, 110 + 38),
|
||||
Point::new(
|
||||
CONTENT_PADDING,
|
||||
BUTTON_AREA_START + BUTTON_HEIGHT + BUTTON_SPACING,
|
||||
),
|
||||
Point::new(
|
||||
WIDTH - CONTENT_PADDING,
|
||||
BUTTON_AREA_START + 2 * BUTTON_HEIGHT + BUTTON_SPACING,
|
||||
),
|
||||
));
|
||||
bounds
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
trezorhal::io::io_touch_read,
|
||||
ui::{
|
||||
component::{Component, Event, EventCtx, Never},
|
||||
component::{Component, Event, EventCtx, Label, Never},
|
||||
display::{self, Font},
|
||||
event::TouchEvent,
|
||||
geometry::Point,
|
||||
@ -23,20 +23,20 @@ use crate::{
|
||||
component::text::paragraphs::{Paragraph, ParagraphVecShort, Paragraphs, VecExt},
|
||||
constant::screen,
|
||||
display::{Color, Icon},
|
||||
geometry::{LinearPlacement, CENTER},
|
||||
geometry::{Alignment, LinearPlacement, CENTER},
|
||||
model_tt::{
|
||||
bootloader::{
|
||||
connect::Connect,
|
||||
theme::{
|
||||
button_install_cancel, button_install_confirm, button_wipe_cancel,
|
||||
button_wipe_confirm, BLD_BG, BLD_FG, BLD_WIPE_COLOR, ERASE_BIG, LOGO_EMPTY,
|
||||
RECEIVE, TEXT_WIPE_BOLD, WELCOME_COLOR,
|
||||
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,
|
||||
},
|
||||
},
|
||||
component::{Button, ResultScreen},
|
||||
theme::{
|
||||
BACKLIGHT_DIM, BACKLIGHT_NORMAL, BG, BLACK, FG, GREY_DARK, ICON_SUCCESS_SMALL,
|
||||
ICON_WARN_SMALL, TEXT_ERROR_BOLD, TEXT_ERROR_NORMAL, WHITE,
|
||||
BACKLIGHT_DIM, BACKLIGHT_NORMAL, BLACK, FG, GREY_DARK, TEXT_ERROR_HIGHLIGHT, WHITE,
|
||||
},
|
||||
},
|
||||
util::{from_c_array, from_c_str},
|
||||
@ -66,11 +66,11 @@ where
|
||||
}
|
||||
|
||||
fn fadein() {
|
||||
display::fade_backlight_duration(BACKLIGHT_NORMAL, 500);
|
||||
display::fade_backlight_duration(BACKLIGHT_NORMAL, 150);
|
||||
}
|
||||
|
||||
fn fadeout() {
|
||||
display::fade_backlight_duration(BACKLIGHT_DIM, 500);
|
||||
display::fade_backlight_duration(BACKLIGHT_DIM, 150);
|
||||
}
|
||||
|
||||
fn run<F>(frame: &mut F) -> u32
|
||||
@ -145,34 +145,31 @@ extern "C" fn screen_install_confirm(
|
||||
core::str::from_utf8_unchecked(fingerprint_buffer.as_ref())
|
||||
};
|
||||
|
||||
let mut version_str: String<64> = String::new();
|
||||
let mut version_str: String<128> = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
|
||||
let mut vendor_str: String<64> = String::new();
|
||||
unwrap!(vendor_str.push_str("by "));
|
||||
unwrap!(vendor_str.push_str(text));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(text));
|
||||
|
||||
let title = if downgrade {
|
||||
"DOWNGRADE FW"
|
||||
Label::new("DOWNGRADE FW", Alignment::Start, theme::TEXT_BOLD)
|
||||
} else if vendor {
|
||||
"CHANGE FW VENDOR"
|
||||
Label::new("CHANGE FW\nVENDOR", Alignment::Start, theme::TEXT_BOLD)
|
||||
} else {
|
||||
"UPDATE FIRMWARE"
|
||||
Label::new("UPDATE FIRMWARE", Alignment::Start, theme::TEXT_BOLD)
|
||||
};
|
||||
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
let msg = Label::new(version_str.as_ref(), Alignment::Start, theme::TEXT_NORMAL);
|
||||
|
||||
messages.add(Paragraph::new(&theme::TEXT_NORMAL, version_str.as_ref()));
|
||||
messages.add(Paragraph::new(&theme::TEXT_NORMAL, vendor_str.as_ref()));
|
||||
|
||||
if vendor || downgrade {
|
||||
messages
|
||||
.add(Paragraph::new(&theme::TEXT_BOLD, "Seed will be erased!").with_top_padding(16));
|
||||
}
|
||||
|
||||
let message =
|
||||
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
let alert = if vendor || downgrade {
|
||||
Some(Label::new(
|
||||
"SEED WILL BE ERASED!",
|
||||
Alignment::Start,
|
||||
theme::TEXT_BOLD,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
messages.add(Paragraph::new(&theme::TEXT_FINGERPRINT, fingerprint_str));
|
||||
@ -180,16 +177,24 @@ extern "C" fn screen_install_confirm(
|
||||
let fingerprint =
|
||||
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
|
||||
let left = Button::with_text("CANCEL").styled(button_install_cancel());
|
||||
let right = Button::with_text("INSTALL").styled(button_install_confirm());
|
||||
let (left, right) = if !(vendor || downgrade) {
|
||||
let l = Button::with_text("CANCEL").styled(button_bld());
|
||||
let r = Button::with_text("INSTALL").styled(button_confirm());
|
||||
(l, r)
|
||||
} else {
|
||||
let l = Button::with_icon(Icon::new(X24)).styled(button_bld());
|
||||
let r = Button::with_icon(Icon::new(CHECK24)).styled(button_confirm());
|
||||
(l, r)
|
||||
};
|
||||
|
||||
let mut frame = Confirm::new(
|
||||
BLD_BG,
|
||||
None,
|
||||
left,
|
||||
right,
|
||||
false,
|
||||
(Some(title), message),
|
||||
Some(title),
|
||||
msg,
|
||||
alert,
|
||||
Some(("FW FINGERPRINT", fingerprint)),
|
||||
);
|
||||
|
||||
@ -198,32 +203,30 @@ extern "C" fn screen_install_confirm(
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_confirm() -> u32 {
|
||||
let icon = Some(Icon::new(ERASE_BIG));
|
||||
let icon = Some(Icon::new(FIRE40));
|
||||
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
|
||||
messages.add(
|
||||
Paragraph::new(
|
||||
&TEXT_ERROR_NORMAL,
|
||||
"Are you sure you want to factory reset the device?",
|
||||
)
|
||||
.centered(),
|
||||
let msg = Label::new(
|
||||
"Are you sure you want to factory reset the device?",
|
||||
Alignment::Center,
|
||||
TEXT_WIPE_NORMAL,
|
||||
);
|
||||
let alert = Label::new(
|
||||
"SEED AND FIRMWARE\nWILL BE ERASED!",
|
||||
Alignment::Center,
|
||||
TEXT_WIPE_BOLD,
|
||||
);
|
||||
messages.add(Paragraph::new(&TEXT_ERROR_BOLD, "Seed and firmware\nwill be erased!").centered());
|
||||
|
||||
let message =
|
||||
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
|
||||
let left = Button::with_text("RESET").styled(button_wipe_confirm());
|
||||
let right = Button::with_text("CANCEL").styled(button_wipe_cancel());
|
||||
let right = Button::with_text("RESET").styled(button_wipe_confirm());
|
||||
let left = Button::with_text("CANCEL").styled(button_wipe_cancel());
|
||||
|
||||
let mut frame = Confirm::new(
|
||||
BLD_WIPE_COLOR,
|
||||
icon,
|
||||
left,
|
||||
right,
|
||||
true,
|
||||
(None, message),
|
||||
None,
|
||||
msg,
|
||||
Some(alert),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -261,7 +264,7 @@ extern "C" fn screen_intro(
|
||||
messages.add(Paragraph::new(&theme::TEXT_NORMAL, fw.as_ref()));
|
||||
messages.add(Paragraph::new(&theme::TEXT_NORMAL, vendor_.as_ref()));
|
||||
|
||||
let p = Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_start());
|
||||
let p = Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
|
||||
let mut frame = Intro::new(bld_version, p);
|
||||
|
||||
@ -282,7 +285,7 @@ fn screen_progress(
|
||||
}
|
||||
|
||||
display::text_center(
|
||||
Point::new(constant::WIDTH / 2, 214),
|
||||
Point::new(constant::WIDTH / 2, 195),
|
||||
text,
|
||||
Font::NORMAL,
|
||||
fg_color,
|
||||
@ -296,28 +299,28 @@ fn screen_progress(
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_progress(progress: u16, initialize: bool, initial_setup: bool) {
|
||||
let bg_color = if initial_setup { WELCOME_COLOR } else { BG };
|
||||
let bg_color = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let fg_color = if initial_setup { FG } else { BLD_FG };
|
||||
|
||||
screen_progress(
|
||||
"Installing firmware...",
|
||||
"Installing firmware",
|
||||
progress,
|
||||
initialize,
|
||||
fg_color,
|
||||
bg_color,
|
||||
Some((Icon::new(RECEIVE), fg_color)),
|
||||
Some((Icon::new(DOWNLOAD32), fg_color)),
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
screen_progress(
|
||||
"Resetting Trezor...",
|
||||
"Resetting Trezor",
|
||||
progress,
|
||||
initialize,
|
||||
theme::BLD_FG,
|
||||
BLD_WIPE_COLOR,
|
||||
Some((Icon::new(ERASE_BIG), theme::BLD_FG)),
|
||||
Some((Icon::new(FIRE32), theme::BLD_FG)),
|
||||
)
|
||||
}
|
||||
|
||||
@ -331,15 +334,15 @@ extern "C" fn screen_connect() {
|
||||
extern "C" fn screen_wipe_success() {
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
|
||||
messages.add(Paragraph::new(&TEXT_ERROR_BOLD, "Trezor reset").centered());
|
||||
messages.add(Paragraph::new(&TEXT_ERROR_BOLD, "successfully.").centered());
|
||||
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_WIPE_BOLD, "PLEASE RECONNECT").centered());
|
||||
messages.add(Paragraph::new(&TEXT_WIPE_BOLD, "THE DEVICE").centered());
|
||||
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());
|
||||
@ -347,7 +350,8 @@ extern "C" fn screen_wipe_success() {
|
||||
let mut frame = ResultScreen::new(
|
||||
WHITE,
|
||||
BLD_WIPE_COLOR,
|
||||
Icon::new(ICON_SUCCESS_SMALL),
|
||||
BLD_WIPE_CANCEL_BTN_COLOR,
|
||||
Icon::new(CHECK40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
true,
|
||||
@ -359,22 +363,23 @@ extern "C" fn screen_wipe_success() {
|
||||
extern "C" fn screen_wipe_fail() {
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
|
||||
messages.add(Paragraph::new(&TEXT_ERROR_BOLD, "Trezor reset was").centered());
|
||||
messages.add(Paragraph::new(&TEXT_ERROR_BOLD, "not successful.").centered());
|
||||
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_WIPE_BOLD, "PLEASE RECONNECT").centered());
|
||||
messages.add(Paragraph::new(&TEXT_WIPE_BOLD, "THE DEVICE").centered());
|
||||
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,
|
||||
Icon::new(ICON_WARN_SMALL),
|
||||
BLD_WIPE_CANCEL_BTN_COLOR,
|
||||
Icon::new(WARNING40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
true,
|
||||
@ -408,8 +413,8 @@ extern "C" fn screen_boot_empty(firmware_present: bool, fading: bool) {
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_fail() {
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
messages.add(Paragraph::new(&theme::TEXT_BOLD, "Firmware installation was").centered());
|
||||
messages.add(Paragraph::new(&theme::TEXT_BOLD, "not successful.").centered());
|
||||
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());
|
||||
@ -423,7 +428,8 @@ extern "C" fn screen_install_fail() {
|
||||
let mut frame = ResultScreen::new(
|
||||
WHITE,
|
||||
BLD_BG,
|
||||
Icon::new(ICON_WARN_SMALL),
|
||||
BLD_BTN_COLOR,
|
||||
Icon::new(WARNING40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
true,
|
||||
@ -433,8 +439,8 @@ extern "C" fn screen_install_fail() {
|
||||
|
||||
fn screen_install_success_bld(msg: &'static str, complete_draw: bool) {
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
messages.add(Paragraph::new(&theme::TEXT_BOLD, "Firmware installed").centered());
|
||||
messages.add(Paragraph::new(&theme::TEXT_BOLD, "successfully.").centered());
|
||||
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());
|
||||
|
||||
@ -446,7 +452,8 @@ fn screen_install_success_bld(msg: &'static str, complete_draw: bool) {
|
||||
let mut frame = ResultScreen::new(
|
||||
WHITE,
|
||||
BLD_BG,
|
||||
Icon::new(ICON_SUCCESS_SMALL),
|
||||
BLD_BTN_COLOR,
|
||||
Icon::new(CHECK40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
complete_draw,
|
||||
@ -456,8 +463,8 @@ fn screen_install_success_bld(msg: &'static str, complete_draw: bool) {
|
||||
|
||||
fn screen_install_success_initial(msg: &'static str, complete_draw: bool) {
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
messages.add(Paragraph::new(&theme::TEXT_WELCOME_BOLD, "Firmware installed").centered());
|
||||
messages.add(Paragraph::new(&theme::TEXT_WELCOME_BOLD, "successfully.").centered());
|
||||
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());
|
||||
@ -471,7 +478,8 @@ fn screen_install_success_initial(msg: &'static str, complete_draw: bool) {
|
||||
let mut frame = ResultScreen::new(
|
||||
FG,
|
||||
WELCOME_COLOR,
|
||||
Icon::new(ICON_SUCCESS_SMALL),
|
||||
WELCOME_HIGHLIGHT_COLOR,
|
||||
Icon::new(CHECK40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
complete_draw,
|
||||
@ -501,11 +509,7 @@ extern "C" fn screen_welcome() {
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
messages.add(Paragraph::new(&theme::TEXT_WELCOME, "Get started with").centered());
|
||||
messages.add(Paragraph::new(&theme::TEXT_WELCOME, "your trezor at").centered());
|
||||
messages.add(
|
||||
Paragraph::new(&theme::TEXT_WELCOME_BOLD, "trezor.io/start")
|
||||
.centered()
|
||||
.with_top_padding(2),
|
||||
);
|
||||
messages.add(Paragraph::new(&theme::TEXT_WELCOME_URL, "trezor.io/start").centered());
|
||||
let mut frame =
|
||||
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
show(&mut frame, false);
|
||||
|
@ -1,107 +1,77 @@
|
||||
use crate::{
|
||||
alpha,
|
||||
ui::{
|
||||
component::{text::TextStyle, LineBreaking::BreakWordsNoHyphen},
|
||||
constant::WIDTH,
|
||||
display::{Color, Font},
|
||||
geometry::{Offset, Point, Rect},
|
||||
model_tt::{
|
||||
component::{ButtonStyle, ButtonStyleSheet},
|
||||
theme::{BLACK, FG, GREY_DARK, GREY_LIGHT, GREY_MEDIUM, WHITE},
|
||||
},
|
||||
use crate::ui::{
|
||||
component::{text::TextStyle, LineBreaking::BreakWordsNoHyphen},
|
||||
constant::WIDTH,
|
||||
display::{Color, Font},
|
||||
geometry::{Offset, Point, Rect},
|
||||
model_tt::{
|
||||
component::{ButtonStyle, ButtonStyleSheet},
|
||||
theme::{BLACK, FG, GREY_DARK, GREY_LIGHT, GREY_MEDIUM, WHITE},
|
||||
},
|
||||
};
|
||||
|
||||
pub const BLD_BG: Color = Color::rgb(0x00, 0x17, 0xA3);
|
||||
pub const BLD_BG: Color = Color::rgb(0x00, 0x1E, 0xAD);
|
||||
pub const BLD_FG: Color = WHITE;
|
||||
pub const BLD_WIPE_COLOR: Color = Color::rgb(0xAD, 0x2B, 0x2B);
|
||||
pub const BLD_WIPE_TEXT_COLOR: Color = Color::rgb(0xD6, 0x95, 0x95);
|
||||
pub const BLD_WIPE_COLOR: Color = Color::rgb(0xE7, 0x0E, 0x0E);
|
||||
pub const BLD_WIPE_TEXT_COLOR: Color = WHITE;
|
||||
|
||||
pub const BLD_WIPE_BTN_COLOR: Color = Color::alpha(BLD_WIPE_COLOR, alpha!(0.3));
|
||||
pub const BLD_WIPE_BTN_COLOR_ACTIVE: Color = Color::rgb(0xB9, 0x4B, 0x4B);
|
||||
pub const BLD_WIPE_CANCEL_BTN_COLOR_ACTIVE: Color = Color::rgb(0xF3, 0xDF, 0xDF);
|
||||
pub const BLD_WIPE_BTN_COLOR: Color = WHITE;
|
||||
pub const BLD_WIPE_BTN_COLOR_ACTIVE: Color = Color::rgb(0xFA, 0xCF, 0xCF);
|
||||
|
||||
pub const BLD_INSTALL_BTN_COLOR: Color = Color::alpha(BLD_BG, alpha!(0.3));
|
||||
pub const BLD_INSTALL_BTN_COLOR_ACTIVE: Color = Color::rgb(0xD9, 0xDC, 0xF1);
|
||||
pub const BLD_INSTALL_CANCEL_BTN_COLOR_ACTIVE: Color = Color::rgb(0x26, 0x3A, 0xB1);
|
||||
pub const BLD_WIPE_CANCEL_BTN_COLOR: Color = Color::rgb(0xFF, 0x41, 0x41);
|
||||
pub const BLD_WIPE_CANCEL_BTN_COLOR_ACTIVE: Color = Color::rgb(0xAE, 0x09, 0x09);
|
||||
|
||||
pub const BLD_COLOR_SUBMSG: Color = Color::rgb(0x80, 0x8B, 0xD1);
|
||||
pub const BLD_INSTALL_BTN_COLOR_ACTIVE: Color = Color::rgb(0xCD, 0xD2, 0xEF);
|
||||
|
||||
pub const BLD_BTN_MENU_COLOR: Color = Color::alpha(BLD_BG, alpha!(0.22));
|
||||
pub const BLD_BTN_MENU_COLOR_ACTIVE: Color = Color::alpha(BLD_BG, alpha!(0.11));
|
||||
pub const BLD_BTN_MENUITEM_COLOR: Color = Color::alpha(BLD_BG, alpha!(0.33));
|
||||
pub const BLD_BTN_MENUITEM_COLOR_ACTIVE: Color =
|
||||
Color::rgba(BLD_BG, 0xFF, 0xFF, 0xFF, alpha!(0.11));
|
||||
pub const BLD_TITLE_COLOR: Color = Color::rgba(BLD_BG, 0xFF, 0xFF, 0xFF, alpha!(0.75));
|
||||
pub const BLD_BTN_COLOR: Color = Color::rgb(0x2D, 0x42, 0xBF);
|
||||
pub const BLD_BTN_COLOR_ACTIVE: Color = Color::rgb(0x04, 0x10, 0x58);
|
||||
|
||||
pub const BLD_TITLE_COLOR: Color = WHITE;
|
||||
|
||||
pub const WELCOME_COLOR: Color = BLACK;
|
||||
pub const WELCOME_HIGHLIGHT_COLOR: Color = Color::rgb(0x28, 0x28, 0x28);
|
||||
|
||||
// Commonly used corner radius (i.e. for buttons).
|
||||
pub const RADIUS: u8 = 2;
|
||||
|
||||
// Commonly used constants for UI elements.
|
||||
pub const CONTENT_PADDING: i16 = 10;
|
||||
pub const TITLE_AREA: Rect = Rect::new(Point::new(15, 14), Point::new(200, 30));
|
||||
pub const CORNER_BUTTON_SIZE: i16 = 32;
|
||||
pub const CORNER_BUTTON_PADDING: i16 = 8;
|
||||
pub const CONTENT_PADDING: i16 = 6;
|
||||
pub const TITLE_AREA: Rect = Rect::new(
|
||||
Point::new(CONTENT_PADDING, CONTENT_PADDING),
|
||||
Point::new(WIDTH, CORNER_BUTTON_SIZE + CONTENT_PADDING),
|
||||
);
|
||||
|
||||
pub const CORNER_BUTTON_TOUCH_EXPANSION: i16 = 13;
|
||||
pub const CORNER_BUTTON_SIZE: i16 = 44;
|
||||
pub const CORNER_BUTTON_AREA: Rect = Rect::from_top_left_and_size(
|
||||
Point::new(
|
||||
WIDTH - CORNER_BUTTON_SIZE - CORNER_BUTTON_PADDING,
|
||||
CORNER_BUTTON_PADDING,
|
||||
WIDTH - CORNER_BUTTON_SIZE - CONTENT_PADDING,
|
||||
CONTENT_PADDING,
|
||||
),
|
||||
Offset::uniform(CORNER_BUTTON_SIZE),
|
||||
);
|
||||
pub const TITLE_AREA_HEIGHT: i16 = 16;
|
||||
pub const TITLE_AREA_START_Y: i16 = 8;
|
||||
pub const BUTTON_AREA_START: i16 = 188;
|
||||
|
||||
// UI icons.
|
||||
pub const ICON_CANCEL: &[u8] = include_res!("model_tt/res/x24.toif");
|
||||
pub const ICON_CONFIRM: &[u8] = include_res!("model_tt/res/check24.toif");
|
||||
pub const BUTTON_AREA_START: i16 = 184;
|
||||
pub const BUTTON_HEIGHT: i16 = 50;
|
||||
pub const TITLE_Y_ADJUSTMENT: i16 = 3;
|
||||
|
||||
// BLD icons
|
||||
pub const CLOSE: &[u8] = include_res!("model_tt/res/close.toif");
|
||||
pub const ERASE: &[u8] = include_res!("model_tt/res/erase.toif");
|
||||
pub const ERASE_BIG: &[u8] = include_res!("model_tt/res/erase_big.toif");
|
||||
pub const REBOOT: &[u8] = include_res!("model_tt/res/reboot.toif");
|
||||
pub const MENU: &[u8] = include_res!("model_tt/res/menu.toif");
|
||||
pub const RECEIVE: &[u8] = include_res!("model_tt/res/receive.toif");
|
||||
pub const X24: &[u8] = include_res!("model_tt/res/x24.toif");
|
||||
pub const X32: &[u8] = include_res!("model_tt/res/x32.toif");
|
||||
pub const FIRE24: &[u8] = include_res!("model_tt/res/fire24.toif");
|
||||
pub const FIRE32: &[u8] = include_res!("model_tt/res/fire32.toif");
|
||||
pub const FIRE40: &[u8] = include_res!("model_tt/res/fire40.toif");
|
||||
pub const REFRESH24: &[u8] = include_res!("model_tt/res/refresh24.toif");
|
||||
pub const MENU32: &[u8] = include_res!("model_tt/res/menu32.toif");
|
||||
pub const INFO32: &[u8] = include_res!("model_tt/res/info32.toif");
|
||||
pub const DOWNLOAD32: &[u8] = include_res!("model_tt/res/download32.toif");
|
||||
pub const WARNING40: &[u8] = include_res!("model_tt/res/warning40.toif");
|
||||
pub const CHECK24: &[u8] = include_res!("model_tt/res/check24.toif");
|
||||
pub const CHECK40: &[u8] = include_res!("model_tt/res/check40.toif");
|
||||
|
||||
pub const LOGO_EMPTY: &[u8] = include_res!("model_tt/res/trezor_empty.toif");
|
||||
pub const INFO_SMALL: &[u8] = include_res!("model_tt/res/info_small.toif");
|
||||
|
||||
pub fn button_install_cancel() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: WHITE,
|
||||
button_color: BLD_BTN_MENUITEM_COLOR,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 0,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: WHITE,
|
||||
button_color: BLD_INSTALL_CANCEL_BTN_COLOR_ACTIVE,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: RADIUS,
|
||||
border_width: 0,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: GREY_LIGHT,
|
||||
button_color: GREY_DARK,
|
||||
background_color: WHITE,
|
||||
border_color: WHITE,
|
||||
border_radius: RADIUS,
|
||||
border_width: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn button_install_confirm() -> ButtonStyleSheet {
|
||||
pub fn button_confirm() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
@ -137,8 +107,8 @@ pub fn button_wipe_cancel() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: BLD_WIPE_COLOR,
|
||||
button_color: WHITE,
|
||||
text_color: WHITE,
|
||||
button_color: BLD_WIPE_CANCEL_BTN_COLOR,
|
||||
background_color: BLD_WIPE_COLOR,
|
||||
border_color: BLD_WIPE_COLOR,
|
||||
border_radius: RADIUS,
|
||||
@ -146,7 +116,7 @@ pub fn button_wipe_cancel() -> ButtonStyleSheet {
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: BLD_WIPE_COLOR,
|
||||
text_color: WHITE,
|
||||
button_color: BLD_WIPE_CANCEL_BTN_COLOR_ACTIVE,
|
||||
background_color: BLD_WIPE_COLOR,
|
||||
border_color: BLD_WIPE_COLOR,
|
||||
@ -169,7 +139,7 @@ pub fn button_wipe_confirm() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: WHITE,
|
||||
text_color: BLD_WIPE_COLOR,
|
||||
button_color: BLD_WIPE_BTN_COLOR,
|
||||
background_color: BLD_WIPE_COLOR,
|
||||
border_color: BLD_WIPE_COLOR,
|
||||
@ -178,7 +148,7 @@ pub fn button_wipe_confirm() -> ButtonStyleSheet {
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: WHITE,
|
||||
text_color: BLD_WIPE_COLOR,
|
||||
button_color: BLD_WIPE_BTN_COLOR_ACTIVE,
|
||||
background_color: BLD_WIPE_COLOR,
|
||||
border_color: BLD_WIPE_COLOR,
|
||||
@ -202,39 +172,39 @@ pub fn button_bld_menu() -> ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: BLD_FG,
|
||||
button_color: BLD_BTN_MENU_COLOR,
|
||||
button_color: BLD_BG,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: 4,
|
||||
border_width: 0,
|
||||
border_color: BLD_BTN_COLOR,
|
||||
border_radius: 2,
|
||||
border_width: 2,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: BLD_FG,
|
||||
button_color: BLD_BTN_MENU_COLOR_ACTIVE,
|
||||
button_color: BLD_BG,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: 4,
|
||||
border_width: 0,
|
||||
border_color: BLD_BTN_COLOR_ACTIVE,
|
||||
border_radius: 2,
|
||||
border_width: 2,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: GREY_LIGHT,
|
||||
button_color: BLD_BTN_MENU_COLOR,
|
||||
button_color: BLD_BG,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: 4,
|
||||
border_width: 0,
|
||||
border_radius: 2,
|
||||
border_width: 2,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn button_bld_menu_item() -> ButtonStyleSheet {
|
||||
pub fn button_bld() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: BLD_FG,
|
||||
button_color: BLD_BTN_MENUITEM_COLOR,
|
||||
button_color: BLD_BTN_COLOR,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: 4,
|
||||
@ -243,7 +213,7 @@ pub fn button_bld_menu_item() -> ButtonStyleSheet {
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: BLD_FG,
|
||||
button_color: BLD_BTN_MENUITEM_COLOR_ACTIVE,
|
||||
button_color: BLD_BTN_COLOR_ACTIVE,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: 4,
|
||||
@ -252,7 +222,7 @@ pub fn button_bld_menu_item() -> ButtonStyleSheet {
|
||||
disabled: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: GREY_LIGHT,
|
||||
button_color: BLD_BTN_MENUITEM_COLOR,
|
||||
button_color: BLD_BTN_COLOR,
|
||||
background_color: BLD_BG,
|
||||
border_color: BLD_BG,
|
||||
border_radius: 4,
|
||||
@ -267,7 +237,7 @@ pub const TEXT_WELCOME: TextStyle = TextStyle::new(
|
||||
GREY_MEDIUM,
|
||||
GREY_MEDIUM,
|
||||
);
|
||||
pub const TEXT_WELCOME_BOLD: TextStyle = TextStyle::new(Font::BOLD, FG, WELCOME_COLOR, FG, FG);
|
||||
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,
|
||||
@ -277,8 +247,8 @@ pub const TEXT_TITLE: TextStyle = TextStyle::new(
|
||||
);
|
||||
pub const TEXT_SUBMSG_INITIAL: TextStyle = TextStyle::new(
|
||||
Font::BOLD,
|
||||
GREY_MEDIUM,
|
||||
WELCOME_COLOR,
|
||||
WHITE,
|
||||
WELCOME_HIGHLIGHT_COLOR,
|
||||
GREY_MEDIUM,
|
||||
GREY_MEDIUM,
|
||||
);
|
||||
@ -295,10 +265,11 @@ pub const TEXT_WIPE_BOLD: TextStyle = TextStyle::new(
|
||||
BLD_WIPE_TEXT_COLOR,
|
||||
BLD_WIPE_TEXT_COLOR,
|
||||
);
|
||||
pub const TEXT_SUBMSG: TextStyle = TextStyle::new(
|
||||
Font::BOLD,
|
||||
BLD_COLOR_SUBMSG,
|
||||
BLD_BG,
|
||||
BLD_COLOR_SUBMSG,
|
||||
BLD_COLOR_SUBMSG,
|
||||
pub const TEXT_WIPE_NORMAL: TextStyle = TextStyle::new(
|
||||
Font::NORMAL,
|
||||
BLD_WIPE_TEXT_COLOR,
|
||||
BLD_WIPE_COLOR,
|
||||
BLD_WIPE_TEXT_COLOR,
|
||||
BLD_WIPE_TEXT_COLOR,
|
||||
);
|
||||
pub const TEXT_SUBMSG: TextStyle = TextStyle::new(Font::BOLD, WHITE, BLD_BTN_COLOR, WHITE, WHITE);
|
||||
|
@ -1,14 +1,11 @@
|
||||
use crate::{
|
||||
alpha,
|
||||
ui::{
|
||||
component::{
|
||||
text::paragraphs::{ParagraphStrType, ParagraphVecShort, Paragraphs},
|
||||
Child, Component, Event, EventCtx, Never, Pad,
|
||||
},
|
||||
constant::screen,
|
||||
display::{self, Color, Icon},
|
||||
geometry::{Offset, Point, Rect, CENTER},
|
||||
use crate::ui::{
|
||||
component::{
|
||||
text::paragraphs::{ParagraphStrType, ParagraphVecShort, Paragraphs},
|
||||
Child, Component, Event, EventCtx, Never, Pad,
|
||||
},
|
||||
constant::screen,
|
||||
display::{self, Color, Icon},
|
||||
geometry::{Point, Rect, CENTER},
|
||||
};
|
||||
|
||||
use crate::ui::model_tt::constant::{HEIGHT, WIDTH};
|
||||
@ -18,6 +15,7 @@ pub struct ResultScreen<T> {
|
||||
small_pad: Pad,
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
msg_area_color: Color,
|
||||
icon: Icon,
|
||||
message_top: Child<Paragraphs<ParagraphVecShort<T>>>,
|
||||
message_bottom: Child<Paragraphs<ParagraphVecShort<T>>>,
|
||||
@ -27,6 +25,7 @@ impl<T: ParagraphStrType> ResultScreen<T> {
|
||||
pub fn new(
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
msg_area_color: Color,
|
||||
icon: Icon,
|
||||
message_top: Paragraphs<ParagraphVecShort<T>>,
|
||||
message_bottom: Paragraphs<ParagraphVecShort<T>>,
|
||||
@ -37,6 +36,7 @@ impl<T: ParagraphStrType> ResultScreen<T> {
|
||||
small_pad: Pad::with_background(bg_color),
|
||||
fg_color,
|
||||
bg_color,
|
||||
msg_area_color,
|
||||
icon,
|
||||
message_top: Child::new(message_top),
|
||||
message_bottom: Child::new(message_bottom),
|
||||
@ -59,9 +59,9 @@ impl<T: ParagraphStrType> Component for ResultScreen<T> {
|
||||
.place(Rect::new(Point::new(0, 0), Point::new(WIDTH, HEIGHT)));
|
||||
|
||||
self.message_top
|
||||
.place(Rect::new(Point::new(15, 59), Point::new(WIDTH - 15, 149)));
|
||||
.place(Rect::new(Point::new(15, 59), Point::new(WIDTH - 15, 176)));
|
||||
|
||||
let bottom_area = Rect::new(Point::new(15, 151), Point::new(WIDTH - 15, HEIGHT));
|
||||
let bottom_area = Rect::new(Point::new(6, 176), Point::new(WIDTH - 6, 176 + 56));
|
||||
|
||||
self.small_pad.place(bottom_area);
|
||||
self.message_bottom.place(bottom_area);
|
||||
@ -83,11 +83,13 @@ impl<T: ParagraphStrType> Component for ResultScreen<T> {
|
||||
self.fg_color,
|
||||
self.bg_color,
|
||||
);
|
||||
display::rect_fill(
|
||||
Rect::from_top_left_and_size(Point::new(12, 149), Offset::new(216, 1)),
|
||||
Color::alpha(self.bg_color, alpha!(0.2)),
|
||||
);
|
||||
self.message_top.paint();
|
||||
display::rect_fill_rounded(
|
||||
Rect::new(Point::new(6, 176), Point::new(WIDTH - 6, 176 + 56)),
|
||||
self.msg_area_color,
|
||||
self.bg_color,
|
||||
2,
|
||||
);
|
||||
self.message_bottom.paint();
|
||||
}
|
||||
}
|
||||
|
BIN
core/embed/rust/src/ui/model_tt/res/check40.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/download32.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/fire24.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/fire32.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/fire40.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/menu32.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/refresh24.toif
Normal file
BIN
core/embed/rust/src/ui/model_tt/res/warning40.toif
Normal file
@ -10,7 +10,10 @@ use crate::ui::{
|
||||
model_tt::{
|
||||
component::ResultScreen,
|
||||
constant,
|
||||
theme::{FATAL_ERROR_COLOR, ICON_WARN_SMALL, TEXT_ERROR_BOLD, TEXT_ERROR_NORMAL, WHITE},
|
||||
theme::{
|
||||
FATAL_ERROR_COLOR, FATAL_ERROR_HIGHLIGHT_COLOR, ICON_WARNING40, TEXT_ERROR_BOLD,
|
||||
TEXT_ERROR_HIGHLIGHT, TEXT_ERROR_NORMAL, WHITE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -49,15 +52,21 @@ pub fn screen_fatal_error(msg: Option<&str>, file: &str) {
|
||||
};
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
|
||||
messages
|
||||
.add(Paragraph::new(&TEXT_ERROR_BOLD, "PLEASE CONTACT\nTREZOR SUPPORT".into()).centered());
|
||||
messages.add(
|
||||
Paragraph::new(
|
||||
&TEXT_ERROR_HIGHLIGHT,
|
||||
"PLEASE CONTACT\nTREZOR SUPPORT".into(),
|
||||
)
|
||||
.centered(),
|
||||
);
|
||||
let m_bottom =
|
||||
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
|
||||
let mut frame = ResultScreen::new(
|
||||
WHITE,
|
||||
FATAL_ERROR_COLOR,
|
||||
Icon::new(ICON_WARN_SMALL),
|
||||
FATAL_ERROR_HIGHLIGHT_COLOR,
|
||||
Icon::new(ICON_WARNING40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
true,
|
||||
@ -87,14 +96,16 @@ pub fn screen_error_shutdown(label: &str, msg: Option<&str>) {
|
||||
};
|
||||
let mut messages = ParagraphVecShort::new();
|
||||
|
||||
messages.add(Paragraph::new(&TEXT_ERROR_BOLD, "PLEASE UNPLUG\nTHE DEVICE".into()).centered());
|
||||
messages
|
||||
.add(Paragraph::new(&TEXT_ERROR_HIGHLIGHT, "PLEASE UNPLUG\nTHE DEVICE".into()).centered());
|
||||
let m_bottom =
|
||||
Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center());
|
||||
|
||||
let mut frame = ResultScreen::new(
|
||||
WHITE,
|
||||
FATAL_ERROR_COLOR,
|
||||
Icon::new(ICON_WARN_SMALL),
|
||||
FATAL_ERROR_HIGHLIGHT_COLOR,
|
||||
Icon::new(ICON_WARNING40),
|
||||
m_top,
|
||||
m_bottom,
|
||||
true,
|
||||
|
@ -42,7 +42,8 @@ pub const GREY_MEDIUM: Color = Color::rgb(0x4F, 0x4F, 0x4F); // button pressed
|
||||
pub const GREY_DARK: Color = Color::rgb(0x28, 0x28, 0x28); // button
|
||||
pub const VIOLET: Color = Color::rgb(0x95, 0x00, 0xCA);
|
||||
|
||||
pub const FATAL_ERROR_COLOR: Color = Color::rgb(0xAD, 0x2B, 0x2B);
|
||||
pub const FATAL_ERROR_COLOR: Color = Color::rgb(0xE7, 0x0E, 0x0E);
|
||||
pub const FATAL_ERROR_HIGHLIGHT_COLOR: Color = Color::rgb(0xFF, 0x41, 0x41);
|
||||
|
||||
// Commonly used corner radius (i.e. for buttons).
|
||||
pub const RADIUS: u8 = 2;
|
||||
@ -70,6 +71,7 @@ pub const ICON_LIST_CHECK: &[u8] = include_res!("model_tt/res/check16.toif");
|
||||
|
||||
// Homescreen notifications.
|
||||
pub const ICON_WARN: &[u8] = include_res!("model_tt/res/warning16.toif");
|
||||
pub const ICON_WARNING40: &[u8] = include_res!("model_tt/res/warning40.toif");
|
||||
pub const ICON_LOCK: &[u8] = include_res!("model_tt/res/lock16.toif");
|
||||
pub const ICON_COINJOIN: &[u8] = include_res!("model_tt/res/coinjoin16.toif");
|
||||
pub const ICON_MAGIC: &[u8] = include_res!("model_tt/res/magic.toif");
|
||||
@ -108,10 +110,6 @@ pub const DOT_INACTIVE_HALF: &[u8] = include_res!("model_tt/res/scroll-inactive-
|
||||
pub const DOT_INACTIVE_QUARTER: &[u8] = include_res!("model_tt/res/scroll-inactive-quarter.toif");
|
||||
pub const DOT_SMALL: &[u8] = include_res!("model_tt/res/scroll-small.toif");
|
||||
|
||||
// Bootloader. TODO
|
||||
pub const ICON_SUCCESS_SMALL: &[u8] = include_res!("model_tt/res/success_bld.toif");
|
||||
pub const ICON_WARN_SMALL: &[u8] = include_res!("model_tt/res/warn_bld.toif");
|
||||
|
||||
pub const fn label_default() -> TextStyle {
|
||||
TEXT_NORMAL
|
||||
}
|
||||
@ -522,6 +520,13 @@ 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);
|
||||
|