egui/
sense.rs

1/// What sort of interaction is a widget sensitive to?
2#[derive(Clone, Copy, Eq, PartialEq)]
3// #[cfg_attr(feature = "serde", derive(serde::Serialize))]
4pub struct Sense {
5    /// Buttons, sliders, windows, …
6    pub click: bool,
7
8    /// Sliders, windows, scroll bars, scroll areas, …
9    pub drag: bool,
10
11    /// This widget wants focus.
12    ///
13    /// Anything interactive + labels that can be focused
14    /// for the benefit of screen readers.
15    pub focusable: bool,
16}
17
18impl std::fmt::Debug for Sense {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        let Self {
21            click,
22            drag,
23            focusable,
24        } = self;
25
26        write!(f, "Sense {{")?;
27        if *click {
28            write!(f, " click")?;
29        }
30        if *drag {
31            write!(f, " drag")?;
32        }
33        if *focusable {
34            write!(f, " focusable")?;
35        }
36        write!(f, " }}")
37    }
38}
39
40impl Sense {
41    /// Senses no clicks or drags. Only senses mouse hover.
42    #[doc(alias = "none")]
43    #[inline]
44    pub fn hover() -> Self {
45        Self {
46            click: false,
47            drag: false,
48            focusable: false,
49        }
50    }
51
52    /// Senses no clicks or drags, but can be focused with the keyboard.
53    /// Used for labels that can be focused for the benefit of screen readers.
54    #[inline]
55    pub fn focusable_noninteractive() -> Self {
56        Self {
57            click: false,
58            drag: false,
59            focusable: true,
60        }
61    }
62
63    /// Sense clicks and hover, but not drags.
64    #[inline]
65    pub fn click() -> Self {
66        Self {
67            click: true,
68            drag: false,
69            focusable: true,
70        }
71    }
72
73    /// Sense drags and hover, but not clicks.
74    #[inline]
75    pub fn drag() -> Self {
76        Self {
77            click: false,
78            drag: true,
79            focusable: true,
80        }
81    }
82
83    /// Sense both clicks, drags and hover (e.g. a slider or window).
84    ///
85    /// Note that this will introduce a latency when dragging,
86    /// because when the user starts a press egui can't know if this is the start
87    /// of a click or a drag, and it won't know until the cursor has
88    /// either moved a certain distance, or the user has released the mouse button.
89    ///
90    /// See [`crate::PointerState::is_decidedly_dragging`] for details.
91    #[inline]
92    pub fn click_and_drag() -> Self {
93        Self {
94            click: true,
95            drag: true,
96            focusable: true,
97        }
98    }
99
100    /// The logical "or" of two [`Sense`]s.
101    #[must_use]
102    #[inline]
103    pub fn union(self, other: Self) -> Self {
104        Self {
105            click: self.click | other.click,
106            drag: self.drag | other.drag,
107            focusable: self.focusable | other.focusable,
108        }
109    }
110
111    /// Returns true if we sense either clicks or drags.
112    #[inline]
113    pub fn interactive(&self) -> bool {
114        self.click || self.drag
115    }
116}
117
118impl std::ops::BitOr for Sense {
119    type Output = Self;
120
121    #[inline]
122    fn bitor(self, rhs: Self) -> Self {
123        self.union(rhs)
124    }
125}
126
127impl std::ops::BitOrAssign for Sense {
128    #[inline]
129    fn bitor_assign(&mut self, rhs: Self) {
130        *self = self.union(rhs);
131    }
132}