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 <string.h>
21
22 #include <gegl.h>
23 #include <gtk/gtk.h>
24
25 #include "libgimpconfig/gimpconfig.h"
26 #include "libgimpwidgets/gimpwidgets.h"
27
28 #include "tools-types.h"
29
30 #include "operations/gimpbrightnesscontrastconfig.h"
31
32 #include "core/gimpdrawable.h"
33 #include "core/gimperror.h"
34 #include "core/gimpimage.h"
35
36 #include "widgets/gimphelp-ids.h"
37 #include "widgets/gimppropwidgets.h"
38 #include "widgets/gimpspinscale.h"
39 #include "widgets/gimpwidgets-constructors.h"
40
41 #include "display/gimpdisplay.h"
42
43 #include "gimpbrightnesscontrasttool.h"
44 #include "gimpfilteroptions.h"
45 #include "gimptoolcontrol.h"
46
47 #include "gimp-intl.h"
48
49
50 #define SLIDER_WIDTH 200
51
52
53 static gboolean gimp_brightness_contrast_tool_initialize (GimpTool *tool,
54 GimpDisplay *display,
55 GError **error);
56 static void gimp_brightness_contrast_tool_button_press (GimpTool *tool,
57 const GimpCoords *coords,
58 guint32 time,
59 GdkModifierType state,
60 GimpButtonPressType press_type,
61 GimpDisplay *display);
62 static void gimp_brightness_contrast_tool_button_release (GimpTool *tool,
63 const GimpCoords *coords,
64 guint32 time,
65 GdkModifierType state,
66 GimpButtonReleaseType release_type,
67 GimpDisplay *display);
68 static void gimp_brightness_contrast_tool_motion (GimpTool *tool,
69 const GimpCoords *coords,
70 guint32 time,
71 GdkModifierType state,
72 GimpDisplay *display);
73
74 static gchar *
75 gimp_brightness_contrast_tool_get_operation (GimpFilterTool *filter_tool,
76 gchar **description);
77 static void gimp_brightness_contrast_tool_dialog (GimpFilterTool *filter_tool);
78
79 static void brightness_contrast_to_levels_callback (GtkWidget *widget,
80 GimpFilterTool *filter_tool);
81
82
G_DEFINE_TYPE(GimpBrightnessContrastTool,gimp_brightness_contrast_tool,GIMP_TYPE_FILTER_TOOL)83 G_DEFINE_TYPE (GimpBrightnessContrastTool, gimp_brightness_contrast_tool,
84 GIMP_TYPE_FILTER_TOOL)
85
86 #define parent_class gimp_brightness_contrast_tool_parent_class
87
88
89 void
90 gimp_brightness_contrast_tool_register (GimpToolRegisterCallback callback,
91 gpointer data)
92 {
93 (* callback) (GIMP_TYPE_BRIGHTNESS_CONTRAST_TOOL,
94 GIMP_TYPE_FILTER_OPTIONS, NULL,
95 0,
96 "gimp-brightness-contrast-tool",
97 _("Brightness-Contrast"),
98 _("Adjust brightness and contrast"),
99 N_("B_rightness-Contrast..."), NULL,
100 NULL, GIMP_HELP_TOOL_BRIGHTNESS_CONTRAST,
101 GIMP_ICON_TOOL_BRIGHTNESS_CONTRAST,
102 data);
103 }
104
105 static void
gimp_brightness_contrast_tool_class_init(GimpBrightnessContrastToolClass * klass)106 gimp_brightness_contrast_tool_class_init (GimpBrightnessContrastToolClass *klass)
107 {
108 GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
109 GimpFilterToolClass *filter_tool_class = GIMP_FILTER_TOOL_CLASS (klass);
110
111 tool_class->initialize = gimp_brightness_contrast_tool_initialize;
112 tool_class->button_press = gimp_brightness_contrast_tool_button_press;
113 tool_class->button_release = gimp_brightness_contrast_tool_button_release;
114 tool_class->motion = gimp_brightness_contrast_tool_motion;
115
116 filter_tool_class->get_operation = gimp_brightness_contrast_tool_get_operation;
117 filter_tool_class->dialog = gimp_brightness_contrast_tool_dialog;
118 }
119
120 static void
gimp_brightness_contrast_tool_init(GimpBrightnessContrastTool * bc_tool)121 gimp_brightness_contrast_tool_init (GimpBrightnessContrastTool *bc_tool)
122 {
123 }
124
125 static gboolean
gimp_brightness_contrast_tool_initialize(GimpTool * tool,GimpDisplay * display,GError ** error)126 gimp_brightness_contrast_tool_initialize (GimpTool *tool,
127 GimpDisplay *display,
128 GError **error)
129 {
130 GimpBrightnessContrastTool *bc_tool = GIMP_BRIGHTNESS_CONTRAST_TOOL (tool);
131 GimpImage *image = gimp_display_get_image (display);
132 GimpDrawable *drawable = gimp_image_get_active_drawable (image);
133
134 if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error))
135 {
136 return FALSE;
137 }
138
139 if (gimp_drawable_get_component_type (drawable) == GIMP_COMPONENT_TYPE_U8)
140 {
141 gimp_prop_widget_set_factor (bc_tool->brightness_scale,
142 127.0, 1.0, 8.0, 0);
143 gimp_prop_widget_set_factor (bc_tool->contrast_scale,
144 127.0, 1.0, 8.0, 0);
145 }
146 else
147 {
148 gimp_prop_widget_set_factor (bc_tool->brightness_scale,
149 0.5, 0.01, 0.1, 3);
150 gimp_prop_widget_set_factor (bc_tool->contrast_scale,
151 0.5, 0.01, 0.1, 3);
152 }
153
154 return TRUE;
155 }
156
157 static gchar *
gimp_brightness_contrast_tool_get_operation(GimpFilterTool * filter_tool,gchar ** description)158 gimp_brightness_contrast_tool_get_operation (GimpFilterTool *filter_tool,
159 gchar **description)
160 {
161 *description = g_strdup (_("Adjust Brightness and Contrast"));
162
163 return g_strdup ("gimp:brightness-contrast");
164 }
165
166 static void
gimp_brightness_contrast_tool_button_press(GimpTool * tool,const GimpCoords * coords,guint32 time,GdkModifierType state,GimpButtonPressType press_type,GimpDisplay * display)167 gimp_brightness_contrast_tool_button_press (GimpTool *tool,
168 const GimpCoords *coords,
169 guint32 time,
170 GdkModifierType state,
171 GimpButtonPressType press_type,
172 GimpDisplay *display)
173 {
174 GimpBrightnessContrastTool *bc_tool = GIMP_BRIGHTNESS_CONTRAST_TOOL (tool);
175
176 bc_tool->dragging = ! gimp_filter_tool_on_guide (GIMP_FILTER_TOOL (tool),
177 coords, display);
178
179 if (! bc_tool->dragging)
180 {
181 GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
182 press_type, display);
183 }
184 else
185 {
186 gdouble brightness;
187 gdouble contrast;
188
189 g_object_get (GIMP_FILTER_TOOL (tool)->config,
190 "brightness", &brightness,
191 "contrast", &contrast,
192 NULL);
193
194 bc_tool->x = coords->x - contrast * 127.0;
195 bc_tool->y = coords->y + brightness * 127.0;
196 bc_tool->dx = contrast * 127.0;
197 bc_tool->dy = - brightness * 127.0;
198
199 tool->display = display;
200
201 gimp_tool_control_activate (tool->control);
202 }
203 }
204
205 static void
gimp_brightness_contrast_tool_button_release(GimpTool * tool,const GimpCoords * coords,guint32 time,GdkModifierType state,GimpButtonReleaseType release_type,GimpDisplay * display)206 gimp_brightness_contrast_tool_button_release (GimpTool *tool,
207 const GimpCoords *coords,
208 guint32 time,
209 GdkModifierType state,
210 GimpButtonReleaseType release_type,
211 GimpDisplay *display)
212 {
213 GimpBrightnessContrastTool *bc_tool = GIMP_BRIGHTNESS_CONTRAST_TOOL (tool);
214
215 if (! bc_tool->dragging)
216 {
217 GIMP_TOOL_CLASS (parent_class)->button_release (tool, coords, time, state,
218 release_type, display);
219 }
220 else
221 {
222 gimp_tool_control_halt (tool->control);
223
224 bc_tool->dragging = FALSE;
225
226 if (bc_tool->dx == 0 && bc_tool->dy == 0)
227 return;
228
229 if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
230 gimp_config_reset (GIMP_CONFIG (GIMP_FILTER_TOOL (tool)->config));
231 }
232 }
233
234 static void
gimp_brightness_contrast_tool_motion(GimpTool * tool,const GimpCoords * coords,guint32 time,GdkModifierType state,GimpDisplay * display)235 gimp_brightness_contrast_tool_motion (GimpTool *tool,
236 const GimpCoords *coords,
237 guint32 time,
238 GdkModifierType state,
239 GimpDisplay *display)
240 {
241 GimpBrightnessContrastTool *bc_tool = GIMP_BRIGHTNESS_CONTRAST_TOOL (tool);
242
243 if (! bc_tool->dragging)
244 {
245 GIMP_TOOL_CLASS (parent_class)->motion (tool, coords, time, state,
246 display);
247 }
248 else
249 {
250 bc_tool->dx = (coords->x - bc_tool->x);
251 bc_tool->dy = - (coords->y - bc_tool->y);
252
253 g_object_set (GIMP_FILTER_TOOL (tool)->config,
254 "brightness", CLAMP (bc_tool->dy, -127.0, 127.0) / 127.0,
255 "contrast", CLAMP (bc_tool->dx, -127.0, 127.0) / 127.0,
256 NULL);
257 }
258 }
259
260
261 /********************************/
262 /* Brightness Contrast dialog */
263 /********************************/
264
265 static void
gimp_brightness_contrast_tool_dialog(GimpFilterTool * filter_tool)266 gimp_brightness_contrast_tool_dialog (GimpFilterTool *filter_tool)
267 {
268 GimpBrightnessContrastTool *bc_tool = GIMP_BRIGHTNESS_CONTRAST_TOOL (filter_tool);
269 GtkWidget *main_vbox;
270 GtkWidget *scale;
271 GtkWidget *button;
272
273 main_vbox = gimp_filter_tool_dialog_get_vbox (filter_tool);
274
275 /* Create the brightness scale widget */
276 scale = gimp_prop_spin_scale_new (filter_tool->config, "brightness",
277 _("_Brightness"), 0.01, 0.1, 3);
278 gtk_box_pack_start (GTK_BOX (main_vbox), scale, FALSE, FALSE, 0);
279 gtk_widget_show (scale);
280
281 bc_tool->brightness_scale = scale;
282
283 /* Create the contrast scale widget */
284 scale = gimp_prop_spin_scale_new (filter_tool->config, "contrast",
285 _("_Contrast"), 0.01, 0.1, 3);
286 gtk_box_pack_start (GTK_BOX (main_vbox), scale, FALSE, FALSE, 0);
287 gtk_widget_show (scale);
288
289 bc_tool->contrast_scale = scale;
290
291 button = gimp_icon_button_new (GIMP_ICON_TOOL_LEVELS,
292 _("Edit these Settings as Levels"));
293 gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
294 gtk_widget_show (button);
295
296 g_signal_connect (button, "clicked",
297 G_CALLBACK (brightness_contrast_to_levels_callback),
298 filter_tool);
299 }
300
301 static void
brightness_contrast_to_levels_callback(GtkWidget * widget,GimpFilterTool * filter_tool)302 brightness_contrast_to_levels_callback (GtkWidget *widget,
303 GimpFilterTool *filter_tool)
304 {
305 GimpLevelsConfig *levels;
306
307 levels = gimp_brightness_contrast_config_to_levels_config (GIMP_BRIGHTNESS_CONTRAST_CONFIG (filter_tool->config));
308
309 gimp_filter_tool_edit_as (filter_tool,
310 "gimp-levels-tool",
311 GIMP_CONFIG (levels));
312
313 g_object_unref (levels);
314 }
315