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 "tools-types.h"
26
27 #include "paint/gimpdodgeburnoptions.h"
28
29 #include "widgets/gimphelp-ids.h"
30 #include "widgets/gimppropwidgets.h"
31 #include "widgets/gimpwidgets-utils.h"
32
33 #include "gimpdodgeburntool.h"
34 #include "gimppaintoptions-gui.h"
35 #include "gimptoolcontrol.h"
36
37 #include "gimp-intl.h"
38
39
40 static void gimp_dodge_burn_tool_modifier_key (GimpTool *tool,
41 GdkModifierType key,
42 gboolean press,
43 GdkModifierType state,
44 GimpDisplay *display);
45 static void gimp_dodge_burn_tool_cursor_update (GimpTool *tool,
46 const GimpCoords *coords,
47 GdkModifierType state,
48 GimpDisplay *display);
49 static void gimp_dodge_burn_tool_oper_update (GimpTool *tool,
50 const GimpCoords *coords,
51 GdkModifierType state,
52 gboolean proximity,
53 GimpDisplay *display);
54 static void gimp_dodge_burn_tool_status_update (GimpTool *tool,
55 GimpDodgeBurnType type);
56
57 static GtkWidget * gimp_dodge_burn_options_gui (GimpToolOptions *tool_options);
58
59
G_DEFINE_TYPE(GimpDodgeBurnTool,gimp_dodge_burn_tool,GIMP_TYPE_BRUSH_TOOL)60 G_DEFINE_TYPE (GimpDodgeBurnTool, gimp_dodge_burn_tool, GIMP_TYPE_BRUSH_TOOL)
61
62 #define parent_class gimp_dodge_burn_tool_parent_class
63
64
65 void
66 gimp_dodge_burn_tool_register (GimpToolRegisterCallback callback,
67 gpointer data)
68 {
69 (* callback) (GIMP_TYPE_DODGE_BURN_TOOL,
70 GIMP_TYPE_DODGE_BURN_OPTIONS,
71 gimp_dodge_burn_options_gui,
72 GIMP_PAINT_OPTIONS_CONTEXT_MASK,
73 "gimp-dodge-burn-tool",
74 _("Dodge / Burn"),
75 _("Dodge / Burn Tool: Selectively lighten or darken using a brush"),
76 N_("Dod_ge / Burn"), "<shift>D",
77 NULL, GIMP_HELP_TOOL_DODGE_BURN,
78 GIMP_ICON_TOOL_DODGE,
79 data);
80 }
81
82 static void
gimp_dodge_burn_tool_class_init(GimpDodgeBurnToolClass * klass)83 gimp_dodge_burn_tool_class_init (GimpDodgeBurnToolClass *klass)
84 {
85 GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
86
87 tool_class->modifier_key = gimp_dodge_burn_tool_modifier_key;
88 tool_class->cursor_update = gimp_dodge_burn_tool_cursor_update;
89 tool_class->oper_update = gimp_dodge_burn_tool_oper_update;
90 }
91
92 static void
gimp_dodge_burn_tool_init(GimpDodgeBurnTool * dodgeburn)93 gimp_dodge_burn_tool_init (GimpDodgeBurnTool *dodgeburn)
94 {
95 GimpTool *tool = GIMP_TOOL (dodgeburn);
96
97 gimp_tool_control_set_tool_cursor (tool->control,
98 GIMP_TOOL_CURSOR_DODGE);
99 gimp_tool_control_set_toggle_tool_cursor (tool->control,
100 GIMP_TOOL_CURSOR_BURN);
101
102 gimp_dodge_burn_tool_status_update (tool, GIMP_DODGE_BURN_TYPE_BURN);
103 }
104
105 static void
gimp_dodge_burn_tool_modifier_key(GimpTool * tool,GdkModifierType key,gboolean press,GdkModifierType state,GimpDisplay * display)106 gimp_dodge_burn_tool_modifier_key (GimpTool *tool,
107 GdkModifierType key,
108 gboolean press,
109 GdkModifierType state,
110 GimpDisplay *display)
111 {
112 GimpDodgeBurnTool *dodgeburn = GIMP_DODGE_BURN_TOOL (tool);
113 GimpDodgeBurnOptions *options = GIMP_DODGE_BURN_TOOL_GET_OPTIONS (tool);
114 GdkModifierType line_mask = GIMP_PAINT_TOOL_LINE_MASK;
115 GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();
116
117 if ((key == toggle_mask &&
118 ! (state & line_mask) && /* leave stuff untouched in line draw mode */
119 press != dodgeburn->toggled)
120
121 ||
122
123 (key == line_mask && /* toggle back after keypresses CTRL(hold)-> */
124 ! press && /* SHIFT(hold)->CTRL(release)->SHIFT(release) */
125 dodgeburn->toggled &&
126 ! (state & toggle_mask)))
127 {
128 dodgeburn->toggled = press;
129
130 switch (options->type)
131 {
132 case GIMP_DODGE_BURN_TYPE_DODGE:
133 g_object_set (options, "type", GIMP_DODGE_BURN_TYPE_BURN, NULL);
134 break;
135
136 case GIMP_DODGE_BURN_TYPE_BURN:
137 g_object_set (options, "type", GIMP_DODGE_BURN_TYPE_DODGE, NULL);
138 break;
139
140 default:
141 break;
142 }
143 }
144
145 GIMP_TOOL_CLASS (parent_class)->modifier_key (tool, key, press, state,
146 display);
147 }
148
149 static void
gimp_dodge_burn_tool_cursor_update(GimpTool * tool,const GimpCoords * coords,GdkModifierType state,GimpDisplay * display)150 gimp_dodge_burn_tool_cursor_update (GimpTool *tool,
151 const GimpCoords *coords,
152 GdkModifierType state,
153 GimpDisplay *display)
154 {
155 GimpDodgeBurnOptions *options = GIMP_DODGE_BURN_TOOL_GET_OPTIONS (tool);
156
157 gimp_tool_control_set_toggled (tool->control,
158 options->type == GIMP_DODGE_BURN_TYPE_BURN);
159
160 GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state,
161 display);
162 }
163
164 static void
gimp_dodge_burn_tool_oper_update(GimpTool * tool,const GimpCoords * coords,GdkModifierType state,gboolean proximity,GimpDisplay * display)165 gimp_dodge_burn_tool_oper_update (GimpTool *tool,
166 const GimpCoords *coords,
167 GdkModifierType state,
168 gboolean proximity,
169 GimpDisplay *display)
170 {
171 GimpDodgeBurnOptions *options = GIMP_DODGE_BURN_TOOL_GET_OPTIONS (tool);
172
173 gimp_dodge_burn_tool_status_update (tool, options->type);
174
175 GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
176 display);
177 }
178
179 static void
gimp_dodge_burn_tool_status_update(GimpTool * tool,GimpDodgeBurnType type)180 gimp_dodge_burn_tool_status_update (GimpTool *tool,
181 GimpDodgeBurnType type)
182 {
183 GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
184
185 switch (type)
186 {
187 case GIMP_DODGE_BURN_TYPE_DODGE:
188 paint_tool->status = _("Click to dodge");
189 paint_tool->status_line = _("Click to dodge the line");
190 paint_tool->status_ctrl = _("%s to burn");
191 break;
192
193 case GIMP_DODGE_BURN_TYPE_BURN:
194 paint_tool->status = _("Click to burn");
195 paint_tool->status_line = _("Click to burn the line");
196 paint_tool->status_ctrl = _("%s to dodge");
197 break;
198
199 default:
200 break;
201 }
202 }
203
204
205 /* tool options stuff */
206
207 static GtkWidget *
gimp_dodge_burn_options_gui(GimpToolOptions * tool_options)208 gimp_dodge_burn_options_gui (GimpToolOptions *tool_options)
209 {
210 GObject *config = G_OBJECT (tool_options);
211 GtkWidget *vbox = gimp_paint_options_gui (tool_options);
212 GtkWidget *frame;
213 GtkWidget *scale;
214 gchar *str;
215 GdkModifierType toggle_mask;
216
217 toggle_mask = gimp_get_toggle_behavior_mask ();
218
219 /* the type (dodge or burn) */
220 str = g_strdup_printf (_("Type (%s)"),
221 gimp_get_mod_string (toggle_mask));
222
223 frame = gimp_prop_enum_radio_frame_new (config, "type",
224 str, 0, 0);
225 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
226 gtk_widget_show (frame);
227
228 g_free (str);
229
230 /* mode (highlights, midtones, or shadows) */
231 frame = gimp_prop_enum_radio_frame_new (config, "mode", NULL,
232 0, 0);
233 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
234 gtk_widget_show (frame);
235
236 /* the exposure scale */
237 scale = gimp_prop_spin_scale_new (config, "exposure", NULL,
238 1.0, 10.0, 1);
239 gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
240 gtk_widget_show (scale);
241
242 return vbox;
243 }
244