From 510230628b2bede948f07722b8607dcde4653750 Mon Sep 17 00:00:00 2001 From: obrusvit Date: Sun, 28 Jul 2024 18:51:02 +0200 Subject: [PATCH] feat(core): allow BR from rust on every Attach This commit allows creating a rust flow in which a component sends the configured ButtonRequest repeatedly on every Event::Attach. This is necessary in recovery homescreen flow where we want to send ButtonRequest also after restarting the device. [no changelog] --- .../rust/src/ui/component/button_request.rs | 51 +++++++++++++++---- core/embed/rust/src/ui/component/mod.rs | 2 +- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/core/embed/rust/src/ui/component/button_request.rs b/core/embed/rust/src/ui/component/button_request.rs index 7b8d6d903e..273f9858ed 100644 --- a/core/embed/rust/src/ui/component/button_request.rs +++ b/core/embed/rust/src/ui/component/button_request.rs @@ -8,23 +8,36 @@ use crate::ui::{ use crate::ui::component::swipe_detect::SwipeConfig; /// Component that sends a ButtonRequest after receiving Event::Attach. The -/// request is only sent once. +/// request is either sent only once or on every Event::Attach configured by +/// `policy`. #[derive(Clone)] -pub struct OneButtonRequest { +pub struct SendButtonRequest { button_request: Option, pub inner: T, + policy: SendButtonRequestPolicy, } -impl OneButtonRequest { - pub const fn new(button_request: ButtonRequest, inner: T) -> Self { +#[derive(Clone)] +pub enum SendButtonRequestPolicy { + OnAttachOnce, + OnAttachAlways, +} + +impl SendButtonRequest { + pub const fn new( + button_request: ButtonRequest, + inner: T, + policy: SendButtonRequestPolicy, + ) -> Self { Self { button_request: Some(button_request), inner, + policy, } } } -impl Component for OneButtonRequest { +impl Component for SendButtonRequest { type Msg = T::Msg; fn place(&mut self, bounds: Rect) -> Rect { @@ -33,8 +46,17 @@ impl Component for OneButtonRequest { fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option { if matches!(event, Event::Attach(_)) { - if let Some(button_request) = self.button_request.take() { - ctx.send_button_request(button_request.code, button_request.name) + match self.policy { + SendButtonRequestPolicy::OnAttachOnce => { + if let Some(br) = self.button_request.take() { + ctx.send_button_request(br.code, br.name) + } + } + SendButtonRequestPolicy::OnAttachAlways => { + if let Some(br) = self.button_request.clone() { + ctx.send_button_request(br.code, br.name); + } + } } } self.inner.event(ctx, event) @@ -50,7 +72,7 @@ impl Component for OneButtonRequest { } #[cfg(all(feature = "micropython", feature = "touch", feature = "new_rendering"))] -impl crate::ui::flow::Swipable for OneButtonRequest { +impl crate::ui::flow::Swipable for SendButtonRequest { fn get_swipe_config(&self) -> SwipeConfig { self.inner.get_swipe_config() } @@ -61,18 +83,25 @@ impl crate::ui::flow::Swipable for OneButtonReques } #[cfg(feature = "ui_debug")] -impl crate::trace::Trace for OneButtonRequest { +impl crate::trace::Trace for SendButtonRequest { fn trace(&self, t: &mut dyn crate::trace::Tracer) { self.inner.trace(t) } } pub trait ButtonRequestExt { - fn one_button_request(self, br: ButtonRequest) -> OneButtonRequest + fn one_button_request(self, br: ButtonRequest) -> SendButtonRequest where Self: Sized, { - OneButtonRequest::new(br, self) + SendButtonRequest::new(br, self, SendButtonRequestPolicy::OnAttachOnce) + } + + fn repeated_button_request(self, br: ButtonRequest) -> SendButtonRequest + where + Self: Sized, + { + SendButtonRequest::new(br, self, SendButtonRequestPolicy::OnAttachAlways) } } diff --git a/core/embed/rust/src/ui/component/mod.rs b/core/embed/rust/src/ui/component/mod.rs index 16ab3c8698..7cc7b8de77 100644 --- a/core/embed/rust/src/ui/component/mod.rs +++ b/core/embed/rust/src/ui/component/mod.rs @@ -29,7 +29,7 @@ pub mod timeout; pub use bar::Bar; pub use base::{Child, Component, ComponentExt, Event, EventCtx, Never, TimerToken}; pub use border::Border; -pub use button_request::{ButtonRequestExt, OneButtonRequest}; +pub use button_request::{ButtonRequestExt, SendButtonRequest}; #[cfg(all(feature = "jpeg", feature = "ui_image_buffer", feature = "micropython"))] pub use cached_jpeg::CachedJpeg; pub use empty::Empty;