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    /// Runs `task` too, alongside the one it has.
69    pub fn and_task(mut self, task: Task<M>) -> Self
70    where
71        M: Send + 'static,
72    {
73        self.task = Task::batch([self.task, task]);
74        self
75    }
76
77    /// Opens this widget's popover, under its item. Ignored if the widget has no popover.
78    /// Before the item was ever clicked, it opens on the bar the notifications show on.
79    pub fn open_popover(mut self) -> Self {
80        self.popover = Some(PopoverRequest::Open);
81        self
82    }
83
84    pub fn close_popover(mut self) -> Self {
85        self.popover = Some(PopoverRequest::Close);
86        self
87    }
88
89    /// Nudges this widget's island. Ignored while the island is held or has a popover.
90    pub fn nudge(mut self, nudge: Nudge) -> Self {
91        self.nudge = Some(NudgeRequest {
92            nudge,
93            lasting: None,
94        });
95        self
96    }
97
98    /// Nudges this widget's island in step with something else on screen that takes `lasting`,
99    /// like the compositor's own workspace animation: the host plays the same motion, slowed down
100    /// or sped up to settle over about that long.
101    pub fn nudge_lasting(mut self, nudge: Nudge, lasting: Duration) -> Self {
102        self.nudge = Some(NudgeRequest {
103            nudge,
104            lasting: Some(lasting),
105        });
106        self
107    }
108
109    #[doc(hidden)]
110    pub fn into_parts(self) -> (Task<M>, Option<PopoverRequest>, Option<NudgeRequest>) {
111        (self.task, self.popover, self.nudge)
112    }
113}
114
115impl<M> From<Task<M>> for Effect<M> {
116    fn from(task: Task<M>) -> Self {
117        Self::task(task)
118    }
119}