diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h index 7727bbb3..66a47c43 100644 --- a/libview/ev-view-private.h +++ b/libview/ev-view-private.h @@ -222,6 +222,10 @@ struct _EvView { gboolean cursor_visible; guint cursor_blink_timeout_id; guint cursor_blink_time; + + /* Gestures */ + GtkGesture *zoom_gesture; + gdouble prev_zoom_gesture_scale; }; struct _EvViewClass { diff --git a/libview/ev-view.c b/libview/ev-view.c index 4b64e22c..17371396 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -4707,7 +4707,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); } @@ -5028,6 +5031,9 @@ ev_view_motion_notify_event (GtkWidget *widget, if (!view->document) return FALSE; + if (gtk_gesture_is_recognized (view->zoom_gesture)) + return TRUE; + window = gtk_widget_get_window (widget); if (event->is_hint || event->window != window) { @@ -5184,6 +5190,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; @@ -6303,6 +6312,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); } @@ -6985,6 +6996,33 @@ on_notify_scale_factor (EvView *view, view_update_range_and_current_page (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) { @@ -7000,6 +7038,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 | @@ -7037,6 +7076,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 ***/