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:
parent
f167a2bef2
commit
695d80bf54
@ -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);
|
||||
|
@ -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]),
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user