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}