1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-10 15:30:55 +00:00

refactor(core/rust/ui): uPy buffer support for TT buttons

[no changelog]
This commit is contained in:
Martin Milata 2022-01-18 23:22:35 +01:00
parent f167a2bef2
commit 695d80bf54
5 changed files with 46 additions and 33 deletions

View File

@ -20,6 +20,12 @@ impl Trace for &[u8] {
}
}
impl<const N: usize> Trace for &[u8; N] {
fn trace(&self, t: &mut dyn Tracer) {
t.bytes(&self[..])
}
}
impl Trace for &str {
fn trace(&self, t: &mut dyn Tracer) {
t.string(self);

View File

@ -11,15 +11,15 @@ pub enum ButtonMsg {
Clicked,
}
pub struct Button {
pub struct Button<T> {
area: Rect,
content: ButtonContent,
content: ButtonContent<T>,
styles: ButtonStyleSheet,
state: State,
}
impl Button {
pub fn new(area: Rect, content: ButtonContent) -> Self {
impl<T> Button<T> {
pub fn new(area: Rect, content: ButtonContent<T>) -> Self {
Self {
area,
content,
@ -28,7 +28,7 @@ impl Button {
}
}
pub fn with_text(area: Rect, text: &'static [u8]) -> Self {
pub fn with_text(area: Rect, text: T) -> Self {
Self::new(area, ButtonContent::Text(text))
}
@ -68,7 +68,7 @@ impl Button {
matches!(self.state, State::Disabled)
}
pub fn content(&self) -> &ButtonContent {
pub fn content(&self) -> &ButtonContent<T> {
&self.content
}
@ -88,7 +88,10 @@ impl Button {
}
}
impl Component for Button {
impl<T> Component for Button<T>
where
T: AsRef<[u8]>,
{
type Msg = ButtonMsg;
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
@ -175,6 +178,7 @@ impl Component for Button {
match &self.content {
ButtonContent::Text(text) => {
let text = text.as_ref();
let width = display::text_width(text, style.font);
let height = style.font.text_height();
let start_of_baseline = self.area.center() + Offset::new(-width / 2, height / 2);
@ -199,11 +203,14 @@ impl Component for Button {
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for Button {
impl<T> crate::trace::Trace for Button<T>
where
T: AsRef<[u8]> + crate::trace::Trace,
{
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.open("Button");
match self.content {
ButtonContent::Text(text) => t.field("text", &text),
match &self.content {
ButtonContent::Text(text) => t.field("text", text),
ButtonContent::Icon(_) => t.symbol("icon"),
}
t.close();
@ -218,8 +225,8 @@ enum State {
Disabled,
}
pub enum ButtonContent {
Text(&'static [u8]),
pub enum ButtonContent<T> {
Text(T),
Icon(&'static [u8]),
}

View File

@ -17,8 +17,8 @@ pub enum HoldToConfirmMsg<T> {
pub struct HoldToConfirm<T> {
loader: Loader,
content: Child<T>,
cancel: Child<Button>,
confirm: Child<Button>,
cancel: Child<Button<&'static str>>,
confirm: Child<Button<&'static str>>,
pad: Pad,
}
@ -31,8 +31,8 @@ where
Self {
loader: Loader::new(0),
content: content(layout.content).into_child(),
cancel: Button::with_text(layout.left, b"Cancel").into_child(),
confirm: Button::with_text(layout.right, b"Hold").into_child(),
cancel: Button::with_text(layout.left, "Cancel").into_child(),
confirm: Button::with_text(layout.right, "Hold").into_child(),
pad: Pad::with_background(layout.content, theme::BG),
}
}

View File

@ -23,9 +23,9 @@ pub enum PassphraseKeyboardMsg {
pub struct PassphraseKeyboard {
page_swipe: Swipe,
textbox: Child<TextBox>,
back_btn: Child<Button>,
confirm_btn: Child<Button>,
key_btns: [[Child<Button>; KEYS]; PAGES],
back_btn: Child<Button<&'static str>>,
confirm_btn: Child<Button<&'static str>>,
key_btns: [[Child<Button<&'static [u8]>>; KEYS]; PAGES],
key_page: usize,
pending: Option<Pending>,
}
@ -60,10 +60,10 @@ impl PassphraseKeyboard {
let text = Vec::new();
let page_swipe = Swipe::horizontal(area);
let textbox = TextBox::new(textbox_area, text).into_child();
let confirm_btn = Button::with_text(confirm_btn_area, b"Confirm")
let confirm_btn = Button::with_text(confirm_btn_area, "Confirm")
.styled(theme::button_confirm())
.into_child();
let back_btn = Button::with_text(back_btn_area, b"Back")
let back_btn = Button::with_text(back_btn_area, "Back")
.styled(theme::button_clear())
.into_child();
let key_btns = Self::generate_keyboard(&key_grid);
@ -79,17 +79,17 @@ impl PassphraseKeyboard {
}
}
fn generate_keyboard(grid: &Grid) -> [[Child<Button>; KEYS]; PAGES] {
fn generate_keyboard(grid: &Grid) -> [[Child<Button<&'static [u8]>>; KEYS]; PAGES] {
// can't use a range because the result is a fixed-size array
[0, 1, 2, 3].map(|i| Self::generate_key_page(grid, i))
}
fn generate_key_page(grid: &Grid, page: usize) -> [Child<Button>; KEYS] {
fn generate_key_page(grid: &Grid, page: usize) -> [Child<Button<&'static [u8]>>; KEYS] {
// can't use a range because the result is a fixed-size array
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(|i| Self::generate_key(grid, page, i))
}
fn generate_key(grid: &Grid, page: usize, key: usize) -> Child<Button> {
fn generate_key(grid: &Grid, page: usize, key: usize) -> Child<Button<&'static [u8]>> {
// Assign the keys in each page to buttons on a 5x3 grid, starting from the
// second row.
let area = grid.cell(if key < 9 {

View File

@ -31,10 +31,10 @@ pub struct PinDialog {
major_prompt: Label<&'static [u8]>,
minor_prompt: Label<&'static [u8]>,
dots: Child<PinDots>,
reset_btn: Child<Button>,
cancel_btn: Child<Button>,
confirm_btn: Child<Button>,
digit_btns: [Child<Button>; DIGIT_COUNT],
reset_btn: Child<Button<&'static str>>,
cancel_btn: Child<Button<&'static str>>,
confirm_btn: Child<Button<&'static str>>,
digit_btns: [Child<Button<&'static str>>; DIGIT_COUNT],
}
impl PinDialog {
@ -63,7 +63,7 @@ impl PinDialog {
// Control buttons.
let grid = Grid::new(area, 5, 3);
let reset_btn = Button::with_text(grid.row_col(4, 0), b"Reset")
let reset_btn = Button::with_text(grid.row_col(4, 0), "Reset")
.styled(theme::button_clear())
.into_child();
let cancel_btn = Button::with_icon(grid.row_col(4, 0), theme::ICON_CANCEL)
@ -88,9 +88,9 @@ impl PinDialog {
}
}
fn generate_digit_buttons(grid: &Grid) -> [Child<Button>; DIGIT_COUNT] {
fn generate_digit_buttons(grid: &Grid) -> [Child<Button<&'static str>>; DIGIT_COUNT] {
// Generate a random sequence of digits from 0 to 9.
let mut digits = [b"0", b"1", b"2", b"3", b"4", b"5", b"6", b"7", b"8", b"9"];
let mut digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
random::shuffle(&mut digits);
// Assign the digits to buttons on a 5x3 grid, starting from the second row.
@ -102,7 +102,7 @@ impl PinDialog {
// For the last key (the "0" position) we skip one cell.
i + 1 + 3
});
let text: &[u8; 1] = digits[i];
let text = digits[i];
Child::new(Button::with_text(area, text))
};
[
@ -159,7 +159,7 @@ impl Component for PinDialog {
for btn in &mut self.digit_btns {
if let Some(Clicked) = btn.event(ctx, event) {
if let ButtonContent::Text(text) = btn.inner().content() {
if self.digits.extend_from_slice(text).is_err() {
if self.digits.extend_from_slice(text.as_ref()).is_err() {
// `self.pin` is full and wasn't able to accept all of
// `text`. Should not happen.
}