1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3  *
4  * gimppropgui-panorama-projection.c
5  * Copyright (C) 2018 Ell
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.h"
34 #include "gimppropgui-generic.h"
35 #include "gimppropgui-panorama-projection.h"
36 
37 #include "gimp-intl.h"
38 
39 
40 static void
gyroscope_callback(GObject * config,GeglRectangle * area,gdouble yaw,gdouble pitch,gdouble roll,gdouble zoom,gboolean invert)41 gyroscope_callback (GObject       *config,
42                     GeglRectangle *area,
43                     gdouble        yaw,
44                     gdouble        pitch,
45                     gdouble        roll,
46                     gdouble        zoom,
47                     gboolean       invert)
48 {
49   g_object_set_data_full (G_OBJECT (config), "area",
50                           g_memdup (area, sizeof (GeglRectangle)),
51                           (GDestroyNotify) g_free);
52 
53   g_object_set (config,
54                 "pan",     -yaw,
55                 "tilt",    -pitch,
56                 "spin",    -roll,
57                 "zoom",    CLAMP (100.0 * zoom, 0.01, 1000.0),
58                 "inverse", invert,
59                 NULL);
60 }
61 
62 static void
config_notify(GObject * config,const GParamSpec * pspec,gpointer set_data)63 config_notify (GObject          *config,
64                const GParamSpec *pspec,
65                gpointer          set_data)
66 {
67   GimpControllerGyroscopeCallback  set_func;
68   GeglRectangle                   *area;
69   gdouble                          pan;
70   gdouble                          tilt;
71   gdouble                          spin;
72   gdouble                          zoom;
73   gboolean                         inverse;
74 
75   set_func = g_object_get_data (G_OBJECT (config), "set-func");
76   area     = g_object_get_data (G_OBJECT (config), "area");
77 
78   g_object_get (config,
79                 "pan",     &pan,
80                 "tilt",    &tilt,
81                 "spin",    &spin,
82                 "zoom",    &zoom,
83                 "inverse", &inverse,
84                 NULL);
85 
86   set_func (set_data,
87             area,
88             -pan, -tilt, -spin,
89             zoom / 100.0,
90             inverse);
91 }
92 
93 GtkWidget *
_gimp_prop_gui_new_panorama_projection(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_panorama_projection (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_GYROSCOPE,
125                                          _("Panorama Projection: "),
126                                          (GCallback) gyroscope_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