kas_core/event/response.rs
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License in the LICENSE-APACHE file or at:
4// https://www.apache.org/licenses/LICENSE-2.0
5
6//! Event handling: IsUsed and Scroll types
7
8use crate::geom::{Offset, Rect, Vec2};
9
10pub use IsUsed::{Unused, Used};
11
12use super::components::KineticStart;
13
14/// Return type of event-handling methods
15///
16/// This type is convertible to/from `bool` and supports the expected bit-wise
17/// OR operator (`a | b`, `*a |= b`).
18///
19/// The type also implements negation with output type `bool`, thus allowing
20/// `if is_used.into() { ... }` and `if !is_used { ... }`. An implementation of
21/// `Deref` would be preferred, but the trait can only output a reference.
22#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
23pub enum IsUsed {
24 /// Event was unused
25 ///
26 /// Unused events may be used by a parent/ancestor widget or passed to
27 /// another handler until used.
28 Unused,
29 /// Event is used, no other result
30 Used,
31}
32
33impl From<bool> for IsUsed {
34 fn from(is_used: bool) -> Self {
35 match is_used {
36 false => Self::Unused,
37 true => Self::Used,
38 }
39 }
40}
41
42impl From<IsUsed> for bool {
43 fn from(is_used: IsUsed) -> bool {
44 is_used == Used
45 }
46}
47
48impl std::ops::BitOr for IsUsed {
49 type Output = Self;
50 #[inline]
51 fn bitor(self, rhs: Self) -> Self {
52 match (self, rhs) {
53 (Unused, Unused) => Unused,
54 _ => Used,
55 }
56 }
57}
58impl std::ops::BitOrAssign for IsUsed {
59 #[inline]
60 fn bitor_assign(&mut self, rhs: Self) {
61 *self = *self | rhs;
62 }
63}
64
65impl std::ops::Not for IsUsed {
66 type Output = bool;
67 #[inline]
68 fn not(self) -> bool {
69 self != Used
70 }
71}
72
73/// Request to / notification of scrolling from a child
74///
75/// See: [`EventCx::set_scroll`](super::EventCx::set_scroll).
76#[derive(Clone, Debug, Default, PartialEq)]
77#[must_use]
78pub enum Scroll {
79 /// No scrolling
80 #[default]
81 None,
82 /// Child has scrolled; no further scrolling needed
83 ///
84 /// External scroll bars use this as a notification to update self.
85 Scrolled,
86 /// Pan region by the given offset
87 ///
88 /// This may be returned to scroll the closest scrollable ancestor region.
89 /// This region should attempt to scroll self by this offset, then, if all
90 /// the offset was used, return `Scroll::Scrolled`, otherwise return
91 /// `Scroll::Offset(delta)` with the unused offset `delta`.
92 ///
93 /// With the usual scroll offset conventions, this delta must be subtracted
94 /// from the scroll offset.
95 Offset(Vec2),
96 /// Start kinetic scrolling
97 Kinetic(KineticStart),
98 /// Focus the given rect
99 ///
100 /// This is specified in the child's coordinate space. It is assumed that
101 /// any parent with non-zero translation will intercept this value and
102 /// either consume or translate it.
103 Rect(Rect),
104}
105
106impl std::ops::Sub<Offset> for Scroll {
107 type Output = Self;
108
109 #[inline]
110 fn sub(self, rhs: Offset) -> Self {
111 match self {
112 Scroll::Rect(rect) => Scroll::Rect(rect - rhs),
113 other => other,
114 }
115 }
116}