Files
gtk/tests/testgestures.c
Benjamin Otte a28f99bf40 tests: Update testgestures example for new widget APIs
We can now use gtk_widget_add_recognizer()
2012-03-14 19:32:55 +01:00

252 lines
7.3 KiB
C

/*
* Copyright (C) 2012 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gtk/gtk.h>
typedef struct _SwipeData SwipeData;
struct _SwipeData {
double x_offset;
double y_offset;
double progress;
guint color;
};
typedef struct _PinchPanData PinchPanData;
struct _PinchPanData {
cairo_matrix_t matrix;
cairo_matrix_t pending;
GdkPixbuf *pixbuf;
};
static void
update_swipe (GtkEventRecognizer *recognizer,
GtkEventTracker *tracker,
SwipeData *data)
{
GtkSwipeGesture *swipe = GTK_SWIPE_GESTURE (tracker);
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
double x, y;
gtk_swipe_gesture_get_offset (swipe, &x, &y);
x /= gtk_widget_get_allocated_width (widget);
y /= gtk_widget_get_allocated_height (widget);
data->x_offset = CLAMP (x, -1, 1);
data->y_offset = CLAMP (y, -1, 1);
gtk_widget_queue_draw (widget);
}
static void
finish_swipe (GtkEventRecognizer *recognizer,
GtkEventTracker *tracker,
SwipeData *data)
{
GtkSwipeGesture *swipe = GTK_SWIPE_GESTURE (tracker);
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
double x, y;
gtk_swipe_gesture_get_offset (swipe, &x, &y);
x /= gtk_widget_get_allocated_width (widget);
y /= gtk_widget_get_allocated_height (widget);
if (ABS (x) >= 0.5)
data->color ^= 1;
if (ABS (y) >= 0.5)
data->color ^= 2;
data->x_offset = 0;
data->y_offset = 0;
gtk_widget_queue_draw (widget);
}
static void
cancel_swipe (GtkEventRecognizer *recognizer,
GtkEventTracker *tracker,
SwipeData *data)
{
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
data->x_offset = 0;
data->y_offset = 0;
gtk_widget_queue_draw (widget);
}
static gboolean
draw_swipe (GtkWidget *widget,
cairo_t *cr,
SwipeData *data)
{
static const GdkRGBA colors[4] = {
{ 1, 0, 0, 1 },
{ 0, 1, 0, 1 },
{ 0, 0, 1, 1 },
{ 1, 1, 0, 1 },
};
int i, x, y, w, h;
w = gtk_widget_get_allocated_width (widget);
h = gtk_widget_get_allocated_height (widget);
x = data->x_offset * w;
y = data->y_offset * h;
cairo_translate (cr, x, y);
for (i = 0; i < 4; i++)
{
gdk_cairo_set_source_rgba (cr, &colors[data->color ^ i]);
cairo_rectangle (cr,
i % 2 ? (x > 0 ? -w : w) : 0,
i / 2 ? (y > 0 ? -h : h) : 0,
w, h);
cairo_fill (cr);
}
return FALSE;
}
static void
pinch_pan_get_matrix (cairo_matrix_t *matrix,
GtkPinchPanGesture *pinch)
{
double scale;
cairo_matrix_init_identity (matrix);
scale = gtk_pinch_pan_gesture_get_zoom (pinch);
cairo_matrix_translate (matrix,
gtk_pinch_pan_gesture_get_x_offset (pinch),
gtk_pinch_pan_gesture_get_y_offset (pinch));
cairo_matrix_scale (matrix, scale, scale);
cairo_matrix_rotate (matrix, gtk_pinch_pan_gesture_get_rotation (pinch) * G_PI / 180);
}
static void
update_pinch_pan (GtkEventRecognizer *recognizer,
GtkEventTracker *tracker,
PinchPanData *data)
{
GtkPinchPanGesture *pinch = GTK_PINCH_PAN_GESTURE (tracker);
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
pinch_pan_get_matrix (&data->pending, pinch);
gtk_widget_queue_draw (widget);
}
static void
finish_pinch_pan (GtkEventRecognizer *recognizer,
GtkEventTracker *tracker,
PinchPanData *data)
{
GtkPinchPanGesture *pinch = GTK_PINCH_PAN_GESTURE (tracker);
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
pinch_pan_get_matrix (&data->pending, pinch);
cairo_matrix_multiply (&data->matrix, &data->matrix, &data->pending);
cairo_matrix_init_identity (&data->pending);
gtk_widget_queue_draw (widget);
}
static void
cancel_pinch_pan (GtkEventRecognizer *recognizer,
GtkEventTracker *tracker,
PinchPanData *data)
{
GtkWidget *widget = gtk_event_tracker_get_widget (tracker);
cairo_matrix_init_identity (&data->pending);
gtk_widget_queue_draw (widget);
}
static gboolean
draw_pinch_pan (GtkWidget *widget,
cairo_t *cr,
PinchPanData *data)
{
cairo_translate (cr,
gtk_widget_get_allocated_width (widget) / 2.0,
gtk_widget_get_allocated_height (widget) / 2.0);
cairo_transform (cr, &data->pending);
cairo_transform (cr, &data->matrix);
gdk_cairo_set_source_pixbuf (cr,
data->pixbuf,
- gdk_pixbuf_get_width (data->pixbuf) / 2.0,
- gdk_pixbuf_get_height (data->pixbuf) / 2.0);
cairo_paint (cr);
return FALSE;
}
int
main (int argc, char *argv[])
{
GtkEventRecognizer *recognizer;
GtkWidget *window, *area;
SwipeData swipe_data = { 0, };
PinchPanData pinch_pan_data = { { 0 }, };
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
area = gtk_drawing_area_new ();
gtk_widget_set_has_window (area, TRUE);
gtk_widget_set_size_request (area, 400, 300);
recognizer = gtk_swipe_recognizer_new ();
g_signal_connect (recognizer, "started", G_CALLBACK (update_swipe), &swipe_data);
g_signal_connect (recognizer, "updated", G_CALLBACK (update_swipe), &swipe_data);
g_signal_connect (recognizer, "finished", G_CALLBACK (finish_swipe), &swipe_data);
g_signal_connect (recognizer, "cancelled", G_CALLBACK (cancel_swipe), &swipe_data);
#if 0
gtk_widget_add_recognizer (area, recognizer);
#endif
cairo_matrix_init_identity (&pinch_pan_data.matrix);
cairo_matrix_init_identity (&pinch_pan_data.pending);
pinch_pan_data.pixbuf = gdk_pixbuf_new_from_file ("gnome-textfile.png", NULL);
g_assert (pinch_pan_data.pixbuf);
recognizer = gtk_pinch_pan_recognizer_new ();
g_signal_connect (recognizer, "started", G_CALLBACK (update_pinch_pan), &pinch_pan_data);
g_signal_connect (recognizer, "updated", G_CALLBACK (update_pinch_pan), &pinch_pan_data);
g_signal_connect (recognizer, "finished", G_CALLBACK (finish_pinch_pan), &pinch_pan_data);
g_signal_connect (recognizer, "cancelled", G_CALLBACK (cancel_pinch_pan), &pinch_pan_data);
#if 1
gtk_widget_add_recognizer (area, recognizer);
#endif
g_signal_connect_after (area, "draw", G_CALLBACK (draw_swipe), &swipe_data);
g_signal_connect_after (area, "draw", G_CALLBACK (draw_pinch_pan), &pinch_pan_data);
gtk_container_add (GTK_CONTAINER (window), area);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}