Blob Blame History Raw
From 511ab26917ed9e856ebbc8f764a5b68613ebc1cd Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Mon, 9 May 2016 12:57:20 +0200
Subject: [PATCH] libview: Scroll small pages in non-continuous mode

Check whether currently shown page fits actual view and allow user to scroll
to previous/next page in that case (also in Dual page mode).
Allow also scrolling if only one axis fits the view and the event
happenned in the same axis.

https://bugzilla.gnome.org/show_bug.cgi?id=562257
---
 libview/ev-view.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 83 insertions(+), 14 deletions(-)

diff --git a/libview/ev-view.c b/libview/ev-view.c
index f76eca8..f96ad4b 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -247,6 +247,8 @@ static void 	ev_view_zoom_for_size_dual_page 	       (EvView *view,
 static void	ev_view_zoom_for_size_single_page 	       (EvView *view,
 				    			        int     width,
 					    			int     height);
+static gboolean	ev_view_page_fits			       (EvView         *view,
+								GtkOrientation  orientation);
 /*** Cursors ***/
 static void       ev_view_set_cursor                         (EvView             *view,
 							      EvViewCursor        new_cursor);
@@ -973,7 +998,8 @@ ev_view_scroll (EvView        *view,
 
 	view->jump_to_find_result = FALSE;
 
-	if (view->sizing_mode == EV_SIZING_FIT_PAGE) {
+	if ((!horizontal && ev_view_page_fits (view, GTK_ORIENTATION_VERTICAL)) ||
+	    (horizontal && ev_view_page_fits (view, GTK_ORIENTATION_HORIZONTAL))) {
 		switch (scroll) {
 			case GTK_SCROLL_PAGE_BACKWARD:
 			case GTK_SCROLL_STEP_BACKWARD:
@@ -3972,6 +4116,7 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event)
 {
 	EvView *view = EV_VIEW (widget);
 	guint state;
+	gboolean fit_width, fit_height;
 
 	state = event->state & gtk_accelerator_get_default_mod_mask ();
 
@@ -4026,34 +4174,57 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event)
 		state &= ~GDK_SHIFT_MASK;
 	}
 
-	if (state == 0 && view->sizing_mode == EV_SIZING_FIT_PAGE && !view->continuous) {
+	fit_width = ev_view_page_fits (view, GTK_ORIENTATION_HORIZONTAL);
+	fit_height = ev_view_page_fits (view, GTK_ORIENTATION_VERTICAL);
+	if (state == 0 && !view->continuous && (fit_width || fit_height)) {
 		switch (event->direction) {
 		case GDK_SCROLL_DOWN:
+			if (fit_height) {
+				ev_view_next_page (view);
+				return TRUE;
+			}
+			break;
 		case GDK_SCROLL_RIGHT:
-			ev_view_next_page (view);
+			if (fit_width) {
+				ev_view_next_page (view);
+				return TRUE;
+			}
 			break;
 		case GDK_SCROLL_UP:
+			if (fit_height) {
+				ev_view_previous_page (view);
+				return TRUE;
+			}
+			break;
 		case GDK_SCROLL_LEFT:
-			ev_view_previous_page (view);
+			if (fit_width) {
+				ev_view_previous_page (view);
+				return TRUE;
+			}
 			break;
 		case GDK_SCROLL_SMOOTH: {
 			gdouble decrement;
+			if ((fit_width && fit_height) ||
+			    ((fit_height && event->delta_x == 0.0) ||
+			     (fit_width && event->delta_y == 0.0))) {
+				/* 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);
+				}
 
-			/* 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);
+				return TRUE;
 			}
 		}
 			break;
 		}
 
-		return TRUE;
+		return FALSE;
 	}
 
 	return FALSE;
@@ -8111,6 +8571,48 @@ ev_view_zoom_for_size (EvView *view,
 		ev_view_zoom_for_size_single_page (view, width, height);
 }
 
+static gboolean
+ev_view_page_fits (EvView         *view,
+		   GtkOrientation  orientation)
+{
+	GtkRequisition requisition;
+	GtkAllocation  allocation;
+	double         size;
+
+	if (view->sizing_mode == EV_SIZING_FIT_PAGE)
+		return TRUE;
+
+	if (orientation == GTK_ORIENTATION_HORIZONTAL &&
+	    (view->sizing_mode == EV_SIZING_FIT_WIDTH ||
+	     view->sizing_mode == EV_SIZING_AUTOMATIC))
+		return TRUE;
+
+	gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+	ev_view_size_request (GTK_WIDGET (view), &requisition);
+
+	if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+		if (requisition.width == 1) {
+			size = 1.0;
+		} else {
+			if (allocation.width > 0.0)
+				size = (double) requisition.width / allocation.width;
+			else
+				size = 1.0;
+		}
+	} else {
+		if (requisition.height == 1) {
+			size = 1.0;
+		} else {
+			if (allocation.height > 0.0)
+				size = (double) requisition.height / allocation.height;
+			else
+				size = 1.0;
+		}
+	}
+
+	return size <= 1.0;
+}
+
 /*** Find ***/
 static gint
 ev_view_find_get_n_results (EvView *view, gint page)
-- 
2.7.4