[eog/wip/gestures: 1/3] EogScrollView: Add pinch/zoom gesture



commit e25bbcfb39b0aef25b3af84e77d04ad8428ac262
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Mar 27 18:27:41 2014 +0100

    EogScrollView: Add pinch/zoom gesture
    
    GtkGestureZoom is used to handle 2-finger pinch/zoom gestures.
    If the gesture is triggered, scrolling is cancelled, and both
    zoom/offsets are controlled through the 2-sequences bounding box
    and distance.

 src/eog-scroll-view.c |   91 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 89 insertions(+), 2 deletions(-)
---
diff --git a/src/eog-scroll-view.c b/src/eog-scroll-view.c
index 66bd6d3..0593817 100644
--- a/src/eog-scroll-view.c
+++ b/src/eog-scroll-view.c
@@ -160,6 +160,9 @@ struct _EogScrollViewPrivate {
        GdkRGBA *override_bg_color;
 
        cairo_surface_t *background_surface;
+
+       GtkGesture *zoom_gesture;
+       gdouble initial_zoom;
 };
 
 static void scroll_by (EogScrollView *view, int xofs, int yofs);
@@ -1180,8 +1183,10 @@ scroll_to (EogScrollView *view, int x, int y, gboolean change_adjustments)
 #endif
        /* Scroll the window area and process exposure synchronously. */
 
-       gdk_window_scroll (window, -xofs, -yofs);
-       gdk_window_process_updates (window, TRUE);
+       if (!gtk_gesture_is_recognized (priv->zoom_gesture)) {
+               gdk_window_scroll (window, -xofs, -yofs);
+               gdk_window_process_updates (window, TRUE);
+       }
 
  out:
        if (!change_adjustments)
@@ -1325,6 +1330,13 @@ set_zoom (EogScrollView *view, double zoom,
        /* set new values */
        priv->xofs = xofs; /* (img_width * x_rel * zoom) - anchorx; */
        priv->yofs = yofs; /* (img_height * y_rel * zoom) - anchory; */
+
+       if (priv->dragging) {
+               priv->drag_anchor_x = anchorx;
+               priv->drag_anchor_y = anchory;
+               priv->drag_ofs_x = priv->xofs;
+               priv->drag_ofs_y = priv->yofs;
+       }
 #if 0
        g_print ("xofs: %i  yofs: %i\n", priv->xofs, priv->yofs);
 #endif
@@ -1689,6 +1701,9 @@ eog_scroll_view_motion_event (GtkWidget *widget, GdkEventMotion *event, gpointer
        view = EOG_SCROLL_VIEW (data);
        priv = view->priv;
 
+       if (gtk_gesture_is_recognized (priv->zoom_gesture))
+               return TRUE;
+
        if (!priv->dragging)
                return FALSE;
 
@@ -1900,6 +1915,60 @@ display_draw (GtkWidget *widget, cairo_t *cr, gpointer data)
        return TRUE;
 }
 
+static void
+zoom_gesture_begin_cb (GtkGestureZoom   *gesture,
+                      GdkEventSequence *sequence,
+                      EogScrollView    *view)
+{
+       gdouble center_x, center_y;
+       EogScrollViewPrivate *priv;
+
+       priv = view->priv;
+
+       /* Displace dragging point to gesture center */
+       gtk_gesture_get_bounding_box_center (GTK_GESTURE (gesture),
+                                             &center_x, &center_y);
+       priv->drag_anchor_x = center_x;
+       priv->drag_anchor_y = center_y;
+       priv->drag_ofs_x = priv->xofs;
+       priv->drag_ofs_y = priv->yofs;
+       priv->dragging = TRUE;
+       priv->initial_zoom = priv->zoom;
+
+        gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
+static void
+zoom_gesture_update_cb (GtkGestureZoom   *gesture,
+                       GdkEventSequence *sequence,
+                       EogScrollView    *view)
+{
+       gdouble center_x, center_y, scale;
+       EogScrollViewPrivate *priv;
+
+       if (!gtk_gesture_zoom_get_scale_delta (gesture, &scale))
+               return;
+
+       priv = view->priv;
+       gtk_gesture_get_bounding_box_center (GTK_GESTURE (gesture),
+                                             &center_x, &center_y);
+
+       drag_to (view, center_x, center_y);
+       set_zoom (view, priv->initial_zoom * scale, TRUE,
+                 center_x, center_y);
+}
+
+static void
+zoom_gesture_end_cb (GtkGestureZoom   *gesture,
+                    GdkEventSequence *sequence,
+                    EogScrollView    *view)
+{
+       EogScrollViewPrivate *priv;
+
+       priv = view->priv;
+       priv->dragging = FALSE;
+        eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_NORMAL);
+}
 
 /*==================================
 
@@ -2486,6 +2555,7 @@ eog_scroll_view_init (EogScrollView *view)
                               | GDK_BUTTON_RELEASE_MASK
                               | GDK_POINTER_MOTION_MASK
                               | GDK_POINTER_MOTION_HINT_MASK
+                              | GDK_TOUCH_MASK
                               | GDK_SCROLL_MASK
                               | GDK_KEY_PRESS_MASK);
        g_signal_connect (G_OBJECT (priv->display), "configure_event",
@@ -2552,6 +2622,17 @@ eog_scroll_view_init (EogScrollView *view)
                         "antialiasing-out", G_SETTINGS_BIND_GET);
 
        g_object_unref (settings);
+
+       priv->zoom_gesture = gtk_gesture_zoom_new (GTK_WIDGET (view));
+       g_signal_connect (priv->zoom_gesture, "begin",
+                         G_CALLBACK (zoom_gesture_begin_cb), view);
+       g_signal_connect (priv->zoom_gesture, "update",
+                         G_CALLBACK (zoom_gesture_update_cb), view);
+       g_signal_connect (priv->zoom_gesture, "end",
+                         G_CALLBACK (zoom_gesture_end_cb), view);
+       g_signal_connect (priv->zoom_gesture, "cancel",
+                         G_CALLBACK (zoom_gesture_end_cb), view);
+       gtk_gesture_attach (priv->zoom_gesture, GTK_PHASE_CAPTURE);
 }
 
 static void
@@ -2594,6 +2675,12 @@ eog_scroll_view_dispose (GObject *object)
 
        free_image_resources (view);
 
+       if (priv->zoom_gesture) {
+               gtk_gesture_detach (priv->zoom_gesture);
+               g_object_unref (priv->zoom_gesture);
+               priv->zoom_gesture = NULL;
+       }
+
        G_OBJECT_CLASS (eog_scroll_view_parent_class)->dispose (object);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]