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, and make the widget focusable.
57    ///
58    /// Use [`Sense::CLICK`] if you don't want the widget to be focusable.
59    #[inline]
60    pub fn click() -> Self {
61        Self::CLICK | Self::FOCUSABLE
62    }
63
64    /// Sense drags and hover, but not clicks. Make the widget focusable.
65    ///
66    /// Use [`Sense::DRAG`] if you don't want the widget to be focusable
67    #[inline]
68    pub fn drag() -> Self {
69        Self::DRAG | Self::FOCUSABLE
70    }
71
72    /// Sense both clicks, drags and hover (e.g. a slider or window), and make the widget focusable.
73    ///
74    /// Note that this will introduce a latency when dragging,
75    /// because when the user starts a press egui can't know if this is the start
76    /// of a click or a drag, and it won't know until the cursor has
77    /// either moved a certain distance, or the user has released the mouse button.
78    ///
79    /// See [`crate::PointerState::is_decidedly_dragging`] for details.
80    #[inline]
81    pub fn click_and_drag() -> Self {
82        Self::CLICK | Self::FOCUSABLE | Self::DRAG
83    }
84
85    /// Returns true if we sense either clicks or drags.
86    #[inline]
87    pub fn interactive(&self) -> bool {
88        self.intersects(Self::CLICK | Self::DRAG)
89    }
90
91    #[inline]
92    pub fn senses_click(&self) -> bool {
93        self.contains(Self::CLICK)
94    }
95
96    #[inline]
97    pub fn senses_drag(&self) -> bool {
98        self.contains(Self::DRAG)
99    }
100
101    #[inline]
102    pub fn is_focusable(&self) -> bool {
103        self.contains(Self::FOCUSABLE)
104    }
105}