1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * gimpfilter.c
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "config.h"
21 
22 #include <gdk-pixbuf/gdk-pixbuf.h>
23 #include <gegl.h>
24 
25 #include "core-types.h"
26 
27 #include "gimp.h"
28 #include "gimp-memsize.h"
29 #include "gimpfilter.h"
30 #include "gimpmarshal.h"
31 
32 
33 enum
34 {
35   ACTIVE_CHANGED,
36   LAST_SIGNAL
37 };
38 
39 enum
40 {
41   PROP_0,
42   PROP_ACTIVE,
43   PROP_IS_LAST_NODE
44 };
45 
46 
47 typedef struct _GimpFilterPrivate GimpFilterPrivate;
48 
49 struct _GimpFilterPrivate
50 {
51   GeglNode       *node;
52 
53   guint           active       : 1;
54   guint           is_last_node : 1;
55 
56   GimpApplicator *applicator;
57 };
58 
59 #define GET_PRIVATE(filter) ((GimpFilterPrivate *) gimp_filter_get_instance_private ((GimpFilter *) (filter)))
60 
61 
62 /*  local function prototypes  */
63 
64 static void       gimp_filter_finalize      (GObject      *object);
65 static void       gimp_filter_set_property  (GObject      *object,
66                                              guint         property_id,
67                                              const GValue *value,
68                                              GParamSpec   *pspec);
69 static void       gimp_filter_get_property  (GObject      *object,
70                                              guint         property_id,
71                                              GValue       *value,
72                                              GParamSpec   *pspec);
73 
74 static gint64     gimp_filter_get_memsize   (GimpObject   *object,
75                                              gint64       *gui_size);
76 
77 static GeglNode * gimp_filter_real_get_node (GimpFilter   *filter);
78 
79 
80 G_DEFINE_TYPE_WITH_PRIVATE (GimpFilter, gimp_filter, GIMP_TYPE_VIEWABLE)
81 
82 #define parent_class gimp_filter_parent_class
83 
84 static guint gimp_filter_signals[LAST_SIGNAL] = { 0 };
85 
86 
87 static void
gimp_filter_class_init(GimpFilterClass * klass)88 gimp_filter_class_init (GimpFilterClass *klass)
89 {
90   GObjectClass    *object_class      = G_OBJECT_CLASS (klass);
91   GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
92 
93   gimp_filter_signals[ACTIVE_CHANGED] =
94     g_signal_new ("active-changed",
95                   G_TYPE_FROM_CLASS (klass),
96                   G_SIGNAL_RUN_FIRST,
97                   G_STRUCT_OFFSET (GimpFilterClass, active_changed),
98                   NULL, NULL,
99                   gimp_marshal_VOID__VOID,
100                   G_TYPE_NONE, 0);
101 
102   object_class->finalize         = gimp_filter_finalize;
103   object_class->set_property     = gimp_filter_set_property;
104   object_class->get_property     = gimp_filter_get_property;
105 
106   gimp_object_class->get_memsize = gimp_filter_get_memsize;
107 
108   klass->active_changed          = NULL;
109   klass->get_node                = gimp_filter_real_get_node;
110 
111   g_object_class_install_property (object_class, PROP_ACTIVE,
112                                    g_param_spec_boolean ("active", NULL, NULL,
113                                                          TRUE,
114                                                          GIMP_PARAM_READWRITE));
115 
116   g_object_class_install_property (object_class, PROP_IS_LAST_NODE,
117                                    g_param_spec_boolean ("is-last-node",
118                                                          NULL, NULL,
119                                                          FALSE,
120                                                          GIMP_PARAM_READWRITE));
121 }
122 
123 static void
gimp_filter_init(GimpFilter * filter)124 gimp_filter_init (GimpFilter *filter)
125 {
126   GimpFilterPrivate *private = GET_PRIVATE (filter);
127 
128   private->active = TRUE;
129 }
130 
131 static void
gimp_filter_finalize(GObject * object)132 gimp_filter_finalize (GObject *object)
133 {
134   GimpFilterPrivate *private = GET_PRIVATE (object);
135 
136   g_clear_object (&private->node);
137 
138   G_OBJECT_CLASS (parent_class)->finalize (object);
139 }
140 
141 static void
gimp_filter_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)142 gimp_filter_set_property (GObject      *object,
143                           guint         property_id,
144                           const GValue *value,
145                           GParamSpec   *pspec)
146 {
147   GimpFilter *filter = GIMP_FILTER (object);
148 
149   switch (property_id)
150     {
151     case PROP_ACTIVE:
152       gimp_filter_set_active (filter, g_value_get_boolean (value));
153       break;
154     case PROP_IS_LAST_NODE:
155       gimp_filter_set_is_last_node (filter, g_value_get_boolean (value));
156       break;
157 
158     default:
159       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
160       break;
161     }
162 }
163 
164 static void
gimp_filter_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)165 gimp_filter_get_property (GObject    *object,
166                           guint       property_id,
167                           GValue     *value,
168                           GParamSpec *pspec)
169 {
170   GimpFilterPrivate *private = GET_PRIVATE (object);
171 
172   switch (property_id)
173     {
174     case PROP_ACTIVE:
175       g_value_set_boolean (value, private->active);
176       break;
177     case PROP_IS_LAST_NODE:
178       g_value_set_boolean (value, private->is_last_node);
179       break;
180 
181     default:
182       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
183       break;
184     }
185 }
186 
187 static gint64
gimp_filter_get_memsize(GimpObject * object,gint64 * gui_size)188 gimp_filter_get_memsize (GimpObject *object,
189                          gint64     *gui_size)
190 {
191   GimpFilterPrivate *private = GET_PRIVATE (object);
192   gint64             memsize = 0;
193 
194   memsize += gimp_g_object_get_memsize (G_OBJECT (private->node));
195 
196   return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
197                                                                   gui_size);
198 }
199 
200 static GeglNode *
gimp_filter_real_get_node(GimpFilter * filter)201 gimp_filter_real_get_node (GimpFilter *filter)
202 {
203   GimpFilterPrivate *private = GET_PRIVATE (filter);
204 
205   private->node = gegl_node_new ();
206 
207   return private->node;
208 }
209 
210 
211 /*  public functions  */
212 
213 GimpFilter *
gimp_filter_new(const gchar * name)214 gimp_filter_new (const gchar *name)
215 {
216   g_return_val_if_fail (name != NULL, NULL);
217 
218   return g_object_new (GIMP_TYPE_FILTER,
219                        "name", name,
220                        NULL);
221 }
222 
223 GeglNode *
gimp_filter_get_node(GimpFilter * filter)224 gimp_filter_get_node (GimpFilter *filter)
225 {
226   GimpFilterPrivate *private;
227 
228   g_return_val_if_fail (GIMP_IS_FILTER (filter), NULL);
229 
230   private = GET_PRIVATE (filter);
231 
232   if (private->node)
233     return private->node;
234 
235   return GIMP_FILTER_GET_CLASS (filter)->get_node (filter);
236 }
237 
238 GeglNode *
gimp_filter_peek_node(GimpFilter * filter)239 gimp_filter_peek_node (GimpFilter *filter)
240 {
241   g_return_val_if_fail (GIMP_IS_FILTER (filter), NULL);
242 
243   return GET_PRIVATE (filter)->node;
244 }
245 
246 void
gimp_filter_set_active(GimpFilter * filter,gboolean active)247 gimp_filter_set_active (GimpFilter *filter,
248                         gboolean    active)
249 {
250   g_return_if_fail (GIMP_IS_FILTER (filter));
251 
252   active = active ? TRUE : FALSE;
253 
254   if (active != gimp_filter_get_active (filter))
255     {
256       GET_PRIVATE (filter)->active = active;
257 
258       g_signal_emit (filter, gimp_filter_signals[ACTIVE_CHANGED], 0);
259 
260       g_object_notify (G_OBJECT (filter), "active");
261     }
262 }
263 
264 gboolean
gimp_filter_get_active(GimpFilter * filter)265 gimp_filter_get_active (GimpFilter *filter)
266 {
267   g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
268 
269   return GET_PRIVATE (filter)->active;
270 }
271 
272 void
gimp_filter_set_is_last_node(GimpFilter * filter,gboolean is_last_node)273 gimp_filter_set_is_last_node (GimpFilter *filter,
274                               gboolean    is_last_node)
275 {
276   g_return_if_fail (GIMP_IS_FILTER (filter));
277 
278   is_last_node = is_last_node ? TRUE : FALSE;
279 
280   if (is_last_node != gimp_filter_get_is_last_node (filter))
281     {
282       GET_PRIVATE (filter)->is_last_node = is_last_node;
283 
284       g_object_notify (G_OBJECT (filter), "is-last-node");
285     }
286 }
287 
288 gboolean
gimp_filter_get_is_last_node(GimpFilter * filter)289 gimp_filter_get_is_last_node (GimpFilter *filter)
290 {
291   g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
292 
293   return GET_PRIVATE (filter)->is_last_node;
294 }
295 
296 void
gimp_filter_set_applicator(GimpFilter * filter,GimpApplicator * applicator)297 gimp_filter_set_applicator (GimpFilter     *filter,
298                             GimpApplicator *applicator)
299 {
300   GimpFilterPrivate *private;
301 
302   g_return_if_fail (GIMP_IS_FILTER (filter));
303 
304   private = GET_PRIVATE (filter);
305 
306   private->applicator = applicator;
307 }
308 
309 GimpApplicator *
gimp_filter_get_applicator(GimpFilter * filter)310 gimp_filter_get_applicator (GimpFilter *filter)
311 {
312   g_return_val_if_fail (GIMP_IS_FILTER (filter), NULL);
313 
314   return GET_PRIVATE (filter)->applicator;
315 }
316