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(u8);
5
6bitflags::bitflags! {
7    impl Sense: u8 {
8
9        const HOVER = 0;
10
11        /// Buttons, sliders, windows, …
12        const CLICK = 1<<0;
13
14        /// Sliders, windows, scroll bars, scroll areas, …
15        const DRAG = 1<<1;
16
17        /// This widget wants focus.
18        ///
19        /// Anything interactive + labels that can be focused
20        /// for the benefit of screen readers.
21        const FOCUSABLE = 1<<2;
22    }
23}
24
25impl std::fmt::Debug for Sense {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        write!(f, "Sense {{")?;
28        if self.senses_click() {
29            write!(f, " click")?;
30        }
31        if self.senses_drag() {
32            write!(f, " drag")?;
33        }
34        if self.is_focusable() {
35            write!(f, " focusable")?;
36        }
37        write!(f, " }}")
38    }
39}
40
41impl Sense {
42    /// Senses no clicks or drags. Only senses mouse hover.
43    #[doc(alias = "none")]
44    #[inline]
45    pub fn hover() -> Self {
46        Self::empty()
47    }
48
49    /// Senses no clicks or drags, but can be focused with the keyboard.
50    /// Used for labels that can be focused for the benefit of screen readers.
51    #[inline]
52    pub fn focusable_noninteractive() -> Self {
53        Self::FOCUSABLE
54    }
55
56    /// Sense clicks and hover, but not drags.
57    #[inline]
58    pub fn click() -> Self {
59        Self::CLICK | Self::FOCUSABLE
60    }
61
62    /// Sense drags and hover, but not clicks.
63    #[inline]
64    pub fn drag() -> Self {
65        Self::DRAG | Self::FOCUSABLE
66    }
67
68    /// Sense both clicks, drags and hover (e.g. a slider or window).
69    ///
70    /// Note that this will introduce a latency when dragging,
71    /// because when the user starts a press egui can't know if this is the start
72    /// of a click or a drag, and it won't know until the cursor has
73    /// either moved a certain distance, or the user has released the mouse button.
74    ///
75    /// See [`crate::PointerState::is_decidedly_dragging`] for details.
76    #[inline]
77    pub fn click_and_drag() -> Self {
78        Self::CLICK | Self::FOCUSABLE | Self::DRAG
79    }
80
81    /// Returns true if we sense either clicks or drags.
82    #[inline]
83    pub fn interactive(&self) -> bool {
84        self.intersects(Self::CLICK | Self::DRAG)
85    }
86
87    #[inline]
88    pub fn senses_click(&self) -> bool {
89        self.contains(Self::CLICK)
90    }
91
92    #[inline]
93    pub fn senses_drag(&self) -> bool {
94        self.contains(Self::DRAG)
95    }
96
97    #[inline]
98    pub fn is_focusable(&self) -> bool {
99        self.contains(Self::FOCUSABLE)
100    }
101}