Skip to main content

agg_gui/
event.rs

1//! Event types for the widget system.
2//!
3//! All coordinates in events are **first-quadrant (Y-up)** by the time any
4//! widget code sees them. The single Y-down → Y-up conversion happens at the
5//! platform boundary inside [`crate::widget::App`].
6
7use crate::geometry::Point;
8
9/// Which mouse button triggered a `MouseDown` or `MouseUp` event.
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub enum MouseButton {
12    Left,
13    Middle,
14    Right,
15    Other(u8),
16}
17
18/// Modifier keys held at the time of an event.
19///
20/// `meta` is the platform-specific "super" key: **Cmd** on macOS, **Super /
21/// Windows key** on Linux, **Windows key** on Windows. Widgets that want
22/// portable command shortcuts should use the runtime platform helpers rather
23/// than treating `ctrl || meta` as universally equivalent.
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
25pub struct Modifiers {
26    pub shift: bool,
27    pub ctrl: bool,
28    pub alt: bool,
29    pub meta: bool,
30}
31
32/// A logical keyboard key.
33#[derive(Clone, Debug, PartialEq)]
34pub enum Key {
35    /// A printable character, already translated through the keyboard layout.
36    Char(char),
37    Backspace,
38    Delete,
39    /// The `Insert` key.  Paired with `Shift`/`Ctrl` for classic Windows
40    /// clipboard shortcuts (`Shift+Ins` paste, `Ctrl+Ins` copy).
41    Insert,
42    ArrowLeft,
43    ArrowRight,
44    ArrowUp,
45    ArrowDown,
46    Home,
47    End,
48    Tab,
49    Enter,
50    Escape,
51    /// Any key not in the above set — not usually handled, included for
52    /// completeness.
53    Other(String),
54}
55
56/// A GUI event delivered to a widget.
57///
58/// Coordinate positions are in the **local** coordinate space of the widget
59/// receiving the event (bottom-left origin, Y-up). The framework translates
60/// positions as it descends the widget tree.
61#[derive(Clone, Debug)]
62pub enum Event {
63    /// The cursor moved to `pos` (may be outside widget bounds — used to
64    /// clear hover state).
65    MouseMove { pos: Point },
66    /// A mouse button was pressed at `pos`.
67    MouseDown {
68        pos: Point,
69        button: MouseButton,
70        modifiers: Modifiers,
71    },
72    /// A mouse button was released at `pos`.
73    MouseUp {
74        pos: Point,
75        button: MouseButton,
76        modifiers: Modifiers,
77    },
78    /// A key was pressed while this widget (or a descendant) had focus.
79    KeyDown { key: Key, modifiers: Modifiers },
80    /// A key was released.
81    KeyUp { key: Key, modifiers: Modifiers },
82    /// Sent by the framework when this widget gains keyboard focus.
83    FocusGained,
84    /// Sent by the framework when this widget loses keyboard focus.
85    FocusLost,
86    /// Mouse wheel scrolled.  Convention matches `winit` /
87    /// `WheelEvent` after the OS applies its natural-scroll
88    /// preference: **positive `delta_y` means the user wants to see
89    /// content ABOVE the current view** (wheel rotated forward on
90    /// Windows / wheel forward + natural-scroll on macOS).  Scroll
91    /// containers should DECREASE their scroll offset when `delta_y`
92    /// is positive.  `delta_x` follows the same sign rule for
93    /// horizontal scroll (positive = see content to the LEFT).
94    /// Magnitude is in logical pixels; line deltas should be
95    /// pre-scaled by the platform shell (~40 px per line).
96    MouseWheel {
97        pos: Point,
98        delta_y: f64,
99        delta_x: f64,
100        modifiers: Modifiers,
101    },
102    /// One or more files were dropped onto the window at `pos`.
103    ///
104    /// `paths` is non-empty. Native windowing layers (winit) typically
105    /// emit one path per `WindowEvent::DroppedFile` — the framework
106    /// either forwards each as its own `FileDropped` event, or batches
107    /// drops within a single gesture into one event. Receivers should
108    /// not rely on batching behaviour: handle each path in the vec.
109    ///
110    /// Coordinates follow the same convention as `MouseMove`/`MouseDown`:
111    /// widget-local Y-up. The cursor lives at `pos` at the moment of
112    /// drop, so widgets can spawn objects under the user's intent.
113    FileDropped {
114        pos: Point,
115        paths: Vec<std::path::PathBuf>,
116    },
117}
118
119/// What a widget returns from [`crate::widget::Widget::on_event`].
120#[derive(Clone, Copy, Debug, PartialEq, Eq)]
121pub enum EventResult {
122    /// The widget handled the event; stop propagation.
123    Consumed,
124    /// The widget did not handle the event; continue bubbling up.
125    Ignored,
126}