diff options
author | Clement Lefebvre <[email protected]> | 2017-03-14 13:47:19 +0000 |
---|---|---|
committer | raveit65 <[email protected]> | 2017-08-18 21:18:30 +0200 |
commit | 42768626e77556ca28a627e18db87ff7e3d4a61e (patch) | |
tree | 68f4b242998e6e757c56f64cd5665683c0806a28 | |
parent | 126fb75a05e5dccc468738fc614e145728b60613 (diff) | |
download | atril-42768626e77556ca28a627e18db87ff7e3d4a61e.tar.bz2 atril-42768626e77556ca28a627e18db87ff7e3d4a61e.tar.xz |
ev-view: Add pinch/zoom gesture to handle document zooming
This is delegated on a GtkGestureZoom. When triggered, the document
will be zoomed based on the distance changes between both fingers.
When the gesture is not active, regular event handling (text selection,
clicking, etc...) will happen.
Upstream commit from garnacho on 28 Mar 2014:
https://github.com/GNOME/evince/commit/36c7f21
-rw-r--r-- | libview/ev-view-private.h | 4 | ||||
-rw-r--r-- | libview/ev-view.c | 68 | ||||
-rw-r--r-- | libview/ev-view.h | 2 |
3 files changed, 64 insertions, 10 deletions
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h index 8957dad8..6e41d2ad 100644 --- a/libview/ev-view-private.h +++ b/libview/ev-view-private.h @@ -202,6 +202,10 @@ struct _EvView { /* Accessibility */ AtkObject *accessible; + + /* Gestures */ + GtkGesture *zoom_gesture; + gdouble prev_zoom_gesture_scale; }; struct _EvViewClass { diff --git a/libview/ev-view.c b/libview/ev-view.c index 86eef350..77851234 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -3609,7 +3609,10 @@ ev_view_button_press_event (GtkWidget *widget, if (!view->document) return FALSE; - + + if (gtk_gesture_is_recognized (view->zoom_gesture)) + return TRUE; + if (!gtk_widget_has_focus (widget)) { gtk_widget_grab_focus (widget); } @@ -3922,6 +3925,9 @@ ev_view_motion_notify_event (GtkWidget *widget, if (!view->document) return FALSE; + if (gtk_gesture_is_recognized (view->zoom_gesture)) + return TRUE; + bin_window = gtk_widget_get_window (widget); if (event->is_hint || event->window != bin_window) { @@ -4082,6 +4088,9 @@ ev_view_button_release_event (GtkWidget *widget, view->image_dnd_info.in_drag = FALSE; + if (gtk_gesture_is_recognized (view->zoom_gesture)) + return TRUE; + if (view->scroll_info.autoscrolling) { ev_view_autoscroll_stop (view); view->pressed_button = -1; @@ -4567,6 +4576,8 @@ ev_view_finalize (GObject *object) g_object_unref (view->image_dnd_info.image); view->image_dnd_info.image = NULL; + g_object_unref (view->zoom_gesture); + G_OBJECT_CLASS (ev_view_parent_class)->finalize (object); } @@ -4890,6 +4901,33 @@ on_notify_scale_factor (EvView *view, } static void +zoom_gesture_begin_cb (GtkGesture *gesture, + GdkEventSequence *sequence, + EvView *view) +{ + view->prev_zoom_gesture_scale = 1; +} + +static void +zoom_gesture_scale_changed_cb (GtkGestureZoom *gesture, + gdouble scale, + EvView *view) +{ + gdouble factor; + + view->drag_info.in_drag = FALSE; + view->image_dnd_info.in_drag = FALSE; + + factor = scale - view->prev_zoom_gesture_scale + 1; + view->prev_zoom_gesture_scale = scale; + ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE); + + if ((factor < 1.0 && ev_view_can_zoom_out (view)) || + (factor >= 1.0 && ev_view_can_zoom_in (view))) + ev_view_zoom (view, factor); +} + +static void ev_view_init (EvView *view) { GtkStyleContext *context; @@ -4904,6 +4942,7 @@ ev_view_init (EvView *view) gtk_style_context_add_class (context, "view"); gtk_widget_set_events (GTK_WIDGET (view), + GDK_TOUCH_MASK | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -4938,6 +4977,15 @@ ev_view_init (EvView *view) g_signal_connect (view, "notify::scale-factor", G_CALLBACK (on_notify_scale_factor), NULL); + + view->zoom_gesture = gtk_gesture_zoom_new (GTK_WIDGET (view)); + gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (view->zoom_gesture), + GTK_PHASE_CAPTURE); + + g_signal_connect (view->zoom_gesture, "begin", + G_CALLBACK (zoom_gesture_begin_cb), view); + g_signal_connect (view->zoom_gesture, "scale-changed", + G_CALLBACK (zoom_gesture_scale_changed_cb), view); } /*** Callbacks ***/ @@ -5447,27 +5495,27 @@ ev_view_can_zoom_out (EvView *view) } void -ev_view_zoom_in (EvView *view) +ev_view_zoom (EvView *view, gdouble factor) { gdouble scale; g_return_if_fail (view->sizing_mode == EV_SIZING_FREE); view->pending_scroll = SCROLL_TO_CENTER; - scale = ev_document_model_get_scale (view->model) * ZOOM_IN_FACTOR; + scale = ev_document_model_get_scale (view->model) * factor; ev_document_model_set_scale (view->model, scale); } void -ev_view_zoom_out (EvView *view) +ev_view_zoom_in (EvView *view) { - gdouble scale; - - g_return_if_fail (view->sizing_mode == EV_SIZING_FREE); + ev_view_zoom (view, ZOOM_IN_FACTOR); +} - view->pending_scroll = SCROLL_TO_CENTER; - scale = ev_document_model_get_scale (view->model) * ZOOM_OUT_FACTOR; - ev_document_model_set_scale (view->model, scale); +void +ev_view_zoom_out (EvView *view) +{ + ev_view_zoom (view, ZOOM_OUT_FACTOR); } static double diff --git a/libview/ev-view.h b/libview/ev-view.h index 85c942df..31a9bf41 100644 --- a/libview/ev-view.h +++ b/libview/ev-view.h @@ -68,6 +68,8 @@ gboolean ev_view_can_zoom_in (EvView *view); void ev_view_zoom_in (EvView *view); gboolean ev_view_can_zoom_out (EvView *view); void ev_view_zoom_out (EvView *view); +void ev_view_zoom (EvView *view, + gdouble factor); /* Find */ void ev_view_find_next (EvView *view); |