mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 20:38:10 +00:00
feat(core): bootloader: T3T1 startup UI
[no changelog]
This commit is contained in:
parent
c277dbcfcb
commit
804d97c9d8
@ -45,8 +45,8 @@ elif TREZOR_MODEL in ('T', 'DISC1', 'DISC2'):
|
||||
elif TREZOR_MODEL in ('T3T1',):
|
||||
FONT_NORMAL='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_DEMIBOLD='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_BOLD='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_MONO='Font_RobotoMono_Medium_21'
|
||||
FONT_BOLD='Font_TTHoves_Bold_17'
|
||||
FONT_MONO='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_BIG=None
|
||||
|
||||
# modtrezorcrypto
|
||||
|
@ -42,8 +42,8 @@ elif TREZOR_MODEL in ('T', 'DISC2'):
|
||||
elif TREZOR_MODEL in ('T3T1',):
|
||||
FONT_NORMAL='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_DEMIBOLD='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_BOLD='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_MONO='Font_RobotoMono_Medium_21'
|
||||
FONT_BOLD='Font_TTHoves_Bold_17'
|
||||
FONT_MONO='Font_TTSatoshi_DemiBold_21'
|
||||
FONT_BIG=None
|
||||
|
||||
# modtrezorcrypto
|
||||
|
@ -5,7 +5,7 @@ use crate::{
|
||||
ui::{
|
||||
component::{connect::Connect, Label},
|
||||
display::{self, Color, Font, Icon},
|
||||
geometry::{Point, Rect},
|
||||
geometry::{Offset, Point, Rect},
|
||||
layout::simplified::{run, show},
|
||||
},
|
||||
};
|
||||
@ -19,11 +19,11 @@ use super::{
|
||||
theme::{
|
||||
bootloader::{
|
||||
button_bld, button_bld_menu, button_confirm, button_wipe_cancel, button_wipe_confirm,
|
||||
BLD_BG, BLD_FG, BLD_TITLE_COLOR, BLD_WIPE_COLOR, CHECK24, CHECK40, DOWNLOAD32, FIRE32,
|
||||
FIRE40, RESULT_FW_INSTALL, RESULT_INITIAL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL,
|
||||
TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24,
|
||||
BLD_BG, BLD_FG, BLD_TITLE_COLOR, BLD_WIPE_COLOR, CHECK24, CHECK40, DOWNLOAD24, FIRE32,
|
||||
FIRE40, RESULT_FW_INSTALL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL, TEXT_WIPE_BOLD,
|
||||
TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24,
|
||||
},
|
||||
BACKLIGHT_NORMAL, BLACK, FG, WHITE,
|
||||
BACKLIGHT_NORMAL, BLACK, GREEN_LIGHT, GREY, WHITE,
|
||||
},
|
||||
ModelMercuryFeatures,
|
||||
};
|
||||
@ -41,6 +41,7 @@ pub type BootloaderString = String<128>;
|
||||
const RECONNECT_MESSAGE: &str = "PLEASE RECONNECT\nTHE DEVICE";
|
||||
|
||||
const SCREEN: Rect = ModelMercuryFeatures::SCREEN;
|
||||
const PROGRESS_TEXT_ORIGIN: Point = Point::new(2, 28);
|
||||
|
||||
impl ModelMercuryFeatures {
|
||||
fn screen_progress(
|
||||
@ -50,47 +51,32 @@ impl ModelMercuryFeatures {
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
icon: Option<(Icon, Color)>,
|
||||
center_text: Option<&str>,
|
||||
) {
|
||||
let loader_offset: i16 = 19;
|
||||
let center_text_offset: i16 = 10;
|
||||
|
||||
if initialize {
|
||||
ModelMercuryFeatures::fadeout();
|
||||
Self::fadeout();
|
||||
display::rect_fill(SCREEN, bg_color);
|
||||
}
|
||||
|
||||
display::text_left(PROGRESS_TEXT_ORIGIN, text, Font::NORMAL, BLD_FG, bg_color);
|
||||
display::loader(progress, 19, fg_color, bg_color, icon);
|
||||
if let Some(center_text) = center_text {
|
||||
display::text_center(
|
||||
Point::new(SCREEN.width() / 2, SCREEN.height() - 45),
|
||||
text,
|
||||
SCREEN.center() + Offset::y(loader_offset + center_text_offset),
|
||||
center_text,
|
||||
Font::NORMAL,
|
||||
BLD_FG,
|
||||
GREY,
|
||||
bg_color,
|
||||
);
|
||||
display::loader(progress, -20, fg_color, bg_color, icon);
|
||||
}
|
||||
display::refresh();
|
||||
if initialize {
|
||||
ModelMercuryFeatures::fadein();
|
||||
Self::fadein();
|
||||
}
|
||||
}
|
||||
|
||||
fn screen_install_success_bld(msg: &str, complete_draw: bool) {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_FW_INSTALL,
|
||||
Icon::new(CHECK40),
|
||||
"Firmware installed\nsuccessfully".into(),
|
||||
Label::centered(msg.into(), RESULT_FW_INSTALL.title_style()).vertically_centered(),
|
||||
complete_draw,
|
||||
);
|
||||
show(&mut frame, complete_draw);
|
||||
}
|
||||
|
||||
fn screen_install_success_initial(msg: &str, complete_draw: bool) {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_INITIAL,
|
||||
Icon::new(CHECK40),
|
||||
"Firmware installed\nsuccessfully".into(),
|
||||
Label::centered(msg.into(), RESULT_INITIAL.title_style()).vertically_centered(),
|
||||
complete_draw,
|
||||
);
|
||||
show(&mut frame, complete_draw);
|
||||
}
|
||||
}
|
||||
|
||||
impl UIFeaturesBootloader for ModelMercuryFeatures {
|
||||
@ -112,20 +98,36 @@ impl UIFeaturesBootloader for ModelMercuryFeatures {
|
||||
fn screen_install_success(restart_seconds: u8, initial_setup: bool, complete_draw: bool) {
|
||||
let mut reboot_msg = BootloaderString::new();
|
||||
|
||||
let bg_color = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let fg_color = if initial_setup { GREEN_LIGHT } else { BLD_FG };
|
||||
|
||||
if restart_seconds >= 1 {
|
||||
unwrap!(reboot_msg.push_str("RESTARTING IN "));
|
||||
// in practice, restart_seconds is 5 or less so this is fine
|
||||
let seconds_char = b'0' + restart_seconds % 10;
|
||||
unwrap!(reboot_msg.push(seconds_char as char));
|
||||
let progress = (5 - (restart_seconds as u16)).clamp(0, 5) * 200;
|
||||
|
||||
Self::screen_progress(
|
||||
"Restarting device",
|
||||
progress,
|
||||
complete_draw,
|
||||
fg_color,
|
||||
bg_color,
|
||||
None,
|
||||
Some(reboot_msg.as_str()),
|
||||
);
|
||||
} else {
|
||||
unwrap!(reboot_msg.push_str(RECONNECT_MESSAGE));
|
||||
Self::screen_progress(
|
||||
"Firmware installed",
|
||||
1000,
|
||||
complete_draw,
|
||||
fg_color,
|
||||
bg_color,
|
||||
Some((Icon::new(CHECK24), BLD_FG)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
if initial_setup {
|
||||
ModelMercuryFeatures::screen_install_success_initial(reboot_msg.as_str(), complete_draw)
|
||||
} else {
|
||||
ModelMercuryFeatures::screen_install_success_bld(reboot_msg.as_str(), complete_draw)
|
||||
}
|
||||
display::refresh();
|
||||
}
|
||||
|
||||
@ -247,16 +249,16 @@ impl UIFeaturesBootloader for ModelMercuryFeatures {
|
||||
|
||||
fn screen_boot_empty(fading: bool) {
|
||||
if fading {
|
||||
ModelMercuryFeatures::fadeout();
|
||||
Self::fadeout();
|
||||
}
|
||||
|
||||
display::rect_fill(SCREEN, BLACK);
|
||||
|
||||
let mut frame = WelcomeScreen::new(true);
|
||||
let mut frame = WelcomeScreen::new();
|
||||
show(&mut frame, false);
|
||||
|
||||
if fading {
|
||||
ModelMercuryFeatures::fadein();
|
||||
Self::fadein();
|
||||
} else {
|
||||
display::set_backlight(BACKLIGHT_NORMAL);
|
||||
}
|
||||
@ -264,36 +266,30 @@ impl UIFeaturesBootloader for ModelMercuryFeatures {
|
||||
}
|
||||
|
||||
fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
ModelMercuryFeatures::screen_progress(
|
||||
Self::screen_progress(
|
||||
"Resetting Trezor",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_WIPE_COLOR,
|
||||
Some((Icon::new(FIRE32), BLD_FG)),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn screen_install_progress(progress: u16, initialize: bool, initial_setup: bool) {
|
||||
let bg_color = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let fg_color = if initial_setup {
|
||||
Color::rgb(0x0B, 0xA5, 0x67)
|
||||
} else {
|
||||
BLD_FG
|
||||
};
|
||||
let icon_color = if initial_setup {
|
||||
Color::rgb(0x8B, 0x8B, 0x93)
|
||||
} else {
|
||||
BLD_FG
|
||||
};
|
||||
let fg_color = if initial_setup { GREEN_LIGHT } else { BLD_FG };
|
||||
let icon_color = BLD_FG;
|
||||
|
||||
ModelMercuryFeatures::screen_progress(
|
||||
Self::screen_progress(
|
||||
"Installing firmware",
|
||||
progress,
|
||||
initialize,
|
||||
fg_color,
|
||||
bg_color,
|
||||
Some((Icon::new(DOWNLOAD32), icon_color)),
|
||||
Some((Icon::new(DOWNLOAD24), icon_color)),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
use crate::ui::{
|
||||
component::{Component, Event, EventCtx, Never, Pad},
|
||||
constant::screen,
|
||||
display::{self, Font, Icon},
|
||||
geometry::{Alignment2D, Offset, Rect},
|
||||
display::{self, Font},
|
||||
geometry::{Offset, Point, Rect},
|
||||
};
|
||||
|
||||
use super::super::theme::{
|
||||
bootloader::{START_URL, WELCOME_COLOR},
|
||||
BLACK, GREY_MEDIUM, WHITE,
|
||||
};
|
||||
use super::super::theme::{BLACK, GREY, WHITE};
|
||||
|
||||
const TEXT_ORIGIN: Point = Point::new(0, 105);
|
||||
const STRIDE: i16 = 22;
|
||||
|
||||
pub struct Welcome {
|
||||
bg: Pad,
|
||||
@ -17,7 +17,7 @@ pub struct Welcome {
|
||||
impl Welcome {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
bg: Pad::with_background(WELCOME_COLOR).with_clear(),
|
||||
bg: Pad::with_background(BLACK).with_clear(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,24 +35,28 @@ impl Component for Welcome {
|
||||
}
|
||||
|
||||
fn paint(&mut self) {
|
||||
let at_width = Font::NORMAL.text_width("at ");
|
||||
|
||||
self.bg.paint();
|
||||
display::text_center(
|
||||
screen().top_center() + Offset::y(102),
|
||||
"Get started with",
|
||||
display::text_left(TEXT_ORIGIN, "Get started", Font::NORMAL, GREY, BLACK);
|
||||
display::text_left(
|
||||
TEXT_ORIGIN + Offset::y(STRIDE),
|
||||
"with your Trezor",
|
||||
Font::NORMAL,
|
||||
GREY_MEDIUM,
|
||||
GREY,
|
||||
BLACK,
|
||||
);
|
||||
display::text_center(
|
||||
screen().top_center() + Offset::y(126),
|
||||
"your Trezor at",
|
||||
display::text_left(
|
||||
TEXT_ORIGIN + Offset::y(2 * STRIDE),
|
||||
"at",
|
||||
Font::NORMAL,
|
||||
GREY_MEDIUM,
|
||||
GREY,
|
||||
BLACK,
|
||||
);
|
||||
Icon::new(START_URL).draw(
|
||||
screen().top_center() + Offset::y(135),
|
||||
Alignment2D::TOP_CENTER,
|
||||
display::text_left(
|
||||
TEXT_ORIGIN + Offset::new(at_width, 2 * STRIDE),
|
||||
"trezor.io/start",
|
||||
Font::NORMAL,
|
||||
WHITE,
|
||||
BLACK,
|
||||
);
|
||||
|
@ -1,31 +1,25 @@
|
||||
use crate::ui::{
|
||||
component::{Component, Event, EventCtx, Never},
|
||||
display,
|
||||
geometry::{Alignment2D, Offset, Rect},
|
||||
};
|
||||
|
||||
use super::theme;
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
use crate::ui::{display::Icon, model_mercury::theme::bootloader::DEVICE_NAME};
|
||||
|
||||
const TEXT_BOTTOM_MARGIN: i16 = 24; // matching the homescreen label margin
|
||||
const TEXT_BOTTOM_MARGIN: i16 = 54;
|
||||
const ICON_TOP_MARGIN: i16 = 48;
|
||||
#[cfg(not(feature = "bootloader"))]
|
||||
const MODEL_NAME_FONT: display::Font = display::Font::DEMIBOLD;
|
||||
#[cfg(not(feature = "bootloader"))]
|
||||
use crate::{trezorhal::model, ui::display};
|
||||
use crate::trezorhal::model;
|
||||
|
||||
pub struct WelcomeScreen {
|
||||
area: Rect,
|
||||
empty_lock: bool,
|
||||
}
|
||||
|
||||
impl WelcomeScreen {
|
||||
pub fn new(empty_lock: bool) -> Self {
|
||||
Self {
|
||||
area: Rect::zero(),
|
||||
empty_lock,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self { area: Rect::zero() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,29 +36,16 @@ impl Component for WelcomeScreen {
|
||||
}
|
||||
|
||||
fn paint(&mut self) {
|
||||
let logo = if self.empty_lock {
|
||||
theme::ICON_LOGO_EMPTY
|
||||
} else {
|
||||
theme::ICON_LOGO
|
||||
};
|
||||
logo.draw(
|
||||
theme::ICON_LOGO.draw(
|
||||
self.area.top_center() + Offset::y(ICON_TOP_MARGIN),
|
||||
Alignment2D::TOP_CENTER,
|
||||
theme::FG,
|
||||
theme::BG,
|
||||
);
|
||||
#[cfg(not(feature = "bootloader"))]
|
||||
display::text_center(
|
||||
self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN),
|
||||
model::FULL_NAME,
|
||||
MODEL_NAME_FONT,
|
||||
theme::FG,
|
||||
theme::BG,
|
||||
);
|
||||
#[cfg(feature = "bootloader")]
|
||||
Icon::new(DEVICE_NAME).draw(
|
||||
self.area.bottom_center() - Offset::y(TEXT_BOTTOM_MARGIN),
|
||||
Alignment2D::BOTTOM_CENTER,
|
||||
"Trezor Safe 5",
|
||||
display::Font::NORMAL,
|
||||
theme::FG,
|
||||
theme::BG,
|
||||
);
|
||||
|
Binary file not shown.
Binary file not shown.
BIN
core/embed/rust/src/ui/model_mercury/res/download24.toif
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/download24.toif
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -12,7 +12,7 @@ pub fn screen_fatal_error(title: &str, msg: &str, footer: &str) {
|
||||
}
|
||||
|
||||
pub fn screen_boot_full() {
|
||||
let mut frame = WelcomeScreen::new(false);
|
||||
let mut frame = WelcomeScreen::new();
|
||||
frame.place(screen());
|
||||
display::sync();
|
||||
frame.paint();
|
||||
|
@ -64,14 +64,11 @@ pub const FIRE40: &[u8] = include_res!("model_mercury/res/fire40.toif");
|
||||
pub const REFRESH24: &[u8] = include_res!("model_mercury/res/refresh24.toif");
|
||||
pub const MENU32: &[u8] = include_res!("model_mercury/res/menu32.toif");
|
||||
pub const INFO32: &[u8] = include_res!("model_mercury/res/info32.toif");
|
||||
pub const DOWNLOAD32: &[u8] = include_res!("model_mercury/res/download32.toif");
|
||||
pub const DOWNLOAD24: &[u8] = include_res!("model_mercury/res/download24.toif");
|
||||
pub const WARNING40: &[u8] = include_res!("model_mercury/res/warning40.toif");
|
||||
pub const CHECK24: &[u8] = include_res!("model_mercury/res/check24.toif");
|
||||
pub const CHECK40: &[u8] = include_res!("model_mercury/res/check40.toif");
|
||||
|
||||
pub const DEVICE_NAME: &[u8] = include_res!("model_mercury/res/device_name_T.toif");
|
||||
pub const START_URL: &[u8] = include_res!("model_mercury/res/start.toif");
|
||||
|
||||
pub fn button_confirm() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
|
@ -17,19 +17,16 @@ pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF);
|
||||
pub const BLACK: Color = Color::rgb(0, 0, 0);
|
||||
pub const FG: Color = WHITE; // Default foreground (text & icon) color.
|
||||
pub const BG: Color = BLACK; // Default background color.
|
||||
pub const RED: Color = Color::rgb(0xE7, 0x0E, 0x0E); // button
|
||||
pub const RED_DARK: Color = Color::rgb(0xAE, 0x09, 0x09); // button pressed
|
||||
pub const YELLOW: Color = Color::rgb(0xD9, 0x9E, 0x00); // button
|
||||
pub const YELLOW_DARK: Color = Color::rgb(0x7A, 0x58, 0x00); // button pressed
|
||||
pub const GREEN: Color = Color::rgb(0x00, 0xAA, 0x35); // button
|
||||
pub const GREEN_DARK: Color = Color::rgb(0x00, 0x55, 0x1D); // button pressed
|
||||
pub const BLUE: Color = Color::rgb(0x06, 0x1E, 0xAD); // button
|
||||
pub const BLUE_DARK: Color = Color::rgb(0x04, 0x10, 0x58); // button pressed
|
||||
pub const OFF_WHITE: Color = Color::rgb(0xDE, 0xDE, 0xDE); // very light grey
|
||||
pub const GREY_LIGHT: Color = Color::rgb(0x90, 0x90, 0x90); // secondary text
|
||||
pub const GREY_MEDIUM: Color = Color::rgb(0x4F, 0x4F, 0x4F); // button pressed
|
||||
pub const GREY_DARK: Color = Color::rgb(0x35, 0x35, 0x35); // button
|
||||
pub const VIOLET: Color = Color::rgb(0x95, 0x00, 0xCA);
|
||||
pub const GREY_EXTRA_DARK: Color = Color::rgb(0x16, 0x1F, 0x24);
|
||||
pub const GREY_DARK: Color = Color::rgb(0x46, 0x48, 0x4A);
|
||||
pub const GREY: Color = Color::rgb(0x8B, 0x8F, 0x93); // secondary text, subtitle, instructions
|
||||
pub const GREY_LIGHT: Color = Color::rgb(0xC7, 0xCD, 0xD3); // content
|
||||
pub const GREY_EXTRA_LIGHT: Color = Color::rgb(0xF0, 0xF0, 0xF0); // primary text, header
|
||||
pub const GREEN: Color = Color::rgb(0x08, 0x74, 0x48);
|
||||
pub const GREEN_LIGHT: Color = Color::rgb(0x0B, 0xA5, 0x67);
|
||||
pub const GREEN_LIME: Color = Color::rgb(0x9B, 0xE8, 0x87);
|
||||
pub const ORANGE_DIMMED: Color = Color::rgb(0x9E, 0x57, 0x42);
|
||||
pub const ORANGE_LIGHT: Color = Color::rgb(0xFF, 0x8D, 0x6A); // cancel button
|
||||
|
||||
pub const FATAL_ERROR_COLOR: Color = Color::rgb(0xE7, 0x0E, 0x0E);
|
||||
pub const FATAL_ERROR_HIGHLIGHT_COLOR: Color = Color::rgb(0xFF, 0x41, 0x41);
|
||||
@ -59,16 +56,15 @@ include_icon!(ICON_PAGE_NEXT, "model_mercury/res/page-next.toif");
|
||||
include_icon!(ICON_PAGE_PREV, "model_mercury/res/page-prev.toif");
|
||||
|
||||
// Large, three-color icons.
|
||||
pub const WARN_COLOR: Color = YELLOW;
|
||||
pub const INFO_COLOR: Color = BLUE;
|
||||
pub const WARN_COLOR: Color = ORANGE_LIGHT;
|
||||
pub const INFO_COLOR: Color = GREY_LIGHT;
|
||||
pub const SUCCESS_COLOR: Color = GREEN;
|
||||
pub const ERROR_COLOR: Color = RED;
|
||||
pub const ERROR_COLOR: Color = ORANGE_DIMMED;
|
||||
include_icon!(IMAGE_FG_SUCCESS, "model_mercury/res/fg-check48.toif");
|
||||
include_icon!(IMAGE_BG_CIRCLE, "model_mercury/res/circle48.toif");
|
||||
|
||||
// Welcome screen.
|
||||
include_icon!(ICON_LOGO, "model_mercury/res/lock_full.toif");
|
||||
include_icon!(ICON_LOGO_EMPTY, "model_mercury/res/lock_empty.toif");
|
||||
|
||||
pub const fn button_default() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
@ -84,7 +80,7 @@ pub const fn button_default() -> ButtonStyleSheet {
|
||||
active: &ButtonStyle {
|
||||
font: Font::BOLD,
|
||||
text_color: FG,
|
||||
button_color: GREY_MEDIUM,
|
||||
button_color: GREY,
|
||||
background_color: BG,
|
||||
border_color: FG,
|
||||
border_radius: RADIUS,
|
||||
@ -118,7 +114,7 @@ pub const fn button_moreinfo() -> ButtonStyleSheet {
|
||||
text_color: FG,
|
||||
button_color: BG,
|
||||
background_color: BG,
|
||||
border_color: GREY_MEDIUM,
|
||||
border_color: GREY,
|
||||
border_radius: RADIUS,
|
||||
border_width: 2,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user