gui: Add pixel density selector to canvas size dialog ...

which will be shown when selected template pixel density don't
match the image pixel density.

Then user can either keep current image ppi and scale the
template or set image ppi to match the template ppi.

Density selector displayed only when template and image ppi
differs and template unit is matches one of real world units
(e.g. inch, mm, etc).

Closes: GNOME/gimp#1140
This commit is contained in:
Stanislav Grinkov 2021-02-07 22:06:41 +06:00
parent 6488a5e480
commit b21865328c
No known key found for this signature in database
GPG Key ID: F9FF16FBCBF58578
4 changed files with 261 additions and 23 deletions

View File

@ -138,6 +138,9 @@ static void image_resize_callback (GtkWidget *dialog,
GimpUnit unit,
gint offset_x,
gint offset_y,
gdouble xres,
gdouble yres,
GimpUnit res_unit,
GimpFillType fill_type,
GimpItemSet layer_set,
gboolean resize_text_layers,
@ -1362,6 +1365,9 @@ image_resize_callback (GtkWidget *dialog,
GimpUnit unit,
gint offset_x,
gint offset_y,
gdouble xres,
gdouble yres,
GimpUnit res_unit,
GimpFillType fill_type,
GimpItemSet layer_set,
gboolean resize_text_layers,
@ -1376,6 +1382,10 @@ image_resize_callback (GtkWidget *dialog,
GimpImage *image = GIMP_IMAGE (viewable);
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
GimpProgress *progress;
gdouble old_xres;
gdouble old_yres;
GimpUnit old_res_unit;
gboolean update_resolution;
g_object_set (config,
"image-resize-fill-type", fill_type,
@ -1392,9 +1402,26 @@ image_resize_callback (GtkWidget *dialog,
progress = gimp_progress_start (GIMP_PROGRESS (display), FALSE,
_("Resizing"));
gimp_image_get_resolution (image, &old_xres, &old_yres);
old_res_unit = gimp_image_get_unit (image);
update_resolution = xres != old_xres ||
yres != old_yres ||
res_unit != old_res_unit;
if (update_resolution)
{
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_IMAGE_SCALE,
_("Change Canvas Size"));
gimp_image_set_resolution (image, xres, yres);
gimp_image_set_unit (image, res_unit);
}
gimp_image_resize_with_layers (image,
context, fill_type,
width, height, offset_x, offset_y,
width, height,
offset_x, offset_y,
layer_set,
resize_text_layers,
progress);
@ -1402,6 +1429,9 @@ image_resize_callback (GtkWidget *dialog,
if (progress)
gimp_progress_end (progress);
if (update_resolution)
gimp_image_undo_group_end (image);
gimp_image_flush (image);
}
else

View File

@ -159,9 +159,12 @@ static void layers_resize_callback (GtkWidget *dialog,
GimpUnit unit,
gint offset_x,
gint offset_y,
gdouble unused0,
gdouble unused1,
GimpUnit unused2,
GimpFillType fill_type,
GimpItemSet unused,
gboolean unused2,
GimpItemSet unused3,
gboolean unused4,
gpointer data);
static gint layers_mode_index (GimpLayerMode layer_mode,
@ -2542,9 +2545,12 @@ layers_resize_callback (GtkWidget *dialog,
GimpUnit unit,
gint offset_x,
gint offset_y,
gdouble unused0,
gdouble unused1,
GimpUnit unused2,
GimpFillType fill_type,
GimpItemSet unused,
gboolean unused2,
GimpItemSet unused3,
gboolean unused4,
gpointer user_data)
{
layer_resize_unit = unit;

View File

@ -36,6 +36,7 @@
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpsizebox.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimpwidgets-constructors.h"
#include "resize-dialog.h"
@ -59,6 +60,9 @@ struct _ResizeDialog
GimpResizeCallback callback;
gpointer user_data;
gdouble old_xres;
gdouble old_yres;
GimpUnit old_res_unit;
gint old_width;
gint old_height;
GimpUnit old_unit;
@ -72,6 +76,11 @@ struct _ResizeDialog
GtkWidget *layer_set_combo;
GtkWidget *fill_type_combo;
GtkWidget *text_layers_button;
GtkWidget *ppi_box;
GtkWidget *ppi_image;
GtkWidget *ppi_template;
GimpTemplate *template;
};
@ -99,6 +108,11 @@ 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 *
@ -128,6 +142,8 @@ resize_dialog_new (GimpViewable *viewable,
GtkWidget *combo;
GtkWidget *label;
GtkWidget *template_selector;
GtkWidget *ppi_image;
GtkWidget *ppi_template;
GtkAdjustment *adjustment;
GdkPixbuf *pixbuf;
GtkSizeGroup *size_group = NULL;
@ -175,6 +191,12 @@ resize_dialog_new (GimpViewable *viewable,
"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;
@ -251,14 +273,74 @@ resize_dialog_new (GimpViewable *viewable,
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);
/* size select frame */
frame = gimp_frame_new (size_title);
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* size box */
gimp_image_get_resolution (image, &xres, &yres);
private->box = g_object_new (GIMP_TYPE_SIZE_BOX,
"width", width,
"height", height,
@ -271,6 +353,7 @@ resize_dialog_new (GimpViewable *viewable,
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 (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
@ -451,6 +534,9 @@ resize_dialog_response (GtkWidget *dialog,
GimpUnit unit;
gint width;
gint height;
gdouble xres;
gdouble yres;
GimpUnit res_unit;
switch (response_id)
{
@ -460,9 +546,12 @@ resize_dialog_response (GtkWidget *dialog,
case GTK_RESPONSE_OK:
g_object_get (private->box,
"width", &width,
"height", &height,
"unit", &unit,
"width", &width,
"height", &height,
"unit", &unit,
"xresolution", &xres,
"yresolution", &yres,
"resolution-unit", &res_unit,
NULL);
private->callback (dialog,
@ -473,6 +562,9 @@ resize_dialog_response (GtkWidget *dialog,
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,
@ -493,9 +585,12 @@ resize_dialog_reset (ResizeDialog *private)
NULL);
g_object_set (private->box,
"width", private->old_width,
"height", private->old_height,
"unit", private->old_unit,
"width", private->old_width,
"height", private->old_height,
"unit", private->old_unit,
"xresolution", private->old_xres,
"yresolution", private->old_yres,
"resolution-unit", private->old_res_unit,
NULL);
if (private->layer_set_combo)
@ -604,22 +699,126 @@ template_changed (GimpContext *context,
GimpTemplate *template,
ResizeDialog *private)
{
gint width;
gint height;
GimpUnit unit;
GimpUnit unit = private->old_unit;
if (! template)
return;
private->template = template;
width = gimp_template_get_width (template);
height = gimp_template_get_height (template);
unit = gimp_template_get_unit (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);
gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (private->offset), unit);
}
static void
reset_template_clicked (GtkWidget *button,
ResizeDialog *private)
{
gimp_context_set_template (private->context, NULL);
}

View File

@ -27,6 +27,9 @@ typedef void (* GimpResizeCallback) (GtkWidget *dialog,
GimpUnit unit,
gint offset_x,
gint offset_y,
gdouble xres,
gdouble yres,
GimpUnit res_unit,
GimpFillType fill_type,
GimpItemSet layer_set,
gboolean resize_text_layers,