1use std::fmt;
2
3use downcast_rs::{impl_downcast, Downcast};
4
5use crate::{
6 backend::input::TouchSlot,
7 input::SeatHandler,
8 utils::{Logical, Point, Serial},
9};
10
11use super::{DownEvent, MotionEvent, OrientationEvent, ShapeEvent, TouchInnerHandle, UpEvent};
12
13pub trait TouchGrab<D: SeatHandler>: Send + Downcast {
34 fn down(
43 &mut self,
44 data: &mut D,
45 handle: &mut TouchInnerHandle<'_, D>,
46 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
47 event: &DownEvent,
48 seq: Serial,
49 );
50 fn up(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &UpEvent, seq: Serial);
59
60 fn motion(
70 &mut self,
71 data: &mut D,
72 handle: &mut TouchInnerHandle<'_, D>,
73 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
74 event: &MotionEvent,
75 seq: Serial,
76 );
77
78 fn frame(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial);
86
87 fn cancel(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial);
95
96 fn shape(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &ShapeEvent, seq: Serial);
98
99 fn orientation(
101 &mut self,
102 data: &mut D,
103 handle: &mut TouchInnerHandle<'_, D>,
104 event: &OrientationEvent,
105 seq: Serial,
106 );
107
108 fn start_data(&self) -> &GrabStartData<D>;
110
111 fn unset(&mut self, data: &mut D);
113}
114
115impl_downcast!(TouchGrab<D> where D: SeatHandler);
116
117pub struct GrabStartData<D: SeatHandler> {
119 pub focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
123 pub slot: TouchSlot,
125 pub location: Point<f64, Logical>,
127}
128
129impl<D: SeatHandler + 'static> fmt::Debug for GrabStartData<D> {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 f.debug_struct("GrabStartData")
132 .field("focus", &self.focus.as_ref().map(|_| "..."))
133 .field("slot", &self.slot)
134 .field("location", &self.location)
135 .finish()
136 }
137}
138
139impl<D: SeatHandler + 'static> Clone for GrabStartData<D> {
140 fn clone(&self) -> Self {
141 GrabStartData {
142 focus: self.focus.clone(),
143 slot: self.slot,
144 location: self.location,
145 }
146 }
147}
148
149#[derive(Debug)]
151pub struct DefaultGrab;
152
153impl<D: SeatHandler + 'static> TouchGrab<D> for DefaultGrab {
154 fn down(
155 &mut self,
156 data: &mut D,
157 handle: &mut TouchInnerHandle<'_, D>,
158 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
159 event: &DownEvent,
160 seq: Serial,
161 ) {
162 handle.down(data, focus.clone(), event, seq);
163 handle.set_grab(
164 self,
165 data,
166 event.serial,
167 TouchDownGrab {
168 start_data: GrabStartData {
169 focus,
170 slot: event.slot,
171 location: event.location,
172 },
173 touch_points: 1,
174 },
175 );
176 }
177
178 fn up(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &UpEvent, seq: Serial) {
179 handle.up(data, event, seq)
180 }
181
182 fn motion(
183 &mut self,
184 data: &mut D,
185 handle: &mut TouchInnerHandle<'_, D>,
186 focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
187 event: &MotionEvent,
188 seq: Serial,
189 ) {
190 handle.motion(data, focus, event, seq)
191 }
192
193 fn frame(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
194 handle.frame(data, seq)
195 }
196
197 fn cancel(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
198 handle.cancel(data, seq)
199 }
200
201 fn shape(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &ShapeEvent, seq: Serial) {
202 handle.shape(data, event, seq)
203 }
204
205 fn orientation(
206 &mut self,
207 data: &mut D,
208 handle: &mut TouchInnerHandle<'_, D>,
209 event: &OrientationEvent,
210 seq: Serial,
211 ) {
212 handle.orientation(data, event, seq)
213 }
214
215 fn start_data(&self) -> &GrabStartData<D> {
216 unreachable!()
217 }
218
219 fn unset(&mut self, _data: &mut D) {}
220}
221
222pub struct TouchDownGrab<D: SeatHandler> {
228 pub start_data: GrabStartData<D>,
230 pub touch_points: usize,
232}
233
234impl<D: SeatHandler + 'static> fmt::Debug for TouchDownGrab<D> {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 f.debug_struct("TouchDownGrab")
237 .field("start_data", &self.start_data)
238 .field("touch_points", &self.touch_points)
239 .finish()
240 }
241}
242
243impl<D: SeatHandler + 'static> TouchGrab<D> for TouchDownGrab<D> {
244 fn down(
245 &mut self,
246 data: &mut D,
247 handle: &mut TouchInnerHandle<'_, D>,
248 _focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
249 event: &DownEvent,
250 seq: Serial,
251 ) {
252 handle.down(data, self.start_data.focus.clone(), event, seq);
253 self.touch_points += 1;
254 }
255
256 fn up(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &UpEvent, seq: Serial) {
257 handle.up(data, event, seq);
258 self.touch_points = self.touch_points.saturating_sub(1);
259 if self.touch_points == 0 {
260 handle.unset_grab(self, data);
261 }
262 }
263
264 fn motion(
265 &mut self,
266 data: &mut D,
267 handle: &mut TouchInnerHandle<'_, D>,
268 _focus: Option<(<D as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
269 event: &MotionEvent,
270 seq: Serial,
271 ) {
272 handle.motion(data, self.start_data.focus.clone(), event, seq)
273 }
274
275 fn frame(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
276 handle.frame(data, seq)
277 }
278
279 fn cancel(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, seq: Serial) {
280 handle.cancel(data, seq);
281 handle.unset_grab(self, data);
282 }
283
284 fn shape(&mut self, data: &mut D, handle: &mut TouchInnerHandle<'_, D>, event: &ShapeEvent, seq: Serial) {
285 handle.shape(data, event, seq)
286 }
287
288 fn orientation(
289 &mut self,
290 data: &mut D,
291 handle: &mut TouchInnerHandle<'_, D>,
292 event: &OrientationEvent,
293 seq: Serial,
294 ) {
295 handle.orientation(data, event, seq)
296 }
297
298 fn start_data(&self) -> &GrabStartData<D> {
299 &self.start_data
300 }
301
302 fn unset(&mut self, _data: &mut D) {}
303}