Skip to main content

eave_api/
effect.rs

1use std::time::Duration;
2
3use crate::Task;
4
5/// What [`Widget::update`](crate::Widget::update) asks for: async work, plus requests to the host.
6pub struct Effect<M> {
7    task: Task<M>,
8    popover: Option<PopoverRequest>,
9    nudge: Option<NudgeRequest>,
10}
11
12#[doc(hidden)]
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum PopoverRequest {
15    Open,
16    Close,
17}
18
19/// Which way something just went, so the host can give the widget's island a nudge that way.
20///
21/// It says what happened, not how to move: the host picks the motion. A value going up or down
22/// (a volume, a brightness) bumps the island's top or bottom edge out at the widget's item; moving
23/// to the next or previous thing (a workspace, a track) pushes the whole island left or right,
24/// and it springs back into place.
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum Nudge {
27    Up,
28    Down,
29    Left,
30    Right,
31}
32
33/// A nudge as the host gets it: which way, and how long what it follows takes on screen, if the
34/// widget knows.
35#[doc(hidden)]
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub struct NudgeRequest {
38    pub nudge: Nudge,
39    pub lasting: Option<Duration>,
40}
41
42impl From<Nudge> for NudgeRequest {
43    fn from(nudge: Nudge) -> Self {
44        Self {
45            nudge,
46            lasting: None,
47        }
48    }
49}
50
51impl<M> Effect<M> {
52    pub fn none() -> Self {
53        Self {
54            task: Task::none(),
55            popover: None,
56            nudge: None,
57        }
58    }
59
60    pub fn task(task: Task<M>) -> Self {
61        Self {
62            task,
63            popover: None,
64            nudge: None,
65        }
66    }
67
68    /// Opens this widget's popover, under its item. Ignored if the widget has no popover.
69    pub fn open_popover(mut self) -> Self {
70        self.popover = Some(PopoverRequest::Open);
71        self
72    }
73
74    pub fn close_popover(mut self) -> Self {
75        self.popover = Some(PopoverRequest::Close);
76        self
77    }
78
79    /// Nudges this widget's island. Ignored while the island is held or has a popover.
80    pub fn nudge(mut self, nudge: Nudge) -> Self {
81        self.nudge = Some(NudgeRequest {
82            nudge,
83            lasting: None,
84        });
85        self
86    }
87
88    /// Nudges this widget's island in step with something else on screen that takes `lasting`,
89    /// like the compositor's own workspace animation: the host plays the same motion, slowed down
90    /// or sped up to settle over about that long.
91    pub fn nudge_lasting(mut self, nudge: Nudge, lasting: Duration) -> Self {
92        self.nudge = Some(NudgeRequest {
93            nudge,
94            lasting: Some(lasting),
95        });
96        self
97    }
98
99    #[doc(hidden)]
100    pub fn into_parts(self) -> (Task<M>, Option<PopoverRequest>, Option<NudgeRequest>) {
101        (self.task, self.popover, self.nudge)
102    }
103}
104
105impl<M> From<Task<M>> for Effect<M> {
106    fn from(task: Task<M>) -> Self {
107        Self::task(task)
108    }
109}