mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-03 12:00:59 +00:00
feat(core/ui): T3T1 mnemonic keyboard
These are initial changes to the mnemonic keyboard designs. The designs themselves from Figma are still WIP.
This commit is contained in:
parent
0566f0b7c3
commit
6486b03248
@ -196,7 +196,7 @@ impl Component for Bip39Input {
|
|||||||
let icon_center = area.top_right().center(area.bottom_right()) - Offset::new(16 + 8, 0);
|
let icon_center = area.top_right().center(area.bottom_right()) - Offset::new(16 + 8, 0);
|
||||||
shape::ToifImage::new(icon_center, icon.toif)
|
shape::ToifImage::new(icon_center, icon.toif)
|
||||||
.with_align(Alignment2D::CENTER)
|
.with_align(Alignment2D::CENTER)
|
||||||
.with_fg(style.text_color)
|
.with_fg(style.icon_color)
|
||||||
.render(target);
|
.render(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +227,8 @@ impl Bip39Input {
|
|||||||
|
|
||||||
// Styling the input to reflect already filled word
|
// Styling the input to reflect already filled word
|
||||||
Self {
|
Self {
|
||||||
button: Button::with_icon(theme::ICON_LIST_CHECK).styled(theme::button_pin_confirm()),
|
button: Button::with_icon(theme::ICON_CONFIRM_INPUT)
|
||||||
|
.styled(theme::button_pin_confirm()),
|
||||||
textbox: TextBox::new(unwrap!(String::try_from(word))),
|
textbox: TextBox::new(unwrap!(String::try_from(word))),
|
||||||
multi_tap: MultiTapKeyboard::new(),
|
multi_tap: MultiTapKeyboard::new(),
|
||||||
options_num: bip39::options_num(word),
|
options_num: bip39::options_num(word),
|
||||||
@ -293,7 +294,7 @@ impl Bip39Input {
|
|||||||
self.button.enable(ctx);
|
self.button.enable(ctx);
|
||||||
self.button.set_stylesheet(ctx, theme::button_pin_confirm());
|
self.button.set_stylesheet(ctx, theme::button_pin_confirm());
|
||||||
self.button
|
self.button
|
||||||
.set_content(ctx, ButtonContent::Icon(theme::ICON_LIST_CHECK));
|
.set_content(ctx, ButtonContent::Icon(theme::ICON_CONFIRM_INPUT));
|
||||||
self.button_suggestion
|
self.button_suggestion
|
||||||
.set_stylesheet(ctx, theme::button_suggestion_confirm());
|
.set_stylesheet(ctx, theme::button_suggestion_confirm());
|
||||||
} else {
|
} else {
|
||||||
@ -302,7 +303,7 @@ impl Bip39Input {
|
|||||||
self.button
|
self.button
|
||||||
.set_stylesheet(ctx, theme::button_pin_autocomplete());
|
.set_stylesheet(ctx, theme::button_pin_autocomplete());
|
||||||
self.button
|
self.button
|
||||||
.set_content(ctx, ButtonContent::Icon(theme::ICON_CLICK));
|
.set_content(ctx, ButtonContent::Icon(theme::ICON_AUTOFILL));
|
||||||
self.button_suggestion
|
self.button_suggestion
|
||||||
.set_stylesheet(ctx, theme::button_suggestion_autocomplete());
|
.set_stylesheet(ctx, theme::button_suggestion_autocomplete());
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
strutil::TString,
|
strutil::TString,
|
||||||
ui::{
|
ui::{
|
||||||
component::{maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe},
|
component::{maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe},
|
||||||
geometry::{Alignment2D, Grid, Offset, Rect},
|
geometry::{Alignment, Grid, Rect},
|
||||||
model_mercury::{
|
model_mercury::{
|
||||||
component::{Button, ButtonMsg, Swipe, SwipeDirection},
|
component::{Button, ButtonMsg, Swipe, SwipeDirection},
|
||||||
theme,
|
theme,
|
||||||
@ -44,23 +44,23 @@ where
|
|||||||
Self {
|
Self {
|
||||||
prompt: Child::new(Maybe::new(
|
prompt: Child::new(Maybe::new(
|
||||||
theme::BG,
|
theme::BG,
|
||||||
Label::centered(prompt, theme::label_keyboard_prompt()),
|
Label::centered(prompt, theme::TEXT_MAIN_GREY_LIGHT),
|
||||||
prompt_visible,
|
prompt_visible,
|
||||||
)),
|
)),
|
||||||
back: Child::new(Maybe::new(
|
back: Child::new(Maybe::new(
|
||||||
theme::BG,
|
theme::BG,
|
||||||
Button::with_icon_blend(
|
Button::with_icon(theme::ICON_DELETE)
|
||||||
theme::IMAGE_BG_BACK_BTN_TALL,
|
.styled(theme::button_default())
|
||||||
theme::ICON_BACK,
|
.with_long_press(theme::ERASE_HOLD_DURATION),
|
||||||
Offset::new(30, 17),
|
|
||||||
)
|
|
||||||
.styled(theme::button_reset())
|
|
||||||
.with_long_press(theme::ERASE_HOLD_DURATION),
|
|
||||||
!prompt_visible,
|
!prompt_visible,
|
||||||
)),
|
)),
|
||||||
input: Child::new(Maybe::new(theme::BG, input, !prompt_visible)),
|
input: Child::new(Maybe::new(theme::BG, input, !prompt_visible)),
|
||||||
keys: T::keys()
|
keys: T::keys()
|
||||||
.map(|t| Button::with_text(t.into()).styled(theme::button_pin()))
|
.map(|t| {
|
||||||
|
Button::with_text(t.into())
|
||||||
|
.styled(theme::button_pin())
|
||||||
|
.with_text_align(Alignment::Center)
|
||||||
|
})
|
||||||
.map(Child::new),
|
.map(Child::new),
|
||||||
swipe: Swipe::new().right(),
|
swipe: Swipe::new().right(),
|
||||||
can_go_back,
|
can_go_back,
|
||||||
@ -109,23 +109,27 @@ where
|
|||||||
type Msg = MnemonicKeyboardMsg;
|
type Msg = MnemonicKeyboardMsg;
|
||||||
|
|
||||||
fn place(&mut self, bounds: Rect) -> Rect {
|
fn place(&mut self, bounds: Rect) -> Rect {
|
||||||
let (_, bounds) = bounds
|
let height_input_area: i16 = 30;
|
||||||
.inset(theme::borders())
|
let space_top: i16 = 8;
|
||||||
.split_bottom(4 * theme::MNEMONIC_BUTTON_HEIGHT + 3 * theme::KEYBOARD_SPACING);
|
let (remaining, keyboard_area) =
|
||||||
let grid = Grid::new(bounds, 4, 3).with_spacing(theme::KEYBOARD_SPACING);
|
bounds.split_bottom(3 * theme::BUTTON_HEIGHT + 2 * theme::KEYBOARD_SPACING);
|
||||||
let back_area = grid.row_col(0, 0);
|
let prompt_area = remaining
|
||||||
let input_area = grid.row_col(0, 1).union(grid.row_col(0, 3));
|
.split_top(space_top)
|
||||||
|
.1
|
||||||
|
.split_top(height_input_area)
|
||||||
|
.0;
|
||||||
|
assert!(prompt_area.height() == height_input_area);
|
||||||
|
|
||||||
let prompt_center = grid.row_col(0, 0).union(grid.row_col(0, 3)).center();
|
let (back_btn_area, input_area) = prompt_area.split_left(30);
|
||||||
let prompt_size = self.prompt.inner().inner().max_size();
|
let keyboard_grid = Grid::new(keyboard_area, 3, 3).with_spacing(theme::KEYBOARD_SPACING);
|
||||||
let prompt_area = Rect::snap(prompt_center, prompt_size, Alignment2D::CENTER);
|
|
||||||
|
|
||||||
self.swipe.place(bounds);
|
self.swipe.place(bounds);
|
||||||
self.prompt.place(prompt_area);
|
self.prompt.place(prompt_area);
|
||||||
self.back.place(back_area);
|
self.back.place(back_btn_area);
|
||||||
self.input.place(input_area);
|
self.input.place(input_area);
|
||||||
|
|
||||||
for (key, btn) in self.keys.iter_mut().enumerate() {
|
for (key, btn) in self.keys.iter_mut().enumerate() {
|
||||||
btn.place(grid.cell(key + grid.cols)); // Start in the second row.
|
btn.place(keyboard_grid.cell(key));
|
||||||
}
|
}
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
@ -185,9 +189,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
self.prompt.render(target);
|
if self.input.inner().inner().is_empty() {
|
||||||
self.input.render(target);
|
self.prompt.render(target);
|
||||||
self.back.render(target);
|
} else {
|
||||||
|
self.input.render(target);
|
||||||
|
self.back.render(target);
|
||||||
|
}
|
||||||
|
|
||||||
for btn in &self.keys {
|
for btn in &self.keys {
|
||||||
btn.render(target);
|
btn.render(target);
|
||||||
|
@ -181,7 +181,7 @@ impl Component for Slip39Input {
|
|||||||
icon.draw(
|
icon.draw(
|
||||||
icon_center,
|
icon_center,
|
||||||
Alignment2D::CENTER,
|
Alignment2D::CENTER,
|
||||||
style.text_color,
|
style.icon_color,
|
||||||
style.button_color,
|
style.button_color,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ impl Component for Slip39Input {
|
|||||||
let icon_center = area.top_right().center(area.bottom_right()) - Offset::new(16 + 8, 0);
|
let icon_center = area.top_right().center(area.bottom_right()) - Offset::new(16 + 8, 0);
|
||||||
shape::ToifImage::new(icon_center, icon.toif)
|
shape::ToifImage::new(icon_center, icon.toif)
|
||||||
.with_align(Alignment2D::CENTER)
|
.with_align(Alignment2D::CENTER)
|
||||||
.with_fg(style.text_color)
|
.with_fg(style.icon_color)
|
||||||
.render(target);
|
.render(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -356,7 +356,7 @@ impl Slip39Input {
|
|||||||
// Confirm button.
|
// Confirm button.
|
||||||
self.button.enable(ctx);
|
self.button.enable(ctx);
|
||||||
self.button
|
self.button
|
||||||
.set_content(ctx, ButtonContent::Icon(theme::ICON_LIST_CHECK));
|
.set_content(ctx, ButtonContent::Icon(theme::ICON_CONFIRM_INPUT));
|
||||||
} else {
|
} else {
|
||||||
// Disabled button.
|
// Disabled button.
|
||||||
self.button.disable(ctx);
|
self.button.disable(ctx);
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 542 B After Width: | Height: | Size: 534 B |
Binary file not shown.
BIN
core/embed/rust/src/ui/model_mercury/res/confirm_input30.png
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/confirm_input30.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 526 B |
BIN
core/embed/rust/src/ui/model_mercury/res/confirm_input30.toif
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/confirm_input30.toif
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 389 B |
Binary file not shown.
@ -88,6 +88,7 @@ include_icon!(ICON_WARNING, "model_mercury/res/warning24.toif");
|
|||||||
// 30x30
|
// 30x30
|
||||||
include_icon!(ICON_AUTOFILL, "model_mercury/res/autofill30.toif");
|
include_icon!(ICON_AUTOFILL, "model_mercury/res/autofill30.toif");
|
||||||
include_icon!(ICON_CLOSE, "model_mercury/res/close30.toif");
|
include_icon!(ICON_CLOSE, "model_mercury/res/close30.toif");
|
||||||
|
include_icon!(ICON_CONFIRM_INPUT, "model_mercury/res/confirm_input30.toif");
|
||||||
include_icon!(ICON_DELETE, "model_mercury/res/delete30.toif");
|
include_icon!(ICON_DELETE, "model_mercury/res/delete30.toif");
|
||||||
include_icon!(ICON_MENU, "model_mercury/res/menu30.toif");
|
include_icon!(ICON_MENU, "model_mercury/res/menu30.toif");
|
||||||
include_icon!(
|
include_icon!(
|
||||||
@ -411,27 +412,29 @@ pub const fn button_pin() -> ButtonStyleSheet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: will button_pin_xyz styles be the same for PIN and Mnemonic keyboard?
|
||||||
|
// Wait for Figma
|
||||||
pub const fn button_pin_confirm() -> ButtonStyleSheet {
|
pub const fn button_pin_confirm() -> ButtonStyleSheet {
|
||||||
ButtonStyleSheet {
|
ButtonStyleSheet {
|
||||||
normal: &ButtonStyle {
|
normal: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: FG,
|
text_color: FG,
|
||||||
button_color: GREEN,
|
button_color: BG,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREEN_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
},
|
},
|
||||||
active: &ButtonStyle {
|
active: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: FG,
|
text_color: FG,
|
||||||
button_color: GREEN_DARK,
|
button_color: GREY_DARK,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREEN_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
},
|
},
|
||||||
disabled: &ButtonStyle {
|
disabled: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: GREY_LIGHT,
|
text_color: FG,
|
||||||
button_color: GREY_DARK,
|
button_color: BG,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREEN_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -442,20 +445,20 @@ pub const fn button_pin_autocomplete() -> ButtonStyleSheet {
|
|||||||
normal: &ButtonStyle {
|
normal: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: FG,
|
text_color: FG,
|
||||||
button_color: GREY_DARK, // same as PIN buttons
|
button_color: BG,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREY_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
},
|
},
|
||||||
active: &ButtonStyle {
|
active: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: FG,
|
text_color: FG,
|
||||||
button_color: GREEN_DARK,
|
button_color: BG,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREY_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
},
|
},
|
||||||
disabled: &ButtonStyle {
|
disabled: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: GREY_LIGHT,
|
text_color: FG,
|
||||||
button_color: BG,
|
button_color: BG,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREY_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
@ -467,7 +470,7 @@ pub const fn button_suggestion_confirm() -> ButtonStyleSheet {
|
|||||||
ButtonStyleSheet {
|
ButtonStyleSheet {
|
||||||
normal: &ButtonStyle {
|
normal: &ButtonStyle {
|
||||||
font: Font::MONO,
|
font: Font::MONO,
|
||||||
text_color: GREEN_DARK,
|
text_color: GREY_LIGHT,
|
||||||
button_color: GREEN,
|
button_color: GREEN,
|
||||||
icon_color: GREY_LIGHT,
|
icon_color: GREY_LIGHT,
|
||||||
background_color: BG,
|
background_color: BG,
|
||||||
|
Loading…
Reference in New Issue
Block a user