1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3 *
4 * gimppropgui-motion-blur-linear.c
5 * Copyright (C) 2019 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-motion-blur-linear.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 length;
48 gdouble angle;
49
50 g_object_set_data_full (G_OBJECT (config), "area",
51 g_memdup (area, sizeof (GeglRectangle)),
52 (GDestroyNotify) g_free);
53
54 length = sqrt (SQR (x2 - x1) + SQR (y2 - y1));
55 angle = atan2 (y2 - y1, x2 - x1);
56
57 angle = angle / G_PI * 180.0;
58
59 g_object_set (config,
60 "length", length,
61 "angle", angle,
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 length;
73 gdouble angle;
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 "length", &length,
81 "angle", &angle,
82 NULL);
83
84 angle = angle / 180.0 * G_PI;
85
86 x1 = area->x + area->width / 2.0;
87 y1 = area->x + area->height / 2.0;
88 x2 = x1 + cos (angle) * length;
89 y2 = y1 + sin (angle) * length;
90
91 set_func (set_data, area, x1, y1, x2, y2);
92 }
93
94 GtkWidget *
_gimp_prop_gui_new_motion_blur_linear(GObject * config,GParamSpec ** param_specs,guint n_param_specs,GeglRectangle * area,GimpContext * context,GimpCreatePickerFunc create_picker_func,GimpCreateControllerFunc create_controller_func,gpointer creator)95 _gimp_prop_gui_new_motion_blur_linear (GObject *config,
96 GParamSpec **param_specs,
97 guint n_param_specs,
98 GeglRectangle *area,
99 GimpContext *context,
100 GimpCreatePickerFunc create_picker_func,
101 GimpCreateControllerFunc create_controller_func,
102 gpointer creator)
103 {
104 GtkWidget *vbox;
105
106 g_return_val_if_fail (G_IS_OBJECT (config), NULL);
107 g_return_val_if_fail (param_specs != NULL, NULL);
108 g_return_val_if_fail (n_param_specs > 0, NULL);
109 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
110
111 vbox = _gimp_prop_gui_new_generic (config,
112 param_specs, n_param_specs,
113 area, context,
114 create_picker_func,
115 create_controller_func,
116 creator);
117
118
119 if (create_controller_func)
120 {
121 GCallback set_func;
122 gpointer set_data;
123
124 set_func = create_controller_func (creator,
125 GIMP_CONTROLLER_TYPE_LINE,
126 _("Linear Motion Blur: "),
127 (GCallback) line_callback,
128 config,
129 &set_data);
130
131 g_object_set_data (G_OBJECT (config), "set-func", set_func);
132
133 g_object_set_data_full (G_OBJECT (config), "area",
134 g_memdup (area, sizeof (GeglRectangle)),
135 (GDestroyNotify) g_free);
136
137 config_notify (config, NULL, set_data);
138
139 g_signal_connect (config, "notify",
140 G_CALLBACK (config_notify),
141 set_data);
142 }
143
144 return vbox;
145 }
146