1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-10 05:06:06 +00:00

refactor(core): get rid of font IDs in micropython

- application layer should not deal with fonts at all
- distinction between MONO and others is preserved by bool argument in
`should_show_more` interpreted as `is_data`

[no changelog]
This commit is contained in:
obrusvit 2025-01-20 17:11:06 +01:00 committed by Vít Obrusník
parent 566f82ccd8
commit cf5b89f90a
17 changed files with 63 additions and 103 deletions

View File

@ -1258,7 +1258,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// title: str, /// title: str,
/// button: str, /// button: str,
/// button_style_confirm: bool = False, /// button_style_confirm: bool = False,
/// items: Iterable[tuple[int, str | bytes]], /// items: Iterable[tuple[str | bytes, bool]],
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Confirm long content with the possibility to go back from any page. /// """Confirm long content with the possibility to go back from any page.
/// Meant to be used with confirm_with_info on UI Bolt and Caesar.""" /// Meant to be used with confirm_with_info on UI Bolt and Caesar."""
@ -1299,7 +1299,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// button: str, /// button: str,
/// info_button: str, /// info_button: str,
/// verb_cancel: str | None = None, /// verb_cancel: str | None = None,
/// items: Iterable[tuple[int, str | bytes]], /// items: Iterable[tuple[str | bytes, bool]],
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. Always single page /// """Confirm given items but with third button. Always single page
/// without scrolling. In Delizia, the button is placed in /// without scrolling. In Delizia, the button is placed in

View File

@ -16,8 +16,6 @@ use crate::{
use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet, ResultStyle}; use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet, ResultStyle};
use num_traits::FromPrimitive;
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
// Color palette. // Color palette.
@ -622,17 +620,6 @@ pub fn get_chunkified_text_style(character_length: usize) -> &'static TextStyle
} }
} }
/// Convert Python-side numeric id to a `TextStyle`.
pub fn textstyle_number(num: i32) -> &'static TextStyle {
let font = Font::from_i32(-num);
match font {
Some(Font::DEMIBOLD) => &TEXT_DEMIBOLD,
Some(Font::BOLD_UPPER) => &TEXT_BOLD,
Some(Font::MONO) => &TEXT_MONO,
_ => &TEXT_NORMAL,
}
}
pub const TEXT_NORMAL_OFF_WHITE: TextStyle = pub const TEXT_NORMAL_OFF_WHITE: TextStyle =
TextStyle::new(Font::NORMAL, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT); TextStyle::new(Font::NORMAL, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_CHECKLIST_DEFAULT: TextStyle = pub const TEXT_CHECKLIST_DEFAULT: TextStyle =

View File

@ -340,8 +340,13 @@ impl FirmwareUI for UIBolt {
let mut paragraphs = ParagraphVecLong::new(); let mut paragraphs = ParagraphVecLong::new();
for para in IterBuf::new().try_iterate(items)? { for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?; let [text, is_data]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?); let is_data = is_data.try_into()?;
let style: &TextStyle = if is_data {
&theme::TEXT_MONO
} else {
&theme::TEXT_NORMAL
};
let text: TString = text.try_into()?; let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text)); paragraphs.add(Paragraph::new(style, text));
} }
@ -460,8 +465,13 @@ impl FirmwareUI for UIBolt {
let mut paragraphs = ParagraphVecShort::new(); let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? { for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?; let [text, is_data]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?); let is_data = is_data.try_into()?;
let style: &TextStyle = if is_data {
&theme::TEXT_MONO
} else {
&theme::TEXT_NORMAL
};
let text: TString = text.try_into()?; let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text)); paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() { if paragraphs.is_full() {

View File

@ -8,8 +8,6 @@ use crate::ui::{
util::include_icon, util::include_icon,
}; };
use num_traits::FromPrimitive;
pub mod bootloader; pub mod bootloader;
// Color palette. // Color palette.
@ -53,17 +51,6 @@ pub const TEXT_MONO_ADDRESS_CHUNKS: TextStyle = TEXT_MONO_DATA
// Chunks for this model // Chunks for this model
pub const MONO_CHUNKS: Chunks = Chunks::new(4, 4); pub const MONO_CHUNKS: Chunks = Chunks::new(4, 4);
/// Convert Python-side numeric id to a `TextStyle`.
pub fn textstyle_number(num: i32) -> &'static TextStyle {
let font = Font::from_i32(-num);
match font {
Some(Font::BOLD) => &TEXT_BOLD,
Some(Font::DEMIBOLD) => &TEXT_BOLD,
Some(Font::NORMAL) => &TEXT_NORMAL,
_ => &TEXT_MONO_DATA,
}
}
// Firmware icons // Firmware icons
include_icon!(ICON_ARM_LEFT, "layout_caesar/res/arm_left.toif"); // 10*6 include_icon!(ICON_ARM_LEFT, "layout_caesar/res/arm_left.toif"); // 10*6
include_icon!(ICON_ARM_RIGHT, "layout_caesar/res/arm_right.toif"); // 10*6 include_icon!(ICON_ARM_RIGHT, "layout_caesar/res/arm_right.toif"); // 10*6

View File

@ -390,8 +390,13 @@ impl FirmwareUI for UICaesar {
let mut paragraphs = ParagraphVecLong::new(); let mut paragraphs = ParagraphVecLong::new();
for para in IterBuf::new().try_iterate(items)? { for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?; let [text, is_data]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?); let is_data = is_data.try_into()?;
let style: &TextStyle = if is_data {
&theme::TEXT_MONO_DATA
} else {
&theme::TEXT_NORMAL
};
let text: TString = text.try_into()?; let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text)); paragraphs.add(Paragraph::new(style, text));
} }
@ -599,8 +604,13 @@ impl FirmwareUI for UICaesar {
let mut paragraphs = ParagraphVecShort::new(); let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? { for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?; let [text, is_data]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?); let is_data = is_data.try_into()?;
let style: &TextStyle = if is_data {
&theme::TEXT_MONO_DATA
} else {
&theme::TEXT_NORMAL
};
let text: TString = text.try_into()?; let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text)); paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() { if paragraphs.is_full() {

View File

@ -17,7 +17,6 @@ use crate::{
use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet, ResultStyle}; use super::component::{ButtonStyle, ButtonStyleSheet, LoaderStyle, LoaderStyleSheet, ResultStyle};
use num_traits::FromPrimitive;
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
@ -760,17 +759,6 @@ pub fn get_chunkified_text_style(character_length: usize) -> &'static TextStyle
} }
} }
/// Convert Python-side numeric id to a `TextStyle`.
pub fn textstyle_number(num: i32) -> &'static TextStyle {
let font = Font::from_i32(-num);
match font {
Some(Font::DEMIBOLD) => &TEXT_DEMIBOLD,
Some(Font::BOLD) => &TEXT_BOLD,
Some(Font::MONO) => &TEXT_MONO,
_ => &TEXT_NORMAL,
}
}
pub const TEXT_NORMAL_GREY_EXTRA_LIGHT: TextStyle = pub const TEXT_NORMAL_GREY_EXTRA_LIGHT: TextStyle =
TextStyle::new(Font::NORMAL, GREY_EXTRA_LIGHT, BG, GREY_LIGHT, GREY_LIGHT); TextStyle::new(Font::NORMAL, GREY_EXTRA_LIGHT, BG, GREY_LIGHT, GREY_LIGHT);
pub const TEXT_CHECKLIST_DEFAULT: TextStyle = TextStyle::new(Font::SUB, GREY, BG, GREY, GREY); pub const TEXT_CHECKLIST_DEFAULT: TextStyle = TextStyle::new(Font::SUB, GREY, BG, GREY, GREY);

View File

@ -447,8 +447,13 @@ impl FirmwareUI for UIDelizia {
let mut paragraphs = ParagraphVecShort::new(); let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? { for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?; let [text, is_data]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?); let is_data = is_data.try_into()?;
let style: &TextStyle = if is_data {
&theme::TEXT_MONO
} else {
&theme::TEXT_NORMAL
};
let text: TString = text.try_into()?; let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text)); paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() { if paragraphs.is_full() {

View File

@ -29,10 +29,6 @@
/// """ /// """
/// WIDTH: int # display width in pixels /// WIDTH: int # display width in pixels
/// HEIGHT: int # display height in pixels /// HEIGHT: int # display height in pixels
/// FONT_MONO: int # id of monospace font
/// FONT_NORMAL: int # id of normal-width font
/// FONT_DEMIBOLD: int # id of demibold font
/// FONT_BOLD_UPPER: int # id of bold-width-uppercased font
typedef struct _mp_obj_Display_t { typedef struct _mp_obj_Display_t {
mp_obj_base_t base; mp_obj_base_t base;
@ -144,14 +140,6 @@ STATIC const mp_rom_map_elem_t mod_trezorui_Display_locals_dict_table[] = {
MP_ROM_PTR(&mod_trezorui_Display_clear_save_obj)}, MP_ROM_PTR(&mod_trezorui_Display_clear_save_obj)},
{MP_ROM_QSTR(MP_QSTR_WIDTH), MP_ROM_INT(DISPLAY_RESX)}, {MP_ROM_QSTR(MP_QSTR_WIDTH), MP_ROM_INT(DISPLAY_RESX)},
{MP_ROM_QSTR(MP_QSTR_HEIGHT), MP_ROM_INT(DISPLAY_RESY)}, {MP_ROM_QSTR(MP_QSTR_HEIGHT), MP_ROM_INT(DISPLAY_RESY)},
{MP_ROM_QSTR(MP_QSTR_FONT_NORMAL), MP_ROM_INT(FONT_NORMAL)},
{MP_ROM_QSTR(MP_QSTR_FONT_DEMIBOLD), MP_ROM_INT(FONT_DEMIBOLD)},
{MP_ROM_QSTR(MP_QSTR_FONT_MONO), MP_ROM_INT(FONT_MONO)},
#ifdef FONT_BOLD_UPPER
{MP_ROM_QSTR(MP_QSTR_FONT_BOLD_UPPER), MP_ROM_INT(FONT_BOLD_UPPER)},
#else
{MP_ROM_QSTR(MP_QSTR_FONT_BOLD_UPPER), MP_ROM_INT(FONT_BOLD)},
#endif
}; };
STATIC MP_DEFINE_CONST_DICT(mod_trezorui_Display_locals_dict, STATIC MP_DEFINE_CONST_DICT(mod_trezorui_Display_locals_dict,
mod_trezorui_Display_locals_dict_table); mod_trezorui_Display_locals_dict_table);

View File

@ -8,10 +8,6 @@ class Display:
""" """
WIDTH: int # display width in pixels WIDTH: int # display width in pixels
HEIGHT: int # display height in pixels HEIGHT: int # display height in pixels
FONT_MONO: int # id of monospace font
FONT_NORMAL: int # id of normal-width font
FONT_DEMIBOLD: int # id of demibold font
FONT_BOLD_UPPER: int # id of bold-width-uppercased font
def __init__(self) -> None: def __init__(self) -> None:
""" """

View File

@ -241,7 +241,7 @@ def confirm_more(
title: str, title: str,
button: str, button: str,
button_style_confirm: bool = False, button_style_confirm: bool = False,
items: Iterable[tuple[int, str | bytes]], items: Iterable[tuple[str | bytes, bool]],
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Confirm long content with the possibility to go back from any page. """Confirm long content with the possibility to go back from any page.
Meant to be used with confirm_with_info on UI Bolt and Caesar.""" Meant to be used with confirm_with_info on UI Bolt and Caesar."""
@ -286,7 +286,7 @@ def confirm_with_info(
button: str, button: str,
info_button: str, info_button: str,
verb_cancel: str | None = None, verb_cancel: str | None = None,
items: Iterable[tuple[int, str | bytes]], items: Iterable[tuple[str | bytes, bool]],
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. Always single page """Confirm given items but with third button. Always single page
without scrolling. In Delizia, the button is placed in without scrolling. In Delizia, the button is placed in

View File

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import TR, ui from trezor import TR
from trezor.enums import ( from trezor.enums import (
ButtonRequestType, ButtonRequestType,
CardanoAddressType, CardanoAddressType,
@ -189,11 +189,8 @@ async def show_tx_init(title: str) -> bool:
should_show_details = await layouts.should_show_more( should_show_details = await layouts.should_show_more(
TR.cardano__confirm_transaction, TR.cardano__confirm_transaction,
( (
( (title, False),
ui.DEMIBOLD, (TR.cardano__choose_level_of_details, False),
title,
),
(ui.NORMAL, TR.cardano__choose_level_of_details),
), ),
TR.buttons__show_all, TR.buttons__show_all,
confirm=TR.cardano__show_simple, confirm=TR.cardano__show_simple,

View File

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import TR, ui from trezor import TR
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType
from trezor.ui.layouts import ( from trezor.ui.layouts import (
confirm_blob, confirm_blob,
@ -214,9 +214,9 @@ async def should_show_domain(name: bytes, version: bytes) -> bool:
domain_version = decode_typed_data(version, "string") domain_version = decode_typed_data(version, "string")
para = ( para = (
(ui.NORMAL, TR.ethereum__name_and_version), (TR.ethereum__name_and_version, False),
(ui.DEMIBOLD, domain_name), (domain_name, False),
(ui.DEMIBOLD, domain_version), (domain_version, False),
) )
return await should_show_more( return await should_show_more(
TR.ethereum__title_confirm_domain, TR.ethereum__title_confirm_domain,
@ -243,12 +243,9 @@ async def should_show_struct(
contains_plural = f"{TR.words__contains} {plural}" contains_plural = f"{TR.words__contains} {plural}"
para = ( para = (
(ui.DEMIBOLD, description), (description, False),
( (contains_plural, False),
ui.NORMAL, (", ".join(field.name for field in data_members), False),
contains_plural,
),
(ui.NORMAL, ", ".join(field.name for field in data_members)),
) )
return await should_show_more( return await should_show_more(
title, title,
@ -268,7 +265,7 @@ async def should_show_array(
# Leaving english plural form because of dynamic noun - data_type # Leaving english plural form because of dynamic noun - data_type
plural = format_plural_english("{count} {plural}", size, data_type) plural = format_plural_english("{count} {plural}", size, data_type)
array_of_plural = f"{TR.words__array_of} {plural}" array_of_plural = f"{TR.words__array_of} {plural}"
para = ((ui.NORMAL, array_of_plural),) para = ((array_of_plural, False),)
return await should_show_more( return await should_show_more(
limit_str(".".join(parent_objects)), limit_str(".".join(parent_objects)),
para, para,

View File

@ -177,17 +177,16 @@ async def confirm_unsupported_instruction_details(
signer_path: list[int], signer_path: list[int],
signer_public_key: bytes, signer_public_key: bytes,
) -> None: ) -> None:
from trezor.ui import NORMAL
from trezor.ui.layouts import confirm_properties, should_show_more from trezor.ui.layouts import confirm_properties, should_show_more
should_show_instruction_details = await should_show_more( should_show_instruction_details = await should_show_more(
title, title,
( (
( (
NORMAL,
TR.solana__instruction_accounts_template.format( TR.solana__instruction_accounts_template.format(
len(instruction.accounts), len(instruction.instruction_data) len(instruction.accounts), len(instruction.instruction_data)
), ),
False,
), ),
), ),
TR.buttons__show_details, TR.buttons__show_details,

View File

@ -38,10 +38,6 @@ if __debug__:
display = Display() display = Display()
# re-export constants from modtrezorui # re-export constants from modtrezorui
NORMAL: int = Display.FONT_NORMAL
DEMIBOLD: int = Display.FONT_DEMIBOLD
BOLD_UPPER: int = Display.FONT_BOLD_UPPER
MONO: int = Display.FONT_MONO
WIDTH: int = Display.WIDTH WIDTH: int = Display.WIDTH
HEIGHT: int = Display.HEIGHT HEIGHT: int = Display.HEIGHT

View File

@ -474,8 +474,8 @@ async def should_show_payment_request_details(
result = await interact( result = await interact(
trezorui_api.confirm_with_info( trezorui_api.confirm_with_info(
title=TR.send__title_sending, title=TR.send__title_sending,
items=[(ui.NORMAL, f"{amount} to\n{recipient_name}")] items=[(f"{amount} to\n{recipient_name}", False)]
+ [(ui.NORMAL, memo) for memo in memos], + [(memo, False) for memo in memos],
button=TR.buttons__confirm, button=TR.buttons__confirm,
info_button=TR.buttons__details, info_button=TR.buttons__details,
), ),
@ -493,7 +493,7 @@ async def should_show_payment_request_details(
async def should_show_more( async def should_show_more(
title: str, title: str,
para: Iterable[tuple[int, str | bytes]], para: Iterable[tuple[str | bytes, bool]],
button_text: str | None = None, button_text: str | None = None,
br_name: str = "should_show_more", br_name: str = "should_show_more",
br_code: ButtonRequestType = BR_CODE_OTHER, br_code: ButtonRequestType = BR_CODE_OTHER,
@ -544,12 +544,12 @@ async def _confirm_ask_pagination(
title=title, title=title,
button=TR.buttons__confirm, button=TR.buttons__confirm,
button_style_confirm=True, button_style_confirm=True,
items=[(ui.MONO, data)], items=[(data, True)],
) )
while True: while True:
if not await should_show_more( if not await should_show_more(
title, title,
para=[(ui.NORMAL, description), (ui.MONO, data)], para=[(description, False), (data, True)],
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
): ):

View File

@ -538,7 +538,7 @@ async def should_show_payment_request_details(
async def should_show_more( async def should_show_more(
title: str, title: str,
para: Iterable[tuple[int, str]], para: Iterable[tuple[str, bool]],
button_text: str | None = None, button_text: str | None = None,
br_name: str = "should_show_more", br_name: str = "should_show_more",
br_code: ButtonRequestType = BR_CODE_OTHER, br_code: ButtonRequestType = BR_CODE_OTHER,
@ -625,13 +625,13 @@ async def _confirm_ask_pagination(
confirm_more_layout = trezorui_api.confirm_more( confirm_more_layout = trezorui_api.confirm_more(
title=title, title=title,
button=TR.buttons__confirm, button=TR.buttons__confirm,
items=[(ui.NORMAL, description), (ui.MONO, data)], items=[(description, False), (data, True)],
) )
while True: while True:
if not await should_show_more( if not await should_show_more(
title, title,
para=[(ui.NORMAL, description), (ui.MONO, data)], para=[(description, False), (data, True)],
verb_cancel=None, verb_cancel=None,
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
@ -778,7 +778,7 @@ async def confirm_value(
result = await interact( result = await interact(
trezorui_api.confirm_with_info( trezorui_api.confirm_with_info(
title=title, title=title,
items=((ui.NORMAL, value),), items=((value, False),),
button=verb or TR.buttons__confirm, button=verb or TR.buttons__confirm,
info_button=TR.buttons__info, info_button=TR.buttons__info,
), ),

View File

@ -425,8 +425,8 @@ async def should_show_payment_request_details(
result = await interact( result = await interact(
trezorui_api.confirm_with_info( trezorui_api.confirm_with_info(
title=TR.send__title_sending, title=TR.send__title_sending,
items=[(ui.NORMAL, f"{amount} to\n{recipient_name}")] items=[(f"{amount} to\n{recipient_name}", False)]
+ [(ui.NORMAL, memo) for memo in memos], + [(memo, False) for memo in memos],
button=TR.buttons__confirm, button=TR.buttons__confirm,
info_button=TR.buttons__details, info_button=TR.buttons__details,
), ),
@ -444,7 +444,7 @@ async def should_show_payment_request_details(
async def should_show_more( async def should_show_more(
title: str, title: str,
para: Iterable[tuple[int, str | bytes]], para: Iterable[tuple[str | bytes, bool]],
button_text: str | None = None, button_text: str | None = None,
br_name: str = "should_show_more", br_name: str = "should_show_more",
br_code: ButtonRequestType = BR_CODE_OTHER, br_code: ButtonRequestType = BR_CODE_OTHER,