[eog/gestures: 3/4] EogScrollView: Add next/previous image signals



commit d81d463f4d15ad08b8ca96df387e47e13743e757
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon May 19 14:38:14 2014 +0200

    EogScrollView: Add next/previous image signals
    
    Those are triggered by a pan gesture. If the scrollview is not scrollable
    horizontally, and a horizontal pan gesture happens, next/prev signals are
    emitted on the view. Vertical panning can still trigger scrolling or DnD.

 src/eog-scroll-view.c |   91 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/eog-scroll-view.h |    2 +
 2 files changed, 93 insertions(+), 0 deletions(-)
---
diff --git a/src/eog-scroll-view.c b/src/eog-scroll-view.c
index 57c7065..5fa8190 100644
--- a/src/eog-scroll-view.c
+++ b/src/eog-scroll-view.c
@@ -55,6 +55,8 @@ typedef enum {
 /* Signal IDs */
 enum {
        SIGNAL_ZOOM_CHANGED,
+       SIGNAL_NEXT_IMAGE,
+       SIGNAL_PREVIOUS_IMAGE,
        SIGNAL_LAST
 };
 static gint view_signals [SIGNAL_LAST];
@@ -73,6 +75,12 @@ typedef enum {
        N_EOG_ROTATIONS
 } EogRotationState;
 
+typedef enum {
+       EOG_PAN_ACTION_NONE,
+       EOG_PAN_ACTION_NEXT,
+       EOG_PAN_ACTION_PREV
+} EogPanAction;
+
 /* Drag 'n Drop */
 static GtkTargetEntry target_table[] = {
        { "text/uri-list", 0, 0},
@@ -169,10 +177,12 @@ struct _EogScrollViewPrivate {
 
        cairo_surface_t *background_surface;
 
+       GtkGesture *pan_gesture;
        GtkGesture *zoom_gesture;
        GtkGesture *rotate_gesture;
        gdouble initial_zoom;
        EogRotationState rotate_state;
+       EogPanAction pan_action;
 };
 
 static void scroll_by (EogScrollView *view, int xofs, int yofs);
@@ -1989,6 +1999,56 @@ rotate_gesture_begin_cb (GtkGesture       *gesture,
        priv->rotate_state = EOG_TRANSFORM_NONE;
 }
 
+static void
+pan_gesture_pan_cb (GtkGesturePan   *gesture,
+                   GtkPanDirection  direction,
+                   gdouble          offset,
+                   EogScrollView   *view)
+{
+       EogScrollViewPrivate *priv;
+
+       if (eog_scroll_view_scrollbars_visible (view)) {
+               gtk_gesture_set_state (GTK_GESTURE (gesture),
+                                      GTK_EVENT_SEQUENCE_DENIED);
+               return;
+       }
+
+#define PAN_ACTION_DISTANCE 200
+
+       priv = view->priv;
+       priv->pan_action = EOG_PAN_ACTION_NONE;
+       gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+
+       if (offset > PAN_ACTION_DISTANCE) {
+               if (direction == GTK_PAN_DIRECTION_LEFT ||
+                   gtk_widget_get_direction (GTK_WIDGET (view)) == GTK_TEXT_DIR_RTL)
+                       priv->pan_action = EOG_PAN_ACTION_NEXT;
+               else
+                       priv->pan_action = EOG_PAN_ACTION_PREV;
+       }
+#undef PAN_ACTION_DISTANCE
+}
+
+static void
+pan_gesture_end_cb (GtkGesture       *gesture,
+                   GdkEventSequence *sequence,
+                   EogScrollView    *view)
+{
+       EogScrollViewPrivate *priv;
+
+       if (!gtk_gesture_handles_sequence (gesture, sequence))
+               return;
+
+       priv = view->priv;
+
+       if (priv->pan_action == EOG_PAN_ACTION_PREV)
+               g_signal_emit (view, view_signals [SIGNAL_PREVIOUS_IMAGE], 0);
+       else if (priv->pan_action == EOG_PAN_ACTION_NEXT)
+               g_signal_emit (view, view_signals [SIGNAL_NEXT_IMAGE], 0);
+
+       priv->pan_action = EOG_PAN_ACTION_NONE;
+}
+
 static gboolean
 scroll_view_check_angle (gdouble angle,
                         gdouble min,
@@ -2752,6 +2812,15 @@ eog_scroll_view_init (EogScrollView *view)
                          G_CALLBACK (rotate_gesture_begin_cb), view);
        gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->rotate_gesture),
                                                    GTK_PHASE_CAPTURE);
+
+       priv->pan_gesture = gtk_gesture_pan_new (GTK_WIDGET (view),
+                                                GTK_ORIENTATION_HORIZONTAL);
+       g_signal_connect (priv->pan_gesture, "pan",
+                         G_CALLBACK (pan_gesture_pan_cb), view);
+       g_signal_connect (priv->pan_gesture, "end",
+                         G_CALLBACK (pan_gesture_end_cb), view);
+       gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->pan_gesture),
+                                                   GTK_PHASE_CAPTURE);
 }
 
 static void
@@ -2804,6 +2873,11 @@ eog_scroll_view_dispose (GObject *object)
                priv->rotate_gesture = NULL;
        }
 
+       if (priv->pan_gesture) {
+               g_object_unref (priv->pan_gesture);
+               priv->pan_gesture = NULL;
+       }
+
        G_OBJECT_CLASS (eog_scroll_view_parent_class)->dispose (object);
 }
 
@@ -3035,6 +3109,23 @@ eog_scroll_view_class_init (EogScrollViewClass *klass)
                              G_TYPE_NONE, 1,
                              G_TYPE_DOUBLE);
 
+       view_signals [SIGNAL_NEXT_IMAGE] =
+               g_signal_new ("next-image",
+                             EOG_TYPE_SCROLL_VIEW,
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (EogScrollViewClass, next_image),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
+       view_signals [SIGNAL_PREVIOUS_IMAGE] =
+               g_signal_new ("previous-image",
+                             EOG_TYPE_SCROLL_VIEW,
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (EogScrollViewClass, previous_image),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
+
        widget_class->size_allocate = eog_scroll_view_size_allocate;
        widget_class->style_set = eog_scroll_view_style_set;
 }
diff --git a/src/eog-scroll-view.h b/src/eog-scroll-view.h
index bf3171c..2b31912 100644
--- a/src/eog-scroll-view.h
+++ b/src/eog-scroll-view.h
@@ -27,6 +27,8 @@ struct _EogScrollViewClass {
        GtkGridClass parent_class;
 
        void (* zoom_changed) (EogScrollView *view, double zoom);
+       void (* next_image) (EogScrollView *view);
+       void (* previous_image) (EogScrollView *view);
 };
 
 /**


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