diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 361b56436a..65e7d2064c 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -281,6 +281,7 @@ gtk_public_h_sources = \ gtkfontchooserwidget.h \ gtkframe.h \ gtkgesture.h \ + gtkgesturedrag.h \ gtkgesturelongpress.h \ gtkgesturerotate.h \ gtkgestureswipe.h \ @@ -778,6 +779,7 @@ gtk_base_c_sources = \ gtkframe.c \ gtkgladecatalog.c \ gtkgesture.c \ + gtkgesturedrag.c \ gtkgesturelongpress.c \ gtkgesturerotate.c \ gtkgestureswipe.c \ diff --git a/gtk/gtk.h b/gtk/gtk.h index 7f716da173..d2810a0525 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -107,6 +107,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtkgesturedrag.c b/gtk/gtkgesturedrag.c new file mode 100644 index 0000000000..177471844b --- /dev/null +++ b/gtk/gtkgesturedrag.c @@ -0,0 +1,210 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2014, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author(s): Carlos Garnacho + */ +#include "config.h" +#include + +#define CAPTURE_THRESHOLD_MS 150 + +typedef struct _GtkGestureDragPrivate GtkGestureDragPrivate; +typedef struct _EventData EventData; + +struct _GtkGestureDragPrivate +{ + gdouble start_x; + gdouble start_y; + gdouble last_x; + gdouble last_y; +}; + +enum { + DRAG_BEGIN, + DRAG_UPDATE, + DRAG_END, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkGestureDrag, gtk_gesture_drag, GTK_TYPE_GESTURE) + +static void +gtk_gesture_drag_begin (GtkGesture *gesture, + GdkEventSequence *sequence) +{ + GtkGestureDragPrivate *priv; + + priv = gtk_gesture_drag_get_instance_private (GTK_GESTURE_DRAG (gesture)); + gtk_gesture_get_point (gesture, sequence, &priv->start_x, &priv->start_y); + g_signal_emit (gesture, signals[DRAG_BEGIN], 0, priv->start_x, priv->start_y); +} + +static void +gtk_gesture_drag_update (GtkGesture *gesture, + GdkEventSequence *sequence) +{ + GtkGestureDragPrivate *priv; + gdouble x, y; + + priv = gtk_gesture_drag_get_instance_private (GTK_GESTURE_DRAG (gesture)); + gtk_gesture_get_point (gesture, sequence, &priv->last_x, &priv->last_y); + x = priv->last_x - priv->start_x; + y = priv->last_y - priv->start_y; + + g_signal_emit (gesture, signals[DRAG_UPDATE], 0, x, y); +} + +static void +gtk_gesture_drag_end (GtkGesture *gesture, + GdkEventSequence *sequence) +{ + GtkGestureDragPrivate *priv; + gdouble x, y; + + priv = gtk_gesture_drag_get_instance_private (GTK_GESTURE_DRAG (gesture)); + gtk_gesture_get_point (gesture, sequence, &priv->last_x, &priv->last_y); + x = priv->last_x - priv->start_x; + y = priv->last_y - priv->start_y; + + g_signal_emit (gesture, signals[DRAG_END], 0, x, y); +} + +static void +gtk_gesture_drag_class_init (GtkGestureDragClass *klass) +{ + GtkGestureClass *gesture_class = GTK_GESTURE_CLASS (klass); + + gesture_class->begin = gtk_gesture_drag_begin; + gesture_class->update = gtk_gesture_drag_update; + gesture_class->end = gtk_gesture_drag_end; + + signals[DRAG_BEGIN] = + g_signal_new ("drag-begin", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkGestureDragClass, drag_begin), + NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE); + signals[DRAG_UPDATE] = + g_signal_new ("drag-update", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkGestureDragClass, drag_update), + NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE); + signals[DRAG_END] = + g_signal_new ("drag-end", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkGestureDragClass, drag_end), + NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE); +} + +static void +gtk_gesture_drag_init (GtkGestureDrag *gesture) +{ +} + +/** + * gtk_gesture_drag_new: + * @widget: a #GtkWidget + * + * Returns a newly created #GtkGesture that recognizes drags + * + * Returns: a newly created #GtkGestureDrag + * + * Since: 3.14 + **/ +GtkGesture * +gtk_gesture_drag_new (GtkWidget *widget) +{ + return g_object_new (GTK_TYPE_GESTURE_DRAG, + "widget", widget, + NULL); +} + +/** + * gtk_gesture_drag_get_start_point: + * @gesture: a #GtkGesture + * @x: X coordinate for the drag start point + * @y: Y coordinate for the drag start point + * + * If the @gesture is active, this function returns %TRUE + * and fills in @x and @y with the drag start coordinates, + * in window-relative coordinates. + * + * Returns: #TRUE if the gesture is active. + * + * Since: 3.14 + **/ +gboolean +gtk_gesture_drag_get_start_point (GtkGestureDrag *gesture, + gint *x, + gint *y) +{ + GtkGestureDragPrivate *priv; + + if (!gtk_gesture_is_recognized (GTK_GESTURE (gesture))) + return FALSE; + + priv = gtk_gesture_drag_get_instance_private (gesture); + + if (x) + *x = priv->start_x; + + if (y) + *y = priv->start_y; + + return TRUE; +} + +/** + * gtk_gesture_drag_get_current_point: + * @gesture: a #GtkGesture + * @x: X coordinate for the current point + * @y: Y coordinate for the current point + * + * If the @gesture is active, this function returns %TRUE and + * fills in @x and @y with the coordinates of the current point, + * as an offset to the starting drag point. + * + * Returns: #TRUE if the gesture is active. + * + * Since: 3.14 + **/ +gboolean +gtk_gesture_drag_get_current_point (GtkGestureDrag *gesture, + gint *x, + gint *y) +{ + GtkGestureDragPrivate *priv; + + if (!gtk_gesture_is_recognized (GTK_GESTURE (gesture))) + return FALSE; + + priv = gtk_gesture_drag_get_instance_private (gesture); + + if (x) + *x = priv->last_x; + + if (y) + *y = priv->last_y; + + return TRUE; +} diff --git a/gtk/gtkgesturedrag.h b/gtk/gtkgesturedrag.h new file mode 100644 index 0000000000..f6a0a4d437 --- /dev/null +++ b/gtk/gtkgesturedrag.h @@ -0,0 +1,80 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2014, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author(s): Carlos Garnacho + */ +#ifndef __GTK_GESTURE_DRAG_H__ +#define __GTK_GESTURE_DRAG_H__ + +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_GESTURE_DRAG (gtk_gesture_drag_get_type ()) +#define GTK_GESTURE_DRAG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_GESTURE_DRAG, GtkGestureDrag)) +#define GTK_GESTURE_DRAG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_GESTURE_DRAG, GtkGestureDragClass)) +#define GTK_IS_GESTURE_DRAG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_GESTURE_DRAG)) +#define GTK_IS_GESTURE_DRAG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_GESTURE_DRAG)) +#define GTK_GESTURE_DRAG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_GESTURE_DRAG, GtkGestureDragClass)) + +typedef struct _GtkGestureDrag GtkGestureDrag; +typedef struct _GtkGestureDragClass GtkGestureDragClass; + +struct _GtkGestureDrag +{ + GtkGesture parent_instance; +}; + +struct _GtkGestureDragClass +{ + GtkGestureClass parent_class; + + void (* drag_begin) (GtkGestureDrag *gesture, + gdouble start_x, + gdouble start_y); + void (* drag_update) (GtkGestureDrag *gesture, + gdouble offset_x, + gdouble offset_y); + void (* drag_end) (GtkGestureDrag *gesture, + gdouble offset_x, + gdouble offset_y); + /**/ + gpointer padding[10]; +}; + +GDK_AVAILABLE_IN_3_14 +GType gtk_gesture_drag_get_type (void) G_GNUC_CONST; + +GDK_AVAILABLE_IN_3_14 +GtkGesture * gtk_gesture_drag_new (GtkWidget *widget); + +GDK_AVAILABLE_IN_3_14 +gboolean gtk_gesture_drag_get_start_point (GtkGestureDrag *gesture, + gint *x, + gint *y); +GDK_AVAILABLE_IN_3_14 +gboolean gtk_gesture_drag_get_current_point (GtkGestureDrag *gesture, + gint *x, + gint *y); + +G_END_DECLS + +#endif /* __GTK_GESTURE_DRAG_H__ */