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