summaryrefslogtreecommitdiff
path: root/libview
diff options
context:
space:
mode:
authorClement Lefebvre <[email protected]>2017-03-14 14:35:04 +0000
committerraveit65 <[email protected]>2017-08-18 21:18:30 +0200
commitc508d14764871f4d052cc28b283dc9f0f1416898 (patch)
tree24a7e7a3ba377379568b186c00f5c1487e92d576 /libview
parent3bd070a5580f2d6d678c266af88b7dc0b816f4db (diff)
downloadatril-c508d14764871f4d052cc28b283dc9f0f1416898.tar.bz2
atril-c508d14764871f4d052cc28b283dc9f0f1416898.tar.xz
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. Upstream commits by garnacho on 6 May and 15 Aug 2014: https://github.com/GNOME/evince/commit/afc50e7e07c135e22137a33cbf9913713692bf49 https://github.com/GNOME/evince/commit/2280b09ec71ee88eeeb7fd8d02adb2985d17a765
Diffstat (limited to 'libview')
-rw-r--r--libview/ev-view-private.h8
-rw-r--r--libview/ev-view.c72
2 files changed, 80 insertions, 0 deletions
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 6e41d2ad..1d1220f3 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -73,6 +73,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;
@@ -204,8 +210,10 @@ struct _EvView {
AtkObject *accessible;
/* Gestures */
+ GtkGesture *pan_gesture;
GtkGesture *zoom_gesture;
gdouble prev_zoom_gesture_scale;
+ EvPanAction pan_action;
};
struct _EvViewClass {
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 4bd3b23c..c9d97f44 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -4757,6 +4757,77 @@ ev_view_forall (GtkContainer *container,
}
static void
+pan_gesture_pan_cb (GtkGesturePan *gesture,
+ GtkPanDirection direction,
+ gdouble offset,
+ EvView *view)
+{
+ GtkAllocation allocation;
+
+ 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 && !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_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (view->pan_gesture), TRUE);
+ 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
ev_view_parent_set (GtkWidget *widget,
GtkWidget *previous_parent)
{
@@ -4799,6 +4870,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->parent_set = ev_view_parent_set;
+ widget_class->hierarchy_changed = ev_view_hierarchy_changed;
object_class->dispose = ev_view_dispose;