]> git.sur5r.net Git - glabels/commitdiff
Modified zoom code:
authorJim Evins <evins@snaught.com>
Wed, 26 Nov 2003 01:12:23 +0000 (01:12 +0000)
committerJim Evins <evins@snaught.com>
Wed, 26 Nov 2003 01:12:23 +0000 (01:12 +0000)
- Now keeps track of zoom levels, rather than screen scale
- Calculates home scale from screen DPI
- View size changes are tracked, and if selected zoom_to_fit is maintained.
- New windows default to zoom_to_fit.
- Tracks changes in screen, so that new home scale can be updated

git-svn-id: https://glabels.svn.sourceforge.net/svnroot/glabels/trunk@352 f5e0f49d-192f-0410-a22d-a8d8700d0965

glabels2/src/tools.c
glabels2/src/view-highlight.c
glabels2/src/view.c
glabels2/src/view.h
glabels2/src/window.c

index 9b6e1e8132b7127accb9c09d39d1410191f7585f..d1a745e0af761ec1da2d4367e23227219ce4f5a3 100644 (file)
@@ -238,7 +238,7 @@ gl_tools_zoom_to_fit (BonoboUIComponent *uic,
        window = GL_WINDOW (user_data);
 
        if (window->view != NULL) {
-               gl_view_zoom_best_fit (GL_VIEW(window->view));
+               gl_view_zoom_to_fit (GL_VIEW(window->view));
        }
 }
 
index df8a501cf235d62d811ffcf36c29c1492b687ecc..247190a565d64ab1414c6cb4c57d8bec84a45f96 100644 (file)
@@ -318,7 +318,7 @@ highlight_resizable_box_construct (glViewHighlight        *view_highlight,
        g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
 
        view   = view_highlight->private->view;
-       scale = view->scale;
+       scale = view->zoom * view->home_scale;
 
        object = view_highlight->private->object;
 
@@ -514,7 +514,7 @@ highlight_resizable_line_construct (glViewHighlight *view_highlight,
        g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
 
        view   = view_highlight->private->view;
-       scale = view->scale;
+       scale = view->zoom * view->home_scale;
 
        object = view_highlight->private->object;
 
@@ -791,7 +791,8 @@ update_resizable_box  (glViewHighlight *view_highlight)
 
        g_return_if_fail (view_highlight && GL_IS_VIEW_HIGHLIGHT (view_highlight));
 
-       scale = view_highlight->private->view->scale;
+       scale = view_highlight->private->view->zoom *
+               view_highlight->private->view->home_scale;
 
        gl_label_object_get_size (view_highlight->private->object, &w, &h);
 
@@ -882,7 +883,8 @@ update_resizable_line (glViewHighlight *view_highlight)
 
        g_return_if_fail (view_highlight && GL_IS_VIEW_HIGHLIGHT (view_highlight));
 
-       scale = view_highlight->private->view->scale;
+       scale = view_highlight->private->view->zoom *
+               view_highlight->private->view->home_scale;
 
        gl_label_object_get_size (view_highlight->private->object, &dx, &dy);
 
index 80d96508643b3e08db33ae83c0b7979fb0c25fc8..60e987b574c6512dd6f67f4e4fa4821edada93c9 100644 (file)
@@ -62,7 +62,8 @@
 #define ARC_COURSE       5 /* Resolution in degrees of small arcs */
 
 #define ZOOMTOFIT_PAD   16
-#define HOME_SCALE       2.0
+
+#define POINTS_PER_MM    2.83464566929
 
 /*==========================================================================*/
 /* Private types.                                                           */
@@ -89,22 +90,24 @@ static guint signals[LAST_SIGNAL] = {0};
 /* "CLIPBOARD" selection */
 static GdkAtom clipboard_atom = GDK_NONE;
 
-static gdouble scales[] = {
-       4.00*HOME_SCALE,
-       3.00*HOME_SCALE,
-       2.00*HOME_SCALE,
-       1.50*HOME_SCALE,
-       1.00*HOME_SCALE,
-       0.75*HOME_SCALE,
-       0.67*HOME_SCALE,
-       0.50*HOME_SCALE,
-       0.33*HOME_SCALE,
-       0.25*HOME_SCALE,
-       0.20*HOME_SCALE,
-       0.15*HOME_SCALE,
-       0.10*HOME_SCALE,
+static gdouble zooms[] = {
+       8.00,
+       6.00,
+       4.00,
+       3.00,
+       2.00,
+       1.50,
+       1.00,
+       0.75,
+       0.67,
+       0.50,
+       0.33,
+       0.25,
+       0.20,
+       0.15,
+       0.10,
 };
-#define N_SCALES G_N_ELEMENTS(scales)
+#define N_ZOOMS G_N_ELEMENTS(zooms)
 
 
 /*==========================================================================*/
@@ -119,6 +122,8 @@ static void       gl_view_construct               (glView *view);
 static GtkWidget *gl_view_construct_canvas        (glView *view);
 static void       gl_view_construct_selection     (glView *view);
 
+static gdouble    get_home_scale                  (glView *view);
+
 static void       draw_layers                     (glView *view);
 
 static void       label_resized_cb                (glLabel *label,
@@ -171,6 +176,14 @@ static gboolean   is_item_member_of_group         (glView          *view,
                                                   GnomeCanvasItem *item,
                                                   GnomeCanvasItem *group);
 
+static void       set_zoom_real                   (glView          *view,
+                                                  gdouble          zoom,
+                                                  gboolean         scale_to_fit_flag);
+
+static void       size_allocate_cb                (glView          *view);
+
+static void       screen_changed_cb               (glView          *view);
+
 static int        canvas_event                    (GnomeCanvas *canvas,
                                                   GdkEvent    *event,
                                                   glView      *view);
@@ -392,10 +405,9 @@ gl_view_construct (glView *view)
 static GtkWidget *
 gl_view_construct_canvas (glView *view)
 {
-       gdouble   scale;
-       glLabel  *label;
-       gdouble   label_width, label_height;
-       GdkColor *bg_color;
+       glLabel   *label;
+       gdouble    label_width, label_height;
+       GdkColor  *bg_color;
 
        gl_debug (DEBUG_VIEW, "START");
 
@@ -416,14 +428,9 @@ gl_view_construct_canvas (glView *view)
        gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
                  label_width, label_height);
 
-       scale = HOME_SCALE;
-       gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas), scale);
-       view->scale = scale;
-
-       gl_debug (DEBUG_VIEW, "scale =%lf", scale);
-       gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
-                             scale * label_width + 40,
-                             scale * label_height + 40);
+       view->zoom = 1.0;
+       view->home_scale = get_home_scale (view);
+       gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas), view->home_scale);
 
        gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
                                        0.0, 0.0, label_width, label_height);
@@ -433,11 +440,61 @@ gl_view_construct_canvas (glView *view)
        g_signal_connect (G_OBJECT (view->canvas), "event",
                          G_CALLBACK (canvas_event), view);
 
+       g_signal_connect_swapped (G_OBJECT (view->canvas), "size-allocate",
+                                 G_CALLBACK (size_allocate_cb), view);
+
+       g_signal_connect_swapped (G_OBJECT (view->canvas), "screen-changed",
+                                 G_CALLBACK (screen_changed_cb), view);
+
        gl_debug (DEBUG_VIEW, "END");
 
        return view->canvas;
 }
 
+/*---------------------------------------------------------------------------*/
+/* PRIAVTE.  Calculate 1:1 scale for screen.                                 */
+/*---------------------------------------------------------------------------*/
+static gdouble
+get_home_scale (glView *view)
+{
+       GdkScreen *screen;
+       gdouble    screen_width_pixels, screen_width_mm;
+       gdouble    screen_height_pixels, screen_height_mm;
+       gdouble    x_pixels_per_mm, y_pixels_per_mm;
+       gdouble    scale;
+
+       if (!gtk_widget_has_screen) return 1.0;
+
+       screen = gtk_widget_get_screen (GTK_WIDGET (view->canvas));
+
+       screen_width_pixels  = gdk_screen_get_width (screen);
+       screen_width_mm      = gdk_screen_get_width_mm (screen);
+       screen_height_pixels = gdk_screen_get_height (screen);
+       screen_height_mm     = gdk_screen_get_height_mm (screen);
+
+       x_pixels_per_mm      = screen_width_pixels / screen_width_mm;
+       y_pixels_per_mm      = screen_height_pixels / screen_height_mm;
+
+       gl_debug (DEBUG_VIEW, "Horizontal dot pitch: %g pixels/mm (%g dpi)",
+                 x_pixels_per_mm, x_pixels_per_mm * 25.4);
+       gl_debug (DEBUG_VIEW, "Vertical dot pitch: %g pixels/mm (%g dpi)",
+                 y_pixels_per_mm, y_pixels_per_mm * 25.4);
+
+       scale = (x_pixels_per_mm + y_pixels_per_mm) / 2.0;
+
+       gl_debug (DEBUG_VIEW, "Average dot pitch: %g pixels/mm (%g dpi)",
+                 scale, scale * 25.4);
+
+       scale /= POINTS_PER_MM;
+
+       gl_debug (DEBUG_VIEW, "Scale = %g pixels/point", scale);
+
+       /* Make sure scale is somewhat sane. */
+       if ( (scale < 0.25) || (scale > 4.0) ) return 1.0;
+
+       return scale;
+}
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Create clipboard selection targets.                             */
 /*---------------------------------------------------------------------------*/
@@ -2942,9 +2999,9 @@ gl_view_zoom_in (glView *view)
 
        /* Find index of current scale (or best match) */
        i_min = 1;              /* start with 2nd largest scale */
-       dist_min = fabs (scales[1] - view->scale);
-       for (i = 2; i < N_SCALES; i++) {
-               dist = fabs (scales[i] - view->scale);
+       dist_min = fabs (zooms[1] - view->zoom);
+       for (i = 2; i < N_ZOOMS; i++) {
+               dist = fabs (zooms[i] - view->zoom);
                if (dist < dist_min) {
                        i_min = i;
                        dist_min = dist;
@@ -2953,7 +3010,8 @@ gl_view_zoom_in (glView *view)
 
        /* zoom in one "notch" */
        i = MAX (0, i_min - 1);
-       gl_view_set_zoom (view, scales[i] / HOME_SCALE);
+       gl_debug (DEBUG_VIEW, "zoom[%d] = %g", i, zooms[i]);
+       set_zoom_real (view, zooms[i], FALSE);
 
        gl_debug (DEBUG_VIEW, "END");
 }
@@ -2973,9 +3031,9 @@ gl_view_zoom_out (glView *view)
 
        /* Find index of current scale (or best match) */
        i_min = 0;              /* start with largest scale */
-       dist_min = fabs (scales[0] - view->scale);
-       for (i = 1; i < N_SCALES; i++) {
-               dist = fabs (scales[i] - view->scale);
+       dist_min = fabs (zooms[0] - view->zoom);
+       for (i = 1; i < N_ZOOMS; i++) {
+               dist = fabs (zooms[i] - view->zoom);
                if (dist < dist_min) {
                        i_min = i;
                        dist_min = dist;
@@ -2983,12 +3041,12 @@ gl_view_zoom_out (glView *view)
        }
 
        /* zoom out one "notch" */
-       if (i_min >= N_SCALES)
+       if (i_min >= N_ZOOMS)
                return;
        i = i_min + 1;
-       if (i >= N_SCALES)
+       if (i >= N_ZOOMS)
                return;
-       gl_view_set_zoom (view, scales[i] / HOME_SCALE);
+       set_zoom_real (view, zooms[i], FALSE);
 
        gl_debug (DEBUG_VIEW, "END");
 }
@@ -2997,16 +3055,16 @@ gl_view_zoom_out (glView *view)
 /* Set zoom to best fit.                                                     */
 /*****************************************************************************/
 void
-gl_view_zoom_best_fit (glView *view)
+gl_view_zoom_to_fit (glView *view)
 {
        gint w_view, h_view;
        gdouble w_label, h_label;
-       gdouble x_zoom, y_zoom, new_zoom;
+       gdouble x_scale, y_scale, scale;
 
        gl_debug (DEBUG_VIEW, "");
 
        if ( ! GTK_WIDGET_VISIBLE(view)) {
-               gl_view_set_zoom (view, 1.0);
+               set_zoom_real (view, 1.0, TRUE);
                return;
        }
 
@@ -3018,18 +3076,19 @@ gl_view_zoom_best_fit (glView *view)
        gl_debug (DEBUG_VIEW, "View size: %d, %d", w_view, h_view);
        gl_debug (DEBUG_VIEW, "Label size: %g, %g", w_label, h_label);
 
-       /* Calculate best zoom level */
-       x_zoom = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
-       y_zoom = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
-       new_zoom = MIN (x_zoom, y_zoom) / HOME_SCALE;
-       gl_debug (DEBUG_VIEW, "Candidate scales: %g, %g => %g", x_zoom, y_zoom, new_zoom);
+       /* Calculate best scale */
+       x_scale = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
+       y_scale = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
+       scale = MIN (x_scale, y_scale);
+       gl_debug (DEBUG_VIEW, "Candidate zooms: %g, %g => %g", x_scale, y_scale, scale);
 
        /* Limit */
-       new_zoom = MIN (new_zoom, scales[0]/HOME_SCALE);
-       new_zoom = MAX (new_zoom, scales[N_SCALES-1]/HOME_SCALE);
-       gl_debug (DEBUG_VIEW, "Limitted zoom: %g", new_zoom);
+       gl_debug (DEBUG_VIEW, "Scale: %g", scale);
+       scale = MIN (scale, zooms[0]*view->home_scale);
+       scale = MAX (scale, zooms[N_ZOOMS-1]*view->home_scale);
+       gl_debug (DEBUG_VIEW, "Limitted scale: %g", scale);
 
-       gl_view_set_zoom (view, new_zoom);
+       set_zoom_real (view, scale/view->home_scale, TRUE);
 }
 
 /*****************************************************************************/
@@ -3037,22 +3096,79 @@ gl_view_zoom_best_fit (glView *view)
 /*****************************************************************************/
 void
 gl_view_set_zoom (glView  *view,
-                 gdouble scale)
+                 gdouble zoom)
+{
+       gl_debug (DEBUG_VIEW, "START");
+
+       set_zoom_real (view, zoom, FALSE);
+
+       gl_debug (DEBUG_VIEW, "END");
+}
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE.  Set canvas scale.                                               *
+/*---------------------------------------------------------------------------*/
+static void
+set_zoom_real (glView          *view,
+              gdouble          zoom,
+              gboolean         zoom_to_fit_flag)
 {
        gl_debug (DEBUG_VIEW, "START");
 
        g_return_if_fail (view && GL_IS_VIEW (view));
-       g_return_if_fail (scale > 0.0);
+       g_return_if_fail (zoom > 0.0);
+
+       /* Limit, if needed */
+       gl_debug (DEBUG_VIEW, "Zoom requested: %g", zoom);
+       zoom = MIN (zoom, zooms[0]);
+       zoom = MAX (zoom, zooms[N_ZOOMS-1]);
+       gl_debug (DEBUG_VIEW, "Limitted zoom: %g", zoom);
 
-       view->scale = scale * HOME_SCALE;
+       view->zoom = zoom;
+       view->zoom_to_fit_flag = zoom_to_fit_flag;
        gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
-                                         scale * HOME_SCALE);
+                                         zoom*view->home_scale);
 
-       g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
+       g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, zoom);
 
        gl_debug (DEBUG_VIEW, "END");
+
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE. Size allocation changed callback.                                */
+/*---------------------------------------------------------------------------*/
+static void
+size_allocate_cb (glView          *view)
+{
+       if (view->zoom_to_fit_flag) {
+               /* Maintain best fit zoom */
+               gl_view_zoom_to_fit (view);
+       }
 }
 
+
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE. Screen changed callback.                                         */
+/*---------------------------------------------------------------------------*/
+static void
+screen_changed_cb (glView          *view)
+{
+       view->home_scale = get_home_scale (view);
+
+       gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
+                                         view->zoom * view->home_scale);
+
+       if (view->zoom_to_fit_flag) {
+               /* Maintain best fit zoom */
+               gl_view_zoom_to_fit (view);
+       }
+}
+
+
+
 /*****************************************************************************/
 /* Get current zoom factor.                                                  */
 /*****************************************************************************/
@@ -3063,7 +3179,7 @@ gl_view_get_zoom (glView *view)
 
        g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
 
-       return view->scale / HOME_SCALE;
+       return view->zoom;
 }
 
 /*****************************************************************************/
@@ -3076,7 +3192,7 @@ gl_view_is_zoom_max (glView *view)
 
        g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
 
-       return view->scale >= scales[0];
+       return view->zoom >= zooms[0];
 }
 
 /*****************************************************************************/
@@ -3089,7 +3205,7 @@ gl_view_is_zoom_min (glView *view)
 
        g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
 
-       return view->scale <= scales[N_SCALES-1];
+       return view->zoom <= zooms[N_ZOOMS-1];
 }
 
 /*****************************************************************************/
@@ -3322,22 +3438,22 @@ canvas_event_arrow_mode (GnomeCanvas *canvas,
                        case GDK_Left:
                        case GDK_KP_Left:
                                gl_view_move_selection (view,
-                                                       -1.0 / (view->scale), 0.0);
+                                                       -1.0 / (view->zoom), 0.0);
                                break;
                        case GDK_Up:
                        case GDK_KP_Up:
                                gl_view_move_selection (view,
-                                                       0.0, -1.0 / (view->scale));
+                                                       0.0, -1.0 / (view->zoom));
                                break;
                        case GDK_Right:
                        case GDK_KP_Right:
                                gl_view_move_selection (view,
-                                                       1.0 / (view->scale), 0.0);
+                                                       1.0 / (view->zoom), 0.0);
                                break;
                        case GDK_Down:
                        case GDK_KP_Down:
                                gl_view_move_selection (view,
-                                                       0.0, 1.0 / (view->scale));
+                                                       0.0, 1.0 / (view->zoom));
                                break;
                        case GDK_Delete:
                        case GDK_KP_Delete:
index e36281875a1b1de015083ee6c33a2de3c7aa8fb8..be506a0b2c01e1c9e7d6c5176b99edec28c07e63 100644 (file)
@@ -51,7 +51,9 @@ struct _glView {
        glLabel          *label;
 
        GtkWidget        *canvas;
-       gdouble           scale;
+       gdouble           zoom;
+       gboolean          zoom_to_fit_flag;
+       gdouble           home_scale;
 
        GnomeCanvasGroup *bg_group;              /* Background layer */
        GnomeCanvasGroup *grid_group;            /* Grid layer */
@@ -252,10 +254,10 @@ void       gl_view_zoom_in                 (glView            *view);
 
 void       gl_view_zoom_out                (glView            *view);
 
-void       gl_view_zoom_best_fit           (glView            *view);
+void       gl_view_zoom_to_fit             (glView            *view);
 
 void       gl_view_set_zoom                (glView            *view,
-                                           gdouble            scale);
+                                           gdouble            zoom);
 
 gdouble    gl_view_get_zoom                (glView            *view);
 
index 330dba8dafa4a5fc2ef08aa88e95f430f7dc267e..0c24f889c43c5f682991a65b02cd8644ff6de77d 100644 (file)
@@ -337,6 +337,8 @@ gl_window_set_label (glWindow    *window,
 
        gtk_widget_show_all (window->view);
 
+       gl_view_zoom_to_fit (GL_VIEW(window->view));
+
        if (gl_prefs->grid_visible) {
                gl_view_show_grid (GL_VIEW(window->view));
        } else {