diff --git a/core/embed/bootloader/bootui.c b/core/embed/bootloader/bootui.c index 6c3681543..054ec1247 100644 --- a/core/embed/bootloader/bootui.c +++ b/core/embed/bootloader/bootui.c @@ -175,11 +175,7 @@ uint32_t ui_screen_intro(const vendor_header *const vhdr, return screen_intro(bld_ver, vhdr->vstr, vhdr->vstr_len, ver_str); } -uint32_t ui_screen_menu(void) { - char bld_ver[32]; - format_ver("%d.%d.%d", VERSION_UINT32, bld_ver, sizeof(bld_ver)); - return screen_menu(bld_ver); -} +uint32_t ui_screen_menu(void) { return screen_menu(); } // install UI diff --git a/core/embed/rust/rust_ui.h b/core/embed/rust/rust_ui.h index 044102989..f672ee325 100644 --- a/core/embed/rust/rust_ui.h +++ b/core/embed/rust/rust_ui.h @@ -17,7 +17,7 @@ void screen_install_progress(int16_t progress, bool initialize, void screen_wipe_progress(int16_t progress, bool initialize); uint32_t screen_intro(const char* bld_version_str, const char* vendor_str, uint8_t vendor_str_len, const char* version_str); -uint32_t screen_menu(const char* bld_version_str); +uint32_t screen_menu(void); void screen_connect(void); void screen_fatal_error_rust(const char* title, const char* msg, const char* footer); diff --git a/core/embed/rust/src/ui/model_tt/bootloader/confirm.rs b/core/embed/rust/src/ui/model_tt/bootloader/confirm.rs index 943a3d5a3..c7f5ebe19 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/confirm.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/confirm.rs @@ -1,8 +1,5 @@ use crate::ui::{ - component::{ - text::paragraphs::{ParagraphVecShort, Paragraphs}, - Child, Component, ComponentExt, Event, EventCtx, Label, Pad, - }, + component::{Child, Component, ComponentExt, Event, EventCtx, Label, Pad}, constant, constant::screen, display::{Color, Icon}, @@ -10,7 +7,8 @@ use crate::ui::{ model_tt::{ bootloader::theme::{ 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, + CORNER_BUTTON_TOUCH_EXPANSION, INFO32, TEXT_FINGERPRINT, TEXT_TITLE, TITLE_AREA, + TITLE_Y_ADJUSTMENT, X32, }, component::{Button, ButtonMsg::Clicked}, constant::WIDTH, @@ -28,6 +26,13 @@ pub enum ConfirmMsg { Confirm = 2, } +pub struct ConfirmInfo<'a> { + pub title: Child>, + pub text: Child>, + pub info_button: Child>, + pub close_button: Child>, +} + pub struct Confirm<'a> { bg: Pad, content_pad: Pad, @@ -38,10 +43,7 @@ pub struct Confirm<'a> { alert: Option>>, left_button: Child>, right_button: Child>, - info_button: Option>, - close_button: Option>, - info_title: Option>>, - info_text: Option>>>, + info: Option>, show_info: bool, } @@ -55,7 +57,7 @@ impl<'a> Confirm<'a> { title: Option>, msg: Label<&'a str>, alert: Option>, - info: Option<(&'static str, Paragraphs>)>, + info: Option<(&'a str, &'a str)>, ) -> Self { let mut instance = Self { bg: Pad::with_background(bg_color), @@ -67,26 +69,25 @@ impl<'a> Confirm<'a> { 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, + info: info.map(|(title, text)| ConfirmInfo { + title: Child::new(Label::new(title, Alignment::Start, TEXT_TITLE)), + text: Child::new( + Label::new(text, Alignment::Start, TEXT_FINGERPRINT) + .with_vertical_align(Alignment::Center), + ), + info_button: Child::new( + Button::with_icon(Icon::new(INFO32)) + .styled(button_bld_menu()) + .with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)), + ), + close_button: Child::new( + Button::with_icon(Icon::new(X32)) + .styled(button_bld_menu()) + .with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)), + ), + }), show_info: false, }; - if let Some((title, text)) = info { - instance.info_title = Some(Child::new(Label::new(title, Alignment::Start, TEXT_TITLE))); - instance.info_text = Some(text.into_child()); - instance.info_button = Some( - Button::with_icon(Icon::new(INFO32)) - .styled(button_bld_menu()) - .with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)), - ); - instance.close_button = Some( - Button::with_icon(Icon::new(X32)) - .styled(button_bld_menu()) - .with_expanded_touch_area(Insets::uniform(CORNER_BUTTON_TOUCH_EXPANSION)), - ); - } instance.bg.clear(); instance } @@ -152,21 +153,6 @@ impl<'a> Component for Confirm<'a> { 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); - - 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); @@ -181,28 +167,44 @@ impl<'a> Component for Confirm<'a> { )); } - self.info_text.place(Rect::new( - Point::new(CONTENT_PADDING, TITLE_AREA.y1), - Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START), - )); + if let Some(info) = self.info.as_mut() { + info.info_button.place(CORNER_BUTTON_AREA); + info.close_button.place(CORNER_BUTTON_AREA); + info.text.place(Rect::new( + Point::new(CONTENT_PADDING, TITLE_AREA.y1), + Point::new(WIDTH - CONTENT_PADDING, BUTTON_AREA_START), + )); + + info.title.place(TITLE_AREA); + let title_height = info.title.inner().area().height(); + info.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), + )); + } bounds } fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option { - if self.show_info { - if let Some(Clicked) = self.close_button.event(ctx, event) { - self.show_info = false; + if let Some(info) = self.info.as_mut() { + if self.show_info { + if let Some(Clicked) = info.close_button.event(ctx, event) { + self.show_info = false; + self.content_pad.clear(); + self.title.request_complete_repaint(ctx); + self.message.request_complete_repaint(ctx); + return None; + } + } else if let Some(Clicked) = info.info_button.event(ctx, event) { + self.show_info = true; + info.text.request_complete_repaint(ctx); + info.title.request_complete_repaint(ctx); self.content_pad.clear(); - self.title.request_complete_repaint(ctx); - self.message.request_complete_repaint(ctx); return None; } - } else if let Some(Clicked) = self.info_button.event(ctx, event) { - self.show_info = true; - self.info_text.request_complete_repaint(ctx); - self.info_title.request_complete_repaint(ctx); - self.content_pad.clear(); - return None; } if let Some(Clicked) = self.left_button.event(ctx, event) { return Some(Self::Msg::Cancel); @@ -217,28 +219,34 @@ impl<'a> Component for Confirm<'a> { self.bg.paint(); self.content_pad.paint(); - if self.show_info { - self.close_button.paint(); - self.info_title.paint(); - self.info_text.paint(); - self.left_button.paint(); - self.right_button.paint(); - } else { - self.info_button.paint(); - self.title.paint(); - self.message.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, ICON_TOP), - TOP_CENTER, - WHITE, - self.bg_color, - ); + if let Some(info) = self.info.as_mut() { + if self.show_info { + info.close_button.paint(); + info.title.paint(); + info.text.paint(); + self.left_button.paint(); + self.right_button.paint(); + // short-circuit before painting the main components + return; + } else { + info.info_button.paint(); + // pass through to the rest of the paint } } + + self.title.paint(); + self.message.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, ICON_TOP), + TOP_CENTER, + WHITE, + self.bg_color, + ); + } } #[cfg(feature = "ui_bounds")] diff --git a/core/embed/rust/src/ui/model_tt/bootloader/intro.rs b/core/embed/rust/src/ui/model_tt/bootloader/intro.rs index 4ec81114b..c5f520fc5 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/intro.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/intro.rs @@ -1,26 +1,17 @@ use crate::ui::{ - component::{ - text::paragraphs::{ParagraphVecShort, Paragraphs}, - Child, Component, Event, EventCtx, Label, Pad, - }, + component::{Child, Component, Event, EventCtx, Label, Pad}, constant::screen, display::Icon, geometry::{Alignment, Insets, Point, Rect}, model_tt::{ - bootloader::theme::{button_bld, button_bld_menu, BLD_BG, MENU32}, - component::ButtonMsg::Clicked, + bootloader::theme::{ + button_bld, button_bld_menu, BLD_BG, BUTTON_AREA_START, BUTTON_HEIGHT, CONTENT_PADDING, + CORNER_BUTTON_AREA, MENU32, TEXT_NORMAL, TEXT_TITLE, TITLE_AREA, TITLE_Y_ADJUSTMENT, + }, + component::{Button, ButtonMsg::Clicked}, + constant::WIDTH, }, }; -use heapless::String; - -use crate::ui::model_tt::{ - bootloader::theme::{ - BUTTON_AREA_START, BUTTON_HEIGHT, CONTENT_PADDING, CORNER_BUTTON_AREA, TEXT_TITLE, - TITLE_AREA, TITLE_Y_ADJUSTMENT, - }, - component::Button, - constant::WIDTH, -}; #[repr(u32)] #[derive(Copy, Clone, ToPrimitive)] @@ -31,18 +22,14 @@ pub enum IntroMsg { pub struct Intro<'a> { bg: Pad, - title: Child>>, + title: Child>, menu: Child>, host: Child>, - text: Child>>, + text: Child>, } impl<'a> Intro<'a> { - pub fn new(bld_version: &'static str, content: Paragraphs>) -> Self { - let mut title: String<32> = String::new(); - unwrap!(title.push_str("BOOTLOADER ")); - unwrap!(title.push_str(bld_version)); - + pub fn new(title: &'a str, content: &'a str) -> Self { Self { bg: Pad::with_background(BLD_BG).with_clear(), title: Child::new(Label::new(title, Alignment::Start, TEXT_TITLE)), @@ -52,7 +39,10 @@ impl<'a> Intro<'a> { .with_expanded_touch_area(Insets::uniform(13)), ), host: Child::new(Button::with_text("INSTALL FIRMWARE").styled(button_bld())), - text: Child::new(content), + text: Child::new( + Label::new(content, Alignment::Start, TEXT_NORMAL) + .with_vertical_align(Alignment::Center), + ), } } } diff --git a/core/embed/rust/src/ui/model_tt/bootloader/menu.rs b/core/embed/rust/src/ui/model_tt/bootloader/menu.rs index 319fa5f82..b12f4e1dd 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/menu.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/menu.rs @@ -12,7 +12,6 @@ use crate::ui::{ component::{Button, ButtonMsg::Clicked, IconText}, }, }; -use heapless::String; const BUTTON_AREA_START: i16 = 56; const BUTTON_SPACING: i16 = 8; @@ -27,23 +26,20 @@ pub enum MenuMsg { pub struct Menu { bg: Pad, - title: Child>>, + title: Child>, close: Child>, reboot: Child>, reset: Child>, } impl Menu { - pub fn new(_bld_version: &'static str) -> Self { + pub fn new() -> 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 ")); - let mut instance = Self { bg: Pad::with_background(BLD_BG), - title: Child::new(Label::new(title, Alignment::Start, TEXT_TITLE)), + title: Child::new(Label::new("BOOTLOADER", Alignment::Start, TEXT_TITLE)), close: Child::new( Button::with_icon(Icon::new(X32)) .styled(button_bld_menu()) diff --git a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs index b1377f8ad..9cc0bd8f6 100644 --- a/core/embed/rust/src/ui/model_tt/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tt/bootloader/mod.rs @@ -21,10 +21,9 @@ pub mod welcome; use crate::{ strutil::hexlify, ui::{ - component::text::paragraphs::{Paragraph, ParagraphVecShort, Paragraphs, VecExt}, constant::screen, display::{Color, Icon}, - geometry::{Alignment, LinearPlacement, TOP_CENTER}, + geometry::{Alignment, TOP_CENTER}, model_tt::{ bootloader::{ connect::Connect, @@ -47,6 +46,8 @@ use menu::Menu; use self::theme::{RESULT_FW_INSTALL, RESULT_INITIAL, RESULT_WIPE}; +pub type BootloaderString = String<128>; + const RECONNECT_MESSAGE: &str = "PLEASE RECONNECT\nTHE DEVICE"; pub trait ReturnToC { @@ -150,7 +151,7 @@ extern "C" fn screen_install_confirm( core::str::from_utf8_unchecked(fingerprint_buffer.as_ref()) }; - let mut version_str: String<128> = String::new(); + let mut version_str: BootloaderString = String::new(); unwrap!(version_str.push_str("Firmware version ")); unwrap!(version_str.push_str(version)); unwrap!(version_str.push_str("\nby ")); @@ -176,12 +177,6 @@ extern "C" fn screen_install_confirm( None }; - let mut messages = ParagraphVecShort::new(); - messages.add(Paragraph::new(&theme::TEXT_FINGERPRINT, fingerprint_str)); - - let fingerprint = - Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center()); - let (left, right) = if !(vendor || downgrade) { let l = Button::with_text("CANCEL").styled(button_bld()); let r = Button::with_text("INSTALL").styled(button_confirm()); @@ -200,7 +195,7 @@ extern "C" fn screen_install_confirm( Some(title), msg, alert, - Some(("FW FINGERPRINT", fingerprint)), + Some(("FW FINGERPRINT", fingerprint_str)), ); run(&mut frame) @@ -239,10 +234,8 @@ extern "C" fn screen_wipe_confirm() -> u32 { } #[no_mangle] -extern "C" fn screen_menu(bld_version: *const cty::c_char) -> u32 { - let bld_version = unwrap!(unsafe { from_c_str(bld_version) }); - - run(&mut Menu::new(bld_version)) +extern "C" fn screen_menu() -> u32 { + run(&mut Menu::new()) } #[no_mangle] @@ -256,22 +249,17 @@ extern "C" fn screen_intro( let version = unwrap!(unsafe { from_c_str(version) }); let bld_version = unwrap!(unsafe { from_c_str(bld_version) }); - let mut fw: String<64> = String::new(); - unwrap!(fw.push_str("Firmware ")); - unwrap!(fw.push_str(version)); + let mut title_str: BootloaderString = String::new(); + unwrap!(title_str.push_str("BOOTLOADER ")); + unwrap!(title_str.push_str(bld_version)); - let mut vendor_: String<64> = String::new(); - unwrap!(vendor_.push_str("by ")); - unwrap!(vendor_.push_str(vendor)); + let mut version_str: BootloaderString = String::new(); + unwrap!(version_str.push_str("Firmware version ")); + unwrap!(version_str.push_str(version)); + unwrap!(version_str.push_str("\nby ")); + unwrap!(version_str.push_str(vendor)); - let mut messages = ParagraphVecShort::new(); - - 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_center()); - - let mut frame = Intro::new(bld_version, p); + let mut frame = Intro::new(title_str.as_str(), version_str.as_str()); run(&mut frame) }