diff --git a/app/display/gimpdisplay.c b/app/display/gimpdisplay.c index 6eb9164d53..f7cb07234f 100644 --- a/app/display/gimpdisplay.c +++ b/app/display/gimpdisplay.c @@ -44,6 +44,8 @@ #include "gimpdisplayshell-expose.h" #include "gimpdisplayshell-handlers.h" #include "gimpdisplayshell-icon.h" +#include "gimpdisplayshell-scroll.h" +#include "gimpdisplayshell-scrollbars.h" #include "gimpdisplayshell-transform.h" #include "gimpimagewindow.h" @@ -807,6 +809,9 @@ gimp_display_update_bounding_box (GimpDisplay *display) } private->bounding_box = bounding_box; + + gimp_display_shell_scroll_clamp_and_update (shell); + gimp_display_shell_scrollbars_update (shell); } } else diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index bac6db8753..247a0e0672 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -207,9 +207,18 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget, center_horizontally = sw <= shell->disp_width; center_vertically = sh <= shell->disp_height; - gimp_display_shell_scroll_center_image (shell, - center_horizontally, - center_vertically); + if (! shell->show_all) + { + gimp_display_shell_scroll_center_image (shell, + center_horizontally, + center_vertically); + } + else + { + gimp_display_shell_scroll_center_content (shell, + center_horizontally, + center_vertically); + } /* This is basically the best we can do before we get an * API for storing the image offset at the start of an diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c index d35da74f81..9a66244c13 100644 --- a/app/display/gimpdisplayshell-handlers.c +++ b/app/display/gimpdisplayshell-handlers.c @@ -841,7 +841,11 @@ gimp_display_shell_size_changed_detailed_handler (GimpImage *image, shell->offset_x + scaled_previous_origin_x, shell->offset_y + scaled_previous_origin_y); - gimp_display_shell_scroll_center_image (shell, horizontally, vertically); + if (! shell->show_all) + { + gimp_display_shell_scroll_center_image (shell, + horizontally, vertically); + } /* The above calls might not lead to a call to * gimp_display_shell_scroll_clamp_and_update() and diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c index c9dff0968b..0e782c1625 100644 --- a/app/display/gimpdisplayshell-scale.c +++ b/app/display/gimpdisplayshell-scale.c @@ -398,7 +398,6 @@ gimp_display_shell_scale_image_is_within_viewport (GimpDisplayShell *shell, gboolean *horizontally, gboolean *vertically) { - gint sw, sh; gboolean horizontally_dummy, vertically_dummy; g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE); @@ -406,15 +405,25 @@ gimp_display_shell_scale_image_is_within_viewport (GimpDisplayShell *shell, if (! horizontally) horizontally = &horizontally_dummy; if (! vertically) vertically = &vertically_dummy; - gimp_display_shell_scale_get_image_size (shell, &sw, &sh); + if (! shell->show_all) + { + gint sx, sy; + gint sw, sh; - *horizontally = sw <= shell->disp_width && - shell->offset_x <= 0 && - shell->offset_x >= sw - shell->disp_width; + gimp_display_shell_scale_get_image_bounding_box (shell, + &sx, &sy, &sw, &sh); - *vertically = sh <= shell->disp_height && - shell->offset_y <= 0 && - shell->offset_y >= sh - shell->disp_height; + sx -= shell->offset_x; + sy -= shell->offset_y; + + *horizontally = sx >= 0 && sx + sw <= shell->disp_width; + *vertically = sy >= 0 && sy + sh <= shell->disp_height; + } + else + { + *horizontally = FALSE; + *vertically = FALSE; + } return *vertically && *horizontally; } @@ -1113,22 +1122,25 @@ static void gimp_display_shell_scale_fit_or_fill (GimpDisplayShell *shell, gboolean fill) { - GimpImage *image; - gdouble image_x; - gdouble image_y; - gdouble image_width; - gdouble image_height; - gdouble current_scale; - gdouble zoom_factor; + GeglRectangle bounding_box; + gdouble image_x; + gdouble image_y; + gdouble image_width; + gdouble image_height; + gdouble current_scale; + gdouble zoom_factor; - image = gimp_display_get_image (shell->display); + bounding_box = gimp_display_shell_get_bounding_box (shell); gimp_display_shell_transform_bounds (shell, - 0, 0, - gimp_image_get_width (image), - gimp_image_get_height (image), - &image_x, &image_y, - &image_width, &image_height); + bounding_box.x, + bounding_box.y, + bounding_box.x + bounding_box.width, + bounding_box.y + bounding_box.height, + &image_x, + &image_y, + &image_width, + &image_height); image_width -= image_x; image_height -= image_y; @@ -1151,7 +1163,7 @@ gimp_display_shell_scale_fit_or_fill (GimpDisplayShell *shell, zoom_factor * current_scale, GIMP_ZOOM_FOCUS_BEST_GUESS); - gimp_display_shell_scroll_center_image (shell, TRUE, TRUE); + gimp_display_shell_scroll_center_content (shell, TRUE, TRUE); } static gboolean @@ -1168,7 +1180,7 @@ gimp_display_shell_scale_image_starts_to_fit (GimpDisplayShell *shell, if (! horizontally) horizontally = &horizontally_dummy; /* The image can only start to fit if we zoom out */ - if (new_scale > current_scale) + if (new_scale > current_scale || shell->show_all) { *vertically = FALSE; *horizontally = FALSE; @@ -1229,16 +1241,19 @@ gimp_display_shell_scale_viewport_coord_almost_centered (GimpDisplayShell *shell gboolean *horizontally, gboolean *vertically) { - gboolean local_horizontally; - gboolean local_vertically; - gint center_x = shell->disp_width / 2; - gint center_y = shell->disp_height / 2; + gboolean local_horizontally = FALSE; + gboolean local_vertically = FALSE; + gint center_x = shell->disp_width / 2; + gint center_y = shell->disp_height / 2; - local_horizontally = (x > center_x - ALMOST_CENTERED_THRESHOLD && - x < center_x + ALMOST_CENTERED_THRESHOLD); + if (! shell->show_all) + { + local_horizontally = (x > center_x - ALMOST_CENTERED_THRESHOLD && + x < center_x + ALMOST_CENTERED_THRESHOLD); - local_vertically = (y > center_y - ALMOST_CENTERED_THRESHOLD && - y < center_y + ALMOST_CENTERED_THRESHOLD); + local_vertically = (y > center_y - ALMOST_CENTERED_THRESHOLD && + y < center_y + ALMOST_CENTERED_THRESHOLD); + } if (horizontally) *horizontally = local_horizontally; if (vertically) *vertically = local_vertically; diff --git a/app/display/gimpdisplayshell-scroll.c b/app/display/gimpdisplayshell-scroll.c index 1987d5d9a4..64b15b81c0 100644 --- a/app/display/gimpdisplayshell-scroll.c +++ b/app/display/gimpdisplayshell-scroll.c @@ -160,83 +160,98 @@ gimp_display_shell_scroll_clamp_and_update (GimpDisplayShell *shell) if (image) { - gint bounds_x; - gint bounds_y; - gint bounds_width; - gint bounds_height; - gint min_offset_x; - gint max_offset_x; - gint min_offset_y; - gint max_offset_y; - gint offset_x; - gint offset_y; - - gimp_display_shell_rotate_update_transform (shell); - - gimp_display_shell_scale_get_image_bounds (shell, - &bounds_x, &bounds_y, - &bounds_width, &bounds_height); - - if (shell->disp_width < bounds_width) + if (! shell->show_all) { - min_offset_x = bounds_x - - shell->disp_width * OVERPAN_FACTOR; - max_offset_x = bounds_x + bounds_width - - shell->disp_width * (1.0 - OVERPAN_FACTOR); - } - else - { - gint overpan_amount; - - overpan_amount = shell->disp_width - - bounds_width * (1.0 - OVERPAN_FACTOR); - - min_offset_x = bounds_x - - overpan_amount; - max_offset_x = bounds_x + bounds_width - shell->disp_width + - overpan_amount; - } - - if (shell->disp_height < bounds_height) - { - min_offset_y = bounds_y - - shell->disp_height * OVERPAN_FACTOR; - max_offset_y = bounds_y + bounds_height - - shell->disp_height * (1.0 - OVERPAN_FACTOR); - } - else - { - gint overpan_amount; - - overpan_amount = shell->disp_height - - bounds_height * (1.0 - OVERPAN_FACTOR); - - min_offset_y = bounds_y - - overpan_amount; - max_offset_y = bounds_y + bounds_height + - overpan_amount - shell->disp_height; - } - - /* Clamp */ - - offset_x = CLAMP (shell->offset_x, min_offset_x, max_offset_x); - offset_y = CLAMP (shell->offset_y, min_offset_y, max_offset_y); - - if (offset_x != shell->offset_x || offset_y != shell->offset_y) - { - shell->offset_x = offset_x; - shell->offset_y = offset_y; + gint bounds_x; + gint bounds_y; + gint bounds_width; + gint bounds_height; + gint min_offset_x; + gint max_offset_x; + gint min_offset_y; + gint max_offset_y; + gint offset_x; + gint offset_y; gimp_display_shell_rotate_update_transform (shell); + + gimp_display_shell_scale_get_image_bounds (shell, + &bounds_x, + &bounds_y, + &bounds_width, + &bounds_height); + + if (shell->disp_width < bounds_width) + { + min_offset_x = bounds_x - + shell->disp_width * OVERPAN_FACTOR; + max_offset_x = bounds_x + bounds_width - + shell->disp_width * (1.0 - OVERPAN_FACTOR); + } + else + { + gint overpan_amount; + + overpan_amount = shell->disp_width - + bounds_width * (1.0 - OVERPAN_FACTOR); + + min_offset_x = bounds_x - + overpan_amount; + max_offset_x = bounds_x + bounds_width - shell->disp_width + + overpan_amount; + } + + if (shell->disp_height < bounds_height) + { + min_offset_y = bounds_y - + shell->disp_height * OVERPAN_FACTOR; + max_offset_y = bounds_y + bounds_height - + shell->disp_height * (1.0 - OVERPAN_FACTOR); + } + else + { + gint overpan_amount; + + overpan_amount = shell->disp_height - + bounds_height * (1.0 - OVERPAN_FACTOR); + + min_offset_y = bounds_y - + overpan_amount; + max_offset_y = bounds_y + bounds_height + + overpan_amount - shell->disp_height; + } + + /* Clamp */ + + offset_x = CLAMP (shell->offset_x, min_offset_x, max_offset_x); + offset_y = CLAMP (shell->offset_y, min_offset_y, max_offset_y); + + if (offset_x != shell->offset_x || offset_y != shell->offset_y) + { + shell->offset_x = offset_x; + shell->offset_y = offset_y; + + gimp_display_shell_rotate_update_transform (shell); + } + + /* Set scrollbar stepper sensitiity */ + + gimp_display_shell_scrollbars_update_steppers (shell, + min_offset_x, + max_offset_x, + min_offset_y, + max_offset_y); } + else + { + /* Set scrollbar stepper sensitiity */ - /* Set scrollbar stepper sensitiity */ - - gimp_display_shell_scrollbars_update_steppers (shell, - min_offset_x, - max_offset_x, - min_offset_y, - max_offset_y); + gimp_display_shell_scrollbars_update_steppers (shell, + G_MININT, + G_MAXINT, + G_MININT, + G_MAXINT); + } } else { @@ -278,32 +293,35 @@ gimp_display_shell_scroll_unoverscrollify (GimpDisplayShell *shell, *out_offset_x = in_offset_x; *out_offset_y = in_offset_y; - gimp_display_shell_scale_get_image_size (shell, &sw, &sh); - - if (in_offset_x < 0) + if (! shell->show_all) { - *out_offset_x = MAX (in_offset_x, - MIN (0, 0 - shell->offset_x)); - } - else if (in_offset_x > 0) - { - gint min_offset = sw - shell->disp_width; + gimp_display_shell_scale_get_image_size (shell, &sw, &sh); - *out_offset_x = MIN (in_offset_x, - MAX (0, min_offset - shell->offset_x)); - } + if (in_offset_x < 0) + { + *out_offset_x = MAX (in_offset_x, + MIN (0, 0 - shell->offset_x)); + } + else if (in_offset_x > 0) + { + gint min_offset = sw - shell->disp_width; - if (in_offset_y < 0) - { - *out_offset_y = MAX (in_offset_y, - MIN (0, 0 - shell->offset_y)); - } - else if (in_offset_y > 0) - { - gint min_offset = sh - shell->disp_height; + *out_offset_x = MIN (in_offset_x, + MAX (0, min_offset - shell->offset_x)); + } - *out_offset_y = MIN (in_offset_y, - MAX (0, min_offset - shell->offset_y)); + if (in_offset_y < 0) + { + *out_offset_y = MAX (in_offset_y, + MIN (0, 0 - shell->offset_y)); + } + else if (in_offset_y > 0) + { + gint min_offset = sh - shell->disp_height; + + *out_offset_y = MIN (in_offset_y, + MAX (0, min_offset - shell->offset_y)); + } } } @@ -389,6 +407,65 @@ gimp_display_shell_scroll_center_image (GimpDisplayShell *shell, gimp_display_shell_scroll (shell, offset_x, offset_y); } +/** + * gimp_display_shell_scroll_center_image: + * @shell: + * @horizontally: + * @vertically: + * + * Centers the image content in the display shell on the desired axes. + **/ +void +gimp_display_shell_scroll_center_content (GimpDisplayShell *shell, + gboolean horizontally, + gboolean vertically) +{ + gint content_x; + gint content_y; + gint content_width; + gint content_height; + gint center_x; + gint center_y; + gint offset_x = 0; + gint offset_y = 0; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + if (! shell->display || + ! gimp_display_get_image (shell->display) || + (! vertically && ! horizontally)) + return; + + gimp_display_shell_scale_get_image_bounding_box (shell, + &content_x, + &content_y, + &content_width, + &content_height); + + if (shell->disp_width > content_width) + { + content_x -= (shell->disp_width - content_width) / 2; + content_width = shell->disp_width; + } + + if (shell->disp_height > content_height) + { + content_y -= (shell->disp_height - content_height) / 2; + content_height = shell->disp_height; + } + + center_x = content_x + content_width / 2; + center_y = content_y + content_height / 2; + + if (horizontally) + offset_x = center_x - shell->disp_width / 2 - shell->offset_x; + + if (vertically) + offset_y = center_y - shell->disp_height / 2 - shell->offset_y; + + gimp_display_shell_scroll (shell, offset_x, offset_y); +} + /** * gimp_display_shell_scroll_get_scaled_viewport: * @shell: diff --git a/app/display/gimpdisplayshell-scroll.h b/app/display/gimpdisplayshell-scroll.h index 13cbf1527d..fba444baf2 100644 --- a/app/display/gimpdisplayshell-scroll.h +++ b/app/display/gimpdisplayshell-scroll.h @@ -40,6 +40,9 @@ void gimp_display_shell_scroll_center_image_xy (GimpDisplayShell *shell, void gimp_display_shell_scroll_center_image (GimpDisplayShell *shell, gboolean horizontally, gboolean vertically); +void gimp_display_shell_scroll_center_content (GimpDisplayShell *shell, + gboolean horizontally, + gboolean vertically); void gimp_display_shell_scroll_get_scaled_viewport (GimpDisplayShell *shell, gint *x, diff --git a/app/display/gimpdisplayshell-scrollbars.c b/app/display/gimpdisplayshell-scrollbars.c index f9ffa02c15..58d964eb8a 100644 --- a/app/display/gimpdisplayshell-scrollbars.c +++ b/app/display/gimpdisplayshell-scrollbars.c @@ -93,6 +93,10 @@ gimp_display_shell_scrollbars_setup_horizontal (GimpDisplayShell *shell, { gint bounds_x; gint bounds_width; + gint bounding_box_x; + gint bounding_box_width; + gint x1; + gint x2; gdouble lower; gdouble upper; gdouble scale_x; @@ -103,17 +107,21 @@ gimp_display_shell_scrollbars_setup_horizontal (GimpDisplayShell *shell, return; gimp_display_shell_scale_get_image_bounds (shell, - &bounds_x, NULL, + &bounds_x, NULL, &bounds_width, NULL); - if (shell->disp_width > bounds_width) - { - bounds_x -= (shell->disp_width - bounds_width) / 2; - bounds_width = shell->disp_width; - } + gimp_display_shell_scale_get_image_bounding_box (shell, + &bounding_box_x, NULL, + &bounding_box_width, NULL); - lower = MIN (value, bounds_x); - upper = MAX (value + shell->disp_width, bounds_x + bounds_width); + x1 = bounding_box_x; + x2 = bounding_box_x + bounding_box_width; + + x1 = MIN (x1, bounds_x + bounds_width / 2 - shell->disp_width / 2); + x2 = MAX (x2, bounds_x + bounds_width / 2 + (shell->disp_width + 1) / 2); + + lower = MIN (value, x1); + upper = MAX (value + shell->disp_width, x2); gimp_display_shell_get_rotated_scale (shell, &scale_x, NULL); @@ -137,6 +145,10 @@ gimp_display_shell_scrollbars_setup_vertical (GimpDisplayShell *shell, { gint bounds_y; gint bounds_height; + gint bounding_box_y; + gint bounding_box_height; + gint y1; + gint y2; gdouble lower; gdouble upper; gdouble scale_y; @@ -150,14 +162,18 @@ gimp_display_shell_scrollbars_setup_vertical (GimpDisplayShell *shell, NULL, &bounds_y, NULL, &bounds_height); - if (shell->disp_height > bounds_height) - { - bounds_y -= (shell->disp_height - bounds_height) / 2; - bounds_height = shell->disp_height; - } + gimp_display_shell_scale_get_image_bounding_box (shell, + NULL, &bounding_box_y, + NULL, &bounding_box_height); - lower = MIN (value, bounds_y); - upper = MAX (value + shell->disp_height, bounds_y + bounds_height); + y1 = bounding_box_y; + y2 = bounding_box_y + bounding_box_height; + + y1 = MIN (y1, bounds_y + bounds_height / 2 - shell->disp_height / 2); + y2 = MAX (y2, bounds_y + bounds_height / 2 + (shell->disp_height + 1) / 2); + + lower = MIN (value, y1); + upper = MAX (value + shell->disp_height, y2); gimp_display_shell_get_rotated_scale (shell, NULL, &scale_y); diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 611d1261c9..6d5df4794c 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -75,6 +75,7 @@ #include "gimpdisplayshell-rulers.h" #include "gimpdisplayshell-scale.h" #include "gimpdisplayshell-scroll.h" +#include "gimpdisplayshell-scrollbars.h" #include "gimpdisplayshell-selection.h" #include "gimpdisplayshell-title.h" #include "gimpdisplayshell-tool-events.h" @@ -1848,6 +1849,9 @@ gimp_display_shell_set_show_all (GimpDisplayShell *shell, gimp_display_update_bounding_box (shell->display); + gimp_display_shell_scroll_clamp_and_update (shell); + gimp_display_shell_scrollbars_update (shell); + gimp_display_shell_set_priority_viewport (shell); gimp_display_shell_expose_full (shell); diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c index a5d3a5ede3..59f52aa8c5 100644 --- a/app/display/gimpimagewindow.c +++ b/app/display/gimpimagewindow.c @@ -1465,15 +1465,13 @@ gimp_image_window_shrink_wrap (GimpImageWindow *window, gboolean grow_only) { GimpDisplayShell *active_shell; - GimpImage *image; GtkWidget *widget; GtkAllocation allocation; GdkScreen *screen; GdkRectangle rect; gint monitor; gint disp_width, disp_height; - gdouble x, y; - gdouble width, height; + gint width, height; gint max_auto_width, max_auto_height; gint border_width, border_height; gboolean resize = FALSE; @@ -1490,8 +1488,6 @@ gimp_image_window_shrink_wrap (GimpImageWindow *window, if (!active_shell) return; - image = gimp_display_get_image (active_shell->display); - widget = GTK_WIDGET (window); screen = gtk_widget_get_screen (widget); @@ -1501,15 +1497,9 @@ gimp_image_window_shrink_wrap (GimpImageWindow *window, gtk_widget_get_window (widget)); gdk_screen_get_monitor_workarea (screen, monitor, &rect); - gimp_display_shell_transform_bounds (active_shell, - 0, 0, - gimp_image_get_width (image), - gimp_image_get_height (image), - &x, &y, - &width, &height); - - width = ceil (width - x); - height = ceil (height - y); + gimp_display_shell_scale_get_image_bounding_box (active_shell, + NULL, NULL, + &width, &height); disp_width = active_shell->disp_width; disp_height = active_shell->disp_height; @@ -1612,7 +1602,7 @@ gimp_image_window_shrink_wrap (GimpImageWindow *window, * GimpDisplayShell::configure_event(). */ /* FIXME multiple shells */ - gimp_display_shell_scroll_center_image (active_shell, TRUE, TRUE); + gimp_display_shell_scroll_center_content (active_shell, TRUE, TRUE); } static GtkWidget *