/** * 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); }
/** * gimp_display_shell_scale_dialog: * @shell: the #GimpDisplayShell * * Constructs and displays a dialog allowing the user to enter a * custom display scale. **/ void gimp_display_shell_scale_dialog (GimpDisplayShell *shell) { ScaleDialogData *data; GimpImage *image; GtkWidget *toplevel; GtkWidget *hbox; GtkWidget *grid; GtkWidget *spin; GtkWidget *label; gint num, denom, row; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (shell->scale_dialog) { gtk_window_present (GTK_WINDOW (shell->scale_dialog)); return; } if (SCALE_EQUALS (shell->other_scale, 0.0)) { /* other_scale not yet initialized */ shell->other_scale = gimp_zoom_model_get_factor (shell->zoom); } image = gimp_display_get_image (shell->display); data = g_slice_new (ScaleDialogData); data->shell = shell; data->model = g_object_new (GIMP_TYPE_ZOOM_MODEL, "value", fabs (shell->other_scale), NULL); shell->scale_dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), gimp_get_user_context (shell->display->gimp), _("Zoom Ratio"), "display_scale", "zoom-original", _("Select Zoom Ratio"), GTK_WIDGET (shell), gimp_standard_help_func, GIMP_HELP_VIEW_ZOOM_OTHER, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL); gimp_dialog_set_alternative_button_order (GTK_DIALOG (shell->scale_dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); g_object_weak_ref (G_OBJECT (shell->scale_dialog), (GWeakNotify) gimp_display_shell_scale_dialog_free, data); g_object_weak_ref (G_OBJECT (shell->scale_dialog), (GWeakNotify) g_object_unref, data->model); g_object_add_weak_pointer (G_OBJECT (shell->scale_dialog), (gpointer) &shell->scale_dialog); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell)); gtk_window_set_transient_for (GTK_WINDOW (shell->scale_dialog), GTK_WINDOW (toplevel)); gtk_window_set_destroy_with_parent (GTK_WINDOW (shell->scale_dialog), TRUE); g_signal_connect (shell->scale_dialog, "response", G_CALLBACK (gimp_display_shell_scale_dialog_response), data); grid = gtk_grid_new (); gtk_container_set_border_width (GTK_CONTAINER (grid), 12); gtk_grid_set_column_spacing (GTK_GRID (grid), 6); gtk_grid_set_row_spacing (GTK_GRID (grid), 6); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (shell->scale_dialog))), grid, TRUE, TRUE, 0); gtk_widget_show (grid); row = 0; hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++, _("Zoom ratio:"), 0.0, 0.5, hbox, 1); gimp_zoom_model_get_fraction (data->model, &num, &denom); data->num_adj = gtk_adjustment_new (num, 1, 256, 1, 8, 0); spin = gimp_spin_button_new (data->num_adj, 1.0, 0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE); gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0); gtk_widget_show (spin); label = gtk_label_new (":"); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_widget_show (label); data->denom_adj = gtk_adjustment_new (denom, 1, 256, 1, 8, 0); spin = gimp_spin_button_new (data->denom_adj, 1.0, 0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE); gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0); gtk_widget_show (spin); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++, _("Zoom:"), 0.0, 0.5, hbox, 1); data->scale_adj = gtk_adjustment_new (fabs (shell->other_scale) * 100, 100.0 / 256.0, 25600.0, 10, 50, 0); spin = gimp_spin_button_new (data->scale_adj, 1.0, 2); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE); gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0); gtk_widget_show (spin); label = gtk_label_new ("%"); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_widget_show (label); g_signal_connect (data->scale_adj, "value-changed", G_CALLBACK (update_zoom_values), data); g_signal_connect (data->num_adj, "value-changed", G_CALLBACK (update_zoom_values), data); g_signal_connect (data->denom_adj, "value-changed", G_CALLBACK (update_zoom_values), data); gtk_widget_show (shell->scale_dialog); }
/** * 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)); } } }
/** * 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)); } } }