diff options
author | Clement Lefebvre <[email protected]> | 2017-03-14 14:35:04 +0000 |
---|---|---|
committer | raveit65 <[email protected]> | 2017-08-18 21:18:30 +0200 |
commit | c508d14764871f4d052cc28b283dc9f0f1416898 (patch) | |
tree | 24a7e7a3ba377379568b186c00f5c1487e92d576 | |
parent | 3bd070a5580f2d6d678c266af88b7dc0b816f4db (diff) | |
download | atril-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
-rw-r--r-- | libview/ev-view-private.h | 8 | ||||
-rw-r--r-- | libview/ev-view.c | 72 |
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; |