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 /libview/ev-view.c | |
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
Diffstat (limited to 'libview/ev-view.c')
-rw-r--r-- | libview/ev-view.c | 72 |
1 files changed, 72 insertions, 0 deletions
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; |