mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-22 11:05:43 +00:00
feat(eckhart): make homescreen hold to lock
- lock the device by long-pressing the homescreen anywhere but the action bar
This commit is contained in:
parent
99b48fd578
commit
4e9cbc10fd
@ -221,6 +221,11 @@ impl Button {
|
||||
self.area
|
||||
}
|
||||
|
||||
pub fn touch_area(&self) -> Rect {
|
||||
self.touch_expand
|
||||
.map_or(self.area, |expand| self.area.outset(expand))
|
||||
}
|
||||
|
||||
fn set(&mut self, ctx: &mut EventCtx, state: State) {
|
||||
if self.state != state {
|
||||
self.state = state;
|
||||
@ -364,12 +369,7 @@ impl Component for Button {
|
||||
}
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
let touch_area = if let Some(expand) = self.touch_expand {
|
||||
self.area.outset(expand)
|
||||
} else {
|
||||
self.area
|
||||
};
|
||||
|
||||
let touch_area = self.touch_area();
|
||||
match event {
|
||||
Event::Touch(TouchEvent::TouchStart(pos)) => {
|
||||
match self.state {
|
||||
|
@ -74,6 +74,7 @@ impl ComponentMsgObj for Homescreen {
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
HomescreenMsg::Dismissed => Ok(CANCELLED.as_obj()),
|
||||
HomescreenMsg::Menu => Ok(INFO.as_obj()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,13 @@ impl ActionBar {
|
||||
self.right_button.set_expanded_touch_area(expand);
|
||||
}
|
||||
|
||||
pub fn touch_area(&self) -> Rect {
|
||||
let right_area = self.right_button.touch_area();
|
||||
self.left_button
|
||||
.as_ref()
|
||||
.map_or(right_area, |left| right_area.union(left.touch_area()))
|
||||
}
|
||||
|
||||
pub fn update(&mut self, new_pager: Pager) {
|
||||
// TODO: review `clone()` of `left_content`/`right_content`
|
||||
if let Mode::Double { pager } = &mut self.mode {
|
||||
@ -347,9 +354,7 @@ impl Component for ActionBar {
|
||||
btn.render(target);
|
||||
}
|
||||
self.right_button.render(target);
|
||||
if let Some(htc_anim) = &self.htc_anim {
|
||||
htc_anim.render(target);
|
||||
}
|
||||
self.htc_anim.render(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ use crate::{
|
||||
geometry::{Insets, Offset, Rect},
|
||||
layout::util::get_user_custom_image,
|
||||
shape::{self, Renderer},
|
||||
util::{animation_disabled, Pager},
|
||||
},
|
||||
};
|
||||
|
||||
@ -16,7 +17,7 @@ use super::{
|
||||
super::{component::Button, fonts},
|
||||
constant::{HEIGHT, SCREEN, WIDTH},
|
||||
theme::{self, firmware::button_homebar_style, BLACK, GREEN_DARK, GREEN_EXTRA_DARK},
|
||||
ActionBar, ActionBarMsg, Hint,
|
||||
ActionBar, ActionBarMsg, Hint, HoldToConfirmAnim,
|
||||
};
|
||||
|
||||
/// Full-screen component for the homescreen and lockscreen.
|
||||
@ -33,10 +34,15 @@ pub struct Homescreen {
|
||||
lockable: bool,
|
||||
/// Whether the homescreen is locked
|
||||
locked: bool,
|
||||
/// Hold to lock button placed everywhere except the `action_bar`
|
||||
virtual_locking_button: Button,
|
||||
/// Hold to lock animation
|
||||
htc_anim: Option<HoldToConfirmAnim>,
|
||||
}
|
||||
|
||||
pub enum HomescreenMsg {
|
||||
Dismissed,
|
||||
Menu,
|
||||
}
|
||||
|
||||
impl Homescreen {
|
||||
@ -81,6 +87,20 @@ impl Homescreen {
|
||||
Button::with_homebar_content(None).styled(button_style)
|
||||
};
|
||||
|
||||
let lock_duration = theme::LOCK_HOLD_DURATION;
|
||||
|
||||
// Locking animation
|
||||
let htc_anim = if lockable && !animation_disabled() {
|
||||
Some(
|
||||
HoldToConfirmAnim::new()
|
||||
.with_color(theme::GREY_LIGHT)
|
||||
.with_duration(lock_duration)
|
||||
.with_header_overlay(TR::progress__locking_device.into()),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
label: HomeLabel::new(label),
|
||||
hint,
|
||||
@ -88,8 +108,49 @@ impl Homescreen {
|
||||
image,
|
||||
lockable,
|
||||
locked,
|
||||
virtual_locking_button: Button::empty().with_long_press(lock_duration),
|
||||
htc_anim,
|
||||
})
|
||||
}
|
||||
|
||||
fn event_hold(&mut self, ctx: &mut EventCtx, event: Event) -> bool {
|
||||
self.htc_anim.event(ctx, event);
|
||||
if let Some(msg) = self.virtual_locking_button.event(ctx, event) {
|
||||
match msg {
|
||||
ButtonMsg::Pressed => {
|
||||
if let Some(htc_anim) = &mut self.htc_anim {
|
||||
htc_anim.start();
|
||||
ctx.request_anim_frame();
|
||||
ctx.request_paint();
|
||||
ctx.disable_swipe();
|
||||
}
|
||||
}
|
||||
ButtonMsg::Clicked => {
|
||||
if let Some(htc_anim) = &mut self.htc_anim {
|
||||
htc_anim.stop();
|
||||
ctx.request_anim_frame();
|
||||
ctx.request_paint();
|
||||
ctx.enable_swipe();
|
||||
} else {
|
||||
// Animations disabled
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ButtonMsg::Released => {
|
||||
if let Some(htc_anim) = &mut self.htc_anim {
|
||||
htc_anim.stop();
|
||||
ctx.request_anim_frame();
|
||||
ctx.request_paint();
|
||||
ctx.enable_swipe();
|
||||
}
|
||||
}
|
||||
ButtonMsg::LongPressed => {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Homescreen {
|
||||
@ -114,6 +175,9 @@ impl Component for Homescreen {
|
||||
|
||||
self.label.place(label_area);
|
||||
self.action_bar.place(bar_area);
|
||||
// Locking button is placed everywhere except the action bar
|
||||
let locking_area = bounds.inset(Insets::bottom(self.action_bar.touch_area().height()));
|
||||
self.virtual_locking_button.place(locking_area);
|
||||
bounds
|
||||
}
|
||||
|
||||
@ -122,13 +186,14 @@ impl Component for Homescreen {
|
||||
if self.locked {
|
||||
return Some(HomescreenMsg::Dismissed);
|
||||
} else {
|
||||
// TODO: Show menu and handle "lock" action differently
|
||||
if self.lockable {
|
||||
return Some(HomescreenMsg::Dismissed);
|
||||
}
|
||||
return Some(HomescreenMsg::Menu);
|
||||
}
|
||||
}
|
||||
None
|
||||
if self.lockable {
|
||||
Self::event_hold(self, ctx, event).then_some(HomescreenMsg::Dismissed)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||
@ -142,6 +207,7 @@ impl Component for Homescreen {
|
||||
self.label.render(target);
|
||||
self.hint.render(target);
|
||||
self.action_bar.render(target);
|
||||
self.htc_anim.render(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ use super::{
|
||||
*,
|
||||
};
|
||||
|
||||
pub const LOCK_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
||||
pub const CONFIRM_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
||||
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user