[evince/gestures: 2/2] ev-view: Add pan gesture to switch page
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/gestures: 2/2] ev-view: Add pan gesture to switch page
- Date: Mon, 2 Jun 2014 17:14:25 +0000 (UTC)
commit 57194075ce409c5c2ea6867a382d2ea839a153a3
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue May 6 13:57:00 2014 +0200
ev-view: Add pan gesture to switch page
This only applies on non-continuous mode, and the page fits with no
horizontal scrolling. The gesture is actually connected to the parent
GtkScrolledWindow (tracked through hierarchy events), so it is able
to interact with kinetic scrolling gestures there, and cancel those
if the pan gesture is recognized.
libview/ev-view-private.h | 8 +++++
libview/ev-view.c | 75 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+), 0 deletions(-)
---
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 82cc241..c005632 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -72,6 +72,12 @@ typedef struct {
EvImage *image;
} ImageDNDInfo;
+typedef enum {
+ EV_PAN_ACTION_NONE,
+ EV_PAN_ACTION_NEXT,
+ EV_PAN_ACTION_PREV
+} EvPanAction;
+
/* Annotation popup windows */
typedef struct {
GtkWidget *window;
@@ -223,8 +229,10 @@ struct _EvView {
guint cursor_blink_time;
/* Gestures */
+ GtkGesture *pan_gesture;
GtkGesture *zoom_gesture;
gdouble prev_zoom_scale;
+ EvPanAction pan_action;
};
struct _EvViewClass {
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 6eb1d37..43606e7 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -6445,6 +6445,80 @@ ev_view_screen_changed (GtkWidget *widget,
}
static void
+pan_gesture_pan_cb (GtkGesturePan *gesture,
+ GtkPanDirection direction,
+ gdouble offset,
+ EvView *view)
+{
+ GtkAllocation allocation;
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (view));
+ g_assert (GTK_IS_SCROLLED_WINDOW (parent));
+
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+
+ if (view->continuous ||
+ allocation.width < view->requisition.width) {
+ gtk_gesture_set_state (GTK_GESTURE (gesture),
+ GTK_EVENT_SEQUENCE_DENIED);
+ return;
+ }
+
+#define PAN_ACTION_DISTANCE 200
+
+ view->pan_action = EV_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)
+ view->pan_action = EV_PAN_ACTION_NEXT;
+ else
+ view->pan_action = EV_PAN_ACTION_PREV;
+ }
+#undef PAN_ACTION_DISTANCE
+}
+
+static void
+pan_gesture_end_cb (GtkGesture *gesture,
+ GdkEventSequence *sequence,
+ EvView *view)
+{
+ if (!gtk_gesture_handles_sequence (gesture, sequence))
+ return;
+
+ if (view->pan_action == EV_PAN_ACTION_PREV)
+ ev_view_previous_page (view);
+ else if (view->pan_action == EV_PAN_ACTION_NEXT)
+ ev_view_next_page (view);
+
+ view->pan_action = EV_PAN_ACTION_NONE;
+}
+
+static void
+ev_view_hierarchy_changed (GtkWidget *widget,
+ GtkWidget *previous_toplevel)
+{
+ GtkWidget *parent = gtk_widget_get_parent (widget);
+ EvView *view = EV_VIEW (widget);
+
+ if (parent && GTK_IS_SCROLLED_WINDOW (parent) && !view->pan_gesture) {
+ view->pan_gesture =
+ gtk_gesture_pan_new (parent, GTK_ORIENTATION_HORIZONTAL);
+ g_signal_connect (view->pan_gesture, "pan",
+ G_CALLBACK (pan_gesture_pan_cb), widget);
+ g_signal_connect (view->pan_gesture, "end",
+ G_CALLBACK (pan_gesture_end_cb), widget);
+
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (view->pan_gesture),
+ GTK_PHASE_CAPTURE);
+ } else if (!parent && view->pan_gesture) {
+ g_clear_object (&view->pan_gesture);
+ }
+}
+
+static void
add_move_binding_keypad (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
@@ -6511,6 +6585,7 @@ ev_view_class_init (EvViewClass *class)
widget_class->popup_menu = ev_view_popup_menu;
widget_class->query_tooltip = ev_view_query_tooltip;
widget_class->screen_changed = ev_view_screen_changed;
+ widget_class->hierarchy_changed = ev_view_hierarchy_changed;
container_class->remove = ev_view_remove;
container_class->forall = ev_view_forall;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]