]>
Commit | Line | Data |
---|---|---|
50a14534 EB |
1 | /* |
2 | * viking -- GPS Data and Topo Analyzer, Explorer, and Manager | |
3 | * | |
a482007a GB |
4 | * Copyright (C) 2005, Alex Foobarian <foobarian@gmail.com> |
5 | * Copyright (C) 2003-2007, Evan Battaglia <gtoevan@gmx.net> | |
50a14534 EB |
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 2 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, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | */ | |
22 | ||
4c77d5e0 GB |
23 | #ifdef HAVE_CONFIG_H |
24 | #include "config.h" | |
25 | #endif | |
26 | ||
27 | #include <glib/gi18n.h> | |
28 | ||
50a14534 | 29 | #include "viking.h" |
911400b5 | 30 | #include <string.h> |
a7023a1b RN |
31 | #include <stdlib.h> |
32 | #include "viklayer_defaults.h" | |
50a14534 EB |
33 | |
34 | /* functions common to all layers. */ | |
35 | /* TODO longone: rename interface free -> finalize */ | |
36 | ||
37 | extern VikLayerInterface vik_aggregate_layer_interface; | |
38 | extern VikLayerInterface vik_trw_layer_interface; | |
39 | extern VikLayerInterface vik_maps_layer_interface; | |
40 | extern VikLayerInterface vik_coord_layer_interface; | |
41 | extern VikLayerInterface vik_georef_layer_interface; | |
b364d6bc | 42 | extern VikLayerInterface vik_gps_layer_interface; |
ad0a8c2d | 43 | extern VikLayerInterface vik_dem_layer_interface; |
50a14534 EB |
44 | |
45 | enum { | |
46 | VL_UPDATE_SIGNAL, | |
47 | VL_LAST_SIGNAL | |
48 | }; | |
49 | static guint layer_signals[VL_LAST_SIGNAL] = { 0 }; | |
50 | ||
51 | static GObjectClass *parent_class; | |
52 | ||
a0c65899 GB |
53 | static void vik_layer_finalize ( VikLayer *vl ); |
54 | static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ); | |
a7023a1b | 55 | static gboolean layer_defaults_register ( VikLayerTypeEnum type ); |
50a14534 | 56 | |
a0c65899 | 57 | G_DEFINE_TYPE (VikLayer, vik_layer, G_TYPE_OBJECT) |
50a14534 | 58 | |
a0c65899 | 59 | static void vik_layer_class_init (VikLayerClass *klass) |
50a14534 EB |
60 | { |
61 | GObjectClass *object_class; | |
62 | ||
63 | object_class = G_OBJECT_CLASS (klass); | |
64 | ||
a0c65899 | 65 | object_class->finalize = (GObjectFinalizeFunc) vik_layer_finalize; |
50a14534 EB |
66 | |
67 | parent_class = g_type_class_peek_parent (klass); | |
68 | ||
69 | layer_signals[VL_UPDATE_SIGNAL] = g_signal_new ( "update", G_TYPE_FROM_CLASS (klass), | |
70 | G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikLayerClass, update), NULL, NULL, | |
71 | g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); | |
a7023a1b RN |
72 | |
73 | // Register all parameter defaults, early in the start up sequence | |
74 | VikLayerTypeEnum layer; | |
75 | for ( layer = 0; layer < VIK_LAYER_NUM_TYPES; layer++ ) | |
76 | // ATM ignore the returned value | |
77 | layer_defaults_register ( layer ); | |
50a14534 EB |
78 | } |
79 | ||
f01eebd4 RN |
80 | /** |
81 | * Invoke the actual drawing via signal method | |
82 | */ | |
83 | static gboolean idle_draw ( VikLayer *vl ) | |
84 | { | |
85 | g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 ); | |
86 | return FALSE; // Nothing else to do | |
87 | } | |
88 | ||
89 | /** | |
90 | * Draw specified layer | |
91 | */ | |
da121f9b | 92 | void vik_layer_emit_update ( VikLayer *vl ) |
0df66d57 | 93 | { |
09c91d84 | 94 | if ( vl->visible && vl->realized ) { |
c9177aae | 95 | vik_window_set_redraw_trigger(vl); |
f01eebd4 RN |
96 | |
97 | // Only ever draw when there is time to do so | |
da121f9b RN |
98 | if ( g_thread_self() != vik_window_get_thread (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl))) ) |
99 | // Drawing requested from another (background) thread, so handle via the gdk thread method | |
f01eebd4 RN |
100 | gdk_threads_add_idle ( (GSourceFunc) idle_draw, vl ); |
101 | else | |
102 | g_idle_add ( (GSourceFunc) idle_draw, vl ); | |
0df66d57 EB |
103 | } |
104 | } | |
105 | ||
f01eebd4 RN |
106 | /** |
107 | * should only be done by VikLayersPanel (hence never used from the background) | |
108 | * need to redraw and record trigger when we make a layer invisible. | |
0df66d57 EB |
109 | */ |
110 | void vik_layer_emit_update_although_invisible ( VikLayer *vl ) | |
111 | { | |
c9177aae | 112 | vik_window_set_redraw_trigger(vl); |
f01eebd4 | 113 | g_idle_add ( (GSourceFunc) idle_draw, vl ); |
0df66d57 EB |
114 | } |
115 | ||
0df66d57 EB |
116 | /* doesn't set the trigger. should be done by aggregate layer when child emits update. */ |
117 | void vik_layer_emit_update_secondary ( VikLayer *vl ) | |
50a14534 EB |
118 | { |
119 | if ( vl->visible ) | |
f01eebd4 RN |
120 | // TODO: this can used from the background - eg in acquire |
121 | // so will need to flow background update status through too | |
122 | g_idle_add ( (GSourceFunc) idle_draw, vl ); | |
50a14534 EB |
123 | } |
124 | ||
125 | static VikLayerInterface *vik_layer_interfaces[VIK_LAYER_NUM_TYPES] = { | |
126 | &vik_aggregate_layer_interface, | |
127 | &vik_trw_layer_interface, | |
128 | &vik_coord_layer_interface, | |
129 | &vik_georef_layer_interface, | |
b364d6bc | 130 | &vik_gps_layer_interface, |
50a14534 | 131 | &vik_maps_layer_interface, |
ad0a8c2d | 132 | &vik_dem_layer_interface, |
50a14534 EB |
133 | }; |
134 | ||
b5926b35 | 135 | VikLayerInterface *vik_layer_get_interface ( VikLayerTypeEnum type ) |
50a14534 EB |
136 | { |
137 | g_assert ( type < VIK_LAYER_NUM_TYPES ); | |
138 | return vik_layer_interfaces[type]; | |
139 | } | |
140 | ||
a7023a1b RN |
141 | /** |
142 | * Store default values for this layer | |
143 | * | |
144 | * Returns whether any parameters where registered | |
145 | */ | |
146 | static gboolean layer_defaults_register ( VikLayerTypeEnum type ) | |
147 | { | |
148 | // See if any parameters | |
149 | VikLayerParam *params = vik_layer_interfaces[type]->params; | |
150 | if ( ! params ) | |
151 | return FALSE; | |
152 | ||
153 | gboolean answer = FALSE; // Incase all parameters are 'not in properties' | |
154 | guint16 params_count = vik_layer_interfaces[type]->params_count; | |
155 | guint16 i; | |
156 | // Process each parameter | |
157 | for ( i = 0; i < params_count; i++ ) { | |
158 | if ( params[i].group != VIK_LAYER_NOT_IN_PROPERTIES ) { | |
159 | if ( params[i].default_value ) { | |
160 | VikLayerParamData paramd = params[i].default_value(); | |
161 | a_layer_defaults_register ( ¶ms[i], paramd, vik_layer_interfaces[type]->fixed_layer_name ); | |
162 | answer = TRUE; | |
163 | } | |
164 | } | |
165 | } | |
166 | ||
167 | return answer; | |
168 | } | |
169 | ||
a0c65899 | 170 | static void vik_layer_init ( VikLayer *vl ) |
50a14534 EB |
171 | { |
172 | vl->visible = TRUE; | |
173 | vl->name = NULL; | |
174 | vl->realized = FALSE; | |
175 | } | |
176 | ||
b5926b35 | 177 | void vik_layer_set_type ( VikLayer *vl, VikLayerTypeEnum type ) |
50a14534 EB |
178 | { |
179 | vl->type = type; | |
180 | } | |
181 | ||
182 | /* frees old name */ | |
183 | void vik_layer_rename ( VikLayer *l, const gchar *new_name ) | |
184 | { | |
92558066 GB |
185 | g_assert ( l != NULL ); |
186 | g_assert ( new_name != NULL ); | |
187 | g_free ( l->name ); | |
50a14534 EB |
188 | l->name = g_strdup ( new_name ); |
189 | } | |
190 | ||
191 | void vik_layer_rename_no_copy ( VikLayer *l, gchar *new_name ) | |
192 | { | |
92558066 GB |
193 | g_assert ( l != NULL ); |
194 | g_assert ( new_name != NULL ); | |
195 | g_free ( l->name ); | |
50a14534 EB |
196 | l->name = new_name; |
197 | } | |
198 | ||
92558066 GB |
199 | const gchar *vik_layer_get_name ( VikLayer *l ) |
200 | { | |
201 | g_assert ( l != NULL); | |
202 | return l->name; | |
203 | } | |
204 | ||
b5926b35 | 205 | VikLayer *vik_layer_create ( VikLayerTypeEnum type, gpointer vp, GtkWindow *w, gboolean interactive ) |
50a14534 EB |
206 | { |
207 | VikLayer *new_layer = NULL; | |
208 | g_assert ( type < VIK_LAYER_NUM_TYPES ); | |
209 | ||
210 | new_layer = vik_layer_interfaces[type]->create ( vp ); | |
211 | ||
212 | g_assert ( new_layer != NULL ); | |
213 | ||
214 | if ( interactive ) | |
215 | { | |
216 | if ( vik_layer_properties ( new_layer, vp ) ) | |
4c77d5e0 GB |
217 | /* We translate the name here */ |
218 | /* in order to avoid translating name set by user */ | |
219 | vik_layer_rename ( VIK_LAYER(new_layer), _(vik_layer_interfaces[type]->name) ); | |
50a14534 EB |
220 | else |
221 | { | |
222 | g_object_unref ( G_OBJECT(new_layer) ); /* cancel that */ | |
223 | new_layer = NULL; | |
224 | } | |
225 | } | |
226 | return new_layer; | |
227 | } | |
228 | ||
229 | /* returns TRUE if OK was pressed */ | |
230 | gboolean vik_layer_properties ( VikLayer *layer, gpointer vp ) | |
231 | { | |
232 | if ( vik_layer_interfaces[layer->type]->properties ) | |
233 | return vik_layer_interfaces[layer->type]->properties ( layer, vp ); | |
a0c65899 | 234 | return vik_layer_properties_factory ( layer, vp ); |
50a14534 EB |
235 | } |
236 | ||
45c5ac8e | 237 | void vik_layer_draw ( VikLayer *l, VikViewport *vp ) |
50a14534 EB |
238 | { |
239 | if ( l->visible ) | |
240 | if ( vik_layer_interfaces[l->type]->draw ) | |
45c5ac8e | 241 | vik_layer_interfaces[l->type]->draw ( l, vp ); |
50a14534 EB |
242 | } |
243 | ||
244 | void vik_layer_change_coord_mode ( VikLayer *l, VikCoordMode mode ) | |
245 | { | |
246 | if ( vik_layer_interfaces[l->type]->change_coord_mode ) | |
247 | vik_layer_interfaces[l->type]->change_coord_mode ( l, mode ); | |
248 | } | |
249 | ||
911400b5 | 250 | typedef struct { |
a2fe72b1 | 251 | VikLayerTypeEnum layer_type; |
911400b5 AF |
252 | gint len; |
253 | guint8 data[0]; | |
254 | } header_t; | |
255 | ||
256 | void vik_layer_marshall ( VikLayer *vl, guint8 **data, gint *len ) | |
257 | { | |
258 | header_t *header; | |
259 | if ( vl && vik_layer_interfaces[vl->type]->marshall ) { | |
260 | vik_layer_interfaces[vl->type]->marshall ( vl, data, len ); | |
261 | if (*data) { | |
262 | header = g_malloc(*len + sizeof(*header)); | |
263 | header->layer_type = vl->type; | |
264 | header->len = *len; | |
265 | memcpy(header->data, *data, *len); | |
266 | g_free(*data); | |
267 | *data = (guint8 *)header; | |
268 | *len = *len + sizeof(*header); | |
269 | } | |
270 | } else { | |
271 | *data = NULL; | |
272 | } | |
273 | } | |
274 | ||
275 | void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) | |
276 | { | |
277 | VikLayerParam *params = vik_layer_get_interface(vl->type)->params; | |
278 | VikLayerFuncGetParam get_param = vik_layer_get_interface(vl->type)->get_param; | |
279 | GByteArray* b = g_byte_array_new (); | |
280 | gint len; | |
281 | ||
282 | #define vlm_append(obj, sz) \ | |
283 | len = (sz); \ | |
284 | g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \ | |
285 | g_byte_array_append ( b, (guint8 *)(obj), len ); | |
286 | ||
287 | vlm_append(vl->name, strlen(vl->name)); | |
288 | ||
289 | if ( params && get_param ) | |
290 | { | |
291 | VikLayerParamData d; | |
292 | guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count; | |
293 | for ( i = 0; i < params_count; i++ ) | |
294 | { | |
ce37ab9b | 295 | g_debug("%s: %s", __FUNCTION__, params[i].name); |
158b3642 | 296 | d = get_param(vl, i, FALSE); |
911400b5 AF |
297 | switch ( params[i].type ) |
298 | { | |
299 | case VIK_LAYER_PARAM_STRING: | |
300 | vlm_append(d.s, strlen(d.s)); | |
301 | break; | |
fa86f1c0 EB |
302 | |
303 | /* print out the string list in the array */ | |
304 | case VIK_LAYER_PARAM_STRING_LIST: { | |
305 | GList *list = d.sl; | |
306 | ||
307 | /* write length of list (# of strings) */ | |
308 | gint listlen = g_list_length ( list ); | |
309 | g_byte_array_append ( b, (guint8 *)&listlen, sizeof(listlen) ); | |
310 | ||
311 | /* write each string */ | |
312 | while ( list ) { | |
313 | gchar *s = (gchar *) list->data; | |
314 | vlm_append(s, strlen(s)); | |
315 | list = list->next; | |
316 | } | |
317 | ||
318 | break; | |
319 | } | |
911400b5 AF |
320 | default: |
321 | vlm_append(&d, sizeof(d)); | |
322 | break; | |
323 | } | |
324 | } | |
325 | } | |
326 | ||
327 | *data = b->data; | |
328 | *datalen = b->len; | |
329 | g_byte_array_free ( b, FALSE ); | |
330 | ||
331 | #undef vlm_append | |
332 | } | |
333 | ||
334 | void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, VikViewport *vvp ) | |
335 | { | |
336 | VikLayerParam *params = vik_layer_get_interface(vl->type)->params; | |
337 | VikLayerFuncSetParam set_param = vik_layer_get_interface(vl->type)->set_param; | |
338 | gchar *s; | |
339 | guint8 *b = (guint8 *)data; | |
340 | ||
341 | #define vlm_size (*(gint *)b) | |
342 | #define vlm_read(obj) \ | |
343 | memcpy((obj), b+sizeof(gint), vlm_size); \ | |
344 | b += sizeof(gint) + vlm_size; | |
345 | ||
346 | s = g_malloc(vlm_size + 1); | |
347 | s[vlm_size]=0; | |
348 | vlm_read(s); | |
349 | ||
350 | vik_layer_rename(vl, s); | |
351 | ||
352 | g_free(s); | |
353 | ||
354 | if ( params && set_param ) | |
355 | { | |
356 | VikLayerParamData d; | |
357 | guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count; | |
358 | for ( i = 0; i < params_count; i++ ) | |
359 | { | |
ce37ab9b | 360 | g_debug("%s: %s", __FUNCTION__, params[i].name); |
911400b5 AF |
361 | switch ( params[i].type ) |
362 | { | |
363 | case VIK_LAYER_PARAM_STRING: | |
364 | s = g_malloc(vlm_size + 1); | |
365 | s[vlm_size]=0; | |
366 | vlm_read(s); | |
367 | d.s = s; | |
158b3642 | 368 | set_param(vl, i, d, vvp, FALSE); |
911400b5 AF |
369 | g_free(s); |
370 | break; | |
fa86f1c0 EB |
371 | case VIK_LAYER_PARAM_STRING_LIST: { |
372 | gint listlen = vlm_size, j; | |
373 | GList *list = NULL; | |
374 | b += sizeof(gint); /* skip listlen */; | |
375 | ||
376 | for ( j = 0; j < listlen; j++ ) { | |
377 | /* get a string */ | |
378 | s = g_malloc(vlm_size + 1); | |
379 | s[vlm_size]=0; | |
380 | vlm_read(s); | |
381 | list = g_list_append ( list, s ); | |
382 | } | |
383 | d.sl = list; | |
158b3642 | 384 | set_param(vl, i, d, vvp, FALSE); |
fa86f1c0 EB |
385 | /* don't free -- string list is responsibility of the layer */ |
386 | ||
387 | break; | |
388 | } | |
911400b5 AF |
389 | default: |
390 | vlm_read(&d); | |
158b3642 | 391 | set_param(vl, i, d, vvp, FALSE); |
911400b5 AF |
392 | break; |
393 | } | |
394 | } | |
395 | } | |
396 | } | |
397 | ||
398 | VikLayer *vik_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp ) | |
399 | { | |
400 | header_t *header; | |
401 | ||
402 | header = (header_t *)data; | |
403 | ||
404 | if ( vik_layer_interfaces[header->layer_type]->unmarshall ) { | |
405 | return vik_layer_interfaces[header->layer_type]->unmarshall ( header->data, header->len, vvp ); | |
406 | } else { | |
407 | return NULL; | |
408 | } | |
409 | } | |
50a14534 | 410 | |
a0c65899 | 411 | static void vik_layer_finalize ( VikLayer *vl ) |
50a14534 EB |
412 | { |
413 | g_assert ( vl != NULL ); | |
414 | if ( vik_layer_interfaces[vl->type]->free ) | |
415 | vik_layer_interfaces[vl->type]->free ( vl ); | |
416 | if ( vl->name ) | |
417 | g_free ( vl->name ); | |
418 | G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(vl)); | |
419 | } | |
420 | ||
421 | /* sublayer switching */ | |
422 | gboolean vik_layer_sublayer_toggle_visible ( VikLayer *l, gint subtype, gpointer sublayer ) | |
423 | { | |
424 | if ( vik_layer_interfaces[l->type]->sublayer_toggle_visible ) | |
425 | return vik_layer_interfaces[l->type]->sublayer_toggle_visible ( l, subtype, sublayer ); | |
426 | return TRUE; /* if unknown, will always be visible */ | |
427 | } | |
428 | ||
a5dcfdb7 RN |
429 | gboolean vik_layer_selected ( VikLayer *l, gint subtype, gpointer sublayer, gint type, gpointer vlp ) |
430 | { | |
431 | if ( vik_layer_interfaces[l->type]->layer_selected ) | |
432 | return vik_layer_interfaces[l->type]->layer_selected ( l, subtype, sublayer, type, vlp ); | |
433 | /* Since no 'layer_selected' function explicitly turn off here */ | |
434 | return vik_window_clear_highlight ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l) ); | |
435 | } | |
436 | ||
50a14534 EB |
437 | void vik_layer_realize ( VikLayer *l, VikTreeview *vt, GtkTreeIter *layer_iter ) |
438 | { | |
439 | l->vt = vt; | |
440 | l->iter = *layer_iter; | |
441 | l->realized = TRUE; | |
442 | if ( vik_layer_interfaces[l->type]->realize ) | |
443 | vik_layer_interfaces[l->type]->realize ( l, vt, layer_iter ); | |
444 | } | |
445 | ||
20c7a3a0 QT |
446 | void vik_layer_set_menu_items_selection(VikLayer *l, guint16 selection) |
447 | { | |
448 | if ( vik_layer_interfaces[l->type]->set_menu_selection ) | |
449 | vik_layer_interfaces[l->type]->set_menu_selection ( l, selection ); | |
450 | } | |
451 | ||
452 | guint16 vik_layer_get_menu_items_selection(VikLayer *l) | |
453 | { | |
454 | if ( vik_layer_interfaces[l->type]->get_menu_selection ) | |
455 | return(vik_layer_interfaces[l->type]->get_menu_selection (l)); | |
456 | else | |
457 | return(vik_layer_interfaces[l->type]->menu_items_selection); | |
458 | } | |
459 | ||
50a14534 EB |
460 | void vik_layer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp ) |
461 | { | |
462 | if ( vik_layer_interfaces[l->type]->add_menu_items ) | |
463 | vik_layer_interfaces[l->type]->add_menu_items ( l, menu, vlp ); | |
464 | } | |
465 | ||
50eadc64 | 466 | gboolean vik_layer_sublayer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter, VikViewport *vvp ) |
50a14534 EB |
467 | { |
468 | if ( vik_layer_interfaces[l->type]->sublayer_add_menu_items ) | |
50eadc64 | 469 | return vik_layer_interfaces[l->type]->sublayer_add_menu_items ( l, menu, vlp, subtype, sublayer, iter, vvp ); |
50a14534 EB |
470 | return FALSE; |
471 | } | |
472 | ||
473 | ||
474 | const gchar *vik_layer_sublayer_rename_request ( VikLayer *l, const gchar *newname, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter ) | |
475 | { | |
476 | if ( vik_layer_interfaces[l->type]->sublayer_rename_request ) | |
477 | return vik_layer_interfaces[l->type]->sublayer_rename_request ( l, newname, vlp, subtype, sublayer, iter ); | |
478 | return NULL; | |
479 | } | |
480 | ||
9da7faf2 RN |
481 | const gchar* vik_layer_sublayer_tooltip ( VikLayer *l, gint subtype, gpointer sublayer ) |
482 | { | |
483 | if ( vik_layer_interfaces[l->type]->sublayer_tooltip ) | |
484 | return vik_layer_interfaces[l->type]->sublayer_tooltip ( l, subtype, sublayer ); | |
485 | return NULL; | |
486 | } | |
487 | ||
1e8b7f57 RN |
488 | const gchar* vik_layer_layer_tooltip ( VikLayer *l ) |
489 | { | |
490 | if ( vik_layer_interfaces[l->type]->layer_tooltip ) | |
491 | return vik_layer_interfaces[l->type]->layer_tooltip ( l ); | |
492 | return NULL; | |
493 | } | |
494 | ||
b5926b35 | 495 | GdkPixbuf *vik_layer_load_icon ( VikLayerTypeEnum type ) |
50a14534 EB |
496 | { |
497 | g_assert ( type < VIK_LAYER_NUM_TYPES ); | |
498 | if ( vik_layer_interfaces[type]->icon ) | |
499 | return gdk_pixbuf_from_pixdata ( vik_layer_interfaces[type]->icon, FALSE, NULL ); | |
500 | return NULL; | |
501 | } | |
502 | ||
158b3642 | 503 | gboolean vik_layer_set_param ( VikLayer *layer, guint16 id, VikLayerParamData data, gpointer vp, gboolean is_file_operation ) |
50a14534 EB |
504 | { |
505 | if ( vik_layer_interfaces[layer->type]->set_param ) | |
158b3642 | 506 | return vik_layer_interfaces[layer->type]->set_param ( layer, id, data, vp, is_file_operation ); |
50a14534 EB |
507 | return FALSE; |
508 | } | |
509 | ||
07059501 | 510 | void vik_layer_post_read ( VikLayer *layer, VikViewport *vp, gboolean from_file ) |
50a14534 EB |
511 | { |
512 | if ( vik_layer_interfaces[layer->type]->post_read ) | |
07059501 | 513 | vik_layer_interfaces[layer->type]->post_read ( layer, vp, from_file ); |
50a14534 EB |
514 | } |
515 | ||
a0c65899 | 516 | static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ) |
50a14534 | 517 | { |
13fde155 RN |
518 | switch ( a_uibuilder_properties_factory ( _("Layer Properties"), |
519 | VIK_GTK_WINDOW_FROM_WIDGET(vp), | |
dc2c040e RN |
520 | vik_layer_interfaces[vl->type]->params, |
521 | vik_layer_interfaces[vl->type]->params_count, | |
522 | vik_layer_interfaces[vl->type]->params_groups, | |
523 | vik_layer_interfaces[vl->type]->params_groups_count, | |
524 | (gpointer) vik_layer_interfaces[vl->type]->set_param, | |
525 | vl, | |
526 | vp, | |
527 | (gpointer) vik_layer_interfaces[vl->type]->get_param, | |
528 | vl) ) { | |
28c82d8b | 529 | case 0: |
28c82d8b | 530 | case 3: |
730a38c1 | 531 | return FALSE; |
28c82d8b EB |
532 | /* redraw (?) */ |
533 | case 2: | |
07059501 | 534 | vik_layer_post_read ( vl, vp, FALSE ); /* update any gc's */ |
28c82d8b EB |
535 | default: |
536 | return TRUE; | |
50a14534 EB |
537 | } |
538 | } | |
bce3a7b0 | 539 | |
44b84795 RN |
540 | VikLayerTypeEnum vik_layer_type_from_string ( const gchar *str ) |
541 | { | |
542 | VikLayerTypeEnum i; | |
543 | for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ ) | |
544 | if ( strcasecmp ( str, vik_layer_get_interface(i)->fixed_layer_name ) == 0 ) | |
545 | return i; | |
546 | return VIK_LAYER_NUM_TYPES; | |
547 | } | |
176e0989 RN |
548 | |
549 | void vik_layer_typed_param_data_free ( gpointer gp ) | |
550 | { | |
551 | VikLayerTypedParamData *val = (VikLayerTypedParamData *)gp; | |
552 | switch ( val->type ) { | |
553 | case VIK_LAYER_PARAM_STRING: | |
554 | if ( val->data.s ) | |
555 | g_free ( (gpointer)val->data.s ); | |
556 | break; | |
557 | /* TODO: APPLICABLE TO US? NOTE: string layer works auniquely: data.sl should NOT be free'd when | |
558 | * the internals call get_param -- i.e. it should be managed w/in the layer. | |
559 | * The value passed by the internals into set_param should also be managed | |
560 | * by the layer -- i.e. free'd by the layer. | |
561 | */ | |
562 | case VIK_LAYER_PARAM_STRING_LIST: | |
563 | g_warning ("Param strings not implemented"); //fake it | |
564 | break; | |
565 | default: | |
566 | break; | |
567 | } | |
568 | g_free ( val ); | |
569 | } | |
570 | ||
571 | VikLayerTypedParamData *vik_layer_typed_param_data_copy_from_data (VikLayerParamType type, VikLayerParamData val) { | |
572 | VikLayerTypedParamData *newval = g_new(VikLayerTypedParamData,1); | |
573 | newval->data = val; | |
574 | newval->type = type; | |
575 | switch ( newval->type ) { | |
576 | case VIK_LAYER_PARAM_STRING: { | |
577 | gchar *s = g_strdup(newval->data.s); | |
578 | newval->data.s = s; | |
579 | break; | |
580 | } | |
581 | /* TODO: APPLICABLE TO US? NOTE: string layer works auniquely: data.sl should NOT be free'd when | |
582 | * the internals call get_param -- i.e. it should be managed w/in the layer. | |
583 | * The value passed by the internals into set_param should also be managed | |
584 | * by the layer -- i.e. free'd by the layer. | |
585 | */ | |
586 | case VIK_LAYER_PARAM_STRING_LIST: | |
587 | g_critical ( "Param strings not implemented"); //fake it | |
588 | break; | |
589 | default: | |
590 | break; | |
591 | } | |
592 | return newval; | |
593 | } | |
594 | ||
595 | #define TEST_BOOLEAN(str) (! ((str)[0] == '\0' || (str)[0] == '0' || (str)[0] == 'n' || (str)[0] == 'N' || (str)[0] == 'f' || (str)[0] == 'F') ) | |
596 | ||
597 | VikLayerTypedParamData *vik_layer_data_typed_param_copy_from_string ( VikLayerParamType type, const gchar *str ) | |
598 | { | |
599 | VikLayerTypedParamData *rv = g_new(VikLayerTypedParamData,1); | |
600 | rv->type = type; | |
601 | switch ( type ) | |
602 | { | |
603 | case VIK_LAYER_PARAM_DOUBLE: rv->data.d = strtod(str, NULL); break; | |
604 | case VIK_LAYER_PARAM_UINT: rv->data.u = strtoul(str, NULL, 10); break; | |
605 | case VIK_LAYER_PARAM_INT: rv->data.i = strtol(str, NULL, 10); break; | |
606 | case VIK_LAYER_PARAM_BOOLEAN: rv->data.b = TEST_BOOLEAN(str); break; | |
607 | case VIK_LAYER_PARAM_COLOR: memset(&(rv->data.c), 0, sizeof(rv->data.c)); /* default: black */ | |
608 | gdk_color_parse ( str, &(rv->data.c) ); break; | |
609 | /* STRING or STRING_LIST -- if STRING_LIST, just set param to add a STRING */ | |
610 | default: { | |
611 | gchar *s = g_strdup(str); | |
612 | rv->data.s = s; | |
613 | } | |
614 | } | |
615 | return rv; | |
616 | } | |
617 | ||
a7023a1b RN |
618 | |
619 | /** | |
620 | * vik_layer_set_defaults: | |
621 | * | |
622 | * Loop around all parameters for the specified layer to call the function to get the | |
623 | * default value for that parameter | |
624 | */ | |
625 | void vik_layer_set_defaults ( VikLayer *vl, VikViewport *vvp ) | |
626 | { | |
627 | VikLayerInterface *vli = vik_layer_get_interface ( vl->type ); | |
628 | const gchar *layer_name = vli->fixed_layer_name; | |
629 | VikLayerParamData data; | |
630 | ||
631 | int i; | |
632 | for ( i = 0; i < vli->params_count; i++ ) { | |
633 | // Ensure parameter is for use | |
634 | if ( vli->params[i].group > VIK_LAYER_NOT_IN_PROPERTIES ) { | |
635 | // ATM can't handle string lists | |
636 | // only DEM files uses this currently | |
637 | if ( vli->params[i].type != VIK_LAYER_PARAM_STRING_LIST ) { | |
638 | data = a_layer_defaults_get ( layer_name, vli->params[i].name, vli->params[i].type ); | |
b03ae39b | 639 | vik_layer_set_param ( vl, i, data, vvp, TRUE ); // Possibly come from a file |
a7023a1b RN |
640 | } |
641 | } | |
642 | } | |
643 | } |