[gtk+/multitouch: 18/27] tests: Add testgestures
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multitouch: 18/27] tests: Add testgestures
- Date: Wed, 23 Nov 2011 23:11:57 +0000 (UTC)
commit 1c06e5c50a2faaa348240d34025d22cad494972e
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Oct 25 02:27:18 2011 +0200
tests: Add testgestures
This testcase handles all gestures offered by GtkGestureType,
and also creates and registers a custom M-shaped GtkGesture.
tests/Makefile.am | 6 +
tests/testgestures.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 360 insertions(+), 0 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4d18638..f9198bb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -54,6 +54,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testfontchooserdialog \
testframe \
testgeometry \
+ testgestures \
testgiconpixbuf \
testgrid \
testgtk \
@@ -174,6 +175,7 @@ testfontchooser_DEPENDENCIES = $(TEST_DEPS)
testfontchooserdialog_DEPENDENCIES = $(TEST_DEPS)
testframe_DEPENDENCIES = $(TEST_DEPS)
testgeometry_DEPENDENCIES = $(TEST_DEPS)
+testgestures_DEPENDENCIES = $(TEST_DEPS)
testgiconpixbuf = $(TEST_DEPS)
testgrid_DEPENDENCIES = $(TEST_DEPS)
testgtk_DEPENDENCIES = $(TEST_DEPS)
@@ -268,6 +270,7 @@ testfontchooser_LDADD = $(LDADDS)
testfontchooserdialog_LDADD = $(LDADDS)
testframe_LDADD = $(LDADDS)
testgeometry_LDADD = $(LDADDS)
+testgestures_LDADD = $(LDADDS)
testgiconpixbuf_LDADD = $(LDADDS)
testgrid_LDADD = $(LDADDS)
testgtk_LDADD = $(LDADDS)
@@ -437,6 +440,9 @@ testframe_SOURCES = \
testgeometry_SOURCES = \
testgeometry.c
+testgestures_SOURCES = \
+ testgestures.c
+
testgiconpixbuf_SOURCES = \
testgiconpixbuf.c
diff --git a/tests/testgestures.c b/tests/testgestures.c
new file mode 100644
index 0000000..9ff6dcb
--- /dev/null
+++ b/tests/testgestures.c
@@ -0,0 +1,354 @@
+#include <gtk/gtk.h>
+
+#define GTK_COMPILATION
+#include <gtk/gtkgesturesinterpreter.h>
+#undef GTK_COMPILATION
+
+static GHashTable *strokes;
+static guint shown_gesture = 0;
+static guint timeout_id = 0;
+static guint m_shaped_gesture_id = 0;
+
+static void
+free_stroke (GArray *array)
+{
+ g_array_free (array, TRUE);
+}
+
+static gboolean
+hide_gesture_cb (gpointer user_data)
+{
+ timeout_id = 0;
+ shown_gesture = 0;
+
+ g_hash_table_remove_all (strokes);
+ gtk_widget_queue_draw (GTK_WIDGET (user_data));
+
+ return FALSE;
+}
+
+static gboolean
+draw_cb (GtkWidget *widget,
+ cairo_t *cr,
+ gpointer user_data)
+{
+ GdkPoint *point;
+ GHashTableIter iter;
+ gpointer value;
+ gint i;
+
+ if (shown_gesture != 0)
+ {
+ gint width, height, size;
+
+ cairo_save (cr);
+ width = gdk_window_get_width (gtk_widget_get_window (widget));
+ height = gdk_window_get_height (gtk_widget_get_window (widget));
+
+ size = MIN (width, height);
+ size -= size / 4;
+
+ cairo_translate (cr, width / 2, height / 2);
+
+ cairo_set_line_width (cr, 10);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
+
+ switch (shown_gesture)
+ {
+ case GTK_GESTURE_SWIPE_LEFT:
+ case GTK_GESTURE_SWIPE_RIGHT:
+ case GTK_GESTURE_SWIPE_UP:
+ case GTK_GESTURE_SWIPE_DOWN:
+ if (shown_gesture == GTK_GESTURE_SWIPE_RIGHT)
+ cairo_rotate (cr, (G_PI * 3) / 2);
+ else if (shown_gesture == GTK_GESTURE_SWIPE_LEFT)
+ cairo_rotate (cr, G_PI / 2);
+ else if (shown_gesture == GTK_GESTURE_SWIPE_UP)
+ cairo_rotate (cr, G_PI);
+
+ cairo_move_to (cr, 0, - size / 2);
+ cairo_line_to (cr, 0, size / 2);
+
+ cairo_move_to (cr, 0, size / 2);
+ cairo_rel_line_to (cr, -size / 4, -size / 4);
+
+ cairo_move_to (cr, 0, size / 2);
+ cairo_rel_line_to (cr, size / 4, -size / 4);
+
+ cairo_stroke (cr);
+ break;
+ case GTK_GESTURE_CIRCULAR_COUNTERCLOCKWISE:
+ cairo_move_to (cr, 0, - size / 2);
+ cairo_rel_line_to (cr, size / 8, - size / 8);
+
+ cairo_move_to (cr, 0, - size / 2);
+ cairo_rel_line_to (cr, size / 8, size / 8);
+
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, 0, 0, size / 2, (3 * G_PI) / 2, (5 * G_PI) / 4);
+
+ cairo_stroke (cr);
+ break;
+ case GTK_GESTURE_CIRCULAR_CLOCKWISE:
+ cairo_move_to (cr, 0, - size / 2);
+ cairo_rel_line_to (cr, - size / 8, - size / 8);
+
+ cairo_move_to (cr, 0, - size / 2);
+ cairo_rel_line_to (cr, - size / 8, size / 8);
+
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, 0, 0, size / 2, (3 * G_PI) / 2, (7* G_PI) / 4);
+
+ cairo_stroke (cr);
+ break;
+ default:
+ if (shown_gesture == m_shaped_gesture_id)
+ {
+ PangoAttrList *attr_list;
+ PangoLayout *layout;
+
+ layout = gtk_widget_create_pango_layout (widget, "M");
+
+ attr_list = pango_layout_get_attributes (layout);
+
+ if (!attr_list)
+ attr_list = pango_attr_list_new ();
+
+ pango_attr_list_insert (attr_list,
+ pango_attr_size_new_absolute (200 * PANGO_SCALE));
+ pango_layout_set_attributes (layout, attr_list);
+
+ cairo_move_to (cr, -100, -100);
+ pango_cairo_show_layout (cr, layout);
+ }
+ break;
+ }
+
+ cairo_restore (cr);
+ }
+
+ g_hash_table_iter_init (&iter, strokes);
+
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ {
+ GArray *coords = value;
+
+ if (coords->len > 0)
+ {
+ cairo_save (cr);
+ cairo_set_line_width (cr, 2);
+
+ point = &g_array_index (coords, GdkPoint, 0);
+ cairo_move_to (cr, point->x, point->y);
+
+ for (i = 0; i < coords->len; i++)
+ {
+ point = &g_array_index (coords, GdkPoint, i);
+ cairo_line_to (cr, point->x, point->y);
+ }
+
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean
+append_event_coordinates (GdkEvent *event)
+{
+ GdkPoint point;
+ gdouble x, y;
+ guint touch_id;
+ GArray *coords;
+
+ if (!gdk_event_get_coords (event, &x, &y))
+ return FALSE;
+
+ if (!gdk_event_get_touch_id (event, &touch_id))
+ touch_id = 0;
+
+ coords = g_hash_table_lookup (strokes,
+ GUINT_TO_POINTER (touch_id));
+ point.x = x;
+ point.y = y;
+ g_array_append_val (coords, point);
+
+ return TRUE;
+}
+
+static gboolean
+motion_notify_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ GtkGesturesInterpreter *interpreter;
+ GdkModifierType state;
+
+ interpreter = user_data;
+
+ if (!gdk_event_get_state (event, &state))
+ return FALSE;
+
+ if ((state & GDK_BUTTON1_MASK) == 0)
+ return FALSE;
+
+ append_event_coordinates (event);
+ gtk_gestures_interpreter_feed_event (interpreter, event);
+ gtk_widget_queue_draw (widget);
+
+ return FALSE;
+}
+
+static gboolean
+button_release_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ GtkGesturesInterpreter *interpreter;
+ guint gesture_id;
+
+ interpreter = user_data;
+
+ if (timeout_id != 0)
+ g_source_remove (timeout_id);
+
+ timeout_id = g_timeout_add (500, hide_gesture_cb, widget);
+
+ append_event_coordinates (event);
+ gtk_gestures_interpreter_feed_event (interpreter, event);
+
+ if (gtk_gestures_interpreter_finish (interpreter, &gesture_id))
+ shown_gesture = gesture_id;
+
+ gtk_widget_queue_draw (widget);
+
+ return FALSE;
+}
+
+static gboolean
+button_press_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ GtkGesturesInterpreter *interpreter;
+ GArray *coords;
+ guint touch_id;
+
+ interpreter = user_data;
+
+ if (timeout_id != 0)
+ {
+ g_hash_table_remove_all (strokes);
+ g_source_remove (timeout_id);
+ timeout_id = 0;
+ }
+
+ shown_gesture = 0;
+
+ if (!gdk_event_get_touch_id (event, &touch_id))
+ touch_id = 0;
+
+ coords = g_array_new (FALSE, FALSE, sizeof (GdkPoint));
+ g_hash_table_insert (strokes,
+ GUINT_TO_POINTER (touch_id),
+ coords);
+
+ append_event_coordinates (event);
+ gtk_gestures_interpreter_feed_event (interpreter, event);
+ gtk_widget_queue_draw (widget);
+
+ return FALSE;
+}
+
+static GtkWidget *
+create_window (GtkGesturesInterpreter *interpreter)
+{
+ GtkWidget *window;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_app_paintable (window, TRUE);
+ gtk_widget_set_size_request (window, 400, 400);
+ gtk_window_set_title (GTK_WINDOW (window), "Gestures demo");
+
+ gtk_widget_add_events (window,
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_TOUCH_MASK);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect (window, "motion-notify-event",
+ G_CALLBACK (motion_notify_cb), interpreter);
+ g_signal_connect (window, "button-release-event",
+ G_CALLBACK (button_release_cb), interpreter);
+ g_signal_connect (window, "button-press-event",
+ G_CALLBACK (button_press_cb), interpreter);
+ g_signal_connect (window, "draw",
+ G_CALLBACK (draw_cb), NULL);
+
+ gtk_widget_show (window);
+
+ return window;
+}
+
+static GtkGesture *
+create_m_shaped_gesture (void)
+{
+ GtkGestureStroke *stroke;
+
+ stroke = gtk_gesture_stroke_new ();
+
+ gtk_gesture_stroke_append_vector (stroke, 0, 100);
+ gtk_gesture_stroke_append_vector (stroke, 3 * G_PI_4, 50);
+ gtk_gesture_stroke_append_vector (stroke, G_PI_4, 50);
+ gtk_gesture_stroke_append_vector (stroke, G_PI, 100);
+
+ return gtk_gesture_new (stroke, 0);
+}
+
+static GtkGesturesInterpreter *
+create_interpreter (void)
+{
+ GtkGesturesInterpreter *interpreter;
+ GtkGesture *gesture;
+
+ interpreter = gtk_gestures_interpreter_new ();
+ gtk_gestures_interpreter_add_gesture (interpreter, GTK_GESTURE_SWIPE_RIGHT);
+ gtk_gestures_interpreter_add_gesture (interpreter, GTK_GESTURE_SWIPE_LEFT);
+ gtk_gestures_interpreter_add_gesture (interpreter, GTK_GESTURE_SWIPE_UP);
+ gtk_gestures_interpreter_add_gesture (interpreter, GTK_GESTURE_SWIPE_DOWN);
+ gtk_gestures_interpreter_add_gesture (interpreter, GTK_GESTURE_CIRCULAR_CLOCKWISE);
+ gtk_gestures_interpreter_add_gesture (interpreter, GTK_GESTURE_CIRCULAR_COUNTERCLOCKWISE);
+
+ gesture = create_m_shaped_gesture ();
+ m_shaped_gesture_id = gtk_gesture_register_static (gesture);
+ gtk_gestures_interpreter_add_gesture (interpreter, m_shaped_gesture_id);
+
+ return interpreter;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkGesturesInterpreter *interpreter;
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ strokes = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) free_stroke);
+
+ interpreter = create_interpreter ();
+ window = create_window (interpreter);
+
+ gtk_main ();
+
+ gtk_widget_destroy (window);
+ g_object_unref (interpreter);
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]