From 3a93a28882529fd6ff31e64d01f05a73d19e16ab Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 10 Nov 2022 17:42:01 +0100 Subject: [PATCH] model R bld --- core/Makefile | 2 +- .../src/ui/model_tr/bootloader/confirm.rs | 57 ++++--- .../rust/src/ui/model_tr/bootloader/intro.rs | 9 +- .../rust/src/ui/model_tr/bootloader/menu.rs | 141 +++++++++++------- .../rust/src/ui/model_tr/bootloader/mod.rs | 31 ++-- .../rust/src/ui/model_tr/bootloader/theme.rs | 64 ++++---- .../rust/src/ui/model_tr/component/mod.rs | 18 +++ core/embed/rust/src/ui/model_tr/screens.rs | 7 +- 8 files changed, 184 insertions(+), 145 deletions(-) diff --git a/core/Makefile b/core/Makefile index b276239bd..17c9bb148 100644 --- a/core/Makefile +++ b/core/Makefile @@ -21,7 +21,7 @@ CROSS_PORT_OPTS ?= PRODUCTION ?= 0 PYOPT ?= 1 BITCOIN_ONLY ?= 0 -TREZOR_MODEL ?= T +TREZOR_MODEL ?= R TREZOR_MEMPERF ?= 0 TREZOR_EMULATOR_FROZEN ?= 0 ADDRESS_SANITIZER ?= 0 diff --git a/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs b/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs index f0bc4688c..0c6472fe3 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/confirm.rs @@ -8,9 +8,9 @@ use crate::ui::{ display::Color, geometry::{Point, Rect}, model_tr::{ - component::{Button, ButtonMsg::Clicked}, + bootloader::theme::WHITE, + component::{ButtonController, ButtonControllerMsg, ButtonLayout, ButtonPos}, constant::{HEIGHT, WIDTH}, - theme::WHITE, }, }; @@ -33,8 +33,7 @@ pub struct Confirm { bg_color: Color, icon: Option<&'static [u8]>, message: Child>>, - left: Child>, - right: Child>, + buttons: ButtonController<&'static str>, confirm_left: bool, } @@ -43,8 +42,7 @@ impl Confirm { bg_color: Color, icon: Option<&'static [u8]>, message: Paragraphs>, - left: Button<&'static str>, - right: Button<&'static str>, + text: &'static str, confirm_left: bool, ) -> Self { let mut instance = Self { @@ -52,8 +50,7 @@ impl Confirm { bg_color, icon, message: Child::new(message), - left: Child::new(left), - right: Child::new(right), + buttons: ButtonController::new(ButtonLayout::cancel_and_text(text)), confirm_left, }; instance.bg.clear(); @@ -71,28 +68,32 @@ impl Component for Confirm { .place(Rect::new(Point::new(10, 0), Point::new(118, 50))); let button_area = bounds.split_bottom(12).1; - self.left.place(button_area); - self.right.place(button_area); + self.buttons.place(button_area); bounds } fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option { - 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.right.event(ctx, event) { - return if self.confirm_left { - Some(Self::Msg::Cancel) - } else { - Some(Self::Msg::Confirm) - }; - }; - None + match self.buttons.event(ctx, event) { + Some(ButtonControllerMsg::Triggered(ButtonPos::Left)) => Some(ConfirmMsg::Cancel), + Some(ButtonControllerMsg::Triggered(ButtonPos::Right)) => Some(ConfirmMsg::Confirm), + _ => 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.right.event(ctx, event) { + // return if self.confirm_left { + // Some(Self::Msg::Cancel) + // } else { + // Some(Self::Msg::Confirm) + // }; + // }; + //None } fn paint(&mut self) { @@ -108,12 +109,10 @@ impl Component for Confirm { } self.message.paint(); - self.left.paint(); - self.right.paint(); + self.buttons.paint(); } fn bounds(&self, sink: &mut dyn FnMut(Rect)) { - self.left.bounds(sink); - self.right.bounds(sink); + self.buttons.bounds(sink); } } diff --git a/core/embed/rust/src/ui/model_tr/bootloader/intro.rs b/core/embed/rust/src/ui/model_tr/bootloader/intro.rs index 0e23ebdd7..bb075fc4a 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/intro.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/intro.rs @@ -15,8 +15,7 @@ use crate::ui::{ }; use crate::ui::model_tr::{ - bootloader::theme::bld_button_default, - component::{Button, ButtonPos}, + component::{Button, ButtonPos, ButtonStyleSheet}, constant::{HEIGHT, WIDTH}, }; @@ -55,13 +54,13 @@ impl Intro { title: Child::new(Title::new(bld_version)), host: Child::new(Button::with_text( ButtonPos::Left, - "INSTALL FIRMWARE", - bld_button_default(), + "INSTALL FW", + ButtonStyleSheet::default(true, false, None, None), )), menu: Child::new(Button::with_text( ButtonPos::Right, "MENU", - bld_button_default(), + ButtonStyleSheet::default(true, false, None, None), )), text: Child::new(p1), }; diff --git a/core/embed/rust/src/ui/model_tr/bootloader/menu.rs b/core/embed/rust/src/ui/model_tr/bootloader/menu.rs index ee8f41567..eeed30178 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/menu.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/menu.rs @@ -1,9 +1,18 @@ +#[cfg(feature = "ui_debug")] +use crate::trace::Tracer; use crate::ui::{ - component::{Child, Component, Event, EventCtx, Pad}, - geometry::{Point, Rect}, + component::{Child, Component, ComponentExt, Event, EventCtx, Pad}, + constant::screen, + display, + display::Font, + geometry::{Offset, Rect}, model_tr::{ - bootloader::{theme::BLD_BG, title::Title, ReturnToC}, - constant::{HEIGHT, WIDTH}, + bootloader::{ + theme::{BLD_BG, BLD_FG}, + ReturnToC, + }, + component::{ChoiceFactory, ChoicePage, ChoicePageMsg}, + theme::ICON_BIN, }, }; @@ -20,33 +29,71 @@ impl ReturnToC for MenuMsg { } } +const CHOICE_LENGTH: usize = 3; + +pub struct MenuChoiceFactory; + +impl MenuChoiceFactory { + const CHOICES: [(&'static str, &'static str, &'static [u8]); CHOICE_LENGTH] = [ + ("WIPE", "DEVICE", ICON_BIN.0), + ("REBOOT", "TREZOR", ICON_BIN.0), + ("EXIT", "MENU", ICON_BIN.0), + ]; + + pub fn new() -> Self { + Self {} + } + fn get(&self, choice_index: u8) -> (&'static str, &'static str, &'static [u8]) { + MenuChoiceFactory::CHOICES[choice_index as usize] + } +} + +impl ChoiceFactory for MenuChoiceFactory { + fn count(&self) -> u8 { + CHOICE_LENGTH as u8 + } + + fn paint_center(&self, choice_index: u8, _area: Rect, _inverse: bool) { + let content = self.get(choice_index); + + let text_1 = content.0; + let text_2 = content.1; + let icon = content.2; + + display::icon(screen().center() + Offset::y(-20), icon, BLD_FG, BLD_BG); + display::text_center( + screen().center() + Offset::y(0), + text_1, + Font::NORMAL, + BLD_FG, + BLD_BG, + ); + display::text_center( + screen().center() + Offset::y(10), + text_2, + Font::NORMAL, + BLD_FG, + BLD_BG, + ); + } + + #[cfg(feature = "ui_debug")] + fn trace(&self, t: &mut dyn Tracer, name: &str, choice_index: u8) { + t.field(name, &self.get(choice_index)); + } +} + pub struct Menu { bg: Pad, - title: Child, - // close: Child<Button<&'static str>>, - // reboot: Child<Button<&'static str>>, - // reset: Child<Button<&'static str>>, + pg: Child<ChoicePage<MenuChoiceFactory>>, } impl Menu { - pub fn new(bld_version: &'static str) -> Self { - // let content_reboot = IconText::new("REBOOT", REBOOT); - // let content_reset = IconText::new("FACTORY RESET", ERASE); - + pub fn new() -> Self { + let choices = MenuChoiceFactory::new(); let mut instance = Self { bg: Pad::with_background(BLD_BG), - title: Child::new(Title::new(bld_version)), - // close: Child::new( - // Button::with_icon(CLOSE) - // .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()), - // ), + pg: ChoicePage::new(choices).with_carousel(true).into_child(), }; instance.bg.clear(); instance @@ -57,48 +104,26 @@ impl Component for Menu { type Msg = MenuMsg; fn place(&mut self, bounds: Rect) -> Rect { - self.bg - .place(Rect::new(Point::new(0, 0), Point::new(WIDTH, HEIGHT))); - self.title - .place(Rect::new(Point::new(10, 0), Point::new(128, 8))); - // self.close.place(Rect::new( - // Point::new(187, 15), - // Point::new(187 + 38, 15 + 38), - // )); - // self.reboot - // .place(Rect::new(Point::new(16, 66), Point::new(16 + 209, 66 + 48))); - // self.reset.place(Rect::new( - // Point::new(16, 122), - // Point::new(16 + 209, 122 + 48), - // )); + self.bg.place(bounds); + self.pg.place(bounds); bounds } - fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option<Self::Msg> { - // if let Some(Clicked) = self.close.event(ctx, event) { - // return Some(Self::Msg::Close); - // } - // if let Some(Clicked) = self.reboot.event(ctx, event) { - // return Some(Self::Msg::Reboot); - // } - // if let Some(Clicked) = self.reset.event(ctx, event) { - // return Some(Self::Msg::FactoryReset); - // } - - None + fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> { + match self.pg.event(ctx, event) { + Some(ChoicePageMsg::Choice(0)) => Some(MenuMsg::FactoryReset), + Some(ChoicePageMsg::Choice(1)) => Some(MenuMsg::Reboot), + Some(ChoicePageMsg::Choice(2)) => Some(MenuMsg::Close), + _ => None, + } } fn paint(&mut self) { self.bg.paint(); - self.title.paint(); - // self.close.paint(); - // self.reboot.paint(); - // self.reset.paint(); + self.pg.paint(); } - fn bounds(&self, _sink: &mut dyn FnMut(Rect)) { - // self.close.bounds(sink); - // self.reboot.bounds(sink); - // self.reset.bounds(sink); + fn bounds(&self, sink: &mut dyn FnMut(Rect)) { + self.pg.bounds(sink) } } diff --git a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs index 01d25bd74..70fbe8ece 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/mod.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/mod.rs @@ -28,10 +28,9 @@ use crate::ui::{ confirm::Confirm, intro::Intro, menu::Menu, - theme::{bld_button_cancel, bld_button_default, BLD_BG, BLD_FG}, + theme::{BLD_BG, BLD_FG, LOGO_EMPTY}, }, - component::{Button, ButtonPos, ResultScreen}, - theme::LOGO_EMPTY, + component::ResultScreen, }, util::{from_c_array, from_c_str}, }; @@ -128,15 +127,11 @@ extern "C" fn screen_install_confirm( message.add(Paragraph::new(&theme::TEXT_BOLD, "Seed will be erased!").centered()); } - let left = Button::with_text(ButtonPos::Left, "CANCEL", bld_button_cancel()); - let right = Button::with_text(ButtonPos::Right, "INSTALL", bld_button_default()); - let mut frame = Confirm::new( BLD_BG, ICON, Paragraphs::new(message).with_placement(LinearPlacement::vertical().align_at_center()), - left, - right, + "INSTALL", false, ); @@ -161,19 +156,14 @@ extern "C" fn screen_wipe_confirm() -> u32 { let message = Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center()); - let left = Button::with_text(ButtonPos::Left, "WIPE", bld_button_default()); - let right = Button::with_text(ButtonPos::Right, "CANCEL", bld_button_cancel()); - - let mut frame = Confirm::new(BLD_BG, ICON, message, left, right, true); + let mut frame = Confirm::new(BLD_BG, ICON, message, "WIPE", true); run(&mut frame) } #[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(_bld_version: *const cty::c_char) -> u32 { + run(&mut Menu::new()) } #[no_mangle] @@ -209,7 +199,14 @@ fn screen_progress( let fill_to = (loader_area.width() as u32 * progress as u32) / 1000; - display::bar_with_text_and_fill(loader_area, Some(text), fg_color, bg_color, 0, fill_to as _); + display::bar_with_text_and_fill( + loader_area, + Some(&text), + fg_color, + bg_color, + 0, + fill_to as _, + ); // display::text_center( // Point::new(constant::WIDTH / 2, 100), diff --git a/core/embed/rust/src/ui/model_tr/bootloader/theme.rs b/core/embed/rust/src/ui/model_tr/bootloader/theme.rs index 33335ec83..c285c4b28 100644 --- a/core/embed/rust/src/ui/model_tr/bootloader/theme.rs +++ b/core/embed/rust/src/ui/model_tr/bootloader/theme.rs @@ -1,12 +1,10 @@ use crate::ui::{ component::text::TextStyle, display::{Color, Font}, - model_tr::{ - component::{ButtonStyle, ButtonStyleSheet}, - theme::{BG, BLACK, FG, WHITE}, - }, }; +pub const WHITE: Color = Color::white(); +pub const BLACK: Color = Color::black(); pub const BLD_BG: Color = BLACK; pub const BLD_FG: Color = WHITE; @@ -16,35 +14,37 @@ pub const RADIUS: u8 = 2; // Size of icons in the UI (i.e. inside buttons). pub const ICON_SIZE: i32 = 16; -pub fn bld_button_default() -> ButtonStyleSheet { - ButtonStyleSheet { - normal: &ButtonStyle { - font: Font::NORMAL, - text_color: BG, - border_horiz: true, - }, - active: &ButtonStyle { - font: Font::NORMAL, - text_color: FG, - border_horiz: true, - }, - } -} +pub const LOGO_EMPTY: &[u8] = include_res!("model_tr/res/trezor_empty.toif"); -pub fn bld_button_cancel() -> ButtonStyleSheet { - ButtonStyleSheet { - normal: &ButtonStyle { - font: Font::NORMAL, - text_color: FG, - border_horiz: false, - }, - active: &ButtonStyle { - font: Font::NORMAL, - text_color: BG, - border_horiz: false, - }, - } -} +// pub fn bld_button_default() -> ButtonStyleSheet { +// ButtonStyleSheet { +// normal: &ButtonStyle { +// font: Font::NORMAL, +// text_color: BG, +// border_horiz: true, +// }, +// active: &ButtonStyle { +// font: Font::NORMAL, +// text_color: FG, +// border_horiz: true, +// }, +// } +// } +// +// pub fn bld_button_cancel() -> ButtonStyleSheet { +// ButtonStyleSheet { +// normal: &ButtonStyle { +// font: Font::NORMAL, +// text_color: FG, +// border_horiz: false, +// }, +// active: &ButtonStyle { +// font: Font::NORMAL, +// text_color: BG, +// border_horiz: false, +// }, +// } +// } pub const TEXT_NORMAL: TextStyle = TextStyle::new(Font::NORMAL, BLD_FG, BLD_BG, BLD_FG, BLD_FG); pub const TEXT_BOLD: TextStyle = TextStyle::new(Font::NORMAL, BLD_FG, BLD_BG, BLD_FG, BLD_FG); diff --git a/core/embed/rust/src/ui/model_tr/component/mod.rs b/core/embed/rust/src/ui/model_tr/component/mod.rs index 7222b6f18..e61fc3274 100644 --- a/core/embed/rust/src/ui/model_tr/component/mod.rs +++ b/core/embed/rust/src/ui/model_tr/component/mod.rs @@ -1,29 +1,39 @@ +#[cfg(feature = "micropython")] mod bip39; mod button; mod button_controller; +#[cfg(feature = "micropython")] mod changing_text; mod choice; mod choice_item; mod common; mod confirm; mod dialog; +#[cfg(feature = "micropython")] mod flow; +#[cfg(feature = "micropython")] mod flow_pages; +#[cfg(feature = "micropython")] mod flow_pages_poc_helpers; mod frame; mod loader; +#[cfg(feature = "micropython")] mod page; +#[cfg(feature = "micropython")] mod passphrase; +#[cfg(feature = "micropython")] mod pin; mod result; mod result_anim; mod result_popup; mod scrollbar; +#[cfg(feature = "micropython")] mod share_words; mod simple_choice; use super::theme; +#[cfg(feature = "micropython")] pub use bip39::{Bip39Entry, Bip39EntryMsg}; pub use button::{ Button, ButtonAction, ButtonActions, ButtonContent, ButtonDetails, ButtonLayout, ButtonMsg, @@ -32,21 +42,29 @@ pub use button::{ pub use confirm::{HoldToConfirm, HoldToConfirmMsg}; pub use button_controller::{ButtonController, ButtonControllerMsg}; +#[cfg(feature = "micropython")] pub use changing_text::ChangingTextLine; pub use choice::{ChoiceFactory, ChoicePage, ChoicePageMsg}; pub use choice_item::ChoiceItem; pub use dialog::{Dialog, DialogMsg}; +#[cfg(feature = "micropython")] pub use flow::{Flow, FlowMsg}; +#[cfg(feature = "micropython")] pub use flow_pages::{FlowPages, Page}; +#[cfg(feature = "micropython")] pub use flow_pages_poc_helpers::LineAlignment; pub use frame::Frame; pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet}; +#[cfg(feature = "micropython")] pub use page::ButtonPage; +#[cfg(feature = "micropython")] pub use passphrase::{PassphraseEntry, PassphraseEntryMsg}; +#[cfg(feature = "micropython")] pub use pin::{PinEntry, PinEntryMsg}; pub use result::ResultScreen; pub use result_anim::{ResultAnim, ResultAnimMsg}; pub use result_popup::{ResultPopup, ResultPopupMsg}; pub use scrollbar::ScrollBar; +#[cfg(feature = "micropython")] pub use share_words::ShareWords; pub use simple_choice::{SimpleChoice, SimpleChoiceMsg}; diff --git a/core/embed/rust/src/ui/model_tr/screens.rs b/core/embed/rust/src/ui/model_tr/screens.rs index ee823917a..5dad765e9 100644 --- a/core/embed/rust/src/ui/model_tr/screens.rs +++ b/core/embed/rust/src/ui/model_tr/screens.rs @@ -3,11 +3,12 @@ use crate::ui::{ text::paragraphs::{Paragraph, ParagraphVecShort, Paragraphs, VecExt}, Component, }, + display::Color, geometry::LinearPlacement, model_tr::{ component::ResultScreen, constant, - theme::{BLACK, TEXT_BOLD, TEXT_NORMAL, WHITE}, + theme::{TEXT_BOLD, TEXT_NORMAL}, }, util::from_c_str, }; @@ -40,7 +41,7 @@ extern "C" fn screen_fatal_error(msg: *const cty::c_char, file: *const cty::c_ch let m_bottom = Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center()); - let mut frame = ResultScreen::new(WHITE, BLACK, m_top, m_bottom, true); + let mut frame = ResultScreen::new(Color::white(), Color::black(), m_top, m_bottom, true); frame.place(constant::screen()); frame.paint(); 0 @@ -72,7 +73,7 @@ extern "C" fn screen_error_shutdown(label: *const cty::c_char, msg: *const cty:: let m_bottom = Paragraphs::new(messages).with_placement(LinearPlacement::vertical().align_at_center()); - let mut frame = ResultScreen::new(WHITE, BLACK, m_top, m_bottom, true); + let mut frame = ResultScreen::new(Color::white(), Color::black(), m_top, m_bottom, true); frame.place(constant::screen()); frame.paint(); 0