1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995-1999 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 "libgimpconfig/gimpconfig.h"
24 #include "libgimpwidgets/gimpwidgets.h"
25 
26 #include "tools-types.h"
27 
28 #include "config/gimpcoreconfig.h"
29 
30 #include "core/gimp.h"
31 #include "core/gimptoolinfo.h"
32 
33 #include "widgets/gimppropwidgets.h"
34 #include "widgets/gimpwidgets-utils.h"
35 
36 #include "gimpregionselectoptions.h"
37 #include "gimpregionselecttool.h"
38 #include "gimpfuzzyselecttool.h"
39 
40 #include "gimp-intl.h"
41 
42 
43 enum
44 {
45   PROP_0,
46   PROP_SELECT_TRANSPARENT,
47   PROP_SAMPLE_MERGED,
48   PROP_DIAGONAL_NEIGHBORS,
49   PROP_THRESHOLD,
50   PROP_SELECT_CRITERION,
51   PROP_DRAW_MASK
52 };
53 
54 
55 static void   gimp_region_select_options_config_iface_init (GimpConfigInterface *config_iface);
56 
57 static void   gimp_region_select_options_set_property (GObject         *object,
58                                                        guint            property_id,
59                                                        const GValue    *value,
60                                                        GParamSpec      *pspec);
61 static void   gimp_region_select_options_get_property (GObject         *object,
62                                                        guint            property_id,
63                                                        GValue          *value,
64                                                        GParamSpec      *pspec);
65 
66 static void   gimp_region_select_options_reset        (GimpConfig      *config);
67 
68 
69 G_DEFINE_TYPE_WITH_CODE (GimpRegionSelectOptions, gimp_region_select_options,
70                          GIMP_TYPE_SELECTION_OPTIONS,
71                          G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
72                                                 gimp_region_select_options_config_iface_init))
73 
74 #define parent_class gimp_region_select_options_parent_class
75 
76 static GimpConfigInterface *parent_config_iface = NULL;
77 
78 
79 static void
gimp_region_select_options_class_init(GimpRegionSelectOptionsClass * klass)80 gimp_region_select_options_class_init (GimpRegionSelectOptionsClass *klass)
81 {
82   GObjectClass *object_class = G_OBJECT_CLASS (klass);
83 
84   object_class->set_property = gimp_region_select_options_set_property;
85   object_class->get_property = gimp_region_select_options_get_property;
86 
87   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SELECT_TRANSPARENT,
88                             "select-transparent",
89                             _("Select transparent areas"),
90                             _("Allow completely transparent regions "
91                               "to be selected"),
92                             TRUE,
93                             GIMP_PARAM_STATIC_STRINGS);
94 
95   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAMPLE_MERGED,
96                             "sample-merged",
97                             _("Sample merged"),
98                             _("Base selection on all visible layers"),
99                             FALSE,
100                             GIMP_PARAM_STATIC_STRINGS);
101 
102   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DIAGONAL_NEIGHBORS,
103                             "diagonal-neighbors",
104                             _("Diagonal neighbors"),
105                             _("Treat diagonally neighboring pixels as "
106                               "connected"),
107                             FALSE,
108                             GIMP_PARAM_STATIC_STRINGS);
109 
110   GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_THRESHOLD,
111                            "threshold",
112                            _("Threshold"),
113                            _("Maximum color difference"),
114                            0.0, 255.0, 15.0,
115                            GIMP_PARAM_STATIC_STRINGS);
116 
117   GIMP_CONFIG_PROP_ENUM (object_class, PROP_SELECT_CRITERION,
118                          "select-criterion",
119                          _("Select by"),
120                          _("Selection criterion"),
121                          GIMP_TYPE_SELECT_CRITERION,
122                          GIMP_SELECT_CRITERION_COMPOSITE,
123                          GIMP_PARAM_STATIC_STRINGS);
124 
125   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DRAW_MASK,
126                             "draw-mask",
127                             _("Draw mask"),
128                             _("Draw the selected region's mask"),
129                             FALSE,
130                             GIMP_PARAM_STATIC_STRINGS);
131 }
132 
133 static void
gimp_region_select_options_config_iface_init(GimpConfigInterface * config_iface)134 gimp_region_select_options_config_iface_init (GimpConfigInterface *config_iface)
135 {
136   parent_config_iface = g_type_interface_peek_parent (config_iface);
137 
138   config_iface->reset = gimp_region_select_options_reset;
139 }
140 
141 static void
gimp_region_select_options_init(GimpRegionSelectOptions * options)142 gimp_region_select_options_init (GimpRegionSelectOptions *options)
143 {
144 }
145 
146 static void
gimp_region_select_options_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)147 gimp_region_select_options_set_property (GObject      *object,
148                                          guint         property_id,
149                                          const GValue *value,
150                                          GParamSpec   *pspec)
151 {
152   GimpRegionSelectOptions *options = GIMP_REGION_SELECT_OPTIONS (object);
153 
154   switch (property_id)
155     {
156     case PROP_SELECT_TRANSPARENT:
157       options->select_transparent = g_value_get_boolean (value);
158       break;
159 
160     case PROP_SAMPLE_MERGED:
161       options->sample_merged = g_value_get_boolean (value);
162       break;
163 
164     case PROP_DIAGONAL_NEIGHBORS:
165       options->diagonal_neighbors = g_value_get_boolean (value);
166       break;
167 
168     case PROP_THRESHOLD:
169       options->threshold = g_value_get_double (value);
170       break;
171 
172     case PROP_SELECT_CRITERION:
173       options->select_criterion = g_value_get_enum (value);
174       break;
175 
176     case PROP_DRAW_MASK:
177       options->draw_mask = g_value_get_boolean (value);
178       break;
179 
180     default:
181       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
182       break;
183     }
184 }
185 
186 static void
gimp_region_select_options_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)187 gimp_region_select_options_get_property (GObject    *object,
188                                          guint       property_id,
189                                          GValue     *value,
190                                          GParamSpec *pspec)
191 {
192   GimpRegionSelectOptions *options = GIMP_REGION_SELECT_OPTIONS (object);
193 
194   switch (property_id)
195     {
196     case PROP_SELECT_TRANSPARENT:
197       g_value_set_boolean (value, options->select_transparent);
198       break;
199 
200     case PROP_SAMPLE_MERGED:
201       g_value_set_boolean (value, options->sample_merged);
202       break;
203 
204     case PROP_DIAGONAL_NEIGHBORS:
205       g_value_set_boolean (value, options->diagonal_neighbors);
206       break;
207 
208     case PROP_THRESHOLD:
209       g_value_set_double (value, options->threshold);
210       break;
211 
212     case PROP_SELECT_CRITERION:
213       g_value_set_enum (value, options->select_criterion);
214       break;
215 
216     case PROP_DRAW_MASK:
217       g_value_set_boolean (value, options->draw_mask);
218       break;
219 
220     default:
221       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
222       break;
223     }
224 }
225 
226 static void
gimp_region_select_options_reset(GimpConfig * config)227 gimp_region_select_options_reset (GimpConfig *config)
228 {
229   GimpToolOptions *tool_options = GIMP_TOOL_OPTIONS (config);
230   GParamSpec      *pspec;
231 
232   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
233                                         "threshold");
234 
235   if (pspec)
236     G_PARAM_SPEC_DOUBLE (pspec)->default_value =
237       tool_options->tool_info->gimp->config->default_threshold;
238 
239   parent_config_iface->reset (config);
240 }
241 
242 GtkWidget *
gimp_region_select_options_gui(GimpToolOptions * tool_options)243 gimp_region_select_options_gui (GimpToolOptions *tool_options)
244 {
245   GObject   *config  = G_OBJECT (tool_options);
246   GtkWidget *vbox    = gimp_selection_options_gui (tool_options);
247   GtkWidget *button;
248   GtkWidget *scale;
249   GtkWidget *combo;
250   GType      tool_type;
251 
252   tool_type = tool_options->tool_info->tool_type;
253 
254   /*  the select transparent areas toggle  */
255   button = gimp_prop_check_button_new (config, "select-transparent", NULL);
256   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
257   gtk_widget_show (button);
258 
259   /*  the sample merged toggle  */
260   button = gimp_prop_check_button_new (config, "sample-merged", NULL);
261   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
262   gtk_widget_show (button);
263 
264   /*  the diagonal neighbors toggle  */
265   if (tool_type == GIMP_TYPE_FUZZY_SELECT_TOOL)
266     {
267       button = gimp_prop_check_button_new (config, "diagonal-neighbors", NULL);
268       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
269       gtk_widget_show (button);
270     }
271 
272   /*  the threshold scale  */
273   scale = gimp_prop_spin_scale_new (config, "threshold", NULL,
274                                     1.0, 16.0, 1);
275   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
276   gtk_widget_show (scale);
277 
278   /*  the select criterion combo  */
279   combo = gimp_prop_enum_combo_box_new (config, "select-criterion", 0, 0);
280   gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Select by"));
281   gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, TRUE, 0);
282   gtk_widget_show (combo);
283 
284   /*  the show mask toggle  */
285   button = gimp_prop_check_button_new (config, "draw-mask", NULL);
286   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
287   gtk_widget_show (button);
288 
289   return vbox;
290 }
291