1use std::{
2 mem::{discriminant, Discriminant},
3 ops::Deref,
4};
5
6use pathfinder_geometry::{rect::RectF, vector::Vector2F};
7
8use crate::{MouseButton, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent};
9
10#[derive(Debug, Default, Clone)]
11pub struct MoveRegionEvent {
12 pub region: RectF,
13 pub platform_event: MouseMovedEvent,
14}
15
16impl Deref for MoveRegionEvent {
17 type Target = MouseMovedEvent;
18
19 fn deref(&self) -> &Self::Target {
20 &self.platform_event
21 }
22}
23
24#[derive(Debug, Default, Clone)]
25pub struct DragRegionEvent {
26 pub region: RectF,
27 pub prev_mouse_position: Vector2F,
28 pub platform_event: MouseMovedEvent,
29}
30
31impl Deref for DragRegionEvent {
32 type Target = MouseMovedEvent;
33
34 fn deref(&self) -> &Self::Target {
35 &self.platform_event
36 }
37}
38
39#[derive(Debug, Default, Clone)]
40pub struct HoverRegionEvent {
41 pub region: RectF,
42 pub started: bool,
43 pub platform_event: MouseMovedEvent,
44}
45
46impl Deref for HoverRegionEvent {
47 type Target = MouseMovedEvent;
48
49 fn deref(&self) -> &Self::Target {
50 &self.platform_event
51 }
52}
53
54#[derive(Debug, Default, Clone)]
55pub struct DownRegionEvent {
56 pub region: RectF,
57 pub platform_event: MouseButtonEvent,
58}
59
60impl Deref for DownRegionEvent {
61 type Target = MouseButtonEvent;
62
63 fn deref(&self) -> &Self::Target {
64 &self.platform_event
65 }
66}
67
68#[derive(Debug, Default, Clone)]
69pub struct UpRegionEvent {
70 pub region: RectF,
71 pub platform_event: MouseButtonEvent,
72}
73
74impl Deref for UpRegionEvent {
75 type Target = MouseButtonEvent;
76
77 fn deref(&self) -> &Self::Target {
78 &self.platform_event
79 }
80}
81
82#[derive(Debug, Default, Clone)]
83pub struct ClickRegionEvent {
84 pub region: RectF,
85 pub platform_event: MouseButtonEvent,
86}
87
88impl Deref for ClickRegionEvent {
89 type Target = MouseButtonEvent;
90
91 fn deref(&self) -> &Self::Target {
92 &self.platform_event
93 }
94}
95
96#[derive(Debug, Default, Clone)]
97pub struct DownOutRegionEvent {
98 pub region: RectF,
99 pub platform_event: MouseButtonEvent,
100}
101
102impl Deref for DownOutRegionEvent {
103 type Target = MouseButtonEvent;
104
105 fn deref(&self) -> &Self::Target {
106 &self.platform_event
107 }
108}
109
110#[derive(Debug, Default, Clone)]
111pub struct UpOutRegionEvent {
112 pub region: RectF,
113 pub platform_event: MouseButtonEvent,
114}
115
116impl Deref for UpOutRegionEvent {
117 type Target = MouseButtonEvent;
118
119 fn deref(&self) -> &Self::Target {
120 &self.platform_event
121 }
122}
123
124#[derive(Debug, Default, Clone)]
125pub struct ScrollWheelRegionEvent {
126 pub region: RectF,
127 pub platform_event: ScrollWheelEvent,
128}
129
130impl Deref for ScrollWheelRegionEvent {
131 type Target = ScrollWheelEvent;
132
133 fn deref(&self) -> &Self::Target {
134 &self.platform_event
135 }
136}
137
138#[derive(Debug, Clone)]
139pub enum MouseRegionEvent {
140 Move(MoveRegionEvent),
141 Drag(DragRegionEvent),
142 Hover(HoverRegionEvent),
143 Down(DownRegionEvent),
144 Up(UpRegionEvent),
145 Click(ClickRegionEvent),
146 DownOut(DownOutRegionEvent),
147 UpOut(UpOutRegionEvent),
148 ScrollWheel(ScrollWheelRegionEvent),
149}
150
151impl MouseRegionEvent {
152 pub fn set_region(&mut self, region: RectF) {
153 match self {
154 MouseRegionEvent::Move(r) => r.region = region,
155 MouseRegionEvent::Drag(r) => r.region = region,
156 MouseRegionEvent::Hover(r) => r.region = region,
157 MouseRegionEvent::Down(r) => r.region = region,
158 MouseRegionEvent::Up(r) => r.region = region,
159 MouseRegionEvent::Click(r) => r.region = region,
160 MouseRegionEvent::DownOut(r) => r.region = region,
161 MouseRegionEvent::UpOut(r) => r.region = region,
162 MouseRegionEvent::ScrollWheel(r) => r.region = region,
163 }
164 }
165
166 /// When true, mouse event handlers must call cx.propagate_event() to bubble
167 /// the event to handlers they are painted on top of.
168 pub fn is_capturable(&self) -> bool {
169 match self {
170 MouseRegionEvent::Move(_) => true,
171 MouseRegionEvent::Drag(_) => true,
172 MouseRegionEvent::Hover(_) => false,
173 MouseRegionEvent::Down(_) => true,
174 MouseRegionEvent::Up(_) => true,
175 MouseRegionEvent::Click(_) => true,
176 MouseRegionEvent::DownOut(_) => false,
177 MouseRegionEvent::UpOut(_) => false,
178 MouseRegionEvent::ScrollWheel(_) => true,
179 }
180 }
181}
182
183impl MouseRegionEvent {
184 pub fn move_disc() -> Discriminant<MouseRegionEvent> {
185 discriminant(&MouseRegionEvent::Move(Default::default()))
186 }
187
188 pub fn drag_disc() -> Discriminant<MouseRegionEvent> {
189 discriminant(&MouseRegionEvent::Drag(Default::default()))
190 }
191
192 pub fn hover_disc() -> Discriminant<MouseRegionEvent> {
193 discriminant(&MouseRegionEvent::Hover(Default::default()))
194 }
195
196 pub fn down_disc() -> Discriminant<MouseRegionEvent> {
197 discriminant(&MouseRegionEvent::Down(Default::default()))
198 }
199
200 pub fn up_disc() -> Discriminant<MouseRegionEvent> {
201 discriminant(&MouseRegionEvent::Up(Default::default()))
202 }
203
204 pub fn up_out_disc() -> Discriminant<MouseRegionEvent> {
205 discriminant(&MouseRegionEvent::UpOut(Default::default()))
206 }
207
208 pub fn click_disc() -> Discriminant<MouseRegionEvent> {
209 discriminant(&MouseRegionEvent::Click(Default::default()))
210 }
211
212 pub fn down_out_disc() -> Discriminant<MouseRegionEvent> {
213 discriminant(&MouseRegionEvent::DownOut(Default::default()))
214 }
215
216 pub fn scroll_wheel_disc() -> Discriminant<MouseRegionEvent> {
217 discriminant(&MouseRegionEvent::ScrollWheel(Default::default()))
218 }
219
220 pub fn handler_key(&self) -> (Discriminant<MouseRegionEvent>, Option<MouseButton>) {
221 match self {
222 MouseRegionEvent::Move(_) => (Self::move_disc(), None),
223 MouseRegionEvent::Drag(e) => (Self::drag_disc(), e.pressed_button),
224 MouseRegionEvent::Hover(_) => (Self::hover_disc(), None),
225 MouseRegionEvent::Down(e) => (Self::down_disc(), Some(e.button)),
226 MouseRegionEvent::Up(e) => (Self::up_disc(), Some(e.button)),
227 MouseRegionEvent::Click(e) => (Self::click_disc(), Some(e.button)),
228 MouseRegionEvent::UpOut(e) => (Self::up_out_disc(), Some(e.button)),
229 MouseRegionEvent::DownOut(e) => (Self::down_out_disc(), Some(e.button)),
230 MouseRegionEvent::ScrollWheel(_) => (Self::scroll_wheel_disc(), None),
231 }
232 }
233}