1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-26 09:28:13 +00:00

fix(core): rebase on drawlib

mercury theme.rs needs some cleanup after this action
This commit is contained in:
obrusvit 2024-04-16 23:22:15 +02:00 committed by Martin Milata
parent 1363495165
commit 683ea6ed26
8 changed files with 316 additions and 63 deletions

View File

@ -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,
};

View File

@ -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<CancelConfirmMsg>,
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
>
{
> {
let width = if left_is_small {
theme::BUTTON_WIDTH
} else {
@ -455,8 +456,7 @@ impl Button {
) -> CancelConfirm<
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
impl Fn(ButtonMsg) -> Option<CancelConfirmMsg>,
>
{
> {
let left_is_small: bool;
let left = if let Some(verb) = left {
@ -485,8 +485,7 @@ impl Button {
impl Fn(ButtonMsg) -> Option<CancelInfoConfirmMsg>,
impl Fn(ButtonMsg) -> Option<CancelInfoConfirmMsg>,
impl Fn(ButtonMsg) -> Option<CancelInfoConfirmMsg>,
>
{
> {
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)

View File

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

View File

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

View File

@ -1,6 +1,6 @@
use crate::{
error::Error,
strutil::{self, StringType, TString},
strutil::{self, TString},
translations::TR,
ui::{
component::{

View File

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

View File

@ -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<CancelInfoConfirmMsg> for Obj {
}
}
impl TryFrom<SelectWordMsg> for Obj {
type Error = Error;
fn try_from(value: SelectWordMsg) -> Result<Self, Self::Error> {
match value {
SelectWordMsg::Selected(i) => i.try_into(),
}
}
}
impl TryFrom<SelectWordCountMsg> 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),
]);

View File

@ -1,16 +1,29 @@
pub mod bootloader;
use crate::ui::{
component::text::{LineBreaking, PageBreaking, TextStyle},
use crate::{
time::Duration,
ui::{
component::{
text::{layout::Chunks, LineBreaking, PageBreaking, TextStyle},
FixedHeightBar,
},
display::{Color, Font, Icon},
geometry::Insets,
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<T>(inner: T) -> FixedHeightBar<T> {
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);