1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <gegl.h>
21 #include <gtk/gtk.h>
22
23 #include "libgimpwidgets/gimpwidgets.h"
24
25 #include "dialogs-types.h"
26
27 #include "core/gimpcontext.h"
28 #include "core/gimpimage.h"
29 #include "core/gimpitem.h"
30
31 #include "widgets/gimphelp-ids.h"
32 #include "widgets/gimpmessagebox.h"
33 #include "widgets/gimpsizebox.h"
34 #include "widgets/gimpviewabledialog.h"
35
36 #include "scale-dialog.h"
37
38 #include "gimp-intl.h"
39
40
41 #define RESPONSE_RESET 1
42
43 typedef struct _ScaleDialog ScaleDialog;
44
45 struct _ScaleDialog
46 {
47 GimpViewable *viewable;
48 GimpUnit unit;
49 GimpInterpolationType interpolation;
50 GtkWidget *box;
51 GtkWidget *combo;
52 GimpScaleCallback callback;
53 gpointer user_data;
54 };
55
56
57 /* local function prototypes */
58
59 static void scale_dialog_free (ScaleDialog *private);
60 static void scale_dialog_response (GtkWidget *dialog,
61 gint response_id,
62 ScaleDialog *private);
63 static void scale_dialog_reset (ScaleDialog *private);
64
65
66 /* public function */
67
68 GtkWidget *
scale_dialog_new(GimpViewable * viewable,GimpContext * context,const gchar * title,const gchar * role,GtkWidget * parent,GimpHelpFunc help_func,const gchar * help_id,GimpUnit unit,GimpInterpolationType interpolation,GimpScaleCallback callback,gpointer user_data)69 scale_dialog_new (GimpViewable *viewable,
70 GimpContext *context,
71 const gchar *title,
72 const gchar *role,
73 GtkWidget *parent,
74 GimpHelpFunc help_func,
75 const gchar *help_id,
76 GimpUnit unit,
77 GimpInterpolationType interpolation,
78 GimpScaleCallback callback,
79 gpointer user_data)
80 {
81 GtkWidget *dialog;
82 GtkWidget *vbox;
83 GtkWidget *hbox;
84 GtkWidget *frame;
85 GtkWidget *label;
86 ScaleDialog *private;
87 GimpImage *image = NULL;
88 const gchar *text = NULL;
89 gint width, height;
90 gdouble xres, yres;
91
92 g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
93 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
94 g_return_val_if_fail (callback != NULL, NULL);
95
96 if (GIMP_IS_IMAGE (viewable))
97 {
98 image = GIMP_IMAGE (viewable);
99
100 width = gimp_image_get_width (image);
101 height = gimp_image_get_height (image);
102
103 text = _("Image Size");
104 }
105 else if (GIMP_IS_ITEM (viewable))
106 {
107 GimpItem *item = GIMP_ITEM (viewable);
108
109 image = gimp_item_get_image (item);
110
111 width = gimp_item_get_width (item);
112 height = gimp_item_get_height (item);
113
114 text = _("Layer Size");
115 }
116 else
117 {
118 g_return_val_if_reached (NULL);
119 }
120
121 private = g_slice_new0 (ScaleDialog);
122
123 private->viewable = viewable;
124 private->interpolation = interpolation;
125 private->unit = unit;
126 private->callback = callback;
127 private->user_data = user_data;
128
129 gimp_image_get_resolution (image, &xres, &yres);
130
131 dialog = gimp_viewable_dialog_new (viewable, context,
132 title, role, GIMP_ICON_OBJECT_SCALE, title,
133 parent,
134 help_func, help_id,
135
136 _("_Reset"), RESPONSE_RESET,
137 _("_Cancel"), GTK_RESPONSE_CANCEL,
138 _("_Scale"), GTK_RESPONSE_OK,
139
140 NULL);
141
142 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
143 RESPONSE_RESET,
144 GTK_RESPONSE_OK,
145 GTK_RESPONSE_CANCEL,
146 -1);
147
148 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
149
150 g_object_weak_ref (G_OBJECT (dialog),
151 (GWeakNotify) scale_dialog_free, private);
152
153 g_signal_connect (dialog, "response",
154 G_CALLBACK (scale_dialog_response),
155 private);
156
157 private->box = g_object_new (GIMP_TYPE_SIZE_BOX,
158 "width", width,
159 "height", height,
160 "unit", unit,
161 "xresolution", xres,
162 "yresolution", yres,
163 "resolution-unit", gimp_image_get_unit (image),
164 "keep-aspect", TRUE,
165 "edit-resolution", GIMP_IS_IMAGE (viewable),
166 NULL);
167
168 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
169 gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
170 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
171 vbox, TRUE, TRUE, 0);
172 gtk_widget_show (vbox);
173
174 frame = gimp_frame_new (text);
175 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
176 gtk_widget_show (frame);
177
178 gtk_container_add (GTK_CONTAINER (frame), private->box);
179 gtk_widget_show (private->box);
180
181 frame = gimp_frame_new (_("Quality"));
182 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
183 gtk_widget_show (frame);
184
185 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
186 gtk_container_add (GTK_CONTAINER (frame), vbox);
187 gtk_widget_show (vbox);
188
189 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
190 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
191 gtk_widget_show (hbox);
192
193 label = gtk_label_new_with_mnemonic (_("I_nterpolation:"));
194 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
195 gtk_widget_show (label);
196
197 gtk_size_group_add_widget (GIMP_SIZE_BOX (private->box)->size_group, label);
198
199 private->combo = gimp_enum_combo_box_new (GIMP_TYPE_INTERPOLATION_TYPE);
200 gtk_label_set_mnemonic_widget (GTK_LABEL (label), private->combo);
201 gtk_box_pack_start (GTK_BOX (hbox), private->combo, TRUE, TRUE, 0);
202 gtk_widget_show (private->combo);
203
204 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (private->combo),
205 private->interpolation);
206
207 return dialog;
208 }
209
210
211 /* private functions */
212
213 static void
scale_dialog_free(ScaleDialog * private)214 scale_dialog_free (ScaleDialog *private)
215 {
216 g_slice_free (ScaleDialog, private);
217 }
218
219 static void
scale_dialog_response(GtkWidget * dialog,gint response_id,ScaleDialog * private)220 scale_dialog_response (GtkWidget *dialog,
221 gint response_id,
222 ScaleDialog *private)
223 {
224 GimpUnit unit = private->unit;
225 gint interpolation = private->interpolation;
226 GimpUnit resolution_unit;
227 gint width, height;
228 gdouble xres, yres;
229
230 switch (response_id)
231 {
232 case RESPONSE_RESET:
233 scale_dialog_reset (private);
234 break;
235
236 case GTK_RESPONSE_OK:
237 g_object_get (private->box,
238 "width", &width,
239 "height", &height,
240 "unit", &unit,
241 "xresolution", &xres,
242 "yresolution", &yres,
243 "resolution-unit", &resolution_unit,
244 NULL);
245
246 gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (private->combo),
247 &interpolation);
248
249 private->callback (dialog,
250 private->viewable,
251 width, height, unit, interpolation,
252 xres, yres, resolution_unit,
253 private->user_data);
254 break;
255
256 default:
257 gtk_widget_destroy (dialog);
258 break;
259 }
260 }
261
262 static void
scale_dialog_reset(ScaleDialog * private)263 scale_dialog_reset (ScaleDialog *private)
264 {
265 GimpImage *image;
266 gint width, height;
267 gdouble xres, yres;
268
269 if (GIMP_IS_IMAGE (private->viewable))
270 {
271 image = GIMP_IMAGE (private->viewable);
272
273 width = gimp_image_get_width (image);
274 height = gimp_image_get_height (image);
275 }
276 else if (GIMP_IS_ITEM (private->viewable))
277 {
278 GimpItem *item = GIMP_ITEM (private->viewable);
279
280 image = gimp_item_get_image (item);
281
282 width = gimp_item_get_width (item);
283 height = gimp_item_get_height (item);
284 }
285 else
286 {
287 g_return_if_reached ();
288 }
289
290 gimp_image_get_resolution (image, &xres, &yres);
291
292 g_object_set (private->box,
293 "keep-aspect", FALSE,
294 NULL);
295
296 g_object_set (private->box,
297 "width", width,
298 "height", height,
299 "unit", private->unit,
300 NULL);
301
302 g_object_set (private->box,
303 "keep-aspect", TRUE,
304 "xresolution", xres,
305 "yresolution", yres,
306 "resolution-unit", gimp_image_get_unit (image),
307 NULL);
308
309 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (private->combo),
310 private->interpolation);
311 }
312