diff options
Diffstat (limited to 'libview')
-rw-r--r-- | libview/ev-view-private.h | 2 | ||||
-rw-r--r-- | libview/ev-view.c | 71 |
2 files changed, 52 insertions, 21 deletions
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h index eef79f92..f85af71d 100644 --- a/libview/ev-view-private.h +++ b/libview/ev-view-private.h @@ -150,6 +150,8 @@ struct _EvView { gint scroll_x; gint scroll_y; + /* Delta sum for emulating normal scrolling */ + gdouble total_delta; PendingScroll pending_scroll; gboolean pending_resize; EvPoint pending_point; diff --git a/libview/ev-view.c b/libview/ev-view.c index 3a5fefdd..b7a5335e 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -3287,24 +3287,32 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event) EvView *view = EV_VIEW (widget); guint state; - if (event->direction == GDK_SCROLL_SMOOTH) - return FALSE; - state = event->state & gtk_accelerator_get_default_mod_mask (); if (state == GDK_CONTROL_MASK) { ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE); view->zoom_center_x = event->x; view->zoom_center_y = event->y; - if (event->direction == GDK_SCROLL_UP || - event->direction == GDK_SCROLL_LEFT) { - if (ev_view_can_zoom_in (view)) { - ev_view_zoom_in (view); - } - } else { - if (ev_view_can_zoom_out (view)) { + switch (event->direction) { + case GDK_SCROLL_DOWN: + case GDK_SCROLL_RIGHT: + if (ev_view_can_zoom_out (view)) ev_view_zoom_out (view); - } + break; + case GDK_SCROLL_UP: + case GDK_SCROLL_LEFT: + if (ev_view_can_zoom_in (view)) + ev_view_zoom_in (view); + break; + case GDK_SCROLL_SMOOTH: { + gdouble delta = event->delta_x + event->delta_y; + gdouble factor = pow (delta < 0 ? ZOOM_IN_FACTOR : ZOOM_OUT_FACTOR, fabs (delta)); + + if ((factor < 1.0 && ev_view_can_zoom_out (view)) || + (factor >= 1.0 && ev_view_can_zoom_in (view))) + ev_view_zoom (view, factor); + } + break; } return TRUE; @@ -3322,6 +3330,13 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event) event->direction = GDK_SCROLL_RIGHT; else if (event->direction == GDK_SCROLL_RIGHT) event->direction = GDK_SCROLL_DOWN; + else if (event->direction == GDK_SCROLL_SMOOTH) { + /* Swap the deltas for perpendicular direction */ + gdouble tmp_delta = event->delta_x; + + event->delta_x = event->delta_y; + event->delta_y = tmp_delta; + } event->state &= ~GDK_SHIFT_MASK; state &= ~GDK_SHIFT_MASK; @@ -3329,16 +3344,29 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event) if (state == 0 && view->sizing_mode == EV_SIZING_BEST_FIT && !view->continuous) { switch (event->direction) { - case GDK_SCROLL_DOWN: - case GDK_SCROLL_RIGHT: - ev_view_next_page (view); - break; - case GDK_SCROLL_UP: - case GDK_SCROLL_LEFT: - ev_view_previous_page (view); - break; - case GDK_SCROLL_SMOOTH: - g_assert_not_reached (); + case GDK_SCROLL_DOWN: + case GDK_SCROLL_RIGHT: + ev_view_next_page (view); + break; + case GDK_SCROLL_UP: + case GDK_SCROLL_LEFT: + ev_view_previous_page (view); + break; + case GDK_SCROLL_SMOOTH: { + gdouble decrement; + + /* Emulate normal scrolling by summing the deltas */ + view->total_delta += event->delta_x + event->delta_y; + + decrement = view->total_delta < 0 ? -1.0 : 1.0; + for (; fabs (view->total_delta) >= 1.0; view->total_delta -= decrement) { + if (decrement < 0) + ev_view_previous_page (view); + else + ev_view_next_page (view); + } + } + break; } return TRUE; @@ -5042,6 +5070,7 @@ ev_view_init (EvView *view) GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_SCROLL_MASK | + GDK_SMOOTH_SCROLL_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | |