gimp/app/dialogs/resize-dialog.c
Jehan 3038c751bc app, pdb: use the real theme background color for brushes with GIMP_VIEW_BG_USE_STYLE.
Previous code was using the correct background color from the theme, but
the foreground color was always either white or black (depending on GUI
config color scheme). Instead, just use the foreground color from theme.

Since core/ doesn't have access to GTK, hence the theme, we had to
update GimpViewable's get_preview() and get_pixbuf() abstract methods to
have a color argument for recoloring previews (when relevant, which for
most types of viewables is not).
2025-05-22 21:14:20 +00:00

852 lines
29 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "dialogs-types.h"
#include "core/gimp.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimptemplate.h"
#include "widgets/gimpcontainercombobox.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpsizebox.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimpwidgets-constructors.h"
#include "resize-dialog.h"
#include "gimp-intl.h"
#define RESPONSE_RESET 1
#define SB_WIDTH 8
typedef struct _ResizeDialog ResizeDialog;
struct _ResizeDialog
{
GimpViewable *viewable;
GimpContext *context;
GimpContext *parent_context;
GimpFillType fill_type;
GimpItemSet layer_set;
gboolean resize_text_layers;
GimpResizeCallback callback;
gpointer user_data;
gdouble old_xres;
gdouble old_yres;
GimpUnit *old_res_unit;
gint old_width;
gint old_height;
GimpUnit *old_unit;
GimpFillType old_fill_type;
GimpItemSet old_layer_set;
gboolean old_resize_text_layers;
GtkWidget *box;
GtkWidget *offset;
GtkWidget *area;
GtkWidget *layer_set_combo;
GtkWidget *fill_type_combo;
GtkWidget *text_layers_button;
GtkWidget *ppi_box;
GtkWidget *ppi_image;
GtkWidget *ppi_template;
GimpTemplate *template;
};
/* local function prototypes */
static void resize_dialog_free (ResizeDialog *private);
static void resize_dialog_response (GtkWidget *dialog,
gint response_id,
ResizeDialog *private);
static void resize_dialog_reset (ResizeDialog *private);
static void size_notify (GimpSizeBox *box,
GParamSpec *pspec,
ResizeDialog *private);
static void offset_update (GtkWidget *widget,
ResizeDialog *private);
static void offsets_changed (GtkWidget *area,
gint off_x,
gint off_y,
ResizeDialog *private);
static void offset_center_clicked (GtkWidget *widget,
ResizeDialog *private);
static void template_changed (GimpContext *context,
GimpTemplate *template,
ResizeDialog *private);
static void reset_template_clicked (GtkWidget *button,
ResizeDialog *private);
static void ppi_select_toggled (GtkWidget *radio,
ResizeDialog *private);
/* public function */
GtkWidget *
resize_dialog_new (GimpViewable *viewable,
GimpContext *context,
const gchar *title,
const gchar *role,
GtkWidget *parent,
GimpHelpFunc help_func,
const gchar *help_id,
GimpUnit *unit,
GimpFillType fill_type,
GimpItemSet layer_set,
gboolean resize_text_layers,
GimpResizeCallback callback,
gpointer user_data)
{
ResizeDialog *private;
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *center_hbox;
GtkWidget *center_left_vbox;
GtkWidget *center_right_vbox;
GtkWidget *frame;
GtkWidget *button;
GtkWidget *spinbutton;
GtkWidget *entry;
GtkWidget *hbox;
GtkWidget *combo;
GtkWidget *label;
GtkWidget *template_selector;
GtkWidget *ppi_image;
GtkWidget *ppi_template;
GtkAdjustment *adjustment;
GdkPixbuf *pixbuf;
GtkSizeGroup *size_group = NULL;
GimpImage *image = NULL;
const gchar *size_title = NULL;
const gchar *layers_title = NULL;
gint width, height;
gdouble xres, yres;
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (callback != NULL, NULL);
if (GIMP_IS_IMAGE (viewable))
{
image = GIMP_IMAGE (viewable);
width = gimp_image_get_width (image);
height = gimp_image_get_height (image);
size_title = _("Canvas Size");
layers_title = _("Layers");
}
else if (GIMP_IS_ITEM (viewable))
{
GimpItem *item = GIMP_ITEM (viewable);
image = gimp_item_get_image (item);
width = gimp_item_get_width (item);
height = gimp_item_get_height (item);
size_title = _("Layer Size");
layers_title = _("Fill With");
}
else
{
g_return_val_if_reached (NULL);
}
private = g_slice_new0 (ResizeDialog);
private->parent_context = context;
private->context = gimp_context_new (context->gimp,
"resize-dialog",
context);
gimp_image_get_resolution (image, &xres, &yres);
private->old_xres = xres;
private->old_yres = yres;
private->old_res_unit = gimp_image_get_unit (image);
private->viewable = viewable;
private->fill_type = fill_type;
private->layer_set = layer_set;
private->resize_text_layers = resize_text_layers;
private->callback = callback;
private->user_data = user_data;
private->old_width = width;
private->old_height = height;
private->old_unit = unit;
private->old_fill_type = private->fill_type;
private->old_layer_set = private->layer_set;
private->old_resize_text_layers = private->resize_text_layers;
gimp_context_set_template (private->context, NULL);
dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, viewable), context,
title, role, GIMP_ICON_OBJECT_RESIZE, title,
parent,
help_func, help_id,
_("Re_set"), RESPONSE_RESET,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Resize"), GTK_RESPONSE_OK,
NULL);
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
RESPONSE_RESET,
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
g_object_weak_ref (G_OBJECT (dialog),
(GWeakNotify) resize_dialog_free, private);
g_signal_connect (dialog, "response",
G_CALLBACK (resize_dialog_response),
private);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
/* template selector */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic (_("_Template:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
template_selector = g_object_new (GIMP_TYPE_CONTAINER_COMBO_BOX,
"container", context->gimp->templates,
"context", private->context,
"view-size", 16,
"view-border-width", 0,
"ellipsize", PANGO_ELLIPSIZE_NONE,
"focus-on-click", FALSE,
NULL);
gtk_box_pack_start (GTK_BOX (hbox), template_selector, TRUE, TRUE, 0);
gtk_widget_show (template_selector);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), template_selector);
g_signal_connect (private->context,
"template-changed",
G_CALLBACK (template_changed),
private);
/* reset template button */
button = gimp_icon_button_new (GIMP_ICON_RESET, NULL);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_image_set_from_icon_name (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (button))),
GIMP_ICON_RESET, GTK_ICON_SIZE_MENU);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button,
"clicked",
G_CALLBACK (reset_template_clicked),
private);
gimp_help_set_help_data (button,
_("Reset the template selection"),
NULL);
/* ppi selector box */
private->ppi_box = vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Template and image print resolution don't match.\n"
"Choose how to scale the canvas:"));
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_widget_show (hbox);
/* actual label text is set inside template_change fn. */
ppi_image = gtk_radio_button_new_with_label (NULL, "");
ppi_template = gtk_radio_button_new_with_label (NULL, "");
private->ppi_image = ppi_image;
private->ppi_template = ppi_template;
gtk_radio_button_join_group (GTK_RADIO_BUTTON (ppi_template),
GTK_RADIO_BUTTON (ppi_image));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (ppi_image), FALSE);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (ppi_template), FALSE);
gtk_box_pack_start (GTK_BOX (hbox), ppi_image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), ppi_template, FALSE, FALSE, 0);
gtk_widget_show (ppi_image);
gtk_widget_show (ppi_template);
g_signal_connect (G_OBJECT (ppi_image),
"toggled",
G_CALLBACK (ppi_select_toggled),
private);
g_signal_connect (G_OBJECT (ppi_template),
"toggled",
G_CALLBACK (ppi_select_toggled),
private);
/* For space gain, organize the main widgets in both vertical and
* horizontal layout.
* The size and offset fields are on the center left, while the
* preview and the "Center" button are on center right.
*/
center_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
gtk_box_pack_start (GTK_BOX (main_vbox), center_hbox, FALSE, FALSE, 0);
gtk_widget_show (center_hbox);
center_left_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_box_pack_start (GTK_BOX (center_hbox), center_left_vbox, FALSE, FALSE, 0);
gtk_widget_show (center_left_vbox);
center_right_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start (GTK_BOX (center_hbox), center_right_vbox, FALSE, FALSE, 0);
gtk_widget_show (center_right_vbox);
/* size select frame */
frame = gimp_frame_new (size_title);
gtk_box_pack_start (GTK_BOX (center_left_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* size box */
private->box = g_object_new (GIMP_TYPE_SIZE_BOX,
"width", width,
"height", height,
"unit", unit,
"xresolution", xres,
"yresolution", yres,
"keep-aspect", FALSE,
"edit-resolution", FALSE,
NULL);
gtk_container_add (GTK_CONTAINER (frame), private->box);
gtk_widget_show (private->box);
/* offset frame */
frame = gimp_frame_new (_("Offset"));
gtk_box_pack_start (GTK_BOX (center_left_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* the offset sizeentry */
adjustment = gtk_adjustment_new (1, 1, 1, 1, 10, 0);
spinbutton = gimp_spin_button_new (adjustment, 1.0, 2);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
private->offset = entry = gimp_size_entry_new (1, unit, "%n",
TRUE, FALSE, FALSE, SB_WIDTH,
GIMP_SIZE_ENTRY_UPDATE_SIZE);
gimp_size_entry_add_field (GIMP_SIZE_ENTRY (entry),
GTK_SPIN_BUTTON (spinbutton), NULL);
gtk_grid_attach (GTK_GRID (entry), spinbutton, 1, 0, 1, 1);
gtk_widget_show (spinbutton);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry),
_("_X:"), 0, 0, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry),_("_Y:"), 1, 0, 0.0);
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
gtk_widget_show (entry);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), 0, xres, FALSE);
gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (entry), 1, yres, FALSE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (entry), 0, 0, 0);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (entry), 1, 0, 0);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (entry), 0, 0);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (entry), 1, 0);
g_signal_connect (entry, "value-changed",
G_CALLBACK (offset_update),
private);
frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (center_right_vbox), frame, FALSE, FALSE, 0);
gtk_style_context_add_class (gtk_widget_get_style_context (frame),
"gimp-offset-area-frame");
gtk_widget_show (frame);
private->area = gimp_offset_area_new (width, height);
gtk_container_add (GTK_CONTAINER (frame), private->area);
gtk_widget_show (private->area);
gimp_viewable_get_preview_size (viewable, 200, TRUE, TRUE, &width, &height);
pixbuf = gimp_viewable_get_pixbuf (viewable, context,
width, height, NULL);
if (pixbuf)
gimp_offset_area_set_pixbuf (GIMP_OFFSET_AREA (private->area), pixbuf);
g_signal_connect (private->area, "offsets-changed",
G_CALLBACK (offsets_changed),
private);
g_signal_connect (private->box, "notify",
G_CALLBACK (size_notify),
private);
/* Button to center the image on canvas just below the preview. */
button = gtk_button_new_with_mnemonic (_("C_enter"));
gtk_box_pack_start (GTK_BOX (center_right_vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button, "clicked",
G_CALLBACK (offset_center_clicked),
private);
frame = gimp_frame_new (layers_title);
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
if (GIMP_IS_IMAGE (viewable))
{
GtkWidget *label;
size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic (_("Resize _layers:"));
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_size_group_add_widget (size_group, label);
private->layer_set_combo = combo =
gimp_enum_combo_box_new (GIMP_TYPE_ITEM_SET);
gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
gtk_widget_show (combo);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
private->layer_set,
G_CALLBACK (gimp_int_combo_box_get_active),
&private->layer_set, NULL);
}
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
private->fill_type_combo = combo =
gimp_enum_combo_box_new (GIMP_TYPE_FILL_TYPE);
gtk_box_pack_end (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
gtk_widget_show (combo);
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
private->fill_type,
G_CALLBACK (gimp_int_combo_box_get_active),
&private->fill_type, NULL);
if (GIMP_IS_IMAGE (viewable))
{
GtkWidget *label;
label = gtk_label_new_with_mnemonic (_("_Fill with:"));
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
gtk_size_group_add_widget (size_group, label);
private->text_layers_button = button =
gtk_check_button_new_with_mnemonic (_("Resize _text layers"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
private->resize_text_layers);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&private->resize_text_layers);
gimp_help_set_help_data (button,
_("Resizing text layers will make them uneditable"),
NULL);
g_object_unref (size_group);
}
return dialog;
}
/* private functions */
static void
resize_dialog_free (ResizeDialog *private)
{
g_object_unref (private->context);
g_slice_free (ResizeDialog, private);
}
static void
resize_dialog_response (GtkWidget *dialog,
gint response_id,
ResizeDialog *private)
{
GimpSizeEntry *entry = GIMP_SIZE_ENTRY (private->offset);
GimpUnit *unit;
gint width;
gint height;
gdouble xres;
gdouble yres;
GimpUnit *res_unit;
switch (response_id)
{
case RESPONSE_RESET:
resize_dialog_reset (private);
break;
case GTK_RESPONSE_OK:
g_object_get (private->box,
"width", &width,
"height", &height,
"unit", &unit,
"xresolution", &xres,
"yresolution", &yres,
"resolution-unit", &res_unit,
NULL);
private->callback (dialog,
private->viewable,
private->parent_context,
width,
height,
unit,
gimp_size_entry_get_refval (entry, 0),
gimp_size_entry_get_refval (entry, 1),
xres,
yres,
res_unit,
private->fill_type,
private->layer_set,
private->resize_text_layers,
private->user_data);
break;
default:
gtk_widget_destroy (dialog);
break;
}
}
static void
resize_dialog_reset (ResizeDialog *private)
{
g_object_set (private->box,
"keep-aspect", FALSE,
NULL);
g_object_set (private->box,
"unit", private->old_unit,
"xresolution", private->old_xres,
"yresolution", private->old_yres,
"resolution-unit", private->old_res_unit,
NULL);
/**
* reset width and height after the other properties to avoid the problems
* noted in issue #10225
**/
g_object_set (private->box,
"width", private->old_width,
"height", private->old_height,
NULL);
if (private->layer_set_combo)
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (private->layer_set_combo),
private->old_layer_set);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (private->fill_type_combo),
private->old_fill_type);
if (private->text_layers_button)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (private->text_layers_button),
private->old_resize_text_layers);
gimp_context_set_template (private->context, NULL);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (private->offset),
private->old_unit);
}
static void
size_notify (GimpSizeBox *box,
GParamSpec *pspec,
ResizeDialog *private)
{
gint diff_x = box->width - private->old_width;
gint diff_y = box->height - private->old_height;
gimp_offset_area_set_size (GIMP_OFFSET_AREA (private->area),
box->width, box->height);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (private->offset), 0,
MIN (0, diff_x), MAX (0, diff_x));
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (private->offset), 1,
MIN (0, diff_y), MAX (0, diff_y));
}
static gint
resize_bound_off_x (ResizeDialog *private,
gint offset_x)
{
GimpSizeBox *box = GIMP_SIZE_BOX (private->box);
if (private->old_width <= box->width)
return CLAMP (offset_x, 0, (box->width - private->old_width));
else
return CLAMP (offset_x, (box->width - private->old_width), 0);
}
static gint
resize_bound_off_y (ResizeDialog *private,
gint off_y)
{
GimpSizeBox *box = GIMP_SIZE_BOX (private->box);
if (private->old_height <= box->height)
return CLAMP (off_y, 0, (box->height - private->old_height));
else
return CLAMP (off_y, (box->height - private->old_height), 0);
}
static void
offset_update (GtkWidget *widget,
ResizeDialog *private)
{
GimpSizeEntry *entry = GIMP_SIZE_ENTRY (private->offset);
gint off_x;
gint off_y;
off_x = resize_bound_off_x (private,
RINT (gimp_size_entry_get_refval (entry, 0)));
off_y = resize_bound_off_y (private,
RINT (gimp_size_entry_get_refval (entry, 1)));
gimp_offset_area_set_offsets (GIMP_OFFSET_AREA (private->area), off_x, off_y);
}
static void
offsets_changed (GtkWidget *area,
gint off_x,
gint off_y,
ResizeDialog *private)
{
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset), 0, off_x);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset), 1, off_y);
}
static void
offset_center_clicked (GtkWidget *widget,
ResizeDialog *private)
{
GimpSizeBox *box = GIMP_SIZE_BOX (private->box);
gint off_x;
gint off_y;
off_x = resize_bound_off_x (private, (box->width - private->old_width) / 2);
off_y = resize_bound_off_y (private, (box->height - private->old_height) / 2);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset), 0, off_x);
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset), 1, off_y);
g_signal_emit_by_name (private->offset, "value-changed", 0);
}
static void
template_changed (GimpContext *context,
GimpTemplate *template,
ResizeDialog *private)
{
GimpUnit *unit = private->old_unit;
private->template = template;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (private->ppi_image), TRUE);
gtk_widget_hide (private->ppi_box);
if (template != NULL)
{
gdouble xres;
gdouble yres;
GimpUnit *res_unit;
gboolean resolution_mismatch;
unit = gimp_template_get_unit (template);
xres = gimp_template_get_resolution_x (template);
yres = gimp_template_get_resolution_y (template);
res_unit = gimp_template_get_resolution_unit (template);
resolution_mismatch = xres != private->old_xres ||
yres != private->old_yres ||
res_unit != private->old_res_unit;
if (resolution_mismatch && unit != gimp_unit_pixel ())
{
gchar *text;
text = g_strdup_printf (_("Scale template to %.2f ppi"),
private->old_xres);
gtk_button_set_label (GTK_BUTTON (private->ppi_image), text);
g_free (text);
text = g_strdup_printf (_("Set image to %.2f ppi"),
xres);
gtk_button_set_label (GTK_BUTTON (private->ppi_template), text);
g_free (text);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (private->ppi_image),
TRUE);
gtk_widget_show (private->ppi_box);
}
}
ppi_select_toggled (NULL, private);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (private->offset), unit);
}
static void
ppi_select_toggled (GtkWidget *radio,
ResizeDialog *private)
{
gint width;
gint height;
GimpUnit *unit;
gdouble xres;
gdouble yres;
GimpUnit *res_unit;
GtkToggleButton *image_button;
gboolean use_image_ppi;
width = private->old_width;
height = private->old_height;
xres = private->old_xres;
yres = private->old_yres;
res_unit = private->old_res_unit;
unit = private->old_unit;
image_button = GTK_TOGGLE_BUTTON (private->ppi_image);
use_image_ppi = gtk_toggle_button_get_active (image_button);
if (private->template != NULL)
{
width = gimp_template_get_width (private->template);
height = gimp_template_get_height (private->template);
unit = gimp_template_get_unit (private->template);
xres = gimp_template_get_resolution_x (private->template);
yres = gimp_template_get_resolution_y (private->template);
res_unit = gimp_template_get_resolution_unit (private->template);
}
if (private->template != NULL && unit != gimp_unit_pixel ())
{
if (use_image_ppi)
{
width = ceil (width * (private->old_xres / xres));
height = ceil (height * (private->old_yres / yres));
xres = private->old_xres;
yres = private->old_yres;
}
g_object_set (private->box,
"xresolution", xres,
"yresolution", yres,
"resolution-unit", res_unit,
NULL);
}
else
{
g_object_set (private->box,
"xresolution", private->old_xres,
"yresolution", private->old_yres,
"resolution-unit", private->old_res_unit,
NULL);
}
g_object_set (private->box,
"width", width,
"height", height,
"unit", unit,
NULL);
}
static void
reset_template_clicked (GtkWidget *button,
ResizeDialog *private)
{
gimp_context_set_template (private->context, NULL);
}