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/gimpconvolveoptions.h"
28 
29 #include "widgets/gimphelp-ids.h"
30 #include "widgets/gimppropwidgets.h"
31 #include "widgets/gimpwidgets-utils.h"
32 
33 #include "gimpconvolvetool.h"
34 #include "gimppaintoptions-gui.h"
35 #include "gimptoolcontrol.h"
36 
37 #include "gimp-intl.h"
38 
39 
40 static void   gimp_convolve_tool_modifier_key  (GimpTool         *tool,
41                                                 GdkModifierType   key,
42                                                 gboolean          press,
43                                                 GdkModifierType   state,
44                                                 GimpDisplay      *display);
45 static void   gimp_convolve_tool_cursor_update (GimpTool         *tool,
46                                                 const GimpCoords *coords,
47                                                 GdkModifierType   state,
48                                                 GimpDisplay      *display);
49 static void   gimp_convolve_tool_oper_update   (GimpTool         *tool,
50                                                 const GimpCoords *coords,
51                                                 GdkModifierType   state,
52                                                 gboolean          proximity,
53                                                 GimpDisplay      *display);
54 static void   gimp_convolve_tool_status_update (GimpTool         *tool,
55                                                 GimpConvolveType  type);
56 
57 static GtkWidget * gimp_convolve_options_gui   (GimpToolOptions  *options);
58 
59 
G_DEFINE_TYPE(GimpConvolveTool,gimp_convolve_tool,GIMP_TYPE_BRUSH_TOOL)60 G_DEFINE_TYPE (GimpConvolveTool, gimp_convolve_tool, GIMP_TYPE_BRUSH_TOOL)
61 
62 #define parent_class gimp_convolve_tool_parent_class
63 
64 
65 void
66 gimp_convolve_tool_register (GimpToolRegisterCallback  callback,
67                              gpointer                  data)
68 {
69   (* callback) (GIMP_TYPE_CONVOLVE_TOOL,
70                 GIMP_TYPE_CONVOLVE_OPTIONS,
71                 gimp_convolve_options_gui,
72                 GIMP_PAINT_OPTIONS_CONTEXT_MASK,
73                 "gimp-convolve-tool",
74                 _("Blur / Sharpen"),
75                 _("Blur / Sharpen Tool: Selective blurring or unblurring using a brush"),
76                 N_("Bl_ur / Sharpen"), "<shift>U",
77                 NULL, GIMP_HELP_TOOL_CONVOLVE,
78                 GIMP_ICON_TOOL_BLUR,
79                 data);
80 }
81 
82 static void
gimp_convolve_tool_class_init(GimpConvolveToolClass * klass)83 gimp_convolve_tool_class_init (GimpConvolveToolClass *klass)
84 {
85   GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
86 
87   tool_class->modifier_key  = gimp_convolve_tool_modifier_key;
88   tool_class->cursor_update = gimp_convolve_tool_cursor_update;
89   tool_class->oper_update   = gimp_convolve_tool_oper_update;
90 }
91 
92 static void
gimp_convolve_tool_init(GimpConvolveTool * convolve)93 gimp_convolve_tool_init (GimpConvolveTool *convolve)
94 {
95   GimpTool *tool = GIMP_TOOL (convolve);
96 
97   gimp_tool_control_set_tool_cursor            (tool->control,
98                                                 GIMP_TOOL_CURSOR_BLUR);
99   gimp_tool_control_set_toggle_cursor_modifier (tool->control,
100                                                 GIMP_CURSOR_MODIFIER_MINUS);
101 
102   gimp_convolve_tool_status_update (tool, GIMP_CONVOLVE_BLUR);
103 }
104 
105 static void
gimp_convolve_tool_modifier_key(GimpTool * tool,GdkModifierType key,gboolean press,GdkModifierType state,GimpDisplay * display)106 gimp_convolve_tool_modifier_key (GimpTool        *tool,
107                                  GdkModifierType  key,
108                                  gboolean         press,
109                                  GdkModifierType  state,
110                                  GimpDisplay     *display)
111 {
112   GimpConvolveTool    *convolve    = GIMP_CONVOLVE_TOOL (tool);
113   GimpConvolveOptions *options     = GIMP_CONVOLVE_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 != convolve->toggled)
120 
121       ||
122 
123       (key == line_mask  && /* toggle back after keypresses CTRL(hold)->  */
124        ! press           && /* SHIFT(hold)->CTRL(release)->SHIFT(release) */
125        convolve->toggled &&
126        ! (state & toggle_mask)))
127     {
128       convolve->toggled = press;
129 
130       switch (options->type)
131         {
132         case GIMP_CONVOLVE_BLUR:
133           g_object_set (options, "type", GIMP_CONVOLVE_SHARPEN, NULL);
134           break;
135 
136         case GIMP_CONVOLVE_SHARPEN:
137           g_object_set (options, "type", GIMP_CONVOLVE_BLUR, NULL);
138           break;
139         }
140     }
141 }
142 
143 static void
gimp_convolve_tool_cursor_update(GimpTool * tool,const GimpCoords * coords,GdkModifierType state,GimpDisplay * display)144 gimp_convolve_tool_cursor_update (GimpTool         *tool,
145                                   const GimpCoords *coords,
146                                   GdkModifierType   state,
147                                   GimpDisplay      *display)
148 {
149   GimpConvolveOptions *options = GIMP_CONVOLVE_TOOL_GET_OPTIONS (tool);
150 
151   gimp_tool_control_set_toggled (tool->control,
152                                  options->type == GIMP_CONVOLVE_SHARPEN);
153 
154   GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
155 }
156 
157 static void
gimp_convolve_tool_oper_update(GimpTool * tool,const GimpCoords * coords,GdkModifierType state,gboolean proximity,GimpDisplay * display)158 gimp_convolve_tool_oper_update (GimpTool         *tool,
159                                 const GimpCoords *coords,
160                                 GdkModifierType   state,
161                                 gboolean          proximity,
162                                 GimpDisplay      *display)
163 {
164   GimpConvolveOptions *options = GIMP_CONVOLVE_TOOL_GET_OPTIONS (tool);
165 
166   gimp_convolve_tool_status_update (tool, options->type);
167 
168   GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
169                                                display);
170 }
171 
172 static void
gimp_convolve_tool_status_update(GimpTool * tool,GimpConvolveType type)173 gimp_convolve_tool_status_update (GimpTool         *tool,
174                                   GimpConvolveType  type)
175 {
176   GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
177 
178   switch (type)
179     {
180     case GIMP_CONVOLVE_BLUR:
181       paint_tool->status      = _("Click to blur");
182       paint_tool->status_line = _("Click to blur the line");
183       paint_tool->status_ctrl = _("%s to sharpen");
184       break;
185 
186     case GIMP_CONVOLVE_SHARPEN:
187       paint_tool->status      = _("Click to sharpen");
188       paint_tool->status_line = _("Click to sharpen the line");
189       paint_tool->status_ctrl = _("%s to blur");
190       break;
191 
192     default:
193       break;
194     }
195 }
196 
197 
198 /*  tool options stuff  */
199 
200 static GtkWidget *
gimp_convolve_options_gui(GimpToolOptions * tool_options)201 gimp_convolve_options_gui (GimpToolOptions *tool_options)
202 {
203   GObject         *config = G_OBJECT (tool_options);
204   GtkWidget       *vbox   = gimp_paint_options_gui (tool_options);
205   GtkWidget       *frame;
206   GtkWidget       *scale;
207   gchar           *str;
208   GdkModifierType  toggle_mask;
209 
210   toggle_mask = gimp_get_toggle_behavior_mask ();
211 
212   /*  the type radio box  */
213   str = g_strdup_printf (_("Convolve Type  (%s)"),
214                          gimp_get_mod_string (toggle_mask));
215 
216   frame = gimp_prop_enum_radio_frame_new (config, "type",
217                                           str, 0, 0);
218   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
219   gtk_widget_show (frame);
220 
221   g_free (str);
222 
223   /*  the rate scale  */
224   scale = gimp_prop_spin_scale_new (config, "rate", NULL,
225                                     1.0, 10.0, 1);
226   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
227   gtk_widget_show (scale);
228 
229   return vbox;
230 }
231