1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 05:28:40 +00:00

refactor(core/bootloader): get rid of Paragraphs

for a ~10kB space saving
This commit is contained in:
matejcik 2023-03-30 11:59:13 +02:00
parent 14f0fba949
commit c3af3eafe2
6 changed files with 121 additions and 143 deletions

View File

@ -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

View File

@ -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);

View File

@ -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<Label<&'a str>>,
pub text: Child<Label<&'a str>>,
pub info_button: Child<Button<&'static str>>,
pub close_button: Child<Button<&'static str>>,
}
pub struct Confirm<'a> {
bg: Pad,
content_pad: Pad,
@ -38,10 +43,7 @@ pub struct Confirm<'a> {
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<Child<Paragraphs<ParagraphVecShort<&'a str>>>>,
info: Option<ConfirmInfo<'a>>,
show_info: bool,
}
@ -55,7 +57,7 @@ impl<'a> Confirm<'a> {
title: Option<Label<&'a str>>,
msg: Label<&'a str>,
alert: Option<Label<&'a str>>,
info: Option<(&'static str, Paragraphs<ParagraphVecShort<&'a str>>)>,
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<Self::Msg> {
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")]

View File

@ -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<Label<String<32>>>,
title: Child<Label<&'a str>>,
menu: Child<Button<&'static str>>,
host: Child<Button<&'static str>>,
text: Child<Paragraphs<ParagraphVecShort<&'a str>>>,
text: Child<Label<&'a str>>,
}
impl<'a> Intro<'a> {
pub fn new(bld_version: &'static str, content: Paragraphs<ParagraphVecShort<&'a str>>) -> 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),
),
}
}
}

View File

@ -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<Label<String<32>>>,
title: Child<Label<&'static str>>,
close: Child<Button<&'static str>>,
reboot: Child<Button<&'static str>>,
reset: Child<Button<&'static str>>,
}
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())

View File

@ -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)
}