diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c index 6327b7f1ec..a22aa0f4ca 100644 --- a/app/display/gimpdisplayshell-scale.c +++ b/app/display/gimpdisplayshell-scale.c @@ -48,6 +48,8 @@ #define SCALE_EPSILON 0.0001 #define ALMOST_CENTERED_THRESHOLD 2 +#define SCALE_UPDATE_INTERVAL (1000 / 90) + #define SCALE_EQUALS(a,b) (fabs ((a) - (b)) < SCALE_EPSILON) @@ -494,43 +496,20 @@ gimp_display_shell_scale_update (GimpDisplayShell *shell) } } -/** - * gimp_display_shell_scale: - * @shell: the #GimpDisplayShell - * @zoom_type: whether to zoom in, out or to a specific scale - * @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO - * - * This function figures out the context of the zoom and behaves - * appropriately thereafter. - * - **/ -void -gimp_display_shell_scale (GimpDisplayShell *shell, - GimpZoomType zoom_type, - gdouble new_scale, - GimpZoomFocus zoom_focus) +static gboolean +gimp_display_shell_delayed_scale (GimpDisplayShell *shell) { GimpDisplayConfig *config; gdouble current_scale; - gdouble delta = 0.0; + gdouble new_scale; gboolean resize_window; + GimpZoomFocus zoom_focus = shell->scale_pending_zoom_focus; - g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); - g_return_if_fail (shell->canvas != NULL); + shell->scale_delay_timer = 0; current_scale = gimp_zoom_model_get_factor (shell->zoom); - - if (zoom_type == GIMP_ZOOM_SMOOTH) - delta = -new_scale; - - if (zoom_type == GIMP_ZOOM_PINCH) - delta = new_scale; - - if (zoom_type != GIMP_ZOOM_TO) - new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale, delta); - - if (SCALE_EQUALS (new_scale, current_scale)) - return; + new_scale = shell->scale_pending; + shell->scale_pending = 0.0; config = shell->display->config; @@ -609,6 +588,61 @@ gimp_display_shell_scale (GimpDisplayShell *shell, image_center_almost_centered_vert)); } } + + return G_SOURCE_REMOVE; +} + +/** + * gimp_display_shell_scale: + * @shell: the #GimpDisplayShell + * @zoom_type: whether to zoom in, out or to a specific scale + * @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO + * + * This function figures out the context of the zoom and behaves + * appropriately thereafter. + * + **/ +void +gimp_display_shell_scale (GimpDisplayShell *shell, + GimpZoomType zoom_type, + gdouble new_scale, + GimpZoomFocus zoom_focus) +{ + gdouble current_scale; + gdouble delta = 0.0; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_if_fail (shell->canvas != NULL); + + if (shell->scale_delay_timer) + { + current_scale = shell->scale_pending; + } + else + { + current_scale = gimp_zoom_model_get_factor (shell->zoom); + } + + if (zoom_type == GIMP_ZOOM_SMOOTH) + delta = -new_scale; + + if (zoom_type == GIMP_ZOOM_PINCH) + delta = new_scale; + + if (zoom_type != GIMP_ZOOM_TO) + new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale, delta); + + if (SCALE_EQUALS (new_scale, current_scale)) + return; + + shell->scale_pending = new_scale; + shell->scale_pending_zoom_focus = zoom_focus; + + if (!shell->scale_delay_timer) + { + shell->scale_delay_timer = + g_timeout_add(SCALE_UPDATE_INTERVAL, (GSourceFunc) gimp_display_shell_delayed_scale, shell); + } } /** diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 358ef3dbfe..7e8ca0ffdf 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -388,6 +388,8 @@ gimp_display_shell_init (GimpDisplayShell *shell) shell->near_layer_vertical2 = NULL; shell->drawn = FALSE; + shell->scale_delay_timer = 0; + env = g_getenv ("GIMP_DISPLAY_RENDER_BUF_SIZE"); if (env) diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index c5b345e485..aa1b26dfef 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -226,6 +226,10 @@ struct _GimpDisplayShell gpointer scroll_info; GimpLayer *picked_layer; + gint scale_delay_timer; + gdouble scale_pending; + GimpZoomFocus scale_pending_zoom_focus; + GeglBuffer *mask; gint mask_offset_x; gint mask_offset_y;