]> Pileus Git - grits/blob - src/gis-viewer.c
Fix naming for the GisView/GisWorld -> GisViewer merge
[grits] / src / gis-viewer.c
1 /*
2  * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
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 <http://www.gnu.org/licenses/>.
16  */
17
18 #include <glib.h>
19
20 #include "gis-marshal.h"
21 #include "gis-viewer.h"
22
23 #include "gis-util.h"
24
25
26 /* Constants */
27 enum {
28         PROP_0,
29         PROP_TIME,
30         PROP_SITE,
31         PROP_OFFLINE,
32 };
33 enum {
34         SIG_TIME_CHANGED,
35         SIG_SITE_CHANGED,
36         SIG_LOCATION_CHANGED,
37         SIG_ROTATION_CHANGED,
38         SIG_REFRESH,
39         SIG_OFFLINE,
40         NUM_SIGNALS,
41 };
42 static guint signals[NUM_SIGNALS];
43
44
45 /* Misc helpers */
46 static void _gis_viewer_fix_location(GisViewer *self)
47 {
48         while (self->location[0] <  -90) self->location[0] += 180;
49         while (self->location[0] >   90) self->location[0] -= 180;
50         while (self->location[1] < -180) self->location[1] += 360;
51         while (self->location[1] >  180) self->location[1] -= 360;
52         self->location[2] = ABS(self->location[2]);
53 }
54
55 /* Signal helpers */
56 static void _gis_viewer_emit_location_changed(GisViewer *self)
57 {
58         g_signal_emit(self, signals[SIG_LOCATION_CHANGED], 0,
59                         self->location[0],
60                         self->location[1],
61                         self->location[2]);
62 }
63 static void _gis_viewer_emit_rotation_changed(GisViewer *self)
64 {
65         g_signal_emit(self, signals[SIG_ROTATION_CHANGED], 0,
66                         self->rotation[0],
67                         self->rotation[1],
68                         self->rotation[2]);
69 }
70 static void _gis_viewer_emit_time_changed(GisViewer *self)
71 {
72         g_signal_emit(self, signals[SIG_TIME_CHANGED], 0,
73                         self->time);
74 }
75 static void _gis_viewer_emit_site_changed(GisViewer *self)
76 {
77         g_signal_emit(self, signals[SIG_SITE_CHANGED], 0,
78                         self->site);
79 }
80 static void _gis_viewer_emit_refresh(GisViewer *self)
81 {
82         g_signal_emit(self, signals[SIG_REFRESH], 0);
83 }
84 static void _gis_viewer_emit_offline(GisViewer *self)
85 {
86         g_signal_emit(self, signals[SIG_OFFLINE], 0,
87                         self->offline);
88 }
89
90
91 /***********
92  * Methods *
93  ***********/
94 GisViewer *gis_viewer_new()
95 {
96         g_debug("GisViewer: new");
97         return g_object_new(GIS_TYPE_VIEWER, NULL);
98 }
99
100 void gis_viewer_set_time(GisViewer *self, const char *time)
101 {
102         g_assert(GIS_IS_VIEWER(self));
103         g_debug("GisViewer: set_time - time=%s", time);
104         g_free(self->time);
105         self->time = g_strdup(time);
106         _gis_viewer_emit_time_changed(self);
107 }
108
109 gchar *gis_viewer_get_time(GisViewer *self)
110 {
111         g_assert(GIS_IS_VIEWER(self));
112         g_debug("GisViewer: get_time");
113         return self->time;
114 }
115
116 void gis_viewer_set_location(GisViewer *self, gdouble lat, gdouble lon, gdouble elev)
117 {
118         g_assert(GIS_IS_VIEWER(self));
119         g_debug("GisViewer: set_location");
120         self->location[0] = lat;
121         self->location[1] = lon;
122         self->location[2] = elev;
123         _gis_viewer_fix_location(self);
124         _gis_viewer_emit_location_changed(self);
125 }
126
127 void gis_viewer_get_location(GisViewer *self, gdouble *lat, gdouble *lon, gdouble *elev)
128 {
129         g_assert(GIS_IS_VIEWER(self));
130         //g_debug("GisViewer: get_location");
131         *lat  = self->location[0];
132         *lon  = self->location[1];
133         *elev = self->location[2];
134 }
135
136 void gis_viewer_pan(GisViewer *self, gdouble lat, gdouble lon, gdouble elev)
137 {
138         g_assert(GIS_IS_VIEWER(self));
139         g_debug("GisViewer: pan - lat=%8.3f, lon=%8.3f, elev=%8.3f", lat, lon, elev);
140         self->location[0] += lat;
141         self->location[1] += lon;
142         self->location[2] += elev;
143         _gis_viewer_fix_location(self);
144         _gis_viewer_emit_location_changed(self);
145 }
146
147 void gis_viewer_zoom(GisViewer *self, gdouble scale)
148 {
149         g_assert(GIS_IS_VIEWER(self));
150         g_debug("GisViewer: zoom");
151         self->location[2] *= scale;
152         _gis_viewer_emit_location_changed(self);
153 }
154
155 void gis_viewer_set_rotation(GisViewer *self, gdouble x, gdouble y, gdouble z)
156 {
157         g_assert(GIS_IS_VIEWER(self));
158         g_debug("GisViewer: set_rotation");
159         self->rotation[0] = x;
160         self->rotation[1] = y;
161         self->rotation[2] = z;
162         _gis_viewer_emit_rotation_changed(self);
163 }
164
165 void gis_viewer_get_rotation(GisViewer *self, gdouble *x, gdouble *y, gdouble *z)
166 {
167         g_assert(GIS_IS_VIEWER(self));
168         g_debug("GisViewer: get_rotation");
169         *x = self->rotation[0];
170         *y = self->rotation[1];
171         *z = self->rotation[2];
172 }
173
174 void gis_viewer_rotate(GisViewer *self, gdouble x, gdouble y, gdouble z)
175 {
176         g_assert(GIS_IS_VIEWER(self));
177         g_debug("GisViewer: rotate - x=%.0f, y=%.0f, z=%.0f", x, y, z);
178         self->rotation[0] += x;
179         self->rotation[1] += y;
180         self->rotation[2] += z;
181         _gis_viewer_emit_rotation_changed(self);
182 }
183
184 /* To be deprecated, use {get,set}_location */
185 void gis_viewer_set_site(GisViewer *self, const gchar *site)
186 {
187         g_assert(GIS_IS_VIEWER(self));
188         g_debug("GisViewer: set_site");
189         g_free(self->site);
190         self->site = g_strdup(site);
191         _gis_viewer_emit_site_changed(self);
192 }
193
194 gchar *gis_viewer_get_site(GisViewer *self)
195 {
196         g_assert(GIS_IS_VIEWER(self));
197         g_debug("GisViewer: get_site - %s", self->site);
198         return self->site;
199 }
200
201 void gis_viewer_refresh(GisViewer *self)
202 {
203         g_debug("GisViewer: refresh");
204         _gis_viewer_emit_refresh(self);
205 }
206
207 void gis_viewer_set_offline(GisViewer *self, gboolean offline)
208 {
209         g_assert(GIS_IS_VIEWER(self));
210         g_debug("GisViewer: set_offline - %d", offline);
211         self->offline = offline;
212         _gis_viewer_emit_offline(self);
213 }
214
215 gboolean gis_viewer_get_offline(GisViewer *self)
216 {
217         g_assert(GIS_IS_VIEWER(self));
218         g_debug("GisViewer: get_offline - %d", self->offline);
219         return self->offline;
220 }
221
222
223 /****************
224  * GObject code *
225  ****************/
226 G_DEFINE_TYPE(GisViewer, gis_viewer, G_TYPE_OBJECT);
227 static void gis_viewer_init(GisViewer *self)
228 {
229         g_debug("GisViewer: init");
230         /* Default values */
231         self->time = g_strdup("");
232         self->site = g_strdup("");
233         self->location[0] = 40;
234         self->location[1] = -100;
235         self->location[2] = 1.5*EARTH_R;
236         self->rotation[0] = 0;
237         self->rotation[1] = 0;
238         self->rotation[2] = 0;
239 }
240 static void gis_viewer_dispose(GObject *gobject)
241 {
242         g_debug("GisViewer: dispose");
243         /* Drop references to other GObjects */
244         G_OBJECT_CLASS(gis_viewer_parent_class)->dispose(gobject);
245 }
246 static void gis_viewer_finalize(GObject *gobject)
247 {
248         g_debug("GisViewer: finalize");
249         GisViewer *self = GIS_VIEWER(gobject);
250         g_free(self->time);
251         g_free(self->site);
252         G_OBJECT_CLASS(gis_viewer_parent_class)->finalize(gobject);
253 }
254 static void gis_viewer_set_property(GObject *object, guint property_id,
255                 const GValue *value, GParamSpec *pspec)
256 {
257         g_debug("GisViewer: set_property");
258         GisViewer *self = GIS_VIEWER(object);
259         switch (property_id) {
260         case PROP_TIME:    gis_viewer_set_time   (self, g_value_get_string (value)); break;
261         case PROP_SITE:    gis_viewer_set_site   (self, g_value_get_string (value)); break;
262         case PROP_OFFLINE: gis_viewer_set_offline(self, g_value_get_boolean(value)); break;
263         default:           G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
264         }
265 }
266 static void gis_viewer_get_property(GObject *object, guint property_id,
267                 GValue *value, GParamSpec *pspec)
268 {
269         g_debug("GisViewer: get_property");
270         GisViewer *self = GIS_VIEWER(object);
271         switch (property_id) {
272         case PROP_TIME:    g_value_set_string (value, gis_viewer_get_time   (self)); break;
273         case PROP_SITE:    g_value_set_string (value, gis_viewer_get_site   (self)); break;
274         case PROP_OFFLINE: g_value_set_boolean(value, gis_viewer_get_offline(self)); break;
275         default:           G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
276         }
277 }
278 static void gis_viewer_class_init(GisViewerClass *klass)
279 {
280         g_debug("GisViewer: class_init");
281         GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
282         gobject_class->dispose      = gis_viewer_dispose;
283         gobject_class->finalize     = gis_viewer_finalize;
284         gobject_class->get_property = gis_viewer_get_property;
285         gobject_class->set_property = gis_viewer_set_property;
286         g_object_class_install_property(gobject_class, PROP_TIME,
287                 g_param_spec_pointer(
288                         "time",
289                         "time of the current frame",
290                         "(format unknown)",
291                         G_PARAM_READWRITE));
292         g_object_class_install_property(gobject_class, PROP_SITE,
293                 g_param_spec_pointer(
294                         "site",
295                         "site seen by the viewerport",
296                         "Site of the viewerport. "
297                         "Currently this is the name of the radar site.",
298                         G_PARAM_READWRITE));
299         g_object_class_install_property(gobject_class, PROP_OFFLINE,
300                 g_param_spec_pointer(
301                         "offline",
302                         "whether the viewer should access the network",
303                         "Offline state of the viewer. "
304                         "If set to true, the viewer will not access the network",
305                         G_PARAM_READWRITE));
306         signals[SIG_TIME_CHANGED] = g_signal_new(
307                         "time-changed",
308                         G_TYPE_FROM_CLASS(gobject_class),
309                         G_SIGNAL_RUN_LAST,
310                         0,
311                         NULL,
312                         NULL,
313                         g_cclosure_marshal_VOID__STRING,
314                         G_TYPE_NONE,
315                         1,
316                         G_TYPE_STRING);
317         signals[SIG_SITE_CHANGED] = g_signal_new(
318                         "site-changed",
319                         G_TYPE_FROM_CLASS(gobject_class),
320                         G_SIGNAL_RUN_LAST,
321                         0,
322                         NULL,
323                         NULL,
324                         g_cclosure_marshal_VOID__STRING,
325                         G_TYPE_NONE,
326                         1,
327                         G_TYPE_STRING);
328         signals[SIG_LOCATION_CHANGED] = g_signal_new(
329                         "location-changed",
330                         G_TYPE_FROM_CLASS(gobject_class),
331                         G_SIGNAL_RUN_LAST,
332                         0,
333                         NULL,
334                         NULL,
335                         gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
336                         G_TYPE_NONE,
337                         3,
338                         G_TYPE_DOUBLE,
339                         G_TYPE_DOUBLE,
340                         G_TYPE_DOUBLE);
341         signals[SIG_ROTATION_CHANGED] = g_signal_new(
342                         "rotation-changed",
343                         G_TYPE_FROM_CLASS(gobject_class),
344                         G_SIGNAL_RUN_LAST,
345                         0,
346                         NULL,
347                         NULL,
348                         gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
349                         G_TYPE_NONE,
350                         3,
351                         G_TYPE_DOUBLE,
352                         G_TYPE_DOUBLE,
353                         G_TYPE_DOUBLE);
354         signals[SIG_REFRESH] = g_signal_new(
355                         "refresh",
356                         G_TYPE_FROM_CLASS(gobject_class),
357                         G_SIGNAL_RUN_LAST,
358                         0,
359                         NULL,
360                         NULL,
361                         g_cclosure_marshal_VOID__VOID,
362                         G_TYPE_NONE,
363                         0);
364         signals[SIG_OFFLINE] = g_signal_new(
365                         "offline",
366                         G_TYPE_FROM_CLASS(gobject_class),
367                         G_SIGNAL_RUN_LAST,
368                         0,
369                         NULL,
370                         NULL,
371                         g_cclosure_marshal_VOID__BOOLEAN,
372                         G_TYPE_NONE,
373                         1,
374                         G_TYPE_BOOLEAN);
375 }