diff --git a/core/embed/rust/src/time.rs b/core/embed/rust/src/time.rs index edbfa04371..27b2407593 100644 --- a/core/embed/rust/src/time.rs +++ b/core/embed/rust/src/time.rs @@ -10,6 +10,19 @@ const MILLIS_PER_MINUTE: u32 = MILLIS_PER_SEC * 60; const MILLIS_PER_HOUR: u32 = MILLIS_PER_MINUTE * 60; const MILLIS_PER_DAY: u32 = MILLIS_PER_HOUR * 24; +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct ShortDuration { + millis: u16, +} + +impl ShortDuration { + pub const ZERO: Self = Self::from_millis(0); + + pub const fn from_millis(millis: u16) -> Self { + Self { millis } + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)] pub struct Duration { millis: u32, @@ -168,6 +181,12 @@ impl Div for Duration { } } +impl From for Duration { + fn from(value: ShortDuration) -> Self { + Self::from_millis(value.millis.into()) + } +} + /* Instants can wrap around and we want them to be comparable even after * wrapping around. This works by setting a maximum allowable difference * between two Instants to half the range. In checked_add and checked_sub, we diff --git a/core/embed/rust/src/ui/layout_bolt/component/button.rs b/core/embed/rust/src/ui/layout_bolt/component/button.rs index 81a65e01d7..a99f0509bf 100644 --- a/core/embed/rust/src/ui/layout_bolt/component/button.rs +++ b/core/embed/rust/src/ui/layout_bolt/component/button.rs @@ -2,7 +2,7 @@ use crate::trezorhal::haptic::{self, HapticEffect}; use crate::{ strutil::TString, - time::Duration, + time::ShortDuration, ui::{ component::{ Component, ComponentExt, Event, EventCtx, FixedHeightBar, MsgMap, Split, Timer, @@ -41,7 +41,7 @@ pub struct Button { content: ButtonContent, styles: ButtonStyleSheet, state: State, - long_press: Duration, + long_press: ShortDuration, // long press requires non-zero duration long_timer: Timer, haptics: bool, } @@ -58,7 +58,7 @@ impl Button { touch_expand: Insets::zero(), styles: theme::button_default(), state: State::Initial, - long_press: Duration::ZERO, + long_press: ShortDuration::ZERO, long_timer: Timer::new(), haptics: true, } @@ -94,7 +94,8 @@ impl Button { self } - pub fn with_long_press(mut self, duration: Duration) -> Self { + pub fn with_long_press(mut self, duration: ShortDuration) -> Self { + debug_assert_ne!(duration, ShortDuration::ZERO); self.long_press = duration; self } @@ -251,8 +252,8 @@ impl Component for Button { haptic::play(HapticEffect::ButtonPress); } self.set(ctx, State::Pressed); - if self.long_press != Duration::ZERO { - self.long_timer.start(ctx, self.long_press) + if self.long_press != ShortDuration::ZERO { + self.long_timer.start(ctx, self.long_press.into()) } return Some(ButtonMsg::Pressed); } diff --git a/core/embed/rust/src/ui/layout_bolt/theme/mod.rs b/core/embed/rust/src/ui/layout_bolt/theme/mod.rs index ea1b2c601b..260b40ec40 100644 --- a/core/embed/rust/src/ui/layout_bolt/theme/mod.rs +++ b/core/embed/rust/src/ui/layout_bolt/theme/mod.rs @@ -2,7 +2,7 @@ pub mod backlight; pub mod bootloader; use crate::{ - time::Duration, + time::ShortDuration, ui::{ component::{ text::{layout::Chunks, LineBreaking, PageBreaking, TextStyle}, @@ -19,7 +19,7 @@ use super::{ fonts, }; -pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); +pub const ERASE_HOLD_DURATION: ShortDuration = ShortDuration::from_millis(1500); // Color palette. pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF); diff --git a/core/embed/rust/src/ui/layout_delizia/component/button.rs b/core/embed/rust/src/ui/layout_delizia/component/button.rs index b6225903e6..10bce619f1 100644 --- a/core/embed/rust/src/ui/layout_delizia/component/button.rs +++ b/core/embed/rust/src/ui/layout_delizia/component/button.rs @@ -2,7 +2,7 @@ use crate::trezorhal::haptic::{play, HapticEffect}; use crate::{ strutil::TString, - time::Duration, + time::ShortDuration, ui::{ component::{Component, Event, EventCtx, Timer}, display::{toif::Icon, Color, Font}, @@ -30,7 +30,7 @@ pub struct Button { text_align: Alignment, radius: Option, state: State, - long_press: Option, + long_press: ShortDuration, // long press requires non-zero duration long_timer: Timer, haptic: bool, } @@ -50,7 +50,7 @@ impl Button { text_align: Alignment::Start, radius: None, state: State::Initial, - long_press: None, + long_press: ShortDuration::ZERO, long_timer: Timer::new(), haptic: true, } @@ -87,8 +87,9 @@ impl Button { self } - pub fn with_long_press(mut self, duration: Duration) -> Self { - self.long_press = Some(duration); + pub fn with_long_press(mut self, duration: ShortDuration) -> Self { + debug_assert_ne!(duration, ShortDuration::ZERO); + self.long_press = duration; self } @@ -271,8 +272,8 @@ impl Component for Button { play(HapticEffect::ButtonPress); } self.set(ctx, State::Pressed); - if let Some(duration) = self.long_press { - self.long_timer.start(ctx, duration); + if self.long_press != ShortDuration::ZERO { + self.long_timer.start(ctx, self.long_press.into()); } return Some(ButtonMsg::Pressed); } diff --git a/core/embed/rust/src/ui/layout_delizia/component/hold_to_confirm.rs b/core/embed/rust/src/ui/layout_delizia/component/hold_to_confirm.rs index 248d1a94d5..26056f094b 100644 --- a/core/embed/rust/src/ui/layout_delizia/component/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/layout_delizia/component/hold_to_confirm.rs @@ -1,5 +1,5 @@ use crate::{ - time::Duration, + time::{Duration, ShortDuration}, translations::TR, ui::{ component::{Component, Event, EventCtx}, @@ -180,7 +180,7 @@ impl HoldToConfirm { pub fn new(circle_color: Color, circle_inner_color: Color) -> Self { let button = Button::new(ButtonContent::Empty) .styled(theme::button_default()) - .with_long_press(Duration::from_millis(2200)) + .with_long_press(ShortDuration::from_millis(2200)) .without_haptics(); Self { title: Label::new( diff --git a/core/embed/rust/src/ui/layout_delizia/theme/mod.rs b/core/embed/rust/src/ui/layout_delizia/theme/mod.rs index 39a24898cc..8770ff0ef0 100644 --- a/core/embed/rust/src/ui/layout_delizia/theme/mod.rs +++ b/core/embed/rust/src/ui/layout_delizia/theme/mod.rs @@ -3,7 +3,7 @@ pub mod bootloader; pub mod backlight; use crate::{ - time::Duration, + time::ShortDuration, ui::{ component::{ text::{layout::Chunks, LineBreaking, PageBreaking, TextStyle}, @@ -20,7 +20,7 @@ use super::{ fonts, }; -pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); +pub const ERASE_HOLD_DURATION: ShortDuration = ShortDuration::from_millis(1500); // Color palette. pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF); diff --git a/core/embed/rust/src/ui/layout_eckhart/component/button.rs b/core/embed/rust/src/ui/layout_eckhart/component/button.rs index 33a16ce6ca..e73b3e3842 100644 --- a/core/embed/rust/src/ui/layout_eckhart/component/button.rs +++ b/core/embed/rust/src/ui/layout_eckhart/component/button.rs @@ -2,7 +2,7 @@ use crate::trezorhal::haptic::{play, HapticEffect}; use crate::{ strutil::TString, - time::Duration, + time::{Duration, ShortDuration}, ui::{ component::{text::TextStyle, Component, Event, EventCtx, Timer}, constant, @@ -42,7 +42,7 @@ pub struct Button { text_align: Alignment, radius_or_gradient: RadiusOrGradient, state: State, - long_press: Option, + long_press: ShortDuration, // long press requires non-zero duration long_timer: Timer, haptic: bool, } @@ -76,7 +76,7 @@ impl Button { text_align: Alignment::Center, radius_or_gradient: RadiusOrGradient::None, state: State::Initial, - long_press: None, + long_press: ShortDuration::ZERO, long_timer: Timer::new(), haptic: true, } @@ -168,8 +168,9 @@ impl Button { self } - pub fn with_long_press(mut self, duration: Duration) -> Self { - self.long_press = Some(duration); + pub fn with_long_press(mut self, duration: ShortDuration) -> Self { + debug_assert_ne!(duration, ShortDuration::ZERO); + self.long_press = duration; self } @@ -223,7 +224,11 @@ impl Button { } pub fn long_press(&self) -> Option { - self.long_press + if self.long_press != ShortDuration::ZERO { + Some(self.long_press.into()) + } else { + None + } } pub fn is_disabled(&self) -> bool { @@ -584,7 +589,7 @@ impl Component for Button { play(HapticEffect::ButtonPress); } self.set(ctx, State::Pressed); - if let Some(duration) = self.long_press { + if let Some(duration) = self.long_press() { self.long_timer.start(ctx, duration); } return Some(ButtonMsg::Pressed); diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/hold_to_confirm.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/hold_to_confirm.rs index 74a41bbb46..ba0a9dc026 100644 --- a/core/embed/rust/src/ui/layout_eckhart/firmware/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/layout_eckhart/firmware/hold_to_confirm.rs @@ -57,7 +57,7 @@ impl HoldToConfirmAnim { pub fn new() -> Self { let default_color = theme::GREEN_LIME; Self { - total_duration: theme::CONFIRM_HOLD_DURATION, + total_duration: theme::CONFIRM_HOLD_DURATION.into(), color: default_color, border: ScreenBorder::new(default_color), timer: Stopwatch::default(), diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs index 7407f01f95..8cd3369df2 100644 --- a/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs +++ b/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs @@ -2,7 +2,7 @@ use crate::{ error::Error, io::BinaryData, strutil::TString, - time::Duration, + time::ShortDuration, translations::TR, ui::{ component::{text::TextStyle, Component, Event, EventCtx, Label, Never}, @@ -24,7 +24,7 @@ use super::{ ActionBar, ActionBarMsg, Hint, }; -const LOCK_HOLD_DURATION: Duration = Duration::from_millis(3000); +const LOCK_HOLD_DURATION: ShortDuration = ShortDuration::from_millis(3000); /// Full-screen component for the homescreen and lockscreen. pub struct Homescreen { diff --git a/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs b/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs index 8360cabb75..303f674ec9 100644 --- a/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs +++ b/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs @@ -1,5 +1,5 @@ use crate::{ - time::Duration, + time::ShortDuration, ui::component::text::{ layout::{Chunks, LineBreaking, PageBreaking}, TextStyle, @@ -14,8 +14,8 @@ use super::{ *, }; -pub const CONFIRM_HOLD_DURATION: Duration = Duration::from_millis(1500); -pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); +pub const CONFIRM_HOLD_DURATION: ShortDuration = ShortDuration::from_millis(1500); +pub const ERASE_HOLD_DURATION: ShortDuration = ShortDuration::from_millis(1500); // Text styles /// Alias for use with copied code, might be deleted later