1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-12 18:49:07 +00:00

feat(core/mercury): menu animation

This commit is contained in:
tychovrahe 2024-06-20 13:35:13 +02:00 committed by TychoVrahe
parent 7e26e1df15
commit b99325a764
15 changed files with 45 additions and 37 deletions

View File

@ -0,0 +1 @@
[T3T1] Added menu entry animation

View File

@ -1,4 +1,4 @@
use crate::ui::component::{swipe_detect::SwipeConfig, SwipeDirection}; use crate::ui::component::{base::AttachType, swipe_detect::SwipeConfig, SwipeDirection};
pub trait Swipable { pub trait Swipable {
fn get_swipe_config(&self) -> SwipeConfig; fn get_swipe_config(&self) -> SwipeConfig;
@ -27,7 +27,7 @@ pub enum Decision {
/// Initiate transition to another state, end event processing. /// Initiate transition to another state, end event processing.
/// NOTE: it might make sense to include Option<ButtonRequest> here /// NOTE: it might make sense to include Option<ButtonRequest> here
Transition(SwipeDirection), Transition(AttachType),
/// Yield a message to the caller of the flow (i.e. micropython), end event /// Yield a message to the caller of the flow (i.e. micropython), end event
/// processing. /// processing.
@ -76,7 +76,7 @@ pub trait FlowState {
pub trait DecisionBuilder: FlowState + Sized { pub trait DecisionBuilder: FlowState + Sized {
#[inline] #[inline]
fn swipe(&'static self, direction: SwipeDirection) -> StateChange { fn swipe(&'static self, direction: SwipeDirection) -> StateChange {
(self, Decision::Transition(direction)) (self, Decision::Transition(AttachType::Swipe(direction)))
} }
#[inline] #[inline]
@ -99,6 +99,11 @@ pub trait DecisionBuilder: FlowState + Sized {
self.swipe(SwipeDirection::Down) self.swipe(SwipeDirection::Down)
} }
#[inline]
fn transit(&'static self) -> StateChange {
(self, Decision::Transition(AttachType::Initial))
}
#[inline] #[inline]
fn do_nothing(&'static self) -> StateChange { fn do_nothing(&'static self) -> StateChange {
(self, Decision::Nothing) (self, Decision::Nothing)

View File

@ -7,8 +7,9 @@ use crate::{
}, },
ui::{ ui::{
component::{ component::{
base::AttachType, swipe_detect::SwipeSettings, Component, Event, EventCtx, SwipeDetect, base::{AttachType, AttachType::Swipe},
SwipeDetectMsg, SwipeDirection, swipe_detect::SwipeSettings,
Component, Event, EventCtx, SwipeDetect, SwipeDetectMsg, SwipeDirection,
}, },
display::Color, display::Color,
event::{SwipeEvent, TouchEvent}, event::{SwipeEvent, TouchEvent},
@ -147,20 +148,20 @@ impl SwipeFlow {
&mut self.store[self.state.index()] &mut self.store[self.state.index()]
} }
fn goto(&mut self, ctx: &mut EventCtx, direction: SwipeDirection) { fn goto(&mut self, ctx: &mut EventCtx, attach_type: AttachType) {
self.swipe = SwipeDetect::new(); self.swipe = SwipeDetect::new();
self.allow_swipe = true; self.allow_swipe = true;
self.current_page_mut() self.current_page_mut()
.event(ctx, Event::Attach(AttachType::Swipe(direction))); .event(ctx, Event::Attach(attach_type));
self.internal_pages = self.current_page_mut().get_internal_page_count() as u16; self.internal_pages = self.current_page_mut().get_internal_page_count() as u16;
match direction { match attach_type {
SwipeDirection::Up => { Swipe(SwipeDirection::Up) => {
self.internal_state = 0; self.internal_state = 0;
} }
SwipeDirection::Down => { Swipe(SwipeDirection::Down) => {
self.internal_state = self.internal_pages.saturating_sub(1); self.internal_state = self.internal_pages.saturating_sub(1);
} }
_ => {} _ => {}
@ -297,7 +298,7 @@ impl SwipeFlow {
let config = self.current_page().get_swipe_config(); let config = self.current_page().get_swipe_config();
if let (_, Decision::Transition(direction)) = state_change { if let (_, Decision::Transition(Swipe(direction))) = state_change {
if config.is_allowed(direction) { if config.is_allowed(direction) {
if !animation_disabled() { if !animation_disabled() {
self.swipe.trigger(ctx, direction, config); self.swipe.trigger(ctx, direction, config);
@ -317,9 +318,9 @@ impl SwipeFlow {
let (new_state, decision) = state_change; let (new_state, decision) = state_change;
self.state = new_state; self.state = new_state;
match decision { match decision {
Decision::Transition(direction) => { Decision::Transition(attach) => {
self.state = new_state; self.state = new_state;
self.goto(ctx, direction); self.goto(ctx, attach);
None None
} }
Decision::Return(msg) => { Decision::Return(msg) => {

View File

@ -150,6 +150,7 @@ impl AttachAnimation {
self.attach_top = true; self.attach_top = true;
self.duration = Duration::from_millis(350); self.duration = Duration::from_millis(350);
} else { } else {
self.attach_top = false;
self.duration = Duration::from_millis(350); self.duration = Duration::from_millis(350);
} }
self.reset(); self.reset();

View File

@ -51,12 +51,12 @@ impl FlowState for ConfirmAction {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled), (Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info), (Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info),
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed), (Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Confirm, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Confirm, FlowMsg::Info) => Self::Menu.transit(),
_ => self.do_nothing(), _ => self.do_nothing(),
} }
} }
@ -87,7 +87,7 @@ impl FlowState for ConfirmActionSimple {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled), (Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info), (Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info),

View File

@ -58,12 +58,12 @@ impl FlowState for ConfirmOutput {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.swipe_left(), (_, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::AccountInfo.swipe_left(), (Self::Menu, FlowMsg::Choice(0)) => Self::AccountInfo.transit(),
(Self::Menu, FlowMsg::Choice(1)) => Self::CancelTap.swipe_left(), (Self::Menu, FlowMsg::Choice(1)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled), (Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (_, FlowMsg::Cancelled) => Self::Menu.transit(),
_ => self.do_nothing(), _ => self.do_nothing(),
} }
} }

View File

@ -50,11 +50,11 @@ impl FlowState for ConfirmResetCreate {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled), (Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed), (Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Confirm, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Confirm, FlowMsg::Info) => Self::Menu.transit(),
_ => self.do_nothing(), _ => self.do_nothing(),
} }
} }

View File

@ -46,7 +46,7 @@ impl FlowState for ConfirmResetRecover {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled), (Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
_ => self.do_nothing(), _ => self.do_nothing(),

View File

@ -54,7 +54,7 @@ impl FlowState for SetNewPin {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::CancelPinIntro.swipe_left(), (Self::Menu, FlowMsg::Choice(0)) => Self::CancelPinIntro.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::CancelPinIntro, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::CancelPinIntro, FlowMsg::Cancelled) => Self::Intro.swipe_right(),

View File

@ -55,14 +55,14 @@ impl FlowState for ConfirmSummary {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.swipe_left(), (_, FlowMsg::Info) => Self::Menu.transit(),
(Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed), (Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, FlowMsg::Choice(0)) => Self::FeeInfo.swipe_left(), (Self::Menu, FlowMsg::Choice(0)) => Self::FeeInfo.swipe_left(),
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(), (Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(),
(Self::Menu, FlowMsg::Choice(2)) => Self::CancelTap.swipe_left(), (Self::Menu, FlowMsg::Choice(2)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Summary.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Summary.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled), (Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (_, FlowMsg::Cancelled) => Self::Menu.transit(),
_ => self.do_nothing(), _ => self.do_nothing(),
} }
} }

View File

@ -66,7 +66,7 @@ impl FlowState for GetAddress {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Address, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Address, FlowMsg::Info) => Self::Menu.transit(),
(Self::Tap, FlowMsg::Confirmed) => Self::Confirmed.swipe_up(), (Self::Tap, FlowMsg::Confirmed) => Self::Confirmed.swipe_up(),
(Self::Tap, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Tap, FlowMsg::Info) => Self::Menu.swipe_left(),
(Self::Confirmed, _) => self.return_msg(FlowMsg::Confirmed), (Self::Confirmed, _) => self.return_msg(FlowMsg::Confirmed),
@ -74,11 +74,11 @@ impl FlowState for GetAddress {
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(), (Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(),
(Self::Menu, FlowMsg::Choice(2)) => Self::Cancel.swipe_left(), (Self::Menu, FlowMsg::Choice(2)) => Self::Cancel.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(),
(Self::QrCode, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::QrCode, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::AccountInfo, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::AccountInfo, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::Cancel, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::Cancel, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled), (Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(Self::CancelTap, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::CancelTap, FlowMsg::Cancelled) => Self::Menu.transit(),
_ => self.do_nothing(), _ => self.do_nothing(),
} }
} }

View File

@ -56,10 +56,10 @@ impl FlowState for PromptBackup {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::SkipBackupIntro.swipe_left(), (Self::Menu, FlowMsg::Choice(0)) => Self::SkipBackupIntro.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::SkipBackupIntro, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::SkipBackupIntro, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::SkipBackupConfirm, FlowMsg::Cancelled) => Self::SkipBackupIntro.swipe_right(), (Self::SkipBackupConfirm, FlowMsg::Cancelled) => Self::SkipBackupIntro.swipe_right(),
(Self::SkipBackupConfirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled), (Self::SkipBackupConfirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
_ => self.do_nothing(), _ => self.do_nothing(),

View File

@ -51,10 +51,10 @@ impl FlowState for RequestNumber {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Number, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Number, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::Info.swipe_left(), (Self::Menu, FlowMsg::Choice(0)) => Self::Info.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Number.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Number.swipe_right(),
(Self::Info, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::Info, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::Number, FlowMsg::Choice(n)) => self.return_msg(FlowMsg::Choice(n)), (Self::Number, FlowMsg::Choice(n)) => self.return_msg(FlowMsg::Choice(n)),
_ => self.do_nothing(), _ => self.do_nothing(),
} }

View File

@ -60,12 +60,12 @@ impl FlowState for ShowTutorial {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::StepWelcome, FlowMsg::Confirmed) => Self::StepBegin.swipe_up(), (Self::StepWelcome, FlowMsg::Confirmed) => Self::StepBegin.swipe_up(),
(Self::StepMenu, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::StepMenu, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::DidYouKnow.swipe_left(), (Self::Menu, FlowMsg::Choice(0)) => Self::DidYouKnow.swipe_left(),
(Self::Menu, FlowMsg::Choice(1)) => Self::StepBegin.swipe_right(), (Self::Menu, FlowMsg::Choice(1)) => Self::StepBegin.swipe_right(),
(Self::Menu, FlowMsg::Choice(2)) => Self::HoldToExit.swipe_up(), (Self::Menu, FlowMsg::Choice(2)) => Self::HoldToExit.swipe_up(),
(Self::Menu, FlowMsg::Cancelled) => Self::StepMenu.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::StepMenu.swipe_right(),
(Self::DidYouKnow, FlowMsg::Cancelled) => Self::Menu.swipe_right(), (Self::DidYouKnow, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::StepHold, FlowMsg::Confirmed) => Self::StepDone.swipe_up(), (Self::StepHold, FlowMsg::Confirmed) => Self::StepDone.swipe_up(),
(Self::HoldToExit, FlowMsg::Confirmed) => Self::StepDone.swipe_up(), (Self::HoldToExit, FlowMsg::Confirmed) => Self::StepDone.swipe_up(),
_ => self.do_nothing(), _ => self.do_nothing(),

View File

@ -47,7 +47,7 @@ impl FlowState for WarningHiPrio {
fn handle_event(&'static self, msg: FlowMsg) -> StateChange { fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
match (self, msg) { match (self, msg) {
(Self::Message, FlowMsg::Info) => Self::Menu.swipe_left(), (Self::Message, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Confirmed), (Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, FlowMsg::Choice(_)) => Self::Cancelled.swipe_up(), (Self::Menu, FlowMsg::Choice(_)) => Self::Cancelled.swipe_up(),
(Self::Menu, FlowMsg::Cancelled) => Self::Message.swipe_right(), (Self::Menu, FlowMsg::Cancelled) => Self::Message.swipe_right(),