X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/176e09897201f14c51301e6ff729e3c5e776551c..d3b7baa79d155131dd3e55ddffd881913378aa59:/src/viklayer.c diff --git a/src/viklayer.c b/src/viklayer.c index 5a38f5a2..1f30ca2a 100644 --- a/src/viklayer.c +++ b/src/viklayer.c @@ -3,6 +3,7 @@ * * Copyright (C) 2005, Alex Foobarian * Copyright (C) 2003-2007, Evan Battaglia + * Copyright (C) 2013, Rob Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +29,8 @@ #include "viking.h" #include +#include +#include "viklayer_defaults.h" /* functions common to all layers. */ /* TODO longone: rename interface free -> finalize */ @@ -39,6 +42,9 @@ extern VikLayerInterface vik_coord_layer_interface; extern VikLayerInterface vik_georef_layer_interface; extern VikLayerInterface vik_gps_layer_interface; extern VikLayerInterface vik_dem_layer_interface; +#ifdef HAVE_LIBMAPNIK +extern VikLayerInterface vik_mapnik_layer_interface; +#endif enum { VL_UPDATE_SIGNAL, @@ -50,6 +56,7 @@ static GObjectClass *parent_class; static void vik_layer_finalize ( VikLayer *vl ); static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ); +static gboolean layer_defaults_register ( VikLayerTypeEnum type ); G_DEFINE_TYPE (VikLayer, vik_layer, G_TYPE_OBJECT) @@ -66,6 +73,12 @@ static void vik_layer_class_init (VikLayerClass *klass) layer_signals[VL_UPDATE_SIGNAL] = g_signal_new ( "update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikLayerClass, update), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + // Register all parameter defaults, early in the start up sequence + VikLayerTypeEnum layer; + for ( layer = 0; layer < VIK_LAYER_NUM_TYPES; layer++ ) + // ATM ignore the returned value + layer_defaults_register ( layer ); } /** @@ -83,10 +96,15 @@ static gboolean idle_draw ( VikLayer *vl ) void vik_layer_emit_update ( VikLayer *vl ) { if ( vl->visible && vl->realized ) { + GThread *thread = vik_window_get_thread ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl)) ); + if ( !thread ) + // Do nothing + return; + vik_window_set_redraw_trigger(vl); // Only ever draw when there is time to do so - if ( g_thread_self() != vik_window_get_thread (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl))) ) + if ( g_thread_self() != thread ) // Drawing requested from another (background) thread, so handle via the gdk thread method gdk_threads_add_idle ( (GSourceFunc) idle_draw, vl ); else @@ -121,6 +139,9 @@ static VikLayerInterface *vik_layer_interfaces[VIK_LAYER_NUM_TYPES] = { &vik_gps_layer_interface, &vik_maps_layer_interface, &vik_dem_layer_interface, +#ifdef HAVE_LIBMAPNIK + &vik_mapnik_layer_interface, +#endif }; VikLayerInterface *vik_layer_get_interface ( VikLayerTypeEnum type ) @@ -129,6 +150,35 @@ VikLayerInterface *vik_layer_get_interface ( VikLayerTypeEnum type ) return vik_layer_interfaces[type]; } +/** + * Store default values for this layer + * + * Returns whether any parameters where registered + */ +static gboolean layer_defaults_register ( VikLayerTypeEnum type ) +{ + // See if any parameters + VikLayerParam *params = vik_layer_interfaces[type]->params; + if ( ! params ) + return FALSE; + + gboolean answer = FALSE; // Incase all parameters are 'not in properties' + guint16 params_count = vik_layer_interfaces[type]->params_count; + guint16 i; + // Process each parameter + for ( i = 0; i < params_count; i++ ) { + if ( params[i].group != VIK_LAYER_NOT_IN_PROPERTIES ) { + if ( params[i].default_value ) { + VikLayerParamData paramd = params[i].default_value(); + a_layer_defaults_register ( ¶ms[i], paramd, vik_layer_interfaces[type]->fixed_layer_name ); + answer = TRUE; + } + } + } + + return answer; +} + static void vik_layer_init ( VikLayer *vl ) { vl->visible = TRUE; @@ -164,7 +214,14 @@ const gchar *vik_layer_get_name ( VikLayer *l ) return l->name; } -VikLayer *vik_layer_create ( VikLayerTypeEnum type, gpointer vp, GtkWindow *w, gboolean interactive ) +time_t vik_layer_get_timestamp ( VikLayer *vl ) +{ + if ( vik_layer_interfaces[vl->type]->get_timestamp ) + return vik_layer_interfaces[vl->type]->get_timestamp ( vl ); + return 0; +} + +VikLayer *vik_layer_create ( VikLayerTypeEnum type, VikViewport *vp, gboolean interactive ) { VikLayer *new_layer = NULL; g_assert ( type < VIK_LAYER_NUM_TYPES ); @@ -189,18 +246,18 @@ VikLayer *vik_layer_create ( VikLayerTypeEnum type, gpointer vp, GtkWindow *w, g } /* returns TRUE if OK was pressed */ -gboolean vik_layer_properties ( VikLayer *layer, gpointer vp ) +gboolean vik_layer_properties ( VikLayer *layer, VikViewport *vp ) { if ( vik_layer_interfaces[layer->type]->properties ) return vik_layer_interfaces[layer->type]->properties ( layer, vp ); return vik_layer_properties_factory ( layer, vp ); } -void vik_layer_draw ( VikLayer *l, gpointer data ) +void vik_layer_draw ( VikLayer *l, VikViewport *vp ) { if ( l->visible ) if ( vik_layer_interfaces[l->type]->draw ) - vik_layer_interfaces[l->type]->draw ( l, data ); + vik_layer_interfaces[l->type]->draw ( l, vp ); } void vik_layer_change_coord_mode ( VikLayer *l, VikCoordMode mode ) @@ -210,7 +267,7 @@ void vik_layer_change_coord_mode ( VikLayer *l, VikCoordMode mode ) } typedef struct { - gint layer_type; + VikLayerTypeEnum layer_type; gint len; guint8 data[0]; } header_t; @@ -246,8 +303,11 @@ void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \ g_byte_array_append ( b, (guint8 *)(obj), len ); + // Store the internal properties first + vlm_append(&vl->visible, sizeof(vl->visible)); vlm_append(vl->name, strlen(vl->name)); + // Now the actual parameters if ( params && get_param ) { VikLayerParamData d; @@ -258,10 +318,16 @@ void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) d = get_param(vl, i, FALSE); switch ( params[i].type ) { - case VIK_LAYER_PARAM_STRING: - vlm_append(d.s, strlen(d.s)); - break; - + case VIK_LAYER_PARAM_STRING: + // Remember need braces as these are macro calls, not single statement functions! + if ( d.s ) { + vlm_append(d.s, strlen(d.s)); + } + else { + // Need to insert empty string otherwise the unmarshall will get confused + vlm_append("", 0); + } + break; /* print out the string list in the array */ case VIK_LAYER_PARAM_STRING_LIST: { GList *list = d.sl; @@ -304,13 +370,13 @@ void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, Vik #define vlm_read(obj) \ memcpy((obj), b+sizeof(gint), vlm_size); \ b += sizeof(gint) + vlm_size; - + + vlm_read(&vl->visible); + s = g_malloc(vlm_size + 1); s[vlm_size]=0; vlm_read(s); - vik_layer_rename(vl, s); - g_free(s); if ( params && set_param ) @@ -487,7 +553,8 @@ static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ) vl, vp, (gpointer) vik_layer_interfaces[vl->type]->get_param, - vl) ) { + vl, + (gpointer) vik_layer_interfaces[vl->type]->change_param ) ) { case 0: case 3: return FALSE; @@ -577,3 +644,31 @@ VikLayerTypedParamData *vik_layer_data_typed_param_copy_from_string ( VikLayerPa return rv; } + +/** + * vik_layer_set_defaults: + * + * Loop around all parameters for the specified layer to call the function to get the + * default value for that parameter + */ +void vik_layer_set_defaults ( VikLayer *vl, VikViewport *vvp ) +{ + // Sneaky initialize of the viewport value here + vl->vvp = vvp; + VikLayerInterface *vli = vik_layer_get_interface ( vl->type ); + const gchar *layer_name = vli->fixed_layer_name; + VikLayerParamData data; + + int i; + for ( i = 0; i < vli->params_count; i++ ) { + // Ensure parameter is for use + if ( vli->params[i].group > VIK_LAYER_NOT_IN_PROPERTIES ) { + // ATM can't handle string lists + // only DEM files uses this currently + if ( vli->params[i].type != VIK_LAYER_PARAM_STRING_LIST ) { + data = a_layer_defaults_get ( layer_name, vli->params[i].name, vli->params[i].type ); + vik_layer_set_param ( vl, i, data, vvp, TRUE ); // Possibly come from a file + } + } + } +}