]> www.fi.muni.cz Git - evince.git/commitdiff
add parameters providing allocation width and height without scrollbars
authorMartin Kretzschmar <martink@src.gnome.org>
Tue, 15 Feb 2005 08:26:23 +0000 (08:26 +0000)
committerMartin Kretzschmar <martink@src.gnome.org>
Tue, 15 Feb 2005 08:26:23 +0000 (08:26 +0000)
* shell/ev-view.c (ev_view_best_fit, ev_view_fit_width): add
parameters providing allocation width and height without
scrollbars and width of a possible vertical scrollbar. With this
additional information the functions can work as
intended. Unfortunately they're not idempotent. We should
transform these commands to toggles. Fixes Bug #164976
Initial patch by Stephane Loeuillet, then heavily modified.

* shell/ev-view.h: update prototypes.

* shell/ev-window.c (ev_window_cmd_view_best_fit)
(ev_window_cmd_view_page_width): provide EvView fit functions with
all the information they need. Formulas to calculate this
information taken from GtkScrolledWindow.

ChangeLog
shell/ev-view.c
shell/ev-view.h
shell/ev-window.c

index 42863e253af1a56bec1d3a5bd076d6a4cd4b135d..be9db9a22b08724f6c08bdd4a8cfc416d9e2d2cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-02-14  Martin Kretzschmar  <martink@gnome.org>
+
+       * shell/ev-view.c (ev_view_best_fit, ev_view_fit_width): add
+       parameters providing allocation width and height without
+       scrollbars and width of a possible vertical scrollbar. With this
+       additional information the functions can work as
+       intended. Unfortunately they're not idempotent. We should
+       transform these commands to toggles. Fixes Bug #164976
+       Initial patch by Stephane Loeuillet, then heavily modified.
+
+       * shell/ev-view.h: update prototypes.
+
+       * shell/ev-window.c (ev_window_cmd_view_best_fit)
+       (ev_window_cmd_view_page_width): provide EvView fit functions with
+       all the information they need. Formulas to calculate this
+       information taken from GtkScrolledWindow.
+
 2005-02-14  Crispin Flowerday  <gnome@flowerday.cx>
 
        * shell/ev-sidebar-thumbnails.c: Ensure that after we have
index 8fd87238985e8f0826a0368467c9003aab833d35..e3c81a05b5c85b4d256cf2d93a758fd91e446ba4 100644 (file)
@@ -1233,21 +1233,34 @@ ev_view_normal_size (EvView *view)
        ev_view_zoom (view, 1.0, FALSE);
 }
 
+/* Unfortunately this is not idempotent (!) (numerical stability
+ * issues because width and height are rounded)
+ *
+ * One more reason to make this a toggle and not a command */
 void
-ev_view_best_fit (EvView *view)
+ev_view_best_fit (EvView *view, int allocation_width, int allocation_height)
 {
        double scale;
+       int available_width, available_height;
        int width, height;
 
        width = height = 0;
+       /* This is the bad part. You could make it stable by doing
+        * ev_document_set_scale 1.0. But at least with pdf this means
+        * redrawing the whole page */
        ev_document_get_page_size (view->document, -1, &width, &height);
 
+       LOG ("Best fit %d %d", allocation_width, allocation_height);
+
        scale = 1.0;
        if (width != 0 && height != 0) {
                double scale_w, scale_h;
 
-               scale_w = (double)GTK_WIDGET (view)->allocation.width * view->scale / width;
-               scale_h = (double)GTK_WIDGET (view)->allocation.height * view->scale / height;
+               available_width = MAX (1, allocation_width - 2); /* 1 px border left and right */
+               available_height = MAX (1, allocation_height - 2); /* 1 px border above and below */
+
+               scale_w = (double)available_width * view->scale / (width + 0.5);
+               scale_h = (double)available_height * view->scale / (height + 0.5);
 
                scale = (scale_w < scale_h) ? scale_w : scale_h;
        }
@@ -1256,17 +1269,27 @@ ev_view_best_fit (EvView *view)
 }
 
 void
-ev_view_fit_width (EvView *view)
+ev_view_fit_width (EvView *view, int allocation_width, int allocation_height,
+                  int vsb_width)
 {
+       int available_width, available_height;
+       int width, height;
        double scale = 1.0;
-       int width;
 
-       width = 0;
-       ev_document_get_page_size (view->document, -1, &width, NULL);
+       width = height = 0;
+       ev_document_get_page_size (view->document, -1, &width, &height);
 
        scale = 1.0;
-       if (width != 0)
-               scale = (double)GTK_WIDGET (view)->allocation.width * view->scale / width;
+       if (width != 0) {
+               available_width = MAX (1, allocation_width - 2); /* 1px border */
+               available_height = MAX (1, allocation_height - 2); /* 1px border */
+
+               scale = (double)available_width * view->scale / (width + 0.5);
+
+               if ((height + 0.5) * scale / view->scale > available_height)
+                       scale = ((double)(available_width - vsb_width) * view->scale /
+                                (width + 0.5));
+       }
 
        ev_view_zoom (view, scale, FALSE);
 }
index a72ed6b48f25d0b64b687010ababf1baf505efb7..f108f9f505fa51d7051500184b012e53c4f16319 100644 (file)
@@ -58,8 +58,8 @@ int           ev_view_get_page        (EvView     *view);
 void           ev_view_zoom_in         (EvView     *view);
 void           ev_view_zoom_out        (EvView     *view);
 void           ev_view_normal_size     (EvView     *view);
-void           ev_view_best_fit        (EvView     *view);
-void           ev_view_fit_width       (EvView     *view);
+void           ev_view_best_fit        (EvView     *view, int width, int height);
+void           ev_view_fit_width       (EvView     *view, int width, int height, int vsb_width);
 
 /* Find */
 void            ev_view_find_next       (EvView     *view);
index a1d74f686c6701b8510384f04ea5753254d327f8..547eaf0bec07a1adaa1f325255e5dce39e041f27 100644 (file)
@@ -1197,17 +1197,49 @@ ev_window_cmd_view_normal_size (GtkAction *action, EvWindow *ev_window)
 static void
 ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
 {
+       EvWindowPrivate *priv = ev_window->priv;
+       int width, height;
+
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
-       ev_view_best_fit (EV_VIEW (ev_window->priv->view));
+       width = priv->scrolled_window->allocation.width;
+       height = priv->scrolled_window->allocation.height;
+
+       /* the scrolled window has a GTK_SHADOW_IN */
+       width -= 2 * priv->view->style->xthickness;
+       height -= 2 * priv->view->style->ythickness;
+
+       ev_view_best_fit (EV_VIEW (priv->view),
+                         MAX (1, width), MAX (1, height));
 }
 
 static void
 ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window)
 {
+       EvWindowPrivate *priv = ev_window->priv;
+       int width, height;
+       GtkRequisition vsb_requisition;
+       int scrollbar_spacing;
+
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
-       ev_view_fit_width (EV_VIEW (ev_window->priv->view));
+       width = priv->scrolled_window->allocation.width;
+       height = priv->scrolled_window->allocation.height;
+
+       /* the scrolled window has a GTK_SHADOW_IN */
+       width -= 2 * priv->view->style->xthickness;
+       height -= 2 * priv->view->style->ythickness;
+
+       gtk_widget_size_request (
+               GTK_SCROLLED_WINDOW (priv->scrolled_window)->vscrollbar,
+               &vsb_requisition);
+       gtk_widget_style_get (priv->scrolled_window,
+                             "scrollbar_spacing", &scrollbar_spacing,
+                             NULL);
+
+       ev_view_fit_width (EV_VIEW (ev_window->priv->view),
+                          width, height,
+                          vsb_requisition.width + scrollbar_spacing);
 }
 
 static void