mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
feat(core): lockscreen for mercury_ui
[no changelog]
This commit is contained in:
parent
14c81f6860
commit
0993ca0434
@ -7,8 +7,8 @@ use crate::{
|
|||||||
translations::TR,
|
translations::TR,
|
||||||
trezorhal::usb::usb_configured,
|
trezorhal::usb::usb_configured,
|
||||||
ui::{
|
ui::{
|
||||||
component::{Component, Event, EventCtx, Pad, TimerToken},
|
component::{Component, Event, EventCtx, TimerToken},
|
||||||
display::{self, tjpgd::jpeg_info, toif::Icon, Color, Font},
|
display::{tjpgd::jpeg_info, toif::Icon, Color, Font},
|
||||||
event::{TouchEvent, USBEvent},
|
event::{TouchEvent, USBEvent},
|
||||||
geometry::{Alignment, Alignment2D, Insets, Offset, Point, Rect},
|
geometry::{Alignment, Alignment2D, Insets, Offset, Point, Rect},
|
||||||
layout::util::get_user_custom_image,
|
layout::util::get_user_custom_image,
|
||||||
@ -20,13 +20,16 @@ use crate::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
trezorhal::{buffers::BufferJpegWork, uzlib::UZLIB_WINDOW_SIZE},
|
trezorhal::{buffers::BufferJpegWork, uzlib::UZLIB_WINDOW_SIZE},
|
||||||
ui::{
|
ui::{
|
||||||
constant::HEIGHT,
|
constant::{screen, HEIGHT},
|
||||||
display::{
|
display::{
|
||||||
tjpgd::BufferInput,
|
tjpgd::BufferInput,
|
||||||
toif::{Toif, ToifFormat},
|
toif::{Toif, ToifFormat},
|
||||||
},
|
},
|
||||||
model_mercury::component::homescreen::render::{
|
model_mercury::{
|
||||||
HomescreenJpeg, HomescreenToif, HOMESCREEN_TOIF_SIZE,
|
component::homescreen::render::{HomescreenJpeg, HomescreenToif, HOMESCREEN_TOIF_SIZE},
|
||||||
|
theme::{
|
||||||
|
GREEN_LIGHT, GREY_LIGHT, ICON_CENTRAL_CIRCLE, ICON_KEY, ICON_LOCKSCREEN_FILTER,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -54,8 +57,6 @@ pub struct Homescreen {
|
|||||||
custom_image: Option<Gc<[u8]>>,
|
custom_image: Option<Gc<[u8]>>,
|
||||||
hold_to_lock: bool,
|
hold_to_lock: bool,
|
||||||
loader: Loader,
|
loader: Loader,
|
||||||
pad: Pad,
|
|
||||||
paint_notification_only: bool,
|
|
||||||
delay: Option<TimerToken>,
|
delay: Option<TimerToken>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +76,6 @@ impl Homescreen {
|
|||||||
custom_image: get_user_custom_image().ok(),
|
custom_image: get_user_custom_image().ok(),
|
||||||
hold_to_lock,
|
hold_to_lock,
|
||||||
loader: Loader::with_lock_icon().with_durations(LOADER_DURATION, LOADER_DURATION / 3),
|
loader: Loader::with_lock_icon().with_durations(LOADER_DURATION, LOADER_DURATION / 3),
|
||||||
pad: Pad::with_background(theme::BG),
|
|
||||||
paint_notification_only: false,
|
|
||||||
delay: None,
|
delay: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,13 +132,8 @@ impl Homescreen {
|
|||||||
self.loader.render(target)
|
self.loader.render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_paint_notification(&mut self) {
|
|
||||||
self.paint_notification_only = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn event_usb(&mut self, ctx: &mut EventCtx, event: Event) {
|
fn event_usb(&mut self, ctx: &mut EventCtx, event: Event) {
|
||||||
if let Event::USB(USBEvent::Connected(_)) = event {
|
if let Event::USB(USBEvent::Connected(_)) = event {
|
||||||
self.paint_notification_only = true;
|
|
||||||
ctx.request_paint();
|
ctx.request_paint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,8 +159,6 @@ impl Homescreen {
|
|||||||
}
|
}
|
||||||
Event::Timer(token) if Some(token) == self.delay => {
|
Event::Timer(token) if Some(token) == self.delay => {
|
||||||
self.delay = None;
|
self.delay = None;
|
||||||
self.pad.clear();
|
|
||||||
self.paint_notification_only = false;
|
|
||||||
self.loader.start_growing(ctx, Instant::now());
|
self.loader.start_growing(ctx, Instant::now());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -178,8 +170,6 @@ impl Homescreen {
|
|||||||
}
|
}
|
||||||
Some(LoaderMsg::ShrunkCompletely) => {
|
Some(LoaderMsg::ShrunkCompletely) => {
|
||||||
self.loader.reset();
|
self.loader.reset();
|
||||||
self.pad.clear();
|
|
||||||
self.paint_notification_only = false;
|
|
||||||
ctx.request_paint()
|
ctx.request_paint()
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
@ -193,7 +183,6 @@ impl Component for Homescreen {
|
|||||||
type Msg = HomescreenMsg;
|
type Msg = HomescreenMsg;
|
||||||
|
|
||||||
fn place(&mut self, bounds: Rect) -> Rect {
|
fn place(&mut self, bounds: Rect) -> Rect {
|
||||||
self.pad.place(AREA);
|
|
||||||
self.loader.place(AREA.translate(LOADER_OFFSET));
|
self.loader.place(AREA.translate(LOADER_OFFSET));
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
@ -268,7 +257,6 @@ impl Component for Homescreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
self.pad.render(target);
|
|
||||||
if self.loader.is_animating() || self.loader.is_completely_grown(Instant::now()) {
|
if self.loader.is_animating() || self.loader.is_completely_grown(Instant::now()) {
|
||||||
self.render_loader(target);
|
self.render_loader(target);
|
||||||
} else {
|
} else {
|
||||||
@ -278,7 +266,7 @@ impl Component for Homescreen {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if is_image_jpeg(img_data) {
|
if is_image_jpeg(img_data) {
|
||||||
shape::JpegImage::new(self.pad.area.center(), img_data)
|
shape::JpegImage::new(AREA.center(), img_data)
|
||||||
.with_align(Alignment2D::CENTER)
|
.with_align(Alignment2D::CENTER)
|
||||||
.render(target);
|
.render(target);
|
||||||
} else if is_image_toif(img_data) {
|
} else if is_image_toif(img_data) {
|
||||||
@ -296,7 +284,7 @@ impl Component for Homescreen {
|
|||||||
.render(target);
|
.render(target);
|
||||||
|
|
||||||
let style = theme::TEXT_DEMIBOLD;
|
let style = theme::TEXT_DEMIBOLD;
|
||||||
let pos = Point::new(self.pad.area.center().x, LABEL_Y);
|
let pos = Point::new(AREA.center().x, LABEL_Y);
|
||||||
shape::Text::new(pos, t)
|
shape::Text::new(pos, t)
|
||||||
.with_align(Alignment::Center)
|
.with_align(Alignment::Center)
|
||||||
.with_font(style.text_font)
|
.with_font(style.text_font)
|
||||||
@ -309,9 +297,7 @@ impl Component for Homescreen {
|
|||||||
const NOTIFICATION_BORDER: i16 = 6;
|
const NOTIFICATION_BORDER: i16 = 6;
|
||||||
const TEXT_ICON_SPACE: i16 = 8;
|
const TEXT_ICON_SPACE: i16 = 8;
|
||||||
|
|
||||||
let banner = self
|
let banner = AREA
|
||||||
.pad
|
|
||||||
.area
|
|
||||||
.inset(Insets::sides(NOTIFICATION_BORDER))
|
.inset(Insets::sides(NOTIFICATION_BORDER))
|
||||||
.with_height(NOTIFICATION_HEIGHT)
|
.with_height(NOTIFICATION_HEIGHT)
|
||||||
.translate(Offset::y(NOTIFICATION_BORDER));
|
.translate(Offset::y(NOTIFICATION_BORDER));
|
||||||
@ -350,7 +336,7 @@ impl Component for Homescreen {
|
|||||||
#[cfg(feature = "ui_bounds")]
|
#[cfg(feature = "ui_bounds")]
|
||||||
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
|
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
|
||||||
self.loader.bounds(sink);
|
self.loader.bounds(sink);
|
||||||
sink(self.pad.area);
|
sink(AREA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,15 +463,25 @@ impl Component for Lockscreen<'_> {
|
|||||||
shape::JpegImage::new(center, img_data)
|
shape::JpegImage::new(center, img_data)
|
||||||
.with_align(Alignment2D::CENTER)
|
.with_align(Alignment2D::CENTER)
|
||||||
.with_blur(4)
|
.with_blur(4)
|
||||||
.with_dim(140)
|
.with_dim(102)
|
||||||
.render(target);
|
|
||||||
} else if is_image_toif(img_data) {
|
|
||||||
shape::ToifImage::new(center, unwrap!(Toif::new(img_data)))
|
|
||||||
.with_align(Alignment2D::CENTER)
|
|
||||||
//.with_blur(5)
|
|
||||||
.render(target);
|
.render(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shape::ToifImage::new(center, ICON_LOCKSCREEN_FILTER.toif)
|
||||||
|
.with_align(Alignment2D::CENTER)
|
||||||
|
.with_fg(Color::black())
|
||||||
|
.render(target);
|
||||||
|
|
||||||
|
shape::ToifImage::new(center + Offset::y(12), ICON_CENTRAL_CIRCLE.toif)
|
||||||
|
.with_align(Alignment2D::CENTER)
|
||||||
|
.with_fg(GREEN_LIGHT)
|
||||||
|
.render(target);
|
||||||
|
|
||||||
|
shape::ToifImage::new(center + Offset::y(12), ICON_KEY.toif)
|
||||||
|
.with_align(Alignment2D::CENTER)
|
||||||
|
.with_fg(GREY_LIGHT)
|
||||||
|
.render(target);
|
||||||
|
|
||||||
let (locked, tap) = if self.bootscreen {
|
let (locked, tap) = if self.bootscreen {
|
||||||
(
|
(
|
||||||
TR::lockscreen__title_not_connected,
|
TR::lockscreen__title_not_connected,
|
||||||
@ -498,69 +494,49 @@ impl Component for Lockscreen<'_> {
|
|||||||
let mut label_style = theme::TEXT_DEMIBOLD;
|
let mut label_style = theme::TEXT_DEMIBOLD;
|
||||||
label_style.text_color = theme::GREY_LIGHT;
|
label_style.text_color = theme::GREY_LIGHT;
|
||||||
|
|
||||||
let mut texts: &[HomescreenText] = &[
|
let mut offset = 0;
|
||||||
HomescreenText {
|
|
||||||
text: "".into(),
|
|
||||||
style: theme::TEXT_NORMAL,
|
|
||||||
offset: Offset::new(2, COINJOIN_Y),
|
|
||||||
icon: Some(theme::ICON_COINJOIN),
|
|
||||||
},
|
|
||||||
HomescreenText {
|
|
||||||
text: locked.into(),
|
|
||||||
style: theme::TEXT_BOLD,
|
|
||||||
offset: Offset::y(LOCKED_Y),
|
|
||||||
icon: Some(theme::ICON_LOCK),
|
|
||||||
},
|
|
||||||
HomescreenText {
|
|
||||||
text: tap.into(),
|
|
||||||
style: theme::TEXT_NORMAL,
|
|
||||||
offset: Offset::y(TAP_Y),
|
|
||||||
icon: None,
|
|
||||||
},
|
|
||||||
HomescreenText {
|
|
||||||
text: self.label,
|
|
||||||
style: label_style,
|
|
||||||
offset: Offset::y(LABEL_Y),
|
|
||||||
icon: None,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if !self.coinjoin_authorized {
|
self.label.map(|t| {
|
||||||
texts = &texts[1..];
|
offset = theme::TEXT_DEMIBOLD.text_font.visible_text_height(t);
|
||||||
}
|
|
||||||
|
|
||||||
for item in texts.iter() {
|
let text_pos = Point::new(0, offset);
|
||||||
item.text.map(|t| {
|
|
||||||
const TEXT_ICON_SPACE: i16 = 2;
|
|
||||||
|
|
||||||
let icon_width = match item.icon {
|
shape::Text::new(text_pos, t)
|
||||||
Some(icon) => icon.toif.width() + TEXT_ICON_SPACE,
|
.with_font(theme::TEXT_DEMIBOLD.text_font)
|
||||||
None => 0,
|
.with_fg(theme::GREY_LIGHT)
|
||||||
};
|
.render(target);
|
||||||
|
});
|
||||||
|
|
||||||
let area = constant::screen();
|
offset += 6;
|
||||||
|
|
||||||
let text_pos = Point::new(
|
locked.map_translated(|t| {
|
||||||
item.style
|
offset += theme::TEXT_SUB_GREY.text_font.visible_text_height(t);
|
||||||
.text_font
|
|
||||||
.horz_center(area.x0 + icon_width, area.x1, t),
|
|
||||||
0,
|
|
||||||
) + item.offset;
|
|
||||||
|
|
||||||
shape::Text::new(text_pos, t)
|
let text_pos = Point::new(0, offset);
|
||||||
.with_font(item.style.text_font)
|
|
||||||
.with_fg(item.style.text_color)
|
|
||||||
.render(target);
|
|
||||||
|
|
||||||
if let Some(icon) = item.icon {
|
shape::Text::new(text_pos, t)
|
||||||
let icon_pos = Point::new(text_pos.x - icon_width, text_pos.y);
|
.with_font(theme::TEXT_SUB_GREY.text_font)
|
||||||
shape::ToifImage::new(icon_pos, icon.toif)
|
.with_fg(theme::TEXT_SUB_GREY.text_color)
|
||||||
.with_align(Alignment2D::BOTTOM_LEFT)
|
.render(target);
|
||||||
.with_fg(item.style.text_color)
|
});
|
||||||
.render(target);
|
|
||||||
}
|
tap.map_translated(|t| {
|
||||||
});
|
offset = theme::TEXT_SUB_GREY.text_font.text_baseline();
|
||||||
}
|
|
||||||
|
let text_pos = Point::new(
|
||||||
|
theme::TEXT_SUB_GREY
|
||||||
|
.text_font
|
||||||
|
.horz_center(screen().x0, screen().x1, t),
|
||||||
|
screen().y1 - offset,
|
||||||
|
);
|
||||||
|
|
||||||
|
shape::Text::new(text_pos, t)
|
||||||
|
.with_font(theme::TEXT_SUB_GREY.text_font)
|
||||||
|
.with_fg(theme::GREY_DARK)
|
||||||
|
.render(target);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO coinjoin authorized text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
core/embed/rust/src/ui/model_mercury/res/central_circle.png
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/central_circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
BIN
core/embed/rust/src/ui/model_mercury/res/central_circle.toif
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/central_circle.toif
Normal file
Binary file not shown.
BIN
core/embed/rust/src/ui/model_mercury/res/key30.png
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/key30.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
BIN
core/embed/rust/src/ui/model_mercury/res/key30.toif
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/key30.toif
Normal file
Binary file not shown.
BIN
core/embed/rust/src/ui/model_mercury/res/lockscreen_filter.png
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/lockscreen_filter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
core/embed/rust/src/ui/model_mercury/res/lockscreen_filter.toif
Normal file
BIN
core/embed/rust/src/ui/model_mercury/res/lockscreen_filter.toif
Normal file
Binary file not shown.
@ -91,6 +91,7 @@ include_icon!(ICON_CLOSE, "model_mercury/res/close30.toif");
|
|||||||
include_icon!(ICON_CONFIRM_INPUT, "model_mercury/res/confirm_input30.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!(ICON_KEY, "model_mercury/res/key30.toif");
|
||||||
include_icon!(
|
include_icon!(
|
||||||
ICON_SIMPLE_CHECKMARK,
|
ICON_SIMPLE_CHECKMARK,
|
||||||
"model_mercury/res/simple_checkmark30.toif"
|
"model_mercury/res/simple_checkmark30.toif"
|
||||||
@ -101,6 +102,13 @@ include_icon!(ICON_SIGN, "model_mercury/res/sign30.toif");
|
|||||||
include_icon!(ICON_MINUS, "model_mercury/res/minus40.toif");
|
include_icon!(ICON_MINUS, "model_mercury/res/minus40.toif");
|
||||||
include_icon!(ICON_PLUS, "model_mercury/res/plus40.toif");
|
include_icon!(ICON_PLUS, "model_mercury/res/plus40.toif");
|
||||||
|
|
||||||
|
// Homescreen
|
||||||
|
include_icon!(
|
||||||
|
ICON_LOCKSCREEN_FILTER,
|
||||||
|
"model_mercury/res/lockscreen_filter.toif"
|
||||||
|
);
|
||||||
|
include_icon!(ICON_CENTRAL_CIRCLE, "model_mercury/res/central_circle.toif");
|
||||||
|
|
||||||
// TODO remove TT icons:
|
// TODO remove TT icons:
|
||||||
|
|
||||||
// Button icons.
|
// Button icons.
|
||||||
|
Loading…
Reference in New Issue
Block a user