1use gdk;
6use glib::object::Cast;
7use glib::object::IsA;
8use glib::signal::connect_raw;
9use glib::signal::SignalHandlerId;
10use glib::translate::*;
11use glib::StaticType;
12use glib::ToValue;
13use glib_sys;
14use gtk_sys;
15use libc;
16use std::boxed::Box as Box_;
17use std::fmt;
18use std::mem;
19use std::mem::transmute;
20use EventController;
21use Gesture;
22use GestureSingle;
23use PropagationPhase;
24use Widget;
25
26glib_wrapper! {
27 pub struct GestureDrag(Object<gtk_sys::GtkGestureDrag, gtk_sys::GtkGestureDragClass, GestureDragClass>) @extends GestureSingle, Gesture, EventController;
28
29 match fn {
30 get_type => || gtk_sys::gtk_gesture_drag_get_type(),
31 }
32}
33
34impl GestureDrag {
35 pub fn new<P: IsA<Widget>>(widget: &P) -> GestureDrag {
36 skip_assert_initialized!();
37 unsafe {
38 Gesture::from_glib_full(gtk_sys::gtk_gesture_drag_new(
39 widget.as_ref().to_glib_none().0,
40 ))
41 .unsafe_cast()
42 }
43 }
44}
45
46pub struct GestureDragBuilder {
47 button: Option<u32>,
48 exclusive: Option<bool>,
49 touch_only: Option<bool>,
50 n_points: Option<u32>,
51 window: Option<gdk::Window>,
52 propagation_phase: Option<PropagationPhase>,
53 widget: Option<Widget>,
54}
55
56impl GestureDragBuilder {
57 pub fn new() -> Self {
58 Self {
59 button: None,
60 exclusive: None,
61 touch_only: None,
62 n_points: None,
63 window: None,
64 propagation_phase: None,
65 widget: None,
66 }
67 }
68
69 pub fn build(self) -> GestureDrag {
70 let mut properties: Vec<(&str, &dyn ToValue)> = vec![];
71 if let Some(ref button) = self.button {
72 properties.push(("button", button));
73 }
74 if let Some(ref exclusive) = self.exclusive {
75 properties.push(("exclusive", exclusive));
76 }
77 if let Some(ref touch_only) = self.touch_only {
78 properties.push(("touch-only", touch_only));
79 }
80 if let Some(ref n_points) = self.n_points {
81 properties.push(("n-points", n_points));
82 }
83 if let Some(ref window) = self.window {
84 properties.push(("window", window));
85 }
86 if let Some(ref propagation_phase) = self.propagation_phase {
87 properties.push(("propagation-phase", propagation_phase));
88 }
89 if let Some(ref widget) = self.widget {
90 properties.push(("widget", widget));
91 }
92 glib::Object::new(GestureDrag::static_type(), &properties)
93 .expect("object new")
94 .downcast()
95 .expect("downcast")
96 }
97
98 pub fn button(mut self, button: u32) -> Self {
99 self.button = Some(button);
100 self
101 }
102
103 pub fn exclusive(mut self, exclusive: bool) -> Self {
104 self.exclusive = Some(exclusive);
105 self
106 }
107
108 pub fn touch_only(mut self, touch_only: bool) -> Self {
109 self.touch_only = Some(touch_only);
110 self
111 }
112
113 pub fn n_points(mut self, n_points: u32) -> Self {
114 self.n_points = Some(n_points);
115 self
116 }
117
118 pub fn window(mut self, window: &gdk::Window) -> Self {
119 self.window = Some(window.clone());
120 self
121 }
122
123 pub fn propagation_phase(mut self, propagation_phase: PropagationPhase) -> Self {
124 self.propagation_phase = Some(propagation_phase);
125 self
126 }
127
128 pub fn widget(mut self, widget: &Widget) -> Self {
129 self.widget = Some(widget.clone());
130 self
131 }
132}
133
134pub const NONE_GESTURE_DRAG: Option<&GestureDrag> = None;
135
136pub trait GestureDragExt: 'static {
137 fn get_offset(&self) -> Option<(f64, f64)>;
138
139 fn get_start_point(&self) -> Option<(f64, f64)>;
140
141 fn connect_drag_begin<F: Fn(&Self, f64, f64) + 'static>(&self, f: F) -> SignalHandlerId;
142
143 fn connect_drag_end<F: Fn(&Self, f64, f64) + 'static>(&self, f: F) -> SignalHandlerId;
144
145 fn connect_drag_update<F: Fn(&Self, f64, f64) + 'static>(&self, f: F) -> SignalHandlerId;
146}
147
148impl<O: IsA<GestureDrag>> GestureDragExt for O {
149 fn get_offset(&self) -> Option<(f64, f64)> {
150 unsafe {
151 let mut x = mem::uninitialized();
152 let mut y = mem::uninitialized();
153 let ret = from_glib(gtk_sys::gtk_gesture_drag_get_offset(
154 self.as_ref().to_glib_none().0,
155 &mut x,
156 &mut y,
157 ));
158 if ret {
159 Some((x, y))
160 } else {
161 None
162 }
163 }
164 }
165
166 fn get_start_point(&self) -> Option<(f64, f64)> {
167 unsafe {
168 let mut x = mem::uninitialized();
169 let mut y = mem::uninitialized();
170 let ret = from_glib(gtk_sys::gtk_gesture_drag_get_start_point(
171 self.as_ref().to_glib_none().0,
172 &mut x,
173 &mut y,
174 ));
175 if ret {
176 Some((x, y))
177 } else {
178 None
179 }
180 }
181 }
182
183 fn connect_drag_begin<F: Fn(&Self, f64, f64) + 'static>(&self, f: F) -> SignalHandlerId {
184 unsafe extern "C" fn drag_begin_trampoline<P, F: Fn(&P, f64, f64) + 'static>(
185 this: *mut gtk_sys::GtkGestureDrag,
186 start_x: libc::c_double,
187 start_y: libc::c_double,
188 f: glib_sys::gpointer,
189 ) where
190 P: IsA<GestureDrag>,
191 {
192 let f: &F = &*(f as *const F);
193 f(
194 &GestureDrag::from_glib_borrow(this).unsafe_cast(),
195 start_x,
196 start_y,
197 )
198 }
199 unsafe {
200 let f: Box_<F> = Box_::new(f);
201 connect_raw(
202 self.as_ptr() as *mut _,
203 b"drag-begin\0".as_ptr() as *const _,
204 Some(transmute(drag_begin_trampoline::<Self, F> as usize)),
205 Box_::into_raw(f),
206 )
207 }
208 }
209
210 fn connect_drag_end<F: Fn(&Self, f64, f64) + 'static>(&self, f: F) -> SignalHandlerId {
211 unsafe extern "C" fn drag_end_trampoline<P, F: Fn(&P, f64, f64) + 'static>(
212 this: *mut gtk_sys::GtkGestureDrag,
213 offset_x: libc::c_double,
214 offset_y: libc::c_double,
215 f: glib_sys::gpointer,
216 ) where
217 P: IsA<GestureDrag>,
218 {
219 let f: &F = &*(f as *const F);
220 f(
221 &GestureDrag::from_glib_borrow(this).unsafe_cast(),
222 offset_x,
223 offset_y,
224 )
225 }
226 unsafe {
227 let f: Box_<F> = Box_::new(f);
228 connect_raw(
229 self.as_ptr() as *mut _,
230 b"drag-end\0".as_ptr() as *const _,
231 Some(transmute(drag_end_trampoline::<Self, F> as usize)),
232 Box_::into_raw(f),
233 )
234 }
235 }
236
237 fn connect_drag_update<F: Fn(&Self, f64, f64) + 'static>(&self, f: F) -> SignalHandlerId {
238 unsafe extern "C" fn drag_update_trampoline<P, F: Fn(&P, f64, f64) + 'static>(
239 this: *mut gtk_sys::GtkGestureDrag,
240 offset_x: libc::c_double,
241 offset_y: libc::c_double,
242 f: glib_sys::gpointer,
243 ) where
244 P: IsA<GestureDrag>,
245 {
246 let f: &F = &*(f as *const F);
247 f(
248 &GestureDrag::from_glib_borrow(this).unsafe_cast(),
249 offset_x,
250 offset_y,
251 )
252 }
253 unsafe {
254 let f: Box_<F> = Box_::new(f);
255 connect_raw(
256 self.as_ptr() as *mut _,
257 b"drag-update\0".as_ptr() as *const _,
258 Some(transmute(drag_update_trampoline::<Self, F> as usize)),
259 Box_::into_raw(f),
260 )
261 }
262 }
263}
264
265impl fmt::Display for GestureDrag {
266 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267 write!(f, "GestureDrag")
268 }
269}