/** * gimp_display_shell_scale_by_values: * @shell: the #GimpDisplayShell * @scale: the new scale * @offset_x: the new X offset * @offset_y: the new Y offset * @resize_window: whether the display window should be resized * * Directly sets the image scale and image offsets used by the display. If * @resize_window is %TRUE then the display window is resized to better * accommodate the image, see gimp_display_shell_shrink_wrap(). **/ void gimp_display_shell_scale_by_values (GimpDisplayShell *shell, gdouble scale, gint offset_x, gint offset_y, gboolean resize_window) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); /* Abort early if the values are all setup already. We don't * want to inadvertently resize the window (bug #164281). */ if (SCALE_EQUALS (gimp_zoom_model_get_factor (shell->zoom), scale) && shell->offset_x == offset_x && shell->offset_y == offset_y) return; gimp_display_shell_scale_save_revert_values (shell); /* freeze the active tool */ gimp_display_shell_pause (shell); gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale); shell->offset_x = offset_x; shell->offset_y = offset_y; gimp_display_shell_scale_resize (shell, resize_window, FALSE); /* re-enable the active tool */ gimp_display_shell_resume (shell); }
static void gimp_zoom_model_zoom_out (GimpZoomModel *model) { GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); if (priv->value > priv->minimum) gimp_zoom_model_zoom (model, GIMP_ZOOM_OUT, 0.0); }
static void gimp_zoom_model_zoom_in (GimpZoomModel *model) { GimpZoomModelPrivate *priv = GIMP_ZOOM_MODEL_GET_PRIVATE (model); if (priv->value < priv->maximum) gimp_zoom_model_zoom (model, GIMP_ZOOM_IN, 0.0); }
static void update_zoom_values (GtkAdjustment *adj, ScaleDialogData *dialog) { gint num, denom; gdouble scale; g_signal_handlers_block_by_func (dialog->scale_adj, update_zoom_values, dialog); g_signal_handlers_block_by_func (dialog->num_adj, update_zoom_values, dialog); g_signal_handlers_block_by_func (dialog->denom_adj, update_zoom_values, dialog); if (adj == dialog->scale_adj) { scale = gtk_adjustment_get_value (dialog->scale_adj); gimp_zoom_model_zoom (dialog->model, GIMP_ZOOM_TO, scale / 100.0); gimp_zoom_model_get_fraction (dialog->model, &num, &denom); gtk_adjustment_set_value (dialog->num_adj, num); gtk_adjustment_set_value (dialog->denom_adj, denom); } else /* fraction adjustments */ { scale = (gtk_adjustment_get_value (dialog->num_adj) / gtk_adjustment_get_value (dialog->denom_adj)); gtk_adjustment_set_value (dialog->scale_adj, scale * 100); } g_signal_handlers_unblock_by_func (dialog->scale_adj, update_zoom_values, dialog); g_signal_handlers_unblock_by_func (dialog->num_adj, update_zoom_values, dialog); g_signal_handlers_unblock_by_func (dialog->denom_adj, update_zoom_values, dialog); }
void gimp_display_shell_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GimpDisplayShell *shell) { /* are we in destruction? */ if (! shell->display || ! gimp_display_get_shell (shell->display)) return; if ((shell->disp_width != allocation->width) || (shell->disp_height != allocation->height)) { if (shell->zoom_on_resize && shell->disp_width > 64 && shell->disp_height > 64 && allocation->width > 64 && allocation->height > 64) { gdouble scale = gimp_zoom_model_get_factor (shell->zoom); gint offset_x; gint offset_y; /* FIXME: The code is a bit of a mess */ /* multiply the zoom_factor with the ratio of the new and * old canvas diagonals */ scale *= (sqrt (SQR (allocation->width) + SQR (allocation->height)) / sqrt (SQR (shell->disp_width) + SQR (shell->disp_height))); offset_x = UNSCALEX (shell, shell->offset_x); offset_y = UNSCALEX (shell, shell->offset_y); gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale); shell->offset_x = SCALEX (shell, offset_x); shell->offset_y = SCALEY (shell, offset_y); } shell->disp_width = allocation->width; shell->disp_height = allocation->height; /* When we size-allocate due to resize of the top level window, * we want some additional logic. Don't apply it on * zoom_on_resize though. */ if (shell->size_allocate_from_configure_event && ! shell->zoom_on_resize) { gboolean center_horizontally; gboolean center_vertically; gint target_offset_x; gint target_offset_y; gint sw; gint sh; gimp_display_shell_scale_get_image_size (shell, &sw, &sh); center_horizontally = sw <= shell->disp_width; center_vertically = sh <= shell->disp_height; gimp_display_shell_scroll_center_image (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 * image window resize using the mouse */ target_offset_x = shell->offset_x; target_offset_y = shell->offset_y; if (! center_horizontally) { target_offset_x = MAX (shell->offset_x, 0); } if (! center_vertically) { target_offset_y = MAX (shell->offset_y, 0); } gimp_display_shell_scroll_set_offset (shell, target_offset_x, target_offset_y); } gimp_display_shell_scroll_clamp_and_update (shell); gimp_display_shell_scaled (shell); /* Reset */ shell->size_allocate_from_configure_event = FALSE; } }
void gimp_display_shell_set_initial_scale (GimpDisplayShell *shell, gdouble scale, gint *display_width, gint *display_height) { GimpImage *image; GdkScreen *screen; gint image_width; gint image_height; gint shell_width; gint shell_height; gint screen_width; gint screen_height; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = gimp_display_get_image (shell->display); screen = gtk_widget_get_screen (GTK_WIDGET (shell)); image_width = gimp_image_get_width (image); image_height = gimp_image_get_height (image); screen_width = gdk_screen_get_width (screen) * 0.75; screen_height = gdk_screen_get_height (screen) * 0.75; /* We need to zoom before we use SCALE[XY] */ gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale); shell_width = SCALEX (shell, image_width); shell_height = SCALEY (shell, image_height); if (shell->display->config->initial_zoom_to_fit) { /* Limit to the size of the screen... */ if (shell_width > screen_width || shell_height > screen_height) { gdouble new_scale; gdouble current = gimp_zoom_model_get_factor (shell->zoom); new_scale = current * MIN (((gdouble) screen_height) / shell_height, ((gdouble) screen_width) / shell_width); new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale); /* Since zooming out might skip a zoom step we zoom in * again and test if we are small enough. */ gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, new_scale)); if (SCALEX (shell, image_width) > screen_width || SCALEY (shell, image_height) > screen_height) gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale); shell_width = SCALEX (shell, image_width); shell_height = SCALEY (shell, image_height); } } else { /* Set up size like above, but do not zoom to fit. Useful when * working on large images. */ if (shell_width > screen_width) shell_width = screen_width; if (shell_height > screen_height) shell_height = screen_height; } if (display_width) *display_width = shell_width; if (display_height) *display_height = shell_height; }
/** * gimp_display_shell_scale: * @shell: the #GimpDisplayShell * @zoom_type: whether to zoom in, our or to a specific scale * @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO * * This function figures out the context of the zoom and behaves * appropriatley thereafter. * **/ void gimp_display_shell_scale (GimpDisplayShell *shell, GimpZoomType zoom_type, gdouble new_scale, GimpZoomFocus zoom_focus) { gdouble current_scale; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (shell->canvas != NULL); current_scale = gimp_zoom_model_get_factor (shell->zoom); if (zoom_type != GIMP_ZOOM_TO) new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale); if (! SCALE_EQUALS (new_scale, current_scale)) { GimpDisplayConfig *config = shell->display->config; gboolean resize_window; /* Resize windows only in multi-window mode */ resize_window = (config->resize_windows_on_zoom && ! GIMP_GUI_CONFIG (config)->single_window_mode); if (resize_window) { /* If the window is resized on zoom, simply do the zoom and * get things rolling */ gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale); gimp_display_shell_scale_resize (shell, TRUE, FALSE); } else { gboolean starts_fitting_horiz; gboolean starts_fitting_vert; gboolean zoom_focus_almost_centered_horiz; gboolean zoom_focus_almost_centered_vert; gboolean image_center_almost_centered_horiz; gboolean image_center_almost_centered_vert; gdouble x, y; gint image_center_x; gint image_center_y; gimp_display_shell_scale_get_zoom_focus (shell, new_scale, current_scale, &x, &y, zoom_focus); gimp_display_shell_scale_get_image_center_viewport (shell, &image_center_x, &image_center_y); gimp_display_shell_scale_to (shell, new_scale, x, y); /* If an image axis started to fit due to zooming out or if * the focus point is as good as in the center, center on * that axis */ gimp_display_shell_scale_image_starts_to_fit (shell, new_scale, current_scale, &starts_fitting_horiz, &starts_fitting_vert); gimp_display_shell_scale_viewport_coord_almost_centered (shell, x, y, &zoom_focus_almost_centered_horiz, &zoom_focus_almost_centered_vert); gimp_display_shell_scale_viewport_coord_almost_centered (shell, image_center_x, image_center_y, &image_center_almost_centered_horiz, &image_center_almost_centered_vert); gimp_display_shell_scroll_center_image (shell, starts_fitting_horiz || (zoom_focus_almost_centered_horiz && image_center_almost_centered_horiz), starts_fitting_vert || (zoom_focus_almost_centered_vert && image_center_almost_centered_vert)); } } }
void gimp_display_shell_set_initial_scale (GimpDisplayShell *shell, gdouble scale, gint *display_width, gint *display_height) { GimpImage *image; GdkRectangle workarea; gint image_width; gint image_height; gint monitor_width; gint monitor_height; gint shell_width; gint shell_height; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = gimp_display_get_image (shell->display); gdk_monitor_get_workarea (shell->initial_monitor, &workarea); image_width = gimp_image_get_width (image); image_height = gimp_image_get_height (image); monitor_width = workarea.width * 0.75; monitor_height = workarea.height * 0.75; /* We need to zoom before we use SCALE[XY] */ gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale); shell_width = SCALEX (shell, image_width); shell_height = SCALEY (shell, image_height); if (shell->display->config->initial_zoom_to_fit) { /* Limit to the size of the monitor... */ if (shell_width > monitor_width || shell_height > monitor_height) { gdouble new_scale; gdouble current = gimp_zoom_model_get_factor (shell->zoom); new_scale = current * MIN (((gdouble) monitor_height) / shell_height, ((gdouble) monitor_width) / shell_width); new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale, 0.0); /* Since zooming out might skip a zoom step we zoom in * again and test if we are small enough. */ gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, gimp_zoom_model_zoom_step (GIMP_ZOOM_IN, new_scale, 0.0)); if (SCALEX (shell, image_width) > monitor_width || SCALEY (shell, image_height) > monitor_height) gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale); shell_width = SCALEX (shell, image_width); shell_height = SCALEY (shell, image_height); } } else { /* Set up size like above, but do not zoom to fit. Useful when * working on large images. */ shell_width = MIN (shell_width, monitor_width); shell_height = MIN (shell_height, monitor_height); } if (display_width) *display_width = shell_width; if (display_height) *display_height = shell_height; }
/** * gimp_display_shell_scale: * @shell: the #GimpDisplayShell * @zoom_type: whether to zoom in, our or to a specific scale * @scale: ignored unless @zoom_type == %GIMP_ZOOM_TO * * This function figures out the context of the zoom and behaves * appropriatley thereafter. * **/ void gimp_display_shell_scale (GimpDisplayShell *shell, GimpZoomType zoom_type, gdouble new_scale, GimpZoomFocus zoom_focus) { gint x, y; gdouble current_scale; gdouble real_new_scale; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (shell->canvas != NULL); current_scale = gimp_zoom_model_get_factor (shell->zoom); if (zoom_type != GIMP_ZOOM_TO) { real_new_scale = gimp_zoom_model_zoom_step (zoom_type, current_scale); } else { real_new_scale = new_scale; } if (! SCALE_EQUALS (real_new_scale, current_scale)) { if (shell->display->config->resize_windows_on_zoom) { GimpImageWindow *window = gimp_display_shell_get_window (shell); /* If the window is resized on zoom, simply do the zoom and * get things rolling */ gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, real_new_scale); gimp_display_shell_scaled (shell); if (window && gimp_image_window_get_active_shell (window) == shell) { gimp_image_window_shrink_wrap (window, FALSE); } } else { gboolean starts_fitting_horiz; gboolean starts_fitting_vert; gboolean zoom_focus_almost_centered_horiz; gboolean zoom_focus_almost_centered_vert; gboolean image_center_almost_centered_horiz; gboolean image_center_almost_centered_vert; gint image_center_x; gint image_center_y; gimp_display_shell_scale_get_zoom_focus (shell, real_new_scale, current_scale, &x, &y, zoom_focus); gimp_display_shell_scale_get_image_center_viewport (shell, &image_center_x, &image_center_y); gimp_display_shell_scale_to (shell, real_new_scale, x, y); /* If an image axis started to fit due to zooming out or if * the focus point is as good as in the center, center on * that axis */ gimp_display_shell_scale_image_starts_to_fit (shell, real_new_scale, current_scale, &starts_fitting_horiz, &starts_fitting_vert); gimp_display_shell_scale_viewport_coord_almost_centered (shell, x, y, &zoom_focus_almost_centered_horiz, &zoom_focus_almost_centered_vert); gimp_display_shell_scale_viewport_coord_almost_centered (shell, image_center_x, image_center_y, &image_center_almost_centered_horiz, &image_center_almost_centered_vert); gimp_display_shell_scroll_center_image (shell, starts_fitting_horiz || (zoom_focus_almost_centered_horiz && image_center_almost_centered_horiz), starts_fitting_vert || (zoom_focus_almost_centered_vert && image_center_almost_centered_vert)); } } }