From c8ae8f67b429b152f0cc0a4375567e3af4fad3eb Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 14 Aug 2008 19:23:28 +0000 Subject: [PATCH] New function. 2008-08-14 Martin Nordholts * app/display/gimpdisplayshell-draw.[ch] (gimp_display_shell_draw_get_scaled_image_size_for_scale): New function. * app/display/gimpdisplayshell-scale.[ch] (gimp_display_shell_scale): When zooming out and the image starts to fit the viewport on a given axis, center on that axis. (gimp_display_shell_scale_image_starts_to_fit): New function. (gimp_display_shell_calculate_scale_x_and_y): New function. * app/display/gimpdisplayshell.c (gimp_display_shell_scale_changed): Use gimp_display_shell_calculate_scale_x_and_y(). * app/display/gimpdisplayshell-scroll.c (gimp_display_shell_scroll_center_image): Bail out if neither vertical nor horizontal centering is requested. svn path=/trunk/; revision=26562 --- ChangeLog | 23 ++++++++ app/display/gimpdisplayshell-draw.c | 33 ++++++++++- app/display/gimpdisplayshell-draw.h | 5 ++ app/display/gimpdisplayshell-scale.c | 84 ++++++++++++++++++++++++++- app/display/gimpdisplayshell-scale.h | 62 +++++++++++--------- app/display/gimpdisplayshell-scroll.c | 3 +- app/display/gimpdisplayshell.c | 14 ++--- 7 files changed, 178 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf8036267a..bd3bf8cd86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2008-08-14 Martin Nordholts + + * app/display/gimpdisplayshell-draw.[ch] + (gimp_display_shell_draw_get_scaled_image_size_for_scale): New + function. + + * app/display/gimpdisplayshell-scale.[ch] + (gimp_display_shell_scale): When zooming out and the image + starts to fit the viewport on a given axis, center on that + axis. + + (gimp_display_shell_scale_image_starts_to_fit): New function. + + (gimp_display_shell_calculate_scale_x_and_y): New function. + + * app/display/gimpdisplayshell.c + (gimp_display_shell_scale_changed): Use + gimp_display_shell_calculate_scale_x_and_y(). + + * app/display/gimpdisplayshell-scroll.c + (gimp_display_shell_scroll_center_image): Bail out if neither + vertical nor horizontal centering is requested. + 2008-08-14 Martin Nordholts * app/display/gimpdisplayshell-scale.c diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c index af0cd59246..511918b2c0 100644 --- a/app/display/gimpdisplayshell-draw.c +++ b/app/display/gimpdisplayshell-draw.c @@ -48,6 +48,7 @@ #include "gimpdisplayshell-appearance.h" #include "gimpdisplayshell-draw.h" #include "gimpdisplayshell-render.h" +#include "gimpdisplayshell-scale.h" #include "gimpdisplayshell-scroll.h" #include "gimpdisplayshell-transform.h" @@ -76,9 +77,33 @@ void gimp_display_shell_draw_get_scaled_image_size (const GimpDisplayShell *shell, gint *w, gint *h) +{ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + gimp_display_shell_draw_get_scaled_image_size_for_scale (shell, + gimp_zoom_model_get_factor (shell->zoom), + w, + h); +} + +/** + * gimp_display_shell_draw_get_scaled_image_size_for_scale: + * @shell: + * @scale: + * @w: + * @h: + * + **/ +void +gimp_display_shell_draw_get_scaled_image_size_for_scale (const GimpDisplayShell *shell, + gdouble scale, + gint *w, + gint *h) { GimpProjection *proj; TileManager *tiles; + gdouble scale_x; + gdouble scale_y; gint level; gint level_width; gint level_height; @@ -88,15 +113,17 @@ gimp_display_shell_draw_get_scaled_image_size (const GimpDisplayShell *shell, proj = gimp_image_get_projection (shell->display->image); - level = gimp_projection_get_level (proj, shell->scale_x, shell->scale_y); + gimp_display_shell_calculate_scale_x_and_y (shell, scale, &scale_x, &scale_y); + + level = gimp_projection_get_level (proj, scale_x, scale_y); tiles = gimp_projection_get_tiles_at_level (proj, level, NULL); level_width = tile_manager_width (tiles); level_height = tile_manager_height (tiles); - if (w) *w = PROJ_ROUND (level_width * (shell->scale_x * (1 << level))); - if (h) *h = PROJ_ROUND (level_height * (shell->scale_y * (1 << level))); + if (w) *w = PROJ_ROUND (level_width * (scale_x * (1 << level))); + if (h) *h = PROJ_ROUND (level_height * (scale_y * (1 << level))); } void diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h index a19beec357..d8ee1d3e63 100644 --- a/app/display/gimpdisplayshell-draw.h +++ b/app/display/gimpdisplayshell-draw.h @@ -23,6 +23,11 @@ void gimp_display_shell_draw_get_scaled_image_size (const GimpDisplayShell *shell, gint *w, gint *h); +void gimp_display_shell_draw_get_scaled_image_size_for_scale + (const GimpDisplayShell *shell, + gdouble scale, + gint *w, + gint *h); void gimp_display_shell_draw_guide (const GimpDisplayShell *shell, GimpGuide *guide, gboolean active); diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c index cb0d154d2d..bea596373c 100644 --- a/app/display/gimpdisplayshell-scale.c +++ b/app/display/gimpdisplayshell-scale.c @@ -329,6 +329,45 @@ gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell, } } +static void +gimp_display_shell_scale_image_starts_to_fit (GimpDisplayShell *shell, + gdouble new_scale, + gdouble current_scale, + gboolean *vertically, + gboolean *horizontally) +{ + /* The image can only start to fit if we zoom out */ + if (new_scale > current_scale) + { + *vertically = FALSE; + *horizontally = FALSE; + } + else + { + gint current_scale_width; + gint current_scale_height; + gint new_scale_width; + gint new_scale_height; + + gimp_display_shell_draw_get_scaled_image_size_for_scale (shell, + current_scale, + ¤t_scale_width, + ¤t_scale_height); + + gimp_display_shell_draw_get_scaled_image_size_for_scale (shell, + new_scale, + &new_scale_width, + &new_scale_height); + + *vertically = current_scale_width > shell->disp_width && + new_scale_width < shell->disp_width; + + *horizontally = current_scale_height > shell->disp_height && + new_scale_height < shell->disp_height; + + } +} + /** * gimp_display_shell_scale: * @shell: the #GimpDisplayShell @@ -364,9 +403,25 @@ gimp_display_shell_scale (GimpDisplayShell *shell, if (! SCALE_EQUALS (real_new_scale, current_scale)) { + gboolean vertically; + gboolean horizontally; + + gimp_display_shell_scale_image_starts_to_fit (shell, + real_new_scale, + current_scale, + &vertically, + &horizontally); + gimp_display_shell_scale_get_zoom_focus (shell, real_new_scale, &x, &y); gimp_display_shell_scale_to (shell, real_new_scale, x, y); + + /* If an image axis started to fit due to zooming out, center on + * that axis in the display shell + */ + gimp_display_shell_scroll_center_image (shell, + vertically, + horizontally); } } @@ -591,6 +646,32 @@ gimp_display_shell_scale_resize (GimpDisplayShell *shell, gimp_display_shell_resume (shell); } +/** + * gimp_display_shell_calculate_scale_x_and_y: + * @shell: + * @scale: + * @scale_x: + * @scale_y: + * + **/ +void +gimp_display_shell_calculate_scale_x_and_y (const GimpDisplayShell *shell, + gdouble scale, + gdouble *scale_x, + gdouble *scale_y) +{ + gdouble xres; + gdouble yres; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_if_fail (GIMP_IS_IMAGE (shell->display->image)); + + gimp_image_get_resolution (shell->display->image, &xres, &yres); + + if (scale_x) *scale_x = scale * SCREEN_XRES (shell) / xres; + if (scale_y) *scale_y = scale * SCREEN_YRES (shell) / yres; +} + void gimp_display_shell_set_initial_scale (GimpDisplayShell *shell, gdouble scale, @@ -806,9 +887,6 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) gtk_widget_show (shell->scale_dialog); } - -/* private functions */ - static void gimp_display_shell_scale_dialog_response (GtkWidget *widget, gint response_id, diff --git a/app/display/gimpdisplayshell-scale.h b/app/display/gimpdisplayshell-scale.h index 5e27ffd88f..420a994667 100644 --- a/app/display/gimpdisplayshell-scale.h +++ b/app/display/gimpdisplayshell-scale.h @@ -20,40 +20,44 @@ #define __GIMP_DISPLAY_SHELL_SCALE_H__ -void gimp_display_shell_update_scrollbars_and_rulers (GimpDisplayShell *shell); -void gimp_display_shell_scale_update_scrollbars (GimpDisplayShell *shell); -void gimp_display_shell_scale_update_rulers (GimpDisplayShell *shell); +void gimp_display_shell_update_scrollbars_and_rulers (GimpDisplayShell *shell); +void gimp_display_shell_scale_update_scrollbars (GimpDisplayShell *shell); +void gimp_display_shell_scale_update_rulers (GimpDisplayShell *shell); -gboolean gimp_display_shell_scale_revert (GimpDisplayShell *shell); -gboolean gimp_display_shell_scale_can_revert (GimpDisplayShell *shell); +gboolean gimp_display_shell_scale_revert (GimpDisplayShell *shell); +gboolean gimp_display_shell_scale_can_revert (GimpDisplayShell *shell); -void gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell, - gboolean dot_for_dot); +void gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell, + gboolean dot_for_dot); -void gimp_display_shell_scale (GimpDisplayShell *shell, - GimpZoomType zoom_type, - gdouble scale); -void gimp_display_shell_scale_fit_in (GimpDisplayShell *shell); -gboolean gimp_display_shell_scale_image_is_within_viewport (GimpDisplayShell *shell); -void gimp_display_shell_scale_fill (GimpDisplayShell *shell); -void gimp_display_shell_scale_handle_zoom_revert (GimpDisplayShell *shell); -void gimp_display_shell_scale_by_values (GimpDisplayShell *shell, - gdouble scale, - gint offset_x, - gint offset_y, - gboolean resize_window); -void gimp_display_shell_scale_shrink_wrap (GimpDisplayShell *shell, - gboolean grow_only); +void gimp_display_shell_scale (GimpDisplayShell *shell, + GimpZoomType zoom_type, + gdouble scale); +void gimp_display_shell_scale_fit_in (GimpDisplayShell *shell); +gboolean gimp_display_shell_scale_image_is_within_viewport (GimpDisplayShell *shell); +void gimp_display_shell_scale_fill (GimpDisplayShell *shell); +void gimp_display_shell_scale_handle_zoom_revert (GimpDisplayShell *shell); +void gimp_display_shell_scale_by_values (GimpDisplayShell *shell, + gdouble scale, + gint offset_x, + gint offset_y, + gboolean resize_window); +void gimp_display_shell_scale_shrink_wrap (GimpDisplayShell *shell, + gboolean grow_only); -void gimp_display_shell_scale_resize (GimpDisplayShell *shell, - gboolean resize_window, - gboolean grow_only); -void gimp_display_shell_set_initial_scale (GimpDisplayShell *shell, - gdouble scale, - gint *display_width, - gint *display_height); +void gimp_display_shell_scale_resize (GimpDisplayShell *shell, + gboolean resize_window, + gboolean grow_only); +void gimp_display_shell_calculate_scale_x_and_y (const GimpDisplayShell *shell, + gdouble scale, + gdouble *scale_x, + gdouble *scale_y); +void gimp_display_shell_set_initial_scale (GimpDisplayShell *shell, + gdouble scale, + gint *display_width, + gint *display_height); -void gimp_display_shell_scale_dialog (GimpDisplayShell *shell); +void gimp_display_shell_scale_dialog (GimpDisplayShell *shell); #endif /* __GIMP_DISPLAY_SHELL_SCALE_H__ */ diff --git a/app/display/gimpdisplayshell-scroll.c b/app/display/gimpdisplayshell-scroll.c index 772c62c429..9c76ef1171 100644 --- a/app/display/gimpdisplayshell-scroll.c +++ b/app/display/gimpdisplayshell-scroll.c @@ -267,7 +267,8 @@ gimp_display_shell_scroll_center_image (GimpDisplayShell *shell, g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (! shell->display || - ! shell->display->image) + ! shell->display->image || + (! vertically && ! horizontally)) return; target_offset_x = shell->offset_x; diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index d92ac8f9a9..7c1156b02e 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -1396,16 +1396,10 @@ gimp_display_shell_scale_changed (GimpDisplayShell *shell) if (image) { - gdouble xres; - gdouble yres; - - gimp_image_get_resolution (image, &xres, &yres); - - shell->scale_x = (gimp_zoom_model_get_factor (shell->zoom) * - SCREEN_XRES (shell) / xres); - - shell->scale_y = (gimp_zoom_model_get_factor (shell->zoom) * - SCREEN_YRES (shell) / yres); + gimp_display_shell_calculate_scale_x_and_y (shell, + gimp_zoom_model_get_factor (shell->zoom), + &shell->scale_x, + &shell->scale_y); shell->x_dest_inc = gimp_image_get_width (image); shell->y_dest_inc = gimp_image_get_height (image);