1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3  *
4  * gimppropgui-supernova.c
5  * Copyright (C) 2017  Michael Natterer <mitch@gimp.org>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include <gegl.h>
24 #include <gtk/gtk.h>
25 
26 #include "libgimpmath/gimpmath.h"
27 #include "libgimpwidgets/gimpwidgets.h"
28 
29 #include "propgui-types.h"
30 
31 #include "core/gimpcontext.h"
32 
33 #include "gimppropgui-generic.h"
34 #include "gimppropgui-supernova.h"
35 
36 #include "gimp-intl.h"
37 
38 
39 static void
line_callback(GObject * config,GeglRectangle * area,gdouble x1,gdouble y1,gdouble x2,gdouble y2)40 line_callback (GObject       *config,
41                GeglRectangle *area,
42                gdouble        x1,
43                gdouble        y1,
44                gdouble        x2,
45                gdouble        y2)
46 {
47   gdouble x, y;
48   gint    radius;
49 
50   g_object_set_data_full (G_OBJECT (config), "area",
51                           g_memdup (area, sizeof (GeglRectangle)),
52                           (GDestroyNotify) g_free);
53 
54   x      = x1 / area->width;
55   y      = y1 / area->height;
56   radius = sqrt (SQR (x2 - x1) + SQR (y2 - y1));
57 
58   g_object_set (config,
59                 "center-x", x,
60                 "center-y", y,
61                 "radius",   radius,
62                 NULL);
63 }
64 
65 static void
config_notify(GObject * config,const GParamSpec * pspec,gpointer set_data)66 config_notify (GObject          *config,
67                const GParamSpec *pspec,
68                gpointer          set_data)
69 {
70   GimpControllerLineCallback  set_func;
71   GeglRectangle              *area;
72   gdouble                     x, y;
73   gint                        radius;
74   gdouble                     x1, y1, x2, y2;
75 
76   set_func = g_object_get_data (G_OBJECT (config), "set-func");
77   area     = g_object_get_data (G_OBJECT (config), "area");
78 
79   g_object_get (config,
80                 "center-x", &x,
81                 "center-y", &y,
82                 "radius",   &radius,
83                 NULL);
84 
85   x1 = x * area->width;
86   y1 = y * area->height;
87   x2 = x1 + radius;
88   y2 = y1;
89 
90   set_func (set_data, area, x1, y1, x2, y2);
91 }
92 
93 GtkWidget *
_gimp_prop_gui_new_supernova(GObject * config,GParamSpec ** param_specs,guint n_param_specs,GeglRectangle * area,GimpContext * context,GimpCreatePickerFunc create_picker_func,GimpCreateControllerFunc create_controller_func,gpointer creator)94 _gimp_prop_gui_new_supernova (GObject                  *config,
95                               GParamSpec              **param_specs,
96                               guint                     n_param_specs,
97                               GeglRectangle            *area,
98                               GimpContext              *context,
99                               GimpCreatePickerFunc      create_picker_func,
100                               GimpCreateControllerFunc  create_controller_func,
101                               gpointer                  creator)
102 {
103   GtkWidget *vbox;
104 
105   g_return_val_if_fail (G_IS_OBJECT (config), NULL);
106   g_return_val_if_fail (param_specs != NULL, NULL);
107   g_return_val_if_fail (n_param_specs > 0, NULL);
108   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
109 
110   vbox = _gimp_prop_gui_new_generic (config,
111                                      param_specs, n_param_specs,
112                                      area, context,
113                                      create_picker_func,
114                                      create_controller_func,
115                                      creator);
116 
117 
118   if (create_controller_func)
119     {
120       GCallback set_func;
121       gpointer  set_data;
122 
123       set_func = create_controller_func (creator,
124                                          GIMP_CONTROLLER_TYPE_LINE,
125                                          _("Supernova: "),
126                                          (GCallback) line_callback,
127                                          config,
128                                          &set_data);
129 
130       g_object_set_data (G_OBJECT (config), "set-func", set_func);
131 
132       g_object_set_data_full (G_OBJECT (config), "area",
133                               g_memdup (area, sizeof (GeglRectangle)),
134                               (GDestroyNotify) g_free);
135 
136       config_notify (config, NULL, set_data);
137 
138       g_signal_connect (config, "notify",
139                         G_CALLBACK (config_notify),
140                         set_data);
141     }
142 
143   return vbox;
144 }
145