1 /**
2 * Copyright (C) 2012 hejian <hejian.he@gmail.com>
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 <http://www.gnu.org/licenses/>.
16 */
17
18 #include <libgimp/gimp.h>
19 #include <libgimp/gimpui.h>
20
21 #include "beautify-effect.h"
22
23 #define PLUG_IN_PROC "plug-in-beautify"
24 #define PLUG_IN_BINARY "beautify"
25 #define PLUG_IN_ROLE "gimp-beautify"
26
27 #define PREVIEW_SIZE 480
28 #define THUMBNAIL_SIZE 80
29
30 typedef struct
31 {
32 gint brightness;
33 gint contrast;
34 gdouble saturation;
35 gdouble definition;
36 gdouble hue;
37 gdouble cyan_red;
38 gdouble magenta_green;
39 gdouble yellow_blue;
40
41 BeautifyEffectType effect;
42 gdouble opacity;
43 } BeautifyValues;
44
45 static const BeautifyEffectType basic_effects[] =
46 {
47 BEAUTIFY_EFFECT_SOFT_LIGHT,
48 BEAUTIFY_EFFECT_WARM,
49 BEAUTIFY_EFFECT_SHARPEN,
50 BEAUTIFY_EFFECT_SOFT,
51 BEAUTIFY_EFFECT_STRONG_CONTRAST,
52 BEAUTIFY_EFFECT_SMART_COLOR,
53 BEAUTIFY_EFFECT_BLACK_AND_WHITE,
54 BEAUTIFY_EFFECT_INVERT,
55 };
56
57 static const BeautifyEffectType lomo_effects[] =
58 {
59 BEAUTIFY_EFFECT_CLASSIC_LOMO,
60 BEAUTIFY_EFFECT_RETRO_LOMO,
61 BEAUTIFY_EFFECT_GOTHIC_STYLE,
62 BEAUTIFY_EFFECT_FILM,
63 BEAUTIFY_EFFECT_HDR,
64 BEAUTIFY_EFFECT_CLASSIC_HDR,
65 BEAUTIFY_EFFECT_YELLOWING_DARK_CORNERS,
66 BEAUTIFY_EFFECT_IMPRESSION,
67 BEAUTIFY_EFFECT_DEEP_BLUE_TEAR_RAIN,
68 BEAUTIFY_EFFECT_PURPLE_SENSATION,
69 BEAUTIFY_EFFECT_BRONZE,
70 BEAUTIFY_EFFECT_RECALL,
71 };
72
73 static const BeautifyEffectType studio_effects[] =
74 {
75 BEAUTIFY_EFFECT_ELEGANT,
76 BEAUTIFY_EFFECT_LITTLE_FRESH,
77 BEAUTIFY_EFFECT_CLASSIC_STUDIO,
78 BEAUTIFY_EFFECT_RETRO,
79 BEAUTIFY_EFFECT_PINK_LADY,
80 BEAUTIFY_EFFECT_ABAO_COLOR,
81 BEAUTIFY_EFFECT_ICE_SPIRIT,
82 BEAUTIFY_EFFECT_JAPANESE_STYLE,
83 BEAUTIFY_EFFECT_NEW_JAPANESE_STYLE,
84 BEAUTIFY_EFFECT_MILK,
85 BEAUTIFY_EFFECT_OLD_PHOTOS,
86 BEAUTIFY_EFFECT_WARM_YELLOW,
87 BEAUTIFY_EFFECT_BLUES,
88 BEAUTIFY_EFFECT_COLD_BLUE,
89 BEAUTIFY_EFFECT_COLD_GREEN,
90 BEAUTIFY_EFFECT_PURPLE_FANTASY,
91 BEAUTIFY_EFFECT_COLD_PURPLE,
92 };
93
94 static const BeautifyEffectType fashion_effects[] =
95 {
96 BEAUTIFY_EFFECT_BRIGHT_RED,
97 BEAUTIFY_EFFECT_CHRISTMAS_EVE,
98 BEAUTIFY_EFFECT_NIGHT_VIEW,
99 BEAUTIFY_EFFECT_ASTRAL,
100 BEAUTIFY_EFFECT_COLORFUL_GLOW,
101 BEAUTIFY_EFFECT_PICK_LIGHT,
102 BEAUTIFY_EFFECT_GLASS_DROPS,
103 };
104
105 static const BeautifyEffectType art_effects[] =
106 {
107 BEAUTIFY_EFFECT_SKETCH,
108 BEAUTIFY_EFFECT_LIFE_SKETCH,
109 BEAUTIFY_EFFECT_CLASSIC_SKETCH,
110 BEAUTIFY_EFFECT_COLOR_PENCIL,
111 BEAUTIFY_EFFECT_TV_LINES,
112 BEAUTIFY_EFFECT_RELIEF,
113 };
114
115 static const BeautifyEffectType gradient_effects[] =
116 {
117 BEAUTIFY_EFFECT_BEAM_GRADIENT,
118 BEAUTIFY_EFFECT_SUNSET_GRADIENT,
119 BEAUTIFY_EFFECT_RAINBOW_GRADIENT,
120 BEAUTIFY_EFFECT_PINK_PURPLE_GRADIENG,
121 BEAUTIFY_EFFECT_PINK_BLUE_GRADIENT,
122 };
123
124 static void query (void);
125 static void run (const gchar *name,
126 gint nparams,
127 const GimpParam *param,
128 gint *nreturn_vals,
129 GimpParam **return_vals);
130
131 static void beautify (GimpDrawable *drawable);
132 static void beautify_effect (GimpDrawable *drawable);
133
134 static gboolean beautify_dialog (gint32 image_ID,
135 GimpDrawable *drawable);
136
137 static void create_base_page (GtkNotebook *notebook);
138 static void create_color_page (GtkNotebook *notebook);
139
140 static void brightness_update (GtkRange *range, gpointer data);
141 static void contrast_update (GtkRange *range, gpointer data);
142 static void saturation_update (GtkRange *range, gpointer data);
143 static void definition_update (GtkRange *range, gpointer data);
144 static void hue_update (GtkRange *range, gpointer data);
145 static void cyan_red_update (GtkRange *range, gpointer data);
146 static void magenta_green_update (GtkRange *range, gpointer data);
147 static void yellow_blue_update (GtkRange *range, gpointer data);
148
149 static void adjustment();
150
151 static void reset_pressed (GtkButton *button, gpointer user_date);
152
153 static void preview_update (GtkWidget *preview);
154
155 static GtkWidget* effect_option_new ();
156 static void effect_opacity_update (GtkRange *range, gpointer data);
157
158 static void create_effect_pages (GtkNotebook *notebook);
159 static void create_effect_page (GtkNotebook *notebook, gchar *str);
160 static void effects_switch_page (GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data);
161
162 static GtkWidget* effect_icon_new (BeautifyEffectType effect);
163
164 static gboolean select_effect (GtkWidget *widget, GdkEvent *event, gpointer user_data);
165
166 static void reset_adjustment ();
167
168 static void apply_effect ();
169 static void cancel_effect ();
170
171 const GimpPlugInInfo PLUG_IN_INFO =
172 {
173 NULL, /* init_proc */
174 NULL, /* quit_proc */
175 query, /* query_proc */
176 run, /* run_proc */
177 };
178
179 static BeautifyValues bvals =
180 {
181 0, /* brightness */
182 0, /* contrast */
183 0, /* saturation */
184 0, /* definition */
185 0, /* hue */
186 0, /* cyan_red */
187 0, /* magenta_green */
188 0, /* yellow_blue */
189
190 BEAUTIFY_EFFECT_NONE, /* effect */
191 100, /* opacity */
192 };
193
194 static gint32 image_ID = 0;
195 static gint width;
196 static gint height;
197
198 static GtkWidget *brightness = NULL;
199 static GtkWidget *contrast = NULL;
200 static GtkWidget *saturation = NULL;
201 static GtkWidget *definition = NULL;
202 static GtkWidget *hue = NULL;
203 static GtkWidget *cyan_red = NULL;
204 static GtkWidget *magenta_green = NULL;
205 static GtkWidget *yellow_blue = NULL;
206
207 static GtkWidget *preview = NULL;
208 static gint32 preview_image = 0;
209 static gint32 saved_image = 0;
210
211 static GtkWidget *effect_option = NULL;
212 static GtkWidget *effect_opacity = NULL;
213
214 static BeautifyEffectType current_effect = BEAUTIFY_EFFECT_NONE;
215 gint32 preview_effect_layer = 0;
216
217 /* compatable with gtk2 */
218 #if GTK_MAJOR_VERSION < 3
219 GtkWidget *
gtk_box_new(GtkOrientation orientation,gint spacing)220 gtk_box_new (GtkOrientation orientation,
221 gint spacing)
222 {
223 if (orientation == GTK_ORIENTATION_HORIZONTAL)
224 return gtk_hbox_new (FALSE, spacing);
225 else
226 return gtk_vbox_new (FALSE, spacing);
227 }
228 #endif
229
MAIN()230 MAIN ()
231
232 static void
233 query (void)
234 {
235 static const GimpParamDef args[] =
236 {
237 { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
238 { GIMP_PDB_IMAGE, "image", "Input image" },
239 { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
240 { GIMP_PDB_INT32, "effect", "The effect to apply { SOFT_LIGHT (1), WARM (2), SHARPEN (3), SOFT (4), REMOVE_FOG (5), STRONG_CONTRAST (6), SMART_COLOR (7), FULL_COLOR (8), BLACK_AND_WHITE (9), INVERT (10), NOISE (11), CLASSIC_LOMO (12), RETRO_LOMO (13), GOTHIC_STYLE (14), FILM (15), HDR (16), CLASSIC_HDR (17), REVERSE_COLOR (18) TIME_TUNNEL (19), AFTER_THE_YOUTH (20), AXIS_LENS (21), YELLOWING_DARK_CORNERS (22), OLD_DAYS (23), NOSTALGIA (24), IMPRESSION (25), DEEP_BLUE_TEAR_RAIN (26), PURPLE_SENSATION (27), BRONZE (28), COOL_COLORS (29), RECALL (30), RETRO_BLACK_AND_WHITE (31), COLORFUL_LOMO (32), ELEGANT (33), LITTLE_FRESH (34), CLASSIC_STUDIO (35), RETRO (36), PINK_LADY (37), ABAO_COLOR (38), ICE_SPIRIT (39), MATTE_FINISH_STYLE (40), JAPANESE_STYLE (41), NEW_JAPANESE_STYLE (42), MILK (43), FLEETING_TIME (44), CLOUD (45), OLD_PHOTOS (46), WARM_YELLOW (47), BLUES (48), COLD_BLUE (49), COLD_GREEN (50), PURPLE_FANTASY (51), COLD_PURPLE (52), BRIGHT_RED (53), CHRISTMAS_EVE (54), SNOW (55), NIGHT_VIEW (56), ASTRAL (57), COLORFUL_GLOW (58), BACKLIGHT (59), PICK_LIGHT (60), COLORFUL (61), HEART_SHAPED_HALO (62), BUBBLES_GRADIENT (63), GLASS_DROPS (64), NEW_YEAR_ATMOSPHERE (65), SKETCH (66), LIFE_SKETCH (67), CLASSIC_SKETCH (68), COLOR_PENCIL (69), TV_LINES (70), BLACK_AND_WHITE_NEWSPAPER (71), RELIEF (72), BEAUTIFY_EFFECT_PAINTING (73), BEAM_GRADIENT (74), SUNSET_GRADIENT (75), COOL_GRADIENT (76), BLUE_YELLOW_GRADIENT (77), RAINBOW_GRADIENT (78), FOUR_COLOR_GRADIENT (79), PINK_PURPLE_GRADIENG (80), PINK_BLUE_GRADIENT (81) }" },
241 { GIMP_PDB_FLOAT, "opacity", "The effect opacity (0 <= opacity <= 100)" }
242 };
243
244 gimp_install_procedure (PLUG_IN_PROC,
245 "Quickly and easily beautify the photo.",
246 "Quickly and easily beautify the photo. Goto https://github.com/hejiann/beautify/wiki get more help.",
247 "Hejian <hejian.he@gmail.com>",
248 "Hejian <hejian.he@gmail.com>",
249 "2012",
250 "_Beautify...",
251 "RGB*, GRAY*",
252 GIMP_PLUGIN,
253 G_N_ELEMENTS (args), 0,
254 args, NULL);
255
256 gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Beautify");
257 }
258
259 static void
run(const gchar * name,gint nparams,const GimpParam * param,gint * nreturn_vals,GimpParam ** return_vals)260 run (const gchar *name,
261 gint nparams,
262 const GimpParam *param,
263 gint *nreturn_vals,
264 GimpParam **return_vals)
265 {
266 static GimpParam values[2];
267 GimpDrawable *drawable;
268 GimpRunMode run_mode;
269 GimpPDBStatusType status = GIMP_PDB_SUCCESS;
270
271 run_mode = param[0].data.d_int32;
272
273 *nreturn_vals = 1;
274 *return_vals = values;
275
276 values[0].type = GIMP_PDB_STATUS;
277 values[0].data.d_status = status;
278
279 image_ID = param[1].data.d_image;
280 drawable = gimp_drawable_get (param[2].data.d_drawable);
281
282 width = gimp_image_width (image_ID);
283 height = gimp_image_height (image_ID);
284
285 switch (run_mode)
286 {
287 case GIMP_RUN_INTERACTIVE:
288 if (! beautify_dialog (image_ID, drawable))
289 return;
290 break;
291
292 case GIMP_RUN_NONINTERACTIVE:
293 /* Make sure all the arguments are there! */
294 if (nparams != 5)
295 status = GIMP_PDB_CALLING_ERROR;
296
297 if (status == GIMP_PDB_SUCCESS)
298 {
299 bvals.effect = param[3].data.d_int32;
300 bvals.opacity = param[4].data.d_float;
301 }
302 break;
303
304 case GIMP_RUN_WITH_LAST_VALS:
305 /* Possibly retrieve data */
306 gimp_get_data (PLUG_IN_PROC, &bvals);
307 break;
308
309 default:
310 break;
311 }
312
313 if ((status == GIMP_PDB_SUCCESS) &&
314 (gimp_drawable_is_rgb(drawable->drawable_id) ||
315 gimp_drawable_is_gray(drawable->drawable_id)))
316 {
317 /* Run! */
318 gimp_image_undo_group_start (image_ID);
319 if (run_mode == GIMP_RUN_INTERACTIVE)
320 beautify (drawable);
321 else
322 beautify_effect (drawable);
323 gimp_image_undo_group_end (image_ID);
324
325 /* If run mode is interactive, flush displays */
326 if (run_mode != GIMP_RUN_NONINTERACTIVE)
327 gimp_displays_flush ();
328
329 /* Store data */
330 if (run_mode == GIMP_RUN_INTERACTIVE)
331 gimp_set_data (PLUG_IN_PROC, &bvals, sizeof (BeautifyValues));
332
333 }
334
335 gimp_drawable_detach (drawable);
336 }
337
338 static void
beautify(GimpDrawable * drawable)339 beautify (GimpDrawable *drawable)
340 {
341 apply_effect ();
342 gint32 source = gimp_image_get_active_layer (preview_image);
343 gimp_edit_copy (source);
344 gint32 floating_sel = gimp_edit_paste (drawable->drawable_id, FALSE);
345 gimp_floating_sel_anchor (floating_sel);
346 }
347
348 static void
beautify_effect(GimpDrawable * drawable)349 beautify_effect (GimpDrawable *drawable)
350 {
351 run_effect (image_ID, bvals.effect);
352
353 gint32 layer = gimp_image_get_active_layer (image_ID);
354 gimp_layer_set_opacity (layer, bvals.opacity);
355
356 gimp_image_merge_down (image_ID, layer, GIMP_CLIP_TO_IMAGE);
357 }
358
359 static gboolean
beautify_dialog(gint32 image_ID,GimpDrawable * drawable)360 beautify_dialog (gint32 image_ID,
361 GimpDrawable *drawable)
362 {
363 GtkWidget *dialog;
364 GtkWidget *main_hbox;
365 GtkWidget *left_vbox;
366 GtkWidget *middle_vbox;
367 GtkWidget *right_vbox;
368
369 gimp_ui_init (PLUG_IN_BINARY, FALSE);
370
371 dialog = gimp_dialog_new ("Beautify", PLUG_IN_ROLE,
372 NULL, 0,
373 gimp_standard_help_func, PLUG_IN_PROC,
374
375 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
376 GTK_STOCK_OK, GTK_RESPONSE_OK,
377
378 NULL);
379
380 gimp_window_set_transient (GTK_WINDOW (dialog));
381
382 gtk_widget_show (dialog);
383
384 main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
385 gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
386 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
387 main_hbox, TRUE, TRUE, 0);
388 gtk_widget_show (main_hbox);
389
390 left_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
391 gtk_container_set_border_width (GTK_CONTAINER (left_vbox), 12);
392 gtk_box_pack_start (GTK_BOX (main_hbox), left_vbox, TRUE, TRUE, 0);
393 gtk_widget_show (left_vbox);
394
395 middle_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
396 gtk_container_set_border_width (GTK_CONTAINER (middle_vbox), 12);
397 gtk_box_pack_start (GTK_BOX (main_hbox), middle_vbox, TRUE, TRUE, 0);
398 gtk_widget_show (middle_vbox);
399
400 right_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
401 gtk_container_set_border_width (GTK_CONTAINER (right_vbox), 12);
402 gtk_box_pack_start (GTK_BOX (main_hbox), right_vbox, TRUE, TRUE, 0);
403 gtk_widget_show (right_vbox);
404
405 /* adjustment */
406 GtkWidget *notebook = gtk_notebook_new ();
407 gtk_box_pack_start (GTK_BOX (left_vbox), notebook, FALSE, FALSE, 0);
408 gtk_widget_show (notebook);
409
410 create_base_page (GTK_NOTEBOOK (notebook));
411 create_color_page (GTK_NOTEBOOK (notebook));
412
413 /* buttons */
414 GtkWidget *buttons = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
415 gtk_box_pack_start (GTK_BOX (middle_vbox), buttons, FALSE, FALSE, 0);
416 gtk_widget_show (buttons);
417
418 GtkWidget *reset = gtk_button_new_with_label ("Reset");
419 gtk_box_pack_start (GTK_BOX (buttons), reset, FALSE, FALSE, 0);
420 gtk_widget_show (reset);
421 g_signal_connect (reset, "pressed", G_CALLBACK (reset_pressed), NULL);
422
423 /* preview */
424 preview_image = gimp_image_duplicate (image_ID);
425
426 preview = gtk_image_new();
427 preview_update (preview);
428
429 gtk_box_pack_start (GTK_BOX (middle_vbox), preview, FALSE, FALSE, 0);
430 gtk_widget_show (preview);
431
432 /* effect option */
433 effect_option = effect_option_new ();
434 gtk_box_pack_start (GTK_BOX (middle_vbox), effect_option, FALSE, FALSE, 0);
435
436 /* effects */
437 notebook = gtk_notebook_new ();
438 gtk_box_pack_start (GTK_BOX (right_vbox), notebook, FALSE, FALSE, 0);
439 gtk_widget_show (notebook);
440
441 create_effect_pages (GTK_NOTEBOOK (notebook));
442
443 gboolean run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
444
445 gtk_widget_destroy (dialog);
446
447 return run;
448 }
449
450 static void
create_base_page(GtkNotebook * notebook)451 create_base_page (GtkNotebook *notebook) {
452 GtkWidget *label;
453 GtkWidget *hscale;
454
455 GtkWidget *pagelabel = gtk_label_new ("Basic");
456
457 GtkWidget *thispage = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
458 gtk_container_set_border_width (GTK_CONTAINER (thispage), 12);
459 gtk_widget_show (thispage);
460
461 /* brightness */
462 label = gtk_label_new ("Brightness");
463 gtk_box_pack_start (GTK_BOX (thispage), label, FALSE, FALSE, 0);
464 gtk_widget_show (label);
465
466 brightness = gtk_hscale_new_with_range (-127, 127, 1);
467 gtk_range_set_value (GTK_RANGE (brightness), bvals.brightness);
468 gtk_scale_set_value_pos (GTK_SCALE (brightness), GTK_POS_BOTTOM);
469 gtk_box_pack_start (GTK_BOX (thispage), brightness, FALSE, FALSE, 0);
470 gtk_widget_show (brightness);
471
472 g_signal_connect (brightness, "value-changed",
473 G_CALLBACK (brightness_update),
474 NULL);
475
476 /* contrast */
477 label = gtk_label_new ("Contrast");
478 gtk_box_pack_start (GTK_BOX (thispage), label, FALSE, FALSE, 0);
479 gtk_widget_show (label);
480
481 contrast = gtk_hscale_new_with_range (-50, 50, 1);
482 gtk_range_set_value (GTK_RANGE (contrast), bvals.contrast);
483 gtk_scale_set_value_pos (GTK_SCALE (contrast), GTK_POS_BOTTOM);
484 gtk_box_pack_start (GTK_BOX (thispage), contrast, FALSE, FALSE, 0);
485 gtk_widget_show (contrast);
486
487 g_signal_connect (contrast, "value-changed",
488 G_CALLBACK (contrast_update),
489 NULL);
490
491 /* saturation */
492 label = gtk_label_new ("Saturation");
493 gtk_box_pack_start (GTK_BOX (thispage), label, FALSE, FALSE, 0);
494 gtk_widget_show (label);
495
496 saturation = gtk_hscale_new_with_range (-50, 50, 1);
497 gtk_range_set_value (GTK_RANGE (saturation), bvals.saturation);
498 gtk_scale_set_value_pos (GTK_SCALE (saturation), GTK_POS_BOTTOM);
499 gtk_box_pack_start (GTK_BOX (thispage), saturation, FALSE, FALSE, 0);
500 gtk_widget_show (saturation);
501
502 g_signal_connect (saturation, "value-changed",
503 G_CALLBACK (saturation_update),
504 NULL);
505
506 /* definition */
507 label = gtk_label_new ("Definition");
508 gtk_box_pack_start (GTK_BOX (thispage), label, FALSE, FALSE, 0);
509 gtk_widget_show (label);
510
511 definition = gtk_hscale_new_with_range (-50, 50, 1);
512 gtk_range_set_value (GTK_RANGE (definition), bvals.definition);
513 gtk_scale_set_value_pos (GTK_SCALE (definition), GTK_POS_BOTTOM);
514 gtk_box_pack_start (GTK_BOX (thispage), definition, FALSE, FALSE, 0);
515 gtk_widget_show (definition);
516
517 g_signal_connect (definition, "value-changed",
518 G_CALLBACK (definition_update),
519 NULL);
520
521 gtk_notebook_append_page_menu (notebook, thispage, pagelabel, NULL);
522 }
523
524 static void
brightness_update(GtkRange * range,gpointer data)525 brightness_update (GtkRange *range, gpointer data) {
526 bvals.brightness = gtk_range_get_value (range);
527 adjustment ();
528 preview_update (preview);
529 }
530
531 static void
contrast_update(GtkRange * range,gpointer data)532 contrast_update (GtkRange *range, gpointer data) {
533 bvals.contrast = gtk_range_get_value (range);
534 adjustment ();
535 preview_update (preview);
536 }
537
538 static void
saturation_update(GtkRange * range,gpointer data)539 saturation_update (GtkRange *range, gpointer data) {
540 bvals.saturation = gtk_range_get_value (range);
541 adjustment ();
542 preview_update (preview);
543 }
544
545 static void
definition_update(GtkRange * range,gpointer data)546 definition_update (GtkRange *range, gpointer data) {
547 bvals.definition = gtk_range_get_value (range);
548 adjustment ();
549 preview_update (preview);
550 }
551
552 static void
create_color_page(GtkNotebook * notebook)553 create_color_page (GtkNotebook *notebook) {
554 GtkWidget *label;
555 GtkWidget *hscale;
556
557 GtkWidget *pagelabel = gtk_label_new ("Color");
558
559 GtkWidget *thispage = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
560 gtk_container_set_border_width (GTK_CONTAINER (thispage), 12);
561 gtk_widget_show (thispage);
562
563 /* hue */
564 label = gtk_label_new ("Hue");
565 gtk_box_pack_start (GTK_BOX (thispage), label, FALSE, FALSE, 0);
566 gtk_widget_show (label);
567
568 hue = gtk_hscale_new_with_range (-180, 180, 1);
569 gtk_range_set_value (GTK_RANGE (hue), bvals.hue);
570 gtk_scale_set_value_pos (GTK_SCALE (hue), GTK_POS_BOTTOM);
571 gtk_box_pack_start (GTK_BOX (thispage), hue, FALSE, FALSE, 0);
572 gtk_widget_show (hue);
573
574 g_signal_connect (hue, "value-changed",
575 G_CALLBACK (hue_update),
576 NULL);
577
578 GtkWidget *table = gtk_table_new (3, 3, FALSE);
579 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
580 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
581 gtk_box_pack_start (GTK_BOX (thispage), table, FALSE, FALSE, 0);
582 gtk_widget_show (table);
583
584 /* cyan_red */
585 GtkWidget *event_box;
586 GdkColor color;
587
588 event_box = gtk_event_box_new ();
589 color.red = 0x0; color.green = 0xFFFF; color.blue = 0xFFFF;
590 gtk_widget_modify_bg (event_box, 0, &color);
591
592 label = gtk_label_new ("C");
593 gtk_container_add (GTK_CONTAINER (event_box), label);
594 gtk_widget_show (label);
595 gtk_table_attach_defaults (GTK_TABLE (table), event_box, 0, 1, 0, 1);
596 gtk_widget_show (event_box);
597
598 cyan_red = gtk_hscale_new_with_range (-50, 50, 1);
599 gtk_range_set_value (GTK_RANGE (cyan_red), bvals.cyan_red);
600 gtk_scale_set_value_pos (GTK_SCALE (cyan_red), GTK_POS_BOTTOM);
601 gtk_table_attach_defaults (GTK_TABLE (table), cyan_red, 1, 2, 0, 1);
602 gtk_widget_show (cyan_red);
603
604 gtk_widget_set_size_request (cyan_red, 100, -1);
605
606 g_signal_connect (cyan_red, "value-changed",
607 G_CALLBACK (cyan_red_update),
608 NULL);
609
610 event_box = gtk_event_box_new ();
611 color.red = 0xFFFF; color.green = 0x0; color.blue = 0x0;
612 gtk_widget_modify_bg (event_box, 0, &color);
613
614 label = gtk_label_new ("R");
615 gtk_container_add (GTK_CONTAINER (event_box), label);
616 gtk_widget_show (label);
617 gtk_table_attach_defaults (GTK_TABLE (table), event_box, 2, 3, 0, 1);
618 gtk_widget_show (event_box);
619
620 /* magenta_green */
621 event_box = gtk_event_box_new ();
622 color.red = 0xFFFF; color.green = 0x0; color.blue = 0xFFFF;
623 gtk_widget_modify_bg (event_box, 0, &color);
624
625 label = gtk_label_new ("M");
626 gtk_container_add (GTK_CONTAINER (event_box), label);
627 gtk_widget_show (label);
628 gtk_table_attach_defaults (GTK_TABLE (table), event_box, 0, 1, 1, 2);
629 gtk_widget_show (event_box);
630
631 magenta_green = gtk_hscale_new_with_range (-50, 50, 1);
632 gtk_range_set_value (GTK_RANGE (magenta_green), bvals.magenta_green);
633 gtk_scale_set_value_pos (GTK_SCALE (magenta_green), GTK_POS_BOTTOM);
634 gtk_table_attach_defaults (GTK_TABLE (table), magenta_green, 1, 2, 1, 2);
635 gtk_widget_show (magenta_green);
636
637 g_signal_connect (magenta_green, "value-changed",
638 G_CALLBACK (magenta_green_update),
639 NULL);
640
641 event_box = gtk_event_box_new ();
642 color.red = 0x0; color.green = 0xFFFF; color.blue = 0x0;
643 gtk_widget_modify_bg (event_box, 0, &color);
644
645 label = gtk_label_new ("G");
646 gtk_container_add (GTK_CONTAINER (event_box), label);
647 gtk_widget_show (label);
648 gtk_table_attach_defaults (GTK_TABLE (table), event_box, 2, 3, 1, 2);
649 gtk_widget_show (event_box);
650
651 /* yellow_blue */
652 event_box = gtk_event_box_new ();
653 color.red = 0xFFFF; color.green = 0xFFFF; color.blue = 0x0;
654 gtk_widget_modify_bg (event_box, 0, &color);
655
656 label = gtk_label_new ("Y");
657 gtk_container_add (GTK_CONTAINER (event_box), label);
658 gtk_widget_show (label);
659 gtk_table_attach_defaults (GTK_TABLE (table), event_box, 0, 1, 2, 3);
660 gtk_widget_show (event_box);
661
662 yellow_blue = gtk_hscale_new_with_range (-50, 50, 1);
663 gtk_range_set_value (GTK_RANGE (yellow_blue), bvals.yellow_blue);
664 gtk_scale_set_value_pos (GTK_SCALE (yellow_blue), GTK_POS_BOTTOM);
665 gtk_table_attach_defaults (GTK_TABLE (table), yellow_blue, 1, 2, 2, 3);
666 gtk_widget_show (yellow_blue);
667
668 g_signal_connect (yellow_blue, "value-changed",
669 G_CALLBACK (yellow_blue_update),
670 NULL);
671
672 event_box = gtk_event_box_new ();
673 color.red = 0x0; color.green = 0x0; color.blue = 0xFFFF;
674 gtk_widget_modify_bg (event_box, 0, &color);
675
676 label = gtk_label_new ("B");
677 gtk_container_add (GTK_CONTAINER (event_box), label);
678 gtk_widget_show (label);
679 gtk_table_attach_defaults (GTK_TABLE (table), event_box, 2, 3, 2, 3);
680 gtk_widget_show (event_box);
681
682 gtk_notebook_append_page_menu (notebook, thispage, pagelabel, NULL);
683 }
684
685 static void
hue_update(GtkRange * range,gpointer data)686 hue_update (GtkRange *range, gpointer data) {
687 bvals.hue = gtk_range_get_value (range);
688 adjustment ();
689 preview_update (preview);
690 }
691
692 static void
cyan_red_update(GtkRange * range,gpointer data)693 cyan_red_update (GtkRange *range, gpointer data) {
694 bvals.cyan_red = gtk_range_get_value (range);
695 adjustment ();
696 preview_update (preview);
697 }
698
699 static void
magenta_green_update(GtkRange * range,gpointer data)700 magenta_green_update (GtkRange *range, gpointer data) {
701 bvals.magenta_green = gtk_range_get_value (range);
702 adjustment ();
703 preview_update (preview);
704 }
705
706 static void
yellow_blue_update(GtkRange * range,gpointer data)707 yellow_blue_update (GtkRange *range, gpointer data) {
708 bvals.yellow_blue = gtk_range_get_value (range);
709 adjustment ();
710 preview_update (preview);
711 }
712
713 static void
adjustment()714 adjustment () {
715 if (bvals.brightness == 0 && bvals.contrast == 0 && bvals.saturation == 0 && bvals.definition == 0 && bvals.hue == 0 && bvals.cyan_red == 0 && bvals.magenta_green == 0 && bvals.yellow_blue == 0)
716 return;
717
718 apply_effect ();
719
720 if (!saved_image)
721 saved_image = gimp_image_duplicate (preview_image);
722
723 preview_image = gimp_image_duplicate (saved_image);
724 gint32 layer = gimp_image_get_active_layer (preview_image);
725
726 if (bvals.brightness != 0 || bvals.contrast != 0)
727 {
728 gint low_input = 0;
729 gint high_input = 255;
730 gint low_output = 0;
731 gint high_output = 255;
732
733 if (bvals.brightness > 0)
734 high_input -= bvals.brightness;
735 if (bvals.brightness < 0)
736 high_output += bvals.brightness;
737
738 gint value = 62 * (bvals.contrast / 50);
739 if (value > 0) {
740 low_input += value;
741 high_input -= value;
742 }
743 if (value < 0) {
744 low_output -= value;
745 high_output += value;
746 }
747
748 gimp_levels (layer, GIMP_HISTOGRAM_VALUE,
749 low_input, high_input,
750 1,
751 low_output, high_output);
752 }
753
754 if (bvals.saturation != 0 || bvals.hue)
755 gimp_hue_saturation (layer, GIMP_ALL_HUES, bvals.hue, 0, bvals.saturation);
756
757 if (bvals.definition > 0)
758 {
759 gint nreturn_vals;
760 GimpParam *return_vals;
761 gint32 percent = 78 * (bvals.definition / 50);
762 return_vals = gimp_run_procedure ("plug-in-sharpen",
763 &nreturn_vals,
764 GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
765 GIMP_PDB_IMAGE, image_ID,
766 GIMP_PDB_DRAWABLE, layer,
767 GIMP_PDB_INT32, percent,
768 GIMP_PDB_END);
769 gimp_destroy_params (return_vals, nreturn_vals);
770 }
771 else if (bvals.definition < 0)
772 {
773 // TODO
774 }
775
776 if (bvals.cyan_red != 0 || bvals.magenta_green != 0 || bvals.yellow_blue != 0)
777 {
778 gimp_color_balance (layer, GIMP_SHADOWS, TRUE,
779 bvals.cyan_red, bvals.magenta_green, bvals.yellow_blue);
780 gimp_color_balance (layer, GIMP_MIDTONES, TRUE,
781 bvals.cyan_red, bvals.magenta_green, bvals.yellow_blue);
782 gimp_color_balance (layer, GIMP_HIGHLIGHTS, TRUE,
783 bvals.cyan_red, bvals.magenta_green, bvals.yellow_blue);
784 }
785 }
786
787 static void
reset_pressed(GtkButton * button,gpointer user_date)788 reset_pressed (GtkButton *button, gpointer user_date)
789 {
790 reset_adjustment ();
791 cancel_effect ();
792
793 gimp_image_delete (preview_image);
794 preview_image = gimp_image_duplicate (image_ID);
795 preview_update (preview);
796 }
797
798 static void
preview_update(GtkWidget * preview)799 preview_update (GtkWidget *preview)
800 {
801 gint preview_size = PREVIEW_SIZE;
802 gint max_size = height;
803 if (height < width)
804 max_size = width;
805 if (preview_size > max_size)
806 preview_size = max_size;
807 GdkPixbuf *pixbuf = gimp_image_get_thumbnail (preview_image, preview_size, preview_size, GIMP_PIXBUF_SMALL_CHECKS);
808 gtk_image_set_from_pixbuf (GTK_IMAGE(preview), pixbuf);
809 }
810
811 static GtkWidget*
effect_option_new()812 effect_option_new () {
813 GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
814
815 GtkWidget *label = gtk_label_new ("Effect Opacity:");
816 gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
817 gtk_widget_show (label);
818
819 effect_opacity = gtk_hscale_new_with_range (0, 100, 1);
820 gtk_range_set_value (GTK_RANGE (effect_opacity), 100);
821 gtk_scale_set_value_pos (GTK_SCALE (effect_opacity), GTK_POS_RIGHT);
822 gtk_box_pack_start (GTK_BOX (box), effect_opacity, TRUE, TRUE, 0);
823 gtk_widget_show (effect_opacity);
824
825 g_signal_connect (effect_opacity, "value-changed",
826 G_CALLBACK (effect_opacity_update),
827 NULL);
828
829 return box;
830 }
831
832 static void
effect_opacity_update(GtkRange * range,gpointer data)833 effect_opacity_update (GtkRange *range, gpointer data) {
834 if (current_effect == BEAUTIFY_EFFECT_NONE) {
835 return;
836 }
837
838 gdouble opacity = gtk_range_get_value (range);
839 gint32 layer = gimp_image_get_active_layer (preview_image);
840 gimp_layer_set_opacity (layer, opacity);
841
842 preview_update (preview);
843 }
844
845 static void
create_effect_pages(GtkNotebook * notebook)846 create_effect_pages (GtkNotebook *notebook) {
847 create_effect_page (notebook, "Basic");
848 create_effect_page (notebook, "LOMO");
849 create_effect_page (notebook, "Studio");
850 create_effect_page (notebook, "Fashion");
851 create_effect_page (notebook, "Art");
852 create_effect_page (notebook, "Gradient");
853
854 g_signal_connect (notebook, "switch-page", G_CALLBACK (effects_switch_page), NULL);
855
856 GtkWidget *page = gtk_notebook_get_nth_page (notebook, 0);
857 effects_switch_page(notebook, page, 0, NULL);
858 }
859
860 static void
create_effect_page(GtkNotebook * notebook,gchar * str)861 create_effect_page (GtkNotebook *notebook, gchar *str) {
862 GtkWidget *pagelabel = gtk_label_new (str);
863
864 GtkWidget *thispage = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
865 gtk_container_set_border_width (GTK_CONTAINER (thispage), 12);
866 gtk_widget_show (thispage);
867
868 gtk_notebook_append_page_menu (notebook, thispage, pagelabel, NULL);
869 }
870
871 static void
effects_switch_page(GtkNotebook * notebook,GtkWidget * page,guint page_num,gpointer user_data)872 effects_switch_page (GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data)
873 {
874 static time_t effects_timestamp [] = {0, 0, 0, 0, 0, 0};
875
876 if (effects_timestamp[page_num] > 0)
877 return;
878
879 // fix gtk2
880 page = gtk_notebook_get_nth_page (notebook, page_num);
881
882 const BeautifyEffectType* effects;
883 guint n_effects;
884
885 switch (page_num)
886 {
887 case 0:
888 {
889 effects = basic_effects;
890 n_effects = G_N_ELEMENTS (basic_effects);
891 break;
892 }
893 case 1:
894 {
895 effects = lomo_effects;
896 n_effects = G_N_ELEMENTS (lomo_effects);
897 break;
898 }
899 case 2:
900 {
901 effects = studio_effects;
902 n_effects = G_N_ELEMENTS (studio_effects);
903 break;
904 }
905 case 3:
906 {
907 effects = fashion_effects;
908 n_effects = G_N_ELEMENTS (fashion_effects);
909 break;
910 }
911 case 4:
912 {
913 effects = art_effects;
914 n_effects = G_N_ELEMENTS (art_effects);
915 break;
916 }
917 case 5:
918 {
919 effects = gradient_effects;
920 n_effects = G_N_ELEMENTS (gradient_effects);
921 break;
922 }
923 }
924
925 gtk_container_set_border_width (GTK_CONTAINER (page), 0);
926 gtk_widget_set_size_request (page, -1, 480);
927
928 /* scrolled window */
929 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
930 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
931 gtk_box_pack_start (GTK_BOX (page), scrolled_window, TRUE, TRUE, 0);
932 gtk_widget_show (scrolled_window);
933
934 /* table */
935 gint rows = 5;
936 gint cols = 3;
937 GtkWidget *table = gtk_table_new (rows, cols, FALSE);
938 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
939 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
940 gtk_container_set_border_width (GTK_CONTAINER (table), 10);
941 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
942 gtk_widget_show (table);
943
944 gint row = 1;
945 gint col = 1;
946
947 gint i;
948 for (i = 0; i < n_effects; i++)
949 {
950 GtkWidget *icon = effect_icon_new (effects[i]);
951 gtk_table_attach_defaults (GTK_TABLE (table), icon, col - 1, col, row - 1, row);
952 gtk_widget_show (icon);
953
954 col++;
955 if (col > cols)
956 {
957 row++;
958 col = 1;
959 }
960 }
961
962 effects_timestamp[page_num] = time (NULL);
963 }
964
965 static GtkWidget *
effect_icon_new(BeautifyEffectType effect)966 effect_icon_new (BeautifyEffectType effect)
967 {
968 gchar *title;
969
970 switch (effect) {
971 case BEAUTIFY_EFFECT_SOFT_LIGHT:
972 title = "Soft Light";
973 break;
974 case BEAUTIFY_EFFECT_WARM:
975 title = "Warm";
976 break;
977 case BEAUTIFY_EFFECT_SHARPEN:
978 title = "Sharpen";
979 break;
980 case BEAUTIFY_EFFECT_SOFT:
981 title = "Soft";
982 break;
983 case BEAUTIFY_EFFECT_STRONG_CONTRAST:
984 title = "Strong\nContrast";
985 break;
986 case BEAUTIFY_EFFECT_SMART_COLOR:
987 title = "Smart Color";
988 break;
989 case BEAUTIFY_EFFECT_BLACK_AND_WHITE:
990 title = "Black\nand White";
991 break;
992 case BEAUTIFY_EFFECT_INVERT:
993 title = "Invert";
994 break;
995 case BEAUTIFY_EFFECT_CLASSIC_LOMO:
996 title = "Classic LOMO";
997 break;
998 case BEAUTIFY_EFFECT_RETRO_LOMO:
999 title = "Retro LOMO";
1000 break;
1001 case BEAUTIFY_EFFECT_GOTHIC_STYLE:
1002 title = "Gothic Style";
1003 break;
1004 case BEAUTIFY_EFFECT_FILM:
1005 title = "Film";
1006 break;
1007 case BEAUTIFY_EFFECT_HDR:
1008 title = "HDR";
1009 break;
1010 case BEAUTIFY_EFFECT_CLASSIC_HDR:
1011 title = "Classic HDR";
1012 break;
1013 case BEAUTIFY_EFFECT_YELLOWING_DARK_CORNERS:
1014 title = "Yellow Dark\nCorner";
1015 break;
1016 case BEAUTIFY_EFFECT_IMPRESSION:
1017 title = "Impression";
1018 break;
1019 case BEAUTIFY_EFFECT_DEEP_BLUE_TEAR_RAIN:
1020 title = "Deep Blue\nTear Rain";
1021 break;
1022 case BEAUTIFY_EFFECT_PURPLE_SENSATION:
1023 title = "Purple\nSensation";
1024 break;
1025 case BEAUTIFY_EFFECT_BRONZE:
1026 title = "Bronze";
1027 break;
1028 case BEAUTIFY_EFFECT_RECALL:
1029 title = "Recall";
1030 break;
1031 case BEAUTIFY_EFFECT_ELEGANT:
1032 title = "Elegant";
1033 break;
1034 case BEAUTIFY_EFFECT_LITTLE_FRESH:
1035 title = "Little Fresh";
1036 break;
1037 case BEAUTIFY_EFFECT_CLASSIC_STUDIO:
1038 title = "Classic Studio";
1039 break;
1040 case BEAUTIFY_EFFECT_RETRO:
1041 title = "Retro";
1042 break;
1043 case BEAUTIFY_EFFECT_PINK_LADY:
1044 title = "Pink Lady";
1045 break;
1046 case BEAUTIFY_EFFECT_ABAO_COLOR:
1047 title = "ABao Color";
1048 break;
1049 case BEAUTIFY_EFFECT_ICE_SPIRIT:
1050 title = "Ice Spirit";
1051 break;
1052 case BEAUTIFY_EFFECT_JAPANESE_STYLE:
1053 title = "Japanese";
1054 break;
1055 case BEAUTIFY_EFFECT_NEW_JAPANESE_STYLE:
1056 title = "New\nJapanese";
1057 break;
1058 case BEAUTIFY_EFFECT_MILK:
1059 title = "Milk";
1060 break;
1061 case BEAUTIFY_EFFECT_OLD_PHOTOS:
1062 title = "Old Photos";
1063 break;
1064 case BEAUTIFY_EFFECT_WARM_YELLOW:
1065 title = "Warm Yellow";
1066 break;
1067 case BEAUTIFY_EFFECT_BLUES:
1068 title = "Blues";
1069 break;
1070 case BEAUTIFY_EFFECT_COLD_BLUE:
1071 title = "Cold Blue";
1072 break;
1073 case BEAUTIFY_EFFECT_COLD_GREEN:
1074 title = "Cold Green";
1075 break;
1076 case BEAUTIFY_EFFECT_PURPLE_FANTASY:
1077 title = "Purple\nFantasy";
1078 break;
1079 case BEAUTIFY_EFFECT_COLD_PURPLE:
1080 title = "Cold Purple";
1081 break;
1082 case BEAUTIFY_EFFECT_BRIGHT_RED:
1083 title = "Bright Red";
1084 break;
1085 case BEAUTIFY_EFFECT_CHRISTMAS_EVE:
1086 title = "Christmas Eve";
1087 break;
1088 case BEAUTIFY_EFFECT_NIGHT_VIEW:
1089 title = "Night View";
1090 break;
1091 case BEAUTIFY_EFFECT_ASTRAL:
1092 title = "Astral";
1093 break;
1094 case BEAUTIFY_EFFECT_COLORFUL_GLOW:
1095 title = "Colorful Glow";
1096 break;
1097 case BEAUTIFY_EFFECT_PICK_LIGHT:
1098 title = "Pick Light";
1099 break;
1100 case BEAUTIFY_EFFECT_GLASS_DROPS:
1101 title = "Glass Drops";
1102 break;
1103 case BEAUTIFY_EFFECT_SKETCH:
1104 title = "Sketch";
1105 break;
1106 case BEAUTIFY_EFFECT_LIFE_SKETCH:
1107 title = "Life Sketch";
1108 break;
1109 case BEAUTIFY_EFFECT_CLASSIC_SKETCH:
1110 title = "Classic Sketch";
1111 break;
1112 case BEAUTIFY_EFFECT_COLOR_PENCIL:
1113 title = "Color Pencil";
1114 break;
1115 case BEAUTIFY_EFFECT_TV_LINES:
1116 title = "TV Lines";
1117 break;
1118 case BEAUTIFY_EFFECT_RELIEF:
1119 title = "Relief";
1120 break;
1121 case BEAUTIFY_EFFECT_BEAM_GRADIENT:
1122 title = "Beam\nGradient";
1123 break;
1124 case BEAUTIFY_EFFECT_SUNSET_GRADIENT:
1125 title = "Sunset\nGradient";
1126 break;
1127 case BEAUTIFY_EFFECT_RAINBOW_GRADIENT:
1128 title = "Rainbow\nGradient";
1129 break;
1130 case BEAUTIFY_EFFECT_PINK_PURPLE_GRADIENG:
1131 title = "Pink Purple\nGradient";
1132 break;
1133 case BEAUTIFY_EFFECT_PINK_BLUE_GRADIENT:
1134 title = "Pink Blue\nGradient";
1135 break;
1136 }
1137
1138 gint32 image = gimp_image_duplicate (preview_image);
1139
1140 /*if (width > THUMBNAIL_SIZE && height > THUMBNAIL_SIZE) {
1141 if (width > height)
1142 {
1143 gimp_image_scale (image, THUMBNAIL_SIZE * width / height, THUMBNAIL_SIZE);
1144 }
1145 else
1146 {
1147 gimp_image_scale (image, THUMBNAIL_SIZE, THUMBNAIL_SIZE * height / width);
1148 }
1149 }*/
1150
1151 run_effect (image, effect);
1152
1153 GtkWidget *box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
1154
1155 GdkPixbuf *pixbuf = gimp_image_get_thumbnail (image, THUMBNAIL_SIZE, THUMBNAIL_SIZE, GIMP_PIXBUF_SMALL_CHECKS);
1156 GtkWidget *icon = gtk_image_new_from_pixbuf (pixbuf);
1157 GtkWidget *event_box = gtk_event_box_new ();
1158 gtk_container_add (GTK_CONTAINER (event_box), icon);
1159 gtk_widget_show (icon);
1160 gtk_box_pack_start (GTK_BOX (box), event_box, FALSE, FALSE, 0);
1161 gtk_widget_show (event_box);
1162
1163 GtkWidget *label = gtk_label_new (title);
1164 /* gtk_label_set_line_wrap will let textalign to left instead of center :(
1165 gtk_widget_set_size_request (label, THUMBNAIL_SIZE, -1);
1166 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);*/
1167 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
1168 gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
1169 gtk_widget_show (label);
1170
1171 g_signal_connect (event_box, "button_press_event", G_CALLBACK (select_effect), (gpointer) effect);
1172
1173 gimp_image_delete (image);
1174
1175 return box;
1176 }
1177
1178 static gboolean
select_effect(GtkWidget * widget,GdkEvent * event,gpointer user_data)1179 select_effect (GtkWidget *widget, GdkEvent *event, gpointer user_data)
1180 {
1181 reset_adjustment ();
1182 apply_effect();
1183
1184 BeautifyEffectType effect = (BeautifyEffectType) user_data;
1185 run_effect (preview_image, effect);
1186 current_effect = effect;
1187 preview_update (preview);
1188
1189 /* effect option */
1190 gtk_range_set_value (GTK_RANGE (effect_opacity), 100);
1191 gtk_widget_show (effect_option);
1192
1193 return TRUE;
1194 }
1195
1196 static void
reset_adjustment()1197 reset_adjustment ()
1198 {
1199 if (bvals.brightness != 0) {
1200 bvals.brightness = 0;
1201 gtk_range_set_value (GTK_RANGE (brightness), 0);
1202 }
1203 if (bvals.contrast != 0) {
1204 bvals.contrast = 0;
1205 gtk_range_set_value (GTK_RANGE (contrast), 0);
1206 }
1207 if (bvals.saturation != 0) {
1208 bvals.saturation = 0;
1209 gtk_range_set_value (GTK_RANGE (saturation), 0);
1210 }
1211 if (bvals.definition != 0) {
1212 bvals.definition = 0;
1213 gtk_range_set_value (GTK_RANGE (definition), 0);
1214 }
1215 if (bvals.hue != 0) {
1216 bvals.hue = 0;
1217 gtk_range_set_value (GTK_RANGE (hue), 0);
1218 }
1219 if (bvals.cyan_red != 0) {
1220 bvals.cyan_red = 0;
1221 gtk_range_set_value (GTK_RANGE (cyan_red), 0);
1222 }
1223 if (bvals.magenta_green != 0) {
1224 bvals.magenta_green = 0;
1225 gtk_range_set_value (GTK_RANGE (magenta_green), 0);
1226 }
1227 if (bvals.yellow_blue != 0) {
1228 bvals.yellow_blue = 0;
1229 gtk_range_set_value (GTK_RANGE (yellow_blue), 0);
1230 }
1231 }
1232
1233 static void
apply_effect()1234 apply_effect ()
1235 {
1236 if (current_effect == BEAUTIFY_EFFECT_NONE) {
1237 return;
1238 }
1239
1240 gint32 current_layer = gimp_image_get_active_layer (preview_image);
1241 gimp_image_merge_down (preview_image, current_layer, GIMP_CLIP_TO_IMAGE);
1242
1243 current_effect = BEAUTIFY_EFFECT_NONE;
1244
1245 gtk_widget_hide (effect_option);
1246
1247 if (saved_image) {
1248 gimp_image_delete (saved_image);
1249 saved_image = 0;
1250 }
1251 }
1252
1253 static void
cancel_effect()1254 cancel_effect ()
1255 {
1256 if (current_effect == BEAUTIFY_EFFECT_NONE) {
1257 return;
1258 }
1259
1260 gint32 current_layer = gimp_image_get_active_layer (preview_image);
1261 gimp_drawable_delete (current_layer);
1262
1263 current_effect = BEAUTIFY_EFFECT_NONE;
1264
1265 gtk_widget_hide (effect_option);
1266
1267 if (saved_image) {
1268 gimp_image_delete (saved_image);
1269 saved_image = 0;
1270 }
1271 }
1272
1273