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