1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-26 03:59:08 +00:00

refactor(core): cleanup layout.rs

- last functions of all models moved out
- imports formatted
- tests moved

[no changelog]
This commit is contained in:
obrusvit 2024-12-04 17:43:17 +01:00 committed by Vít Obrusník
parent dd9ac038d0
commit ad9618c282
4 changed files with 100 additions and 230 deletions

View File

@ -1,64 +1,25 @@
use core::{cmp::Ordering, convert::TryInto}; use core::convert::TryInto;
use heapless::Vec;
use super::{ use super::component::{
component::{ AddressDetails, CoinJoinProgress, Frame, FrameMsg, Homescreen, HomescreenMsg, Lockscreen,
AddressDetails, Bip39Input, CoinJoinProgress, Frame, FrameMsg, Homescreen, HomescreenMsg, MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress,
Lockscreen, MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg, PinKeyboard, PromptScreen, SelectWordCount, SelectWordCountMsg, StatusScreen, SwipeUpScreen,
PinKeyboardMsg, Progress, PromptScreen, SelectWordCount, SelectWordCountMsg, Slip39Input, SwipeUpScreenMsg, VerticalMenu, VerticalMenuChoiceMsg,
StatusScreen, SwipeUpScreen, SwipeUpScreenMsg, VerticalMenu, VerticalMenuChoiceMsg,
},
flow::{self},
theme,
}; };
use crate::{ use crate::{
error::{value_error, Error}, error::Error,
io::BinaryData, micropython::{macros::obj_module, module::Module, obj::Obj, qstr::Qstr},
micropython::{
iter::IterBuf,
macros::{obj_fn_0, obj_fn_1, obj_fn_kw, obj_module},
map::Map,
module::Module,
obj::Obj,
qstr::Qstr,
util,
},
strutil::TString,
translations::TR,
trezorhal::model,
ui::{ ui::{
backlight::BACKLIGHT_LEVELS_OBJ,
component::{ component::{
base::ComponentExt, text::paragraphs::{ParagraphSource, Paragraphs},
connect::Connect, Component, Never, Timeout,
swipe_detect::SwipeSettings,
text::{
op::OpTextLayout,
paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
Border, CachedJpeg, Component, FormattedText, Never, Timeout,
}, },
flow::Swipable, flow::Swipable,
geometry::{self, Direction},
layout::{ layout::{
base::LAYOUT_STATE, obj::ComponentMsgObj,
obj::{ComponentMsgObj, LayoutObj, ATTACH_TYPE_OBJ}, result::{CANCELLED, CONFIRMED},
result::{CANCELLED, CONFIRMED, INFO},
util::{upy_disable_animation, PropsList, RecoveryType},
},
model_mercury::{
component::{check_homescreen_format, SwipeContent},
flow::{
new_confirm_action_simple,
util::{ConfirmBlobParams, ShowInfoParams},
ConfirmActionExtra, ConfirmActionMenuStrings, ConfirmActionStrings,
},
theme::ICON_BULLET_CHECKMARK,
}, },
model_mercury::component::SwipeContent,
}, },
}; };

View File

@ -1,55 +1,23 @@
use core::{cmp::Ordering, convert::TryInto}; use core::convert::TryInto;
use heapless::Vec; use super::component::{
AddressDetails, ButtonPage, CancelConfirmMsg, CancelInfoConfirmMsg, CoinJoinProgress,
use super::{ ConfirmHomescreen, Flow, Frame, Homescreen, Lockscreen, NumberInput, Page, PassphraseEntry,
component::{ PinEntry, Progress, ScrollableContent, ScrollableFrame, ShowMore, SimpleChoice, WordlistEntry,
AddressDetails, ButtonActions, ButtonDetails, ButtonLayout, ButtonPage, CancelConfirmMsg,
CancelInfoConfirmMsg, CoinJoinProgress, ConfirmHomescreen, Flow, FlowPages, Frame,
Homescreen, Lockscreen, NumberInput, Page, PassphraseEntry, PinEntry, Progress,
ScrollableContent, ScrollableFrame, ShareWords, ShowMore, SimpleChoice, WordlistEntry,
WordlistType,
},
constant, theme,
}; };
use crate::{ use crate::{
error::Error, error::Error,
maybe_trace::MaybeTrace, micropython::{macros::obj_module, map::Map, module::Module, obj::Obj, qstr::Qstr},
micropython::{
gc::Gc,
iter::IterBuf,
list::List,
macros::{obj_fn_0, obj_fn_1, obj_fn_kw, obj_module},
map::Map,
module::Module,
obj::Obj,
qstr::Qstr,
util,
},
strutil::TString,
translations::TR,
trezorhal::model,
ui::{ ui::{
component::{ component::{
base::Component, base::Component,
connect::Connect,
paginated::{PageMsg, Paginate}, paginated::{PageMsg, Paginate},
text::{ text::paragraphs::{ParagraphSource, Paragraphs},
op::OpTextLayout, Never, Timeout,
paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
ComponentExt, FormattedText, Label, LineBreaking, Never, Timeout,
}, },
display::Font,
geometry,
layout::{ layout::{
obj::{ComponentMsgObj, LayoutObj}, obj::ComponentMsgObj,
result::{CANCELLED, CONFIRMED, INFO}, result::{CANCELLED, CONFIRMED, INFO},
util::{ConfirmBlob, RecoveryType},
}, },
}, },
}; };
@ -233,43 +201,6 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
} }
} }
/// Function to create and call a `ButtonPage` dialog based on paginable content
/// (e.g. `Paragraphs` or `FormattedText`).
/// Has optional title (supply empty `TString` for that) and hold-to-confirm
/// functionality.
fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
title: TString<'static>,
content: T,
verb: TString<'static>,
verb_cancel: Option<TString<'static>>,
hold: bool,
) -> Result<Obj, Error> {
// Left button - icon, text or nothing.
let cancel_btn = verb_cancel.map(ButtonDetails::from_text_possible_icon);
// Right button - text or nothing.
// Optional HoldToConfirm
let mut confirm_btn = if !verb.is_empty() {
Some(ButtonDetails::text(verb))
} else {
None
};
if hold {
confirm_btn = confirm_btn.map(|btn| btn.with_default_duration());
}
let content = ButtonPage::new(content, theme::BG)
.with_cancel_btn(cancel_btn)
.with_confirm_btn(confirm_btn);
let mut frame = ScrollableFrame::new(content);
if !title.is_empty() {
frame = frame.with_title(title);
}
let obj = LayoutObj::new(frame)?;
Ok(obj.into())
}
#[no_mangle] #[no_mangle]
pub static mp_module_trezorui2: Module = obj_module! { pub static mp_module_trezorui2: Module = obj_module! {
/// from trezor import utils /// from trezor import utils

View File

@ -1,59 +1,27 @@
use core::{cmp::Ordering, convert::TryInto}; use core::convert::TryInto;
use super::{ use super::component::{
component::{ AddressDetails, ButtonPage, CancelConfirmMsg, CancelInfoConfirmMsg, CoinJoinProgress, Dialog,
AddressDetails, Bip39Input, Button, ButtonMsg, ButtonPage, ButtonStyleSheet, DialogMsg, FidoConfirm, FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog,
CancelConfirmMsg, CancelInfoConfirmMsg, CoinJoinProgress, Dialog, DialogMsg, FidoConfirm, Lockscreen, MnemonicInput, MnemonicKeyboard, MnemonicKeyboardMsg, NumberInputDialog,
FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog, Lockscreen, MnemonicInput, NumberInputDialogMsg, PassphraseKeyboard, PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg,
MnemonicKeyboard, MnemonicKeyboardMsg, NumberInputDialog, NumberInputDialogMsg, Progress, SelectWordCountMsg, SelectWordMsg, SetBrightnessDialog, SimplePage,
PassphraseKeyboard, PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress,
SelectWordCount, SelectWordCountMsg, SelectWordMsg, SetBrightnessDialog, SimplePage,
Slip39Input,
},
theme,
}; };
use crate::{ use crate::{
error::{value_error, Error}, error::Error,
io::BinaryData, micropython::{macros::obj_module, map::Map, module::Module, obj::Obj, qstr::Qstr, util},
micropython::{
gc::Gc,
iter::IterBuf,
list::List,
macros::{obj_fn_1, obj_fn_kw, obj_module},
map::Map,
module::Module,
obj::Obj,
qstr::Qstr,
util,
},
strutil::TString, strutil::TString,
translations::TR,
trezorhal::model,
ui::{ ui::{
component::{ component::{
base::ComponentExt,
connect::Connect,
image::BlendedImage,
jpeg::Jpeg,
paginated::{PageMsg, Paginate}, paginated::{PageMsg, Paginate},
placed::GridPlaced, placed::GridPlaced,
text::{ text::paragraphs::{ParagraphSource, Paragraphs},
op::OpTextLayout, Component, FormattedText, Never, Timeout,
paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
Border, Component, Empty, FormattedText, Label, Never, Timeout,
}, },
geometry,
layout::{ layout::{
obj::{ComponentMsgObj, LayoutObj}, obj::ComponentMsgObj,
result::{CANCELLED, CONFIRMED, INFO}, result::{CANCELLED, CONFIRMED, INFO},
util::{ConfirmBlob, PropsList, RecoveryType},
}, },
model_tt::component::check_homescreen_format,
}, },
}; };
@ -317,59 +285,10 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
} }
} }
#[no_mangle]
#[cfg(test)] pub static mp_module_trezorui2: Module = obj_module! {
mod tests { /// from trezor import utils
use serde_json; /// from trezorui_api import *
///
use crate::{ Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
trace::tests::trace, };
ui::{component::text::op::OpTextLayout, geometry::Rect, model_tt::constant},
};
use super::*;
const SCREEN: Rect = constant::screen().inset(theme::borders());
#[test]
fn trace_example_layout() {
let buttons = Button::cancel_confirm(
Button::with_text("Left".into()),
Button::with_text("Right".into()),
false,
);
let ops = OpTextLayout::new(theme::TEXT_NORMAL)
.text_normal("Testing text layout, with some text, and some more text. And ")
.text_bold_upper("parameters!");
let formatted = FormattedText::new(ops);
let mut layout = Dialog::new(formatted, buttons);
layout.place(SCREEN);
let expected = serde_json::json!({
"component": "Dialog",
"content": {
"component": "FormattedText",
"text": ["Testing text layout, with", "\n", "some text, and some", "\n",
"more text. And ", "parame", "-", "\n", "ters!"],
"fits": true,
},
"controls": {
"component": "FixedHeightBar",
"inner": {
"component": "Split",
"first": {
"component": "Button",
"text": "Left",
},
"second": {
"component": "Button",
"text": "Right",
},
},
},
});
assert_eq!(trace(&layout), expected);
}
}

View File

@ -1348,3 +1348,62 @@ impl ConfirmBlobParams {
LayoutObj::new(frame) LayoutObj::new(frame)
} }
} }
#[cfg(test)]
mod tests {
use serde_json;
use crate::{
trace::tests::trace,
ui::{
component::text::op::OpTextLayout, component::Component, geometry::Rect,
model_tt::constant,
},
};
use super::*;
const SCREEN: Rect = constant::screen().inset(theme::borders());
#[test]
fn trace_example_layout() {
let buttons = Button::cancel_confirm(
Button::with_text("Left".into()),
Button::with_text("Right".into()),
false,
);
let ops = OpTextLayout::new(theme::TEXT_NORMAL)
.text_normal("Testing text layout, with some text, and some more text. And ")
.text_bold_upper("parameters!");
let formatted = FormattedText::new(ops);
let mut layout = Dialog::new(formatted, buttons);
layout.place(SCREEN);
let expected = serde_json::json!({
"component": "Dialog",
"content": {
"component": "FormattedText",
"text": ["Testing text layout, with", "\n", "some text, and some", "\n",
"more text. And ", "parame", "-", "\n", "ters!"],
"fits": true,
},
"controls": {
"component": "FixedHeightBar",
"inner": {
"component": "Split",
"first": {
"component": "Button",
"text": "Left",
},
"second": {
"component": "Button",
"text": "Right",
},
},
},
});
assert_eq!(trace(&layout), expected);
}
}