use std::fmt;
use downcast_rs::{impl_downcast, Downcast};
use crate::{
backend::input::ButtonState,
input::SeatHandler,
utils::{Logical, Point},
};
use super::{
AxisFrame, ButtonEvent, Focus, GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent,
GestureSwipeUpdateEvent, MotionEvent, PointerInnerHandle, RelativeMotionEvent,
};
pub trait PointerGrab<D: SeatHandler>: Send + Downcast {
fn motion(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
event: &MotionEvent,
);
fn relative_motion(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
event: &RelativeMotionEvent,
);
fn button(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>, event: &ButtonEvent);
fn axis(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>, details: AxisFrame);
fn frame(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>);
fn gesture_swipe_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeBeginEvent,
);
fn gesture_swipe_update(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeUpdateEvent,
);
fn gesture_swipe_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeEndEvent,
);
fn gesture_pinch_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchBeginEvent,
);
fn gesture_pinch_update(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchUpdateEvent,
);
fn gesture_pinch_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchEndEvent,
);
fn gesture_hold_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureHoldBeginEvent,
);
fn gesture_hold_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureHoldEndEvent,
);
fn start_data(&self) -> &GrabStartData<D>;
fn unset(&mut self, data: &mut D);
}
impl_downcast!(PointerGrab<D> where D: SeatHandler);
pub struct GrabStartData<D: SeatHandler> {
pub focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
pub button: u32,
pub location: Point<f64, Logical>,
}
impl<D: SeatHandler + 'static> fmt::Debug for GrabStartData<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GrabStartData")
.field("focus", &self.focus.as_ref().map(|_| "..."))
.field("button", &self.button)
.field("location", &self.location)
.finish()
}
}
impl<D: SeatHandler + 'static> Clone for GrabStartData<D> {
fn clone(&self) -> Self {
GrabStartData {
focus: self.focus.clone(),
button: self.button,
location: self.location,
}
}
}
pub(super) struct DefaultGrab;
impl<D: SeatHandler + 'static> PointerGrab<D> for DefaultGrab {
fn motion(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
event: &MotionEvent,
) {
handle.motion(data, focus, event);
}
fn relative_motion(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
event: &RelativeMotionEvent,
) {
handle.relative_motion(data, focus, event);
}
fn button(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>, event: &ButtonEvent) {
handle.button(data, event);
if event.state == ButtonState::Pressed {
handle.set_grab(
self,
data,
event.serial,
Focus::Keep,
ClickGrab {
start_data: GrabStartData {
focus: handle.current_focus(),
button: event.button,
location: handle.current_location(),
},
},
);
}
}
fn axis(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>, details: AxisFrame) {
handle.axis(data, details);
}
fn frame(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>) {
handle.frame(data);
}
fn gesture_swipe_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event);
}
fn gesture_swipe_update(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event);
}
fn gesture_swipe_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event);
}
fn gesture_pinch_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event);
}
fn gesture_pinch_update(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event);
}
fn gesture_pinch_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event);
}
fn gesture_hold_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event);
}
fn gesture_hold_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event);
}
fn start_data(&self) -> &GrabStartData<D> {
unreachable!()
}
fn unset(&mut self, _data: &mut D) {}
}
pub struct ClickGrab<D: SeatHandler> {
start_data: GrabStartData<D>,
}
impl<D: SeatHandler + 'static> fmt::Debug for ClickGrab<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ClickGrab")
.field("start_data", &self.start_data)
.finish()
}
}
impl<D: SeatHandler + 'static> PointerGrab<D> for ClickGrab<D> {
fn motion(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
_focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
event: &MotionEvent,
) {
handle.motion(data, self.start_data.focus.clone(), event);
}
fn relative_motion(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
focus: Option<(<D as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
event: &RelativeMotionEvent,
) {
handle.relative_motion(data, focus, event);
}
fn button(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>, event: &ButtonEvent) {
handle.button(data, event);
if handle.current_pressed().is_empty() {
handle.unset_grab(self, data, event.serial, event.time, false);
}
}
fn axis(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>, details: AxisFrame) {
handle.axis(data, details);
}
fn frame(&mut self, data: &mut D, handle: &mut PointerInnerHandle<'_, D>) {
handle.frame(data);
}
fn gesture_swipe_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event);
}
fn gesture_swipe_update(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event);
}
fn gesture_swipe_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event);
}
fn gesture_pinch_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event);
}
fn gesture_pinch_update(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event);
}
fn gesture_pinch_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event);
}
fn gesture_hold_begin(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event);
}
fn gesture_hold_end(
&mut self,
data: &mut D,
handle: &mut PointerInnerHandle<'_, D>,
event: &GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event);
}
fn start_data(&self) -> &GrabStartData<D> {
&self.start_data
}
fn unset(&mut self, _data: &mut D) {}
}