mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-24 07:28:34 +00:00
perf(core/eckhart): constructing MenuItems
- self-referential builder pattern is easier on the stack memory usage than consuming builder pattern - store ButtonStyleSheet as a static ref
This commit is contained in:
parent
bd89e13493
commit
d73f0dc79d
@ -70,26 +70,30 @@ pub enum DeviceMenuMsg {
|
||||
struct MenuItem {
|
||||
text: TString<'static>,
|
||||
subtext: Option<(TString<'static>, Option<TextStyle>)>,
|
||||
stylesheet: ButtonStyleSheet,
|
||||
stylesheet: &'static ButtonStyleSheet,
|
||||
action: Option<Action>,
|
||||
}
|
||||
const MENU_ITEM_TITLE_STYLE_SHEET: &ButtonStyleSheet = &theme::menu_item_title();
|
||||
|
||||
impl MenuItem {
|
||||
pub fn new(text: TString<'static>, action: Option<Action>) -> Self {
|
||||
Self {
|
||||
text,
|
||||
subtext: None,
|
||||
stylesheet: theme::menu_item_title(),
|
||||
stylesheet: MENU_ITEM_TITLE_STYLE_SHEET,
|
||||
action,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_subtext(mut self, subtext: Option<(TString<'static>, Option<TextStyle>)>) -> Self {
|
||||
pub fn with_subtext(
|
||||
&mut self,
|
||||
subtext: Option<(TString<'static>, Option<TextStyle>)>,
|
||||
) -> &mut Self {
|
||||
self.subtext = subtext;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_stylesheet(mut self, stylesheet: ButtonStyleSheet) -> Self {
|
||||
pub fn with_stylesheet(&mut self, stylesheet: &'static ButtonStyleSheet) -> &mut Self {
|
||||
self.stylesheet = stylesheet;
|
||||
self
|
||||
}
|
||||
@ -221,12 +225,13 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
) -> usize {
|
||||
let mut items: Vec<MenuItem, SHORT_MENU_ITEMS> = Vec::new();
|
||||
for (device, idx) in paired_devices.iter().zip(paired_device_indices) {
|
||||
unwrap!(items.push(
|
||||
MenuItem::new(*device, Some(Action::GoTo(idx))).with_subtext(Some((
|
||||
"Connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN)
|
||||
))) // TODO: this should be a boolean feature of the device
|
||||
));
|
||||
let mut item_device = MenuItem::new(*device, Some(Action::GoTo(idx)));
|
||||
// TODO: this should be a boolean feature of the device
|
||||
item_device.with_subtext(Some((
|
||||
"Connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN),
|
||||
)));
|
||||
unwrap!(items.push(item_device));
|
||||
}
|
||||
|
||||
let submenu_index = self.add_submenu(Submenu::new("Manage paired devices".into(), items));
|
||||
@ -235,16 +240,15 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
|
||||
fn add_pair_and_connect_menu(&mut self, manage_devices_index: usize) -> usize {
|
||||
let mut items: Vec<MenuItem, SHORT_MENU_ITEMS> = Vec::new();
|
||||
unwrap!(items.push(
|
||||
MenuItem::new(
|
||||
"Manage paired devices".into(),
|
||||
Some(Action::GoTo(manage_devices_index)),
|
||||
)
|
||||
.with_subtext(Some((
|
||||
"1 device connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN)
|
||||
)))
|
||||
));
|
||||
let mut manage_paired_item = MenuItem::new(
|
||||
"Manage paired devices".into(),
|
||||
Some(Action::GoTo(manage_devices_index)),
|
||||
);
|
||||
manage_paired_item.with_subtext(Some((
|
||||
"1 device connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN),
|
||||
)));
|
||||
unwrap!(items.push(manage_paired_item));
|
||||
unwrap!(items.push(MenuItem::new(
|
||||
"Pair new device".into(),
|
||||
Some(Action::Return(DeviceMenuMsg::DevicePair)),
|
||||
@ -291,22 +295,21 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
auto_lock_delay: TString<'static>,
|
||||
) -> usize {
|
||||
let mut items: Vec<MenuItem, SHORT_MENU_ITEMS> = Vec::new();
|
||||
unwrap!(
|
||||
items.push(MenuItem::new("Name".into(), None).with_subtext(Some((device_name, None))))
|
||||
);
|
||||
let mut item_device_name = MenuItem::new("Name".into(), None);
|
||||
item_device_name.with_subtext(Some((device_name, None)));
|
||||
unwrap!(items.push(item_device_name));
|
||||
unwrap!(items.push(MenuItem::new(
|
||||
"Screen brightness".into(),
|
||||
Some(Action::Return(DeviceMenuMsg::ScreenBrightness)),
|
||||
)));
|
||||
|
||||
if has_pin() {
|
||||
unwrap!(items.push(
|
||||
MenuItem::new(
|
||||
"Auto-lock delay".into(),
|
||||
Some(Action::Return(DeviceMenuMsg::AutoLockDelay)),
|
||||
)
|
||||
.with_subtext(Some((auto_lock_delay, None)))
|
||||
));
|
||||
let mut autolock_delay_item = MenuItem::new(
|
||||
"Auto-lock delay".into(),
|
||||
Some(Action::Return(DeviceMenuMsg::AutoLockDelay)),
|
||||
);
|
||||
autolock_delay_item.with_subtext(Some((auto_lock_delay, None)));
|
||||
unwrap!(items.push(autolock_delay_item));
|
||||
}
|
||||
|
||||
unwrap!(items.push(MenuItem::new(
|
||||
@ -326,25 +329,23 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
) -> usize {
|
||||
let mut items: Vec<MenuItem, SHORT_MENU_ITEMS> = Vec::new();
|
||||
if failed_backup {
|
||||
unwrap!(items.push(
|
||||
MenuItem::new(
|
||||
"Backup failed".into(),
|
||||
Some(Action::Return(DeviceMenuMsg::BackupFailed)),
|
||||
)
|
||||
.with_subtext(Some(("Review".into(), None)))
|
||||
.with_stylesheet(theme::menu_item_title_red()),
|
||||
));
|
||||
let mut item_backup_failed = MenuItem::new(
|
||||
"Backup failed".into(),
|
||||
Some(Action::Return(DeviceMenuMsg::BackupFailed)),
|
||||
);
|
||||
item_backup_failed.with_subtext(Some(("Review".into(), None)));
|
||||
item_backup_failed.with_stylesheet(MENU_ITEM_TITLE_STYLE_SHEET);
|
||||
unwrap!(items.push(item_backup_failed));
|
||||
}
|
||||
unwrap!(items.push(
|
||||
MenuItem::new(
|
||||
"Pair & connect".into(),
|
||||
Some(Action::GoTo(pair_and_connect_index)),
|
||||
)
|
||||
.with_subtext(Some((
|
||||
"1 device connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN)
|
||||
)))
|
||||
));
|
||||
let mut item_pair_and_connect = MenuItem::new(
|
||||
"Pair & connect".into(),
|
||||
Some(Action::GoTo(pair_and_connect_index)),
|
||||
);
|
||||
item_pair_and_connect.with_subtext(Some((
|
||||
"1 device connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN),
|
||||
)));
|
||||
unwrap!(items.push(item_pair_and_connect));
|
||||
unwrap!(items.push(MenuItem::new(
|
||||
"Settings".into(),
|
||||
Some(Action::GoTo(settings_index)),
|
||||
@ -379,12 +380,12 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
let button = if let Some((subtext, subtext_style)) = item.subtext {
|
||||
Button::new_menu_item_with_subtext(
|
||||
item.text,
|
||||
item.stylesheet,
|
||||
*item.stylesheet,
|
||||
subtext,
|
||||
subtext_style,
|
||||
)
|
||||
} else {
|
||||
Button::new_menu_item(item.text, item.stylesheet)
|
||||
Button::new_menu_item(item.text, *item.stylesheet)
|
||||
};
|
||||
menu.item(button);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user