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
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the LICENSE-APACHE file or at:
//     https://www.apache.org/licenses/LICENSE-2.0

//! Event handling: Response type

use crate::geom::{Offset, Rect};

/// Response from [`Widget::handle_event`]
///
/// [`Widget::handle_event`]: crate::Widget::handle_event
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum Response {
    /// Event was unused
    ///
    /// Unused events may be used by a parent/ancestor widget or passed to
    /// another handler until used.
    Unused,
    /// Event is used, no other result
    Used,
}

// Unfortunately we cannot write generic `From` / `TryFrom` impls
// due to trait coherence rules, so we impl `from` etc. directly.
impl Response {
    /// True if variant is `Used`
    #[inline]
    pub fn is_used(&self) -> bool {
        matches!(self, Response::Used)
    }

    /// True if variant is `Unused`
    #[inline]
    pub fn is_unused(&self) -> bool {
        matches!(self, Response::Unused)
    }
}

impl std::ops::BitOr for Response {
    type Output = Self;
    #[inline]
    fn bitor(self, rhs: Self) -> Self {
        use Response::{Unused, Used};
        match (self, rhs) {
            (Unused, Unused) => Unused,
            _ => Used,
        }
    }
}
impl std::ops::BitOrAssign for Response {
    #[inline]
    fn bitor_assign(&mut self, rhs: Self) {
        *self = *self | rhs;
    }
}

/// Request to / notification of scrolling from a child
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[must_use]
pub enum Scroll {
    /// No scrolling
    None,
    /// Child has scrolled; no further scrolling needed
    ///
    /// External scroll bars use this as a notification to update self.
    Scrolled,
    /// Pan region by the given offset
    ///
    /// This may be returned to scroll the closest scrollable ancestor region.
    /// This region should attempt to scroll self by this offset, then, if all
    /// the offset was used, return `Scroll::Scrolled`, otherwise return
    /// `Scroll::Offset(delta)` with the unused offset `delta`.
    ///
    /// With the usual scroll offset conventions, this delta must be subtracted
    /// from the scroll offset.
    Offset(Offset),
    /// Focus the given rect
    Rect(Rect),
}