diff --git a/core/embed/rust/src/ui/display/loader/mod.rs b/core/embed/rust/src/ui/display/loader/mod.rs index 691770a4a3..5d41532c04 100644 --- a/core/embed/rust/src/ui/display/loader/mod.rs +++ b/core/embed/rust/src/ui/display/loader/mod.rs @@ -7,7 +7,7 @@ mod starry; use crate::ui::display::{Color, Icon}; -#[cfg(any(feature = "model_tt", feature = "model_mercury"))] +#[cfg(feature = "model_tt")] use crate::ui::display::loader::circular::{ loader_circular as determinate, loader_circular_indeterminate as indeterminate, }; diff --git a/core/embed/rust/src/ui/model_mercury/component/button.rs b/core/embed/rust/src/ui/model_mercury/component/button.rs index 257a3fb921..3b34a3d5e0 100644 --- a/core/embed/rust/src/ui/model_mercury/component/button.rs +++ b/core/embed/rust/src/ui/model_mercury/component/button.rs @@ -4,7 +4,9 @@ use crate::{ strutil::TString, time::Duration, ui::{ - component::{Component, Event, EventCtx, TimerToken}, + component::{ + Component, ComponentExt, Event, EventCtx, FixedHeightBar, MsgMap, Split, TimerToken, + }, display::{self, toif::Icon, Color, Font}, event::TouchEvent, geometry::{Alignment2D, Insets, Offset, Point, Rect}, @@ -255,7 +257,7 @@ impl Button { .render(target); } ButtonContent::IconAndText(child) => { - child.render(target, self.area, style, Self::BASELINE_OFFSET); + child.render(target, self.area, self.style(), Self::BASELINE_OFFSET); } ButtonContent::IconBlend(bg, fg, offset) => { shape::Bar::new(self.area) @@ -430,8 +432,7 @@ impl Button { ) -> CancelConfirm< impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, - > - { + > { let width = if left_is_small { theme::BUTTON_WIDTH } else { @@ -455,8 +456,7 @@ impl Button { ) -> CancelConfirm< impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, - > - { + > { let left_is_small: bool; let left = if let Some(verb) = left { @@ -485,8 +485,7 @@ impl Button { impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, impl Fn(ButtonMsg) -> Option, - > - { + > { let right = Button::with_text(confirm) .styled(theme::button_confirm()) .map(|msg| { @@ -529,7 +528,7 @@ pub enum CancelInfoConfirmMsg { Confirmed, } -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Clone)] pub struct IconText { text: &'static str, icon: Icon, @@ -555,8 +554,7 @@ impl IconText { area.top_left().x + ((Self::ICON_SPACE + Self::ICON_MARGIN) / 2), area.center().y, ); - let mut text_pos = - area.center() + Offset::new(-width / 2, height / 2) + baseline_offset; + let mut text_pos = area.center() + Offset::new(-width / 2, height / 2) + baseline_offset; if area.width() > (Self::ICON_SPACE + Self::TEXT_MARGIN + width) { //display both icon and text @@ -623,9 +621,11 @@ impl IconText { if use_text { shape::Text::new(text_pos, self.text) + .with_font(style.font) .with_fg(style.text_color) .render(target); } + if use_icon { shape::ToifImage::new(icon_pos, self.icon.toif) .with_align(Alignment2D::CENTER) diff --git a/core/embed/rust/src/ui/model_mercury/component/frame.rs b/core/embed/rust/src/ui/model_mercury/component/frame.rs index 62a697adba..ba0b14d661 100644 --- a/core/embed/rust/src/ui/model_mercury/component/frame.rs +++ b/core/embed/rust/src/ui/model_mercury/component/frame.rs @@ -6,12 +6,12 @@ use crate::{ base::ComponentExt, label::Label, text::TextStyle, Child, Component, Event, EventCtx, }, display::Icon, - geometry::{Alignment, Insets, Offset, Rect}, + geometry::{Alignment, Insets, Rect}, shape::Renderer, }, }; -use super::{Button, ButtonMsg, CancelInfoConfirmMsg}; +use super::{constant::SPACING, Button, ButtonMsg, CancelInfoConfirmMsg}; const TITLE_HEIGHT: i16 = 42; @@ -46,15 +46,15 @@ where } } - pub fn left_aligned(style: TextStyle, title: TString<'static>, content: T) -> Self { + pub fn left_aligned(title: TString<'static>, content: T) -> Self { Self::new(Alignment::Start, title, content) } - pub fn right_aligned(style: TextStyle, title: TString<'static>, content: T) -> Self { + pub fn right_aligned(title: TString<'static>, content: T) -> Self { Self::new(Alignment::End, title, content) } - pub fn centered(style: TextStyle, title: TString<'static>, content: T) -> Self { + pub fn centered(title: TString<'static>, content: T) -> Self { Self::new(Alignment::Center, title, content) } diff --git a/core/embed/rust/src/ui/model_mercury/component/mod.rs b/core/embed/rust/src/ui/model_mercury/component/mod.rs index a6da95bc1c..68bd86ce98 100644 --- a/core/embed/rust/src/ui/model_mercury/component/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/component/mod.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "translations")] +mod address_details; pub mod bl_confirm; mod button; #[cfg(feature = "translations")] @@ -10,7 +12,15 @@ mod vertical_menu; mod fido_icons; mod error; mod frame; +#[cfg(feature = "micropython")] +mod homescreen; +mod keyboard; mod loader; +#[cfg(feature = "translations")] +mod number_input; +#[cfg(feature = "translations")] +mod page; +mod progress; mod result; mod scroll; mod share_words; @@ -18,14 +28,21 @@ mod simple_page; mod swipe; mod welcome_screen; +#[cfg(feature = "translations")] +pub use address_details::AddressDetails; pub use button::{ - Button, ButtonContent, ButtonMsg, ButtonStyle, ButtonStyleSheet, CancelInfoConfirmMsg, IconText, + Button, ButtonContent, ButtonMsg, ButtonStyle, ButtonStyleSheet, CancelConfirmMsg, + CancelInfoConfirmMsg, IconText, }; +#[cfg(feature = "translations")] +pub use coinjoin_progress::CoinJoinProgress; +pub use dialog::{Dialog, DialogMsg, IconDialog}; pub use error::ErrorScreen; +pub use fido::{FidoConfirm, FidoMsg}; +pub use footer::Footer; pub use frame::{Frame, FrameMsg}; #[cfg(feature = "micropython")] pub use homescreen::{check_homescreen_format, Homescreen, HomescreenMsg, Lockscreen}; -pub use footer::Footer; pub use keyboard::{ bip39::Bip39Input, mnemonic::{MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg}, @@ -35,6 +52,11 @@ pub use keyboard::{ word_count::{SelectWordCount, SelectWordCountMsg}, }; pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet}; +#[cfg(feature = "translations")] +pub use number_input::{NumberInputDialog, NumberInputDialogMsg}; +#[cfg(feature = "translations")] +pub use page::ButtonPage; +pub use progress::Progress; pub use result::{ResultFooter, ResultScreen, ResultStyle}; pub use scroll::ScrollBar; pub use share_words::ShareWords; diff --git a/core/embed/rust/src/ui/model_mercury/component/number_input.rs b/core/embed/rust/src/ui/model_mercury/component/number_input.rs index c39ac6ba2e..215483fe4c 100644 --- a/core/embed/rust/src/ui/model_mercury/component/number_input.rs +++ b/core/embed/rust/src/ui/model_mercury/component/number_input.rs @@ -1,6 +1,6 @@ use crate::{ error::Error, - strutil::{self, StringType, TString}, + strutil::{self, TString}, translations::TR, ui::{ component::{ diff --git a/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs b/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs index c403f6b244..84b89b2360 100644 --- a/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs +++ b/core/embed/rust/src/ui/model_mercury/component/vertical_menu.rs @@ -3,7 +3,6 @@ use heapless::Vec; use super::theme; use crate::{ micropython::buffer::StrBuffer, - strutil::TString, ui::{ component::{base::Component, Event, EventCtx}, display::Icon, diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index 0afce326ce..d61cc7ef69 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -53,8 +53,8 @@ use super::{ FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog, Lockscreen, MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg, NumberInputDialog, NumberInputDialogMsg, PassphraseKeyboard, PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress, - SelectWordCount, SelectWordCountMsg, SelectWordMsg, ShareWords, SimplePage, Slip39Input, - VerticalMenu, VerticalMenuChoiceMsg, + SelectWordCount, SelectWordCountMsg, ShareWords, SimplePage, Slip39Input, VerticalMenu, + VerticalMenuChoiceMsg, }, flow, theme, }; @@ -82,16 +82,6 @@ impl TryFrom for Obj { } } -impl TryFrom for Obj { - type Error = Error; - - fn try_from(value: SelectWordMsg) -> Result { - match value { - SelectWordMsg::Selected(i) => i.try_into(), - } - } -} - impl TryFrom for Obj { type Error = Error; @@ -1213,10 +1203,7 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut let paragraphs = Paragraphs::new([ Paragraph::new(&theme::TEXT_NORMAL, TR::coinjoin__max_rounds), Paragraph::new(&theme::TEXT_MONO, max_rounds), - Paragraph::new( - &theme::TEXT_NORMAL, - TR::coinjoin__max_mining_fee, - ), + Paragraph::new(&theme::TEXT_NORMAL, TR::coinjoin__max_mining_fee), Paragraph::new(&theme::TEXT_MONO, max_feerate), ]); diff --git a/core/embed/rust/src/ui/model_mercury/theme/mod.rs b/core/embed/rust/src/ui/model_mercury/theme/mod.rs index 1b0f116cb2..f33f0b7540 100644 --- a/core/embed/rust/src/ui/model_mercury/theme/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/theme/mod.rs @@ -1,16 +1,29 @@ pub mod bootloader; -use crate::ui::{ - component::text::{LineBreaking, PageBreaking, TextStyle}, - display::{Color, Font, Icon}, - geometry::Insets, +use crate::{ + time::Duration, + ui::{ + component::{ + text::{layout::Chunks, LineBreaking, PageBreaking, TextStyle}, + FixedHeightBar, + }, + display::{Color, Font, Icon}, + geometry::{Insets, Offset}, + }, }; -use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet}; +use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet, ResultStyle}; + +use num_traits::FromPrimitive; + +pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); // Typical backlight values. pub const BACKLIGHT_NORMAL: u16 = 150; +pub const BACKLIGHT_LOW: u16 = 45; pub const BACKLIGHT_DIM: u16 = 5; +pub const BACKLIGHT_NONE: u16 = 2; +pub const BACKLIGHT_MAX: u16 = 255; // Color palette. pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF); @@ -46,6 +59,9 @@ pub const FATAL_ERROR_HIGHLIGHT_COLOR: Color = Color::rgb(0xFF, 0x41, 0x41); // Commonly used corner radius (i.e. for buttons). pub const RADIUS: u8 = 0; +// Full-size QR code. +pub const QR_SIDE_MAX: u32 = 140; + // UI icons (greyscale). // 20x20 @@ -85,35 +101,124 @@ include_icon!(ICON_PLUS, "model_mercury/res/plus40.toif"); // TODO remove TT icons: // Button icons. -include_icon!(ICON_CANCEL, "model_mercury/res/x24.toif"); -include_icon!(ICON_CONFIRM, "model_mercury/res/check24.toif"); -include_icon!(ICON_UP, "model_mercury/res/caret-up24.toif"); +include_icon!(ICON_CONFIRM, "model_tt/res/check24.toif"); +include_icon!(ICON_SPACE, "model_tt/res/space.toif"); +include_icon!(ICON_BACK, "model_tt/res/caret-left24.toif"); +include_icon!(ICON_FORWARD, "model_tt/res/caret-right24.toif"); +include_icon!(ICON_UP, "model_tt/res/caret-up24.toif"); +include_icon!(ICON_DOWN, "model_tt/res/caret-down24.toif"); +include_icon!(ICON_CLICK, "model_tt/res/finger24.toif"); -include_icon!(ICON_CORNER_CANCEL, "model_mercury/res/x32.toif"); -include_icon!(ICON_CORNER_INFO, "model_mercury/res/info32.toif"); +include_icon!(ICON_CORNER_CANCEL, "model_tt/res/x32.toif"); +include_icon!(ICON_CORNER_INFO, "model_tt/res/info32.toif"); // Checklist symbols. -include_icon!(ICON_LIST_CURRENT, "model_mercury/res/arrow-right16.toif"); -include_icon!(ICON_LIST_CHECK, "model_mercury/res/check16.toif"); +include_icon!(ICON_LIST_CURRENT, "model_tt/res/arrow-right16.toif"); +include_icon!(ICON_LIST_CHECK, "model_tt/res/check16.toif"); // Homescreen notifications. -include_icon!(ICON_WARNING40, "model_mercury/res/warning40.toif"); -include_icon!(ICON_LOCK_BIG, "model_mercury/res/lock24.toif"); +include_icon!(ICON_WARN, "model_tt/res/warning16.toif"); +include_icon!(ICON_WARNING40, "model_tt/res/warning40.toif"); +include_icon!(ICON_LOCK, "model_tt/res/lock16.toif"); +include_icon!(ICON_LOCK_BIG, "model_tt/res/lock24.toif"); +include_icon!(ICON_COINJOIN, "model_tt/res/coinjoin16.toif"); +include_icon!(ICON_MAGIC, "model_tt/res/magic.toif"); // Text arrows. -include_icon!(ICON_PAGE_NEXT, "model_mercury/res/page-next.toif"); -include_icon!(ICON_PAGE_PREV, "model_mercury/res/page-prev.toif"); +include_icon!(ICON_PAGE_NEXT, "model_tt/res/page-next.toif"); +include_icon!(ICON_PAGE_PREV, "model_tt/res/page-prev.toif"); // Large, three-color icons. -pub const WARN_COLOR: Color = ORANGE_LIGHT; -pub const INFO_COLOR: Color = GREY_LIGHT; +pub const WARN_COLOR: Color = YELLOW; +pub const INFO_COLOR: Color = BLUE; pub const SUCCESS_COLOR: Color = GREEN; -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"); +pub const ERROR_COLOR: Color = RED; +include_icon!(IMAGE_FG_WARN, "model_tt/res/fg-warning48.toif"); +include_icon!(IMAGE_FG_SUCCESS, "model_tt/res/fg-check48.toif"); +include_icon!(IMAGE_FG_ERROR, "model_tt/res/fg-error48.toif"); +include_icon!(IMAGE_FG_INFO, "model_tt/res/fg-info48.toif"); +include_icon!(IMAGE_FG_USER, "model_tt/res/fg-user48.toif"); +include_icon!(IMAGE_BG_CIRCLE, "model_tt/res/circle48.toif"); +include_icon!(IMAGE_BG_OCTAGON, "model_tt/res/octagon48.toif"); + +// Non-square button backgrounds. +include_icon!(IMAGE_BG_BACK_BTN, "model_tt/res/bg-back40.toif"); +include_icon!(IMAGE_BG_BACK_BTN_TALL, "model_tt/res/bg-back52.toif"); // Welcome screen. -include_icon!(ICON_LOGO, "model_mercury/res/lock_full.toif"); +include_icon!(ICON_LOGO, "model_tt/res/lock_full.toif"); +include_icon!(ICON_LOGO_EMPTY, "model_tt/res/lock_empty.toif"); + +// Default homescreen +pub const IMAGE_HOMESCREEN: &[u8] = include_res!("model_tt/res/bg.jpg"); + +// Scrollbar/PIN dots. +include_icon!(DOT_ACTIVE, "model_tt/res/scroll-active.toif"); +include_icon!(DOT_INACTIVE, "model_tt/res/scroll-inactive.toif"); +include_icon!(DOT_INACTIVE_HALF, "model_tt/res/scroll-inactive-half.toif"); +include_icon!( + DOT_INACTIVE_QUARTER, + "model_tt/res/scroll-inactive-quarter.toif" +); +include_icon!(DOT_SMALL, "model_tt/res/scroll-small.toif"); + +pub const fn label_default() -> TextStyle { + TEXT_NORMAL +} + +pub const fn label_keyboard() -> TextStyle { + TextStyle::new(Font::DEMIBOLD, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT) +} + +pub const fn label_keyboard_prompt() -> TextStyle { + TextStyle::new(Font::DEMIBOLD, GREY_LIGHT, BG, GREY_LIGHT, GREY_LIGHT) +} + +pub const fn label_keyboard_warning() -> TextStyle { + TextStyle::new(Font::DEMIBOLD, RED, BG, GREY_LIGHT, GREY_LIGHT) +} + +pub const fn label_keyboard_minor() -> TextStyle { + TEXT_NORMAL_OFF_WHITE +} + +pub const fn label_warning() -> TextStyle { + TEXT_DEMIBOLD +} + +pub const fn label_warning_value() -> TextStyle { + TEXT_NORMAL_OFF_WHITE +} + +pub const fn label_recovery_title() -> TextStyle { + TEXT_BOLD +} + +pub const fn label_recovery_description() -> TextStyle { + TEXT_NORMAL_OFF_WHITE +} + +pub const fn label_progress() -> TextStyle { + TEXT_BOLD +} + +pub const fn label_title_main() -> TextStyle { + TextStyle::new( + Font::NORMAL, + GREY_EXTRA_LIGHT, + GREY_DARK, + GREY_LIGHT, + GREY_LIGHT, + ) +} + +pub const fn label_title_sub() -> TextStyle { + TextStyle::new(Font::SUB, GREY, GREY_DARK, GREY_LIGHT, GREY_LIGHT) +} + +pub const fn label_coinjoin_progress() -> TextStyle { + TextStyle::new(Font::BOLD, FG, YELLOW, FG, FG) +} pub const fn button_default() -> ButtonStyleSheet { ButtonStyleSheet { @@ -129,7 +234,7 @@ pub const fn button_default() -> ButtonStyleSheet { active: &ButtonStyle { font: Font::BOLD, text_color: FG, - button_color: GREY, + button_color: GREY_MEDIUM, background_color: BG, border_color: FG, border_radius: RADIUS, @@ -147,6 +252,106 @@ pub const fn button_default() -> ButtonStyleSheet { } } +pub const fn button_confirm() -> ButtonStyleSheet { + ButtonStyleSheet { + normal: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: GREEN, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + active: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: GREEN_DARK, + background_color: BG, + border_color: FG, + border_radius: RADIUS, + border_width: 0, + }, + disabled: &ButtonStyle { + font: Font::BOLD, + text_color: GREY_LIGHT, + button_color: GREEN_DARK, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + } +} + +pub const fn button_cancel() -> ButtonStyleSheet { + ButtonStyleSheet { + normal: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: RED, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + active: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: RED_DARK, + background_color: BG, + border_color: FG, + border_radius: RADIUS, + border_width: 0, + }, + disabled: &ButtonStyle { + font: Font::BOLD, + text_color: GREY_LIGHT, + button_color: RED, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + } +} + +pub const fn button_danger() -> ButtonStyleSheet { + button_cancel() +} + +pub const fn button_reset() -> ButtonStyleSheet { + ButtonStyleSheet { + normal: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: YELLOW, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + active: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: YELLOW_DARK, + background_color: BG, + border_color: FG, + border_radius: RADIUS, + border_width: 0, + }, + disabled: &ButtonStyle { + font: Font::BOLD, + text_color: FG, + button_color: YELLOW, + background_color: BG, + border_color: BG, + border_radius: RADIUS, + border_width: 0, + }, + } +} + pub const fn button_moreinfo() -> ButtonStyleSheet { ButtonStyleSheet { normal: &ButtonStyle { @@ -163,9 +368,9 @@ pub const fn button_moreinfo() -> ButtonStyleSheet { text_color: FG, button_color: BG, background_color: BG, - border_color: GREY, - border_radius: RADIUS, - border_width: 2, + border_color: GREY_DARK, + border_radius: 0, + border_width: 1, }, disabled: &ButtonStyle { font: Font::BOLD, @@ -509,6 +714,18 @@ pub const TEXT_MONO: TextStyle = TextStyle::new(Font::MONO, GREY_EXTRA_LIGHT, BG .with_page_breaking(PageBreaking::CutAndInsertEllipsisBoth) .with_ellipsis_icon(ICON_PAGE_NEXT, 0) .with_prev_page_icon(ICON_PAGE_PREV, 0); +/// Makes sure that the displayed text (usually address) will get divided into +/// smaller chunks. +pub const TEXT_MONO_ADDRESS_CHUNKS: TextStyle = TEXT_MONO + .with_chunks(Chunks::new(4, 9)) + .with_line_spacing(5); +/// Smaller horizontal chunk offset, used e.g. for long Cardano addresses. +/// Also moving the next page ellipsis to the left (as there is a space on the +/// left). Last but not least, maximum number of rows is 4 in this case. +pub const TEXT_MONO_ADDRESS_CHUNKS_SMALLER_X_OFFSET: TextStyle = TEXT_MONO + .with_chunks(Chunks::new(4, 7).with_max_rows(4)) + .with_line_spacing(5) + .with_ellipsis_icon(ICON_PAGE_NEXT, -12); // TODO: remove TextStyles below when ui-t3t1 done pub const TEXT_NORMAL: TextStyle = TextStyle::new(Font::NORMAL, FG, BG, GREY_LIGHT, GREY_LIGHT); @@ -551,9 +768,26 @@ pub const CONTENT_BORDER: i16 = 0; pub const BUTTON_HEIGHT: i16 = 50; pub const BUTTON_WIDTH: i16 = 56; pub const BUTTON_SPACING: i16 = 6; +pub const KEYBOARD_SPACING: i16 = BUTTON_SPACING; +pub const CHECKLIST_SPACING: i16 = 10; +pub const RECOVERY_SPACING: i16 = 18; pub const CORNER_BUTTON_SIDE: i16 = 44; +pub const CORNER_BUTTON_SPACING: i16 = BUTTON_SPACING; +pub const INFO_BUTTON_HEIGHT: i16 = 44; +pub const PIN_BUTTON_HEIGHT: i16 = 40; +pub const MNEMONIC_BUTTON_HEIGHT: i16 = 52; pub const RESULT_PADDING: i16 = 6; pub const RESULT_FOOTER_START: i16 = 171; +pub const RESULT_FOOTER_HEIGHT: i16 = 62; + +// checklist settings +pub const CHECKLIST_CHECK_WIDTH: i16 = 16; +pub const CHECKLIST_DONE_OFFSET: Offset = Offset::new(-2, 6); +pub const CHECKLIST_CURRENT_OFFSET: Offset = Offset::new(2, 3); + +pub const fn button_bar(inner: T) -> FixedHeightBar { + FixedHeightBar::bottom(inner, BUTTON_HEIGHT) +} /// +----------+ /// | 6 | @@ -565,3 +799,14 @@ pub const RESULT_FOOTER_START: i16 = 171; pub const fn borders() -> Insets { Insets::new(0, 0, 0, 0) } + +pub const fn borders_horizontal_scroll() -> Insets { + Insets::new(0, 0, 0, 0) +} + +pub const fn borders_notification() -> Insets { + Insets::new(42, 0, 0, 0) +} + +pub const RESULT_ERROR: ResultStyle = + ResultStyle::new(FG, FATAL_ERROR_COLOR, FATAL_ERROR_HIGHLIGHT_COLOR);