#include "viking.h"
#include "vikradiogroup.h"
+#include "vikfilelist.h"
+#include <string.h>
+
+static VikLayer *trigger = NULL;
/* functions common to all layers. */
/* TODO longone: rename interface free -> finalize */
extern VikLayerInterface vik_maps_layer_interface;
extern VikLayerInterface vik_coord_layer_interface;
extern VikLayerInterface vik_georef_layer_interface;
+extern VikLayerInterface vik_gps_layer_interface;
+extern VikLayerInterface vik_dem_layer_interface;
enum {
VL_UPDATE_SIGNAL,
static void layer_class_init ( VikLayerClass *klass );
static void layer_init ( VikLayer *vl );
static void layer_finalize ( VikLayer *vl );
-static gboolean layer_properties_factory ( VikLayer *vl, gpointer vp );
+static gboolean layer_properties_factory ( VikLayer *vl, VikViewport *vp );
/* TODO longone: rename vik_layer_init -> set_type */
}
void vik_layer_emit_update ( VikLayer *vl )
+{
+ if ( vl->visible ) {
+ trigger = vl;
+ g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 );
+ }
+}
+
+/* should only be done by VikLayersPanel -- need to redraw and record trigger
+ * when we make a layer invisible.
+ */
+void vik_layer_emit_update_although_invisible ( VikLayer *vl )
+{
+ trigger = vl;
+ g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 );
+}
+
+VikLayer *vik_layer_get_and_reset_trigger()
+{
+ VikLayer *rv = trigger;
+ trigger = NULL;
+ return rv;
+}
+
+/* doesn't set the trigger. should be done by aggregate layer when child emits update. */
+void vik_layer_emit_update_secondary ( VikLayer *vl )
{
if ( vl->visible )
g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 );
&vik_trw_layer_interface,
&vik_coord_layer_interface,
&vik_georef_layer_interface,
+ &vik_gps_layer_interface,
&vik_maps_layer_interface,
+ &vik_dem_layer_interface,
};
VikLayerInterface *vik_layer_get_interface ( gint type )
/* frees old name */
void vik_layer_rename ( VikLayer *l, const gchar *new_name )
{
- g_assert ( l != NULL);
- if ( l->name )
- g_free ( l->name );
+ g_assert ( l != NULL );
+ g_assert ( new_name != NULL );
+ g_free ( l->name );
l->name = g_strdup ( new_name );
}
void vik_layer_rename_no_copy ( VikLayer *l, gchar *new_name )
{
- g_assert ( l != NULL);
- if ( l->name )
- g_free ( l->name );
+ g_assert ( l != NULL );
+ g_assert ( new_name != NULL );
+ g_free ( l->name );
l->name = new_name;
}
+const gchar *vik_layer_get_name ( VikLayer *l )
+{
+ g_assert ( l != NULL);
+ return l->name;
+}
+
VikLayer *vik_layer_create ( gint type, gpointer vp, GtkWindow *w, gboolean interactive )
{
VikLayer *new_layer = NULL;
vik_layer_interfaces[l->type]->change_coord_mode ( l, mode );
}
-VikLayer *vik_layer_copy ( VikLayer *vl, gpointer vp )
+typedef struct {
+ gint layer_type;
+ gint len;
+ guint8 data[0];
+} header_t;
+
+void vik_layer_marshall ( VikLayer *vl, guint8 **data, gint *len )
+{
+ header_t *header;
+ if ( vl && vik_layer_interfaces[vl->type]->marshall ) {
+ vik_layer_interfaces[vl->type]->marshall ( vl, data, len );
+ if (*data) {
+ header = g_malloc(*len + sizeof(*header));
+ header->layer_type = vl->type;
+ header->len = *len;
+ memcpy(header->data, *data, *len);
+ g_free(*data);
+ *data = (guint8 *)header;
+ *len = *len + sizeof(*header);
+ }
+ } else {
+ *data = NULL;
+ }
+}
+
+void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen )
{
- if ( vik_layer_interfaces[vl->type]->copy )
+ VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
+ VikLayerFuncGetParam get_param = vik_layer_get_interface(vl->type)->get_param;
+ GByteArray* b = g_byte_array_new ();
+ gint len;
+
+#define vlm_append(obj, sz) \
+ len = (sz); \
+ g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \
+ g_byte_array_append ( b, (guint8 *)(obj), len );
+
+ vlm_append(vl->name, strlen(vl->name));
+
+ if ( params && get_param )
{
- VikLayer *rv = vik_layer_interfaces[vl->type]->copy ( vl, vp );
- if ( rv )
+ VikLayerParamData d;
+ guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
+ for ( i = 0; i < params_count; i++ )
{
- vik_layer_rename ( rv, vl->name );
- rv->visible = vl->visible;
+ d = get_param(vl, i);
+ switch ( params[i].type )
+ {
+ case VIK_LAYER_PARAM_STRING:
+ vlm_append(d.s, strlen(d.s));
+ break;
+
+ /* print out the string list in the array */
+ case VIK_LAYER_PARAM_STRING_LIST: {
+ GList *list = d.sl;
+
+ /* write length of list (# of strings) */
+ gint listlen = g_list_length ( list );
+ g_byte_array_append ( b, (guint8 *)&listlen, sizeof(listlen) );
+
+ /* write each string */
+ while ( list ) {
+ gchar *s = (gchar *) list->data;
+ vlm_append(s, strlen(s));
+ list = list->next;
+ }
+
+ break;
+ }
+ default:
+ vlm_append(&d, sizeof(d));
+ break;
+ }
+ }
+ }
+
+ *data = b->data;
+ *datalen = b->len;
+ g_byte_array_free ( b, FALSE );
+
+#undef vlm_append
+}
+
+void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, VikViewport *vvp )
+{
+ VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
+ VikLayerFuncSetParam set_param = vik_layer_get_interface(vl->type)->set_param;
+ gchar *s;
+ guint8 *b = (guint8 *)data;
+
+#define vlm_size (*(gint *)b)
+#define vlm_read(obj) \
+ memcpy((obj), b+sizeof(gint), vlm_size); \
+ b += sizeof(gint) + vlm_size;
+
+ 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 )
+ {
+ VikLayerParamData d;
+ guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
+ for ( i = 0; i < params_count; i++ )
+ {
+ switch ( params[i].type )
+ {
+ case VIK_LAYER_PARAM_STRING:
+ s = g_malloc(vlm_size + 1);
+ s[vlm_size]=0;
+ vlm_read(s);
+ d.s = s;
+ set_param(vl, i, d, vvp);
+ g_free(s);
+ break;
+ case VIK_LAYER_PARAM_STRING_LIST: {
+ gint listlen = vlm_size, j;
+ GList *list = NULL;
+ b += sizeof(gint); /* skip listlen */;
+
+ for ( j = 0; j < listlen; j++ ) {
+ /* get a string */
+ s = g_malloc(vlm_size + 1);
+ s[vlm_size]=0;
+ vlm_read(s);
+ list = g_list_append ( list, s );
+ }
+ d.sl = list;
+ set_param ( vl, i, d, vvp );
+ /* don't free -- string list is responsibility of the layer */
+
+ break;
+ }
+ default:
+ vlm_read(&d);
+ set_param(vl, i, d, vvp);
+ break;
+ }
}
- return rv;
}
- else
- return NULL;
}
+VikLayer *vik_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp )
+{
+ header_t *header;
+
+ header = (header_t *)data;
+
+ if ( vik_layer_interfaces[header->layer_type]->unmarshall ) {
+ return vik_layer_interfaces[header->layer_type]->unmarshall ( header->data, header->len, vvp );
+ } else {
+ return NULL;
+ }
+}
static void layer_finalize ( VikLayer *vl )
{
vik_layer_interfaces[l->type]->realize ( l, vt, layer_iter );
}
+void vik_layer_set_menu_items_selection(VikLayer *l, guint16 selection)
+{
+ if ( vik_layer_interfaces[l->type]->set_menu_selection )
+ vik_layer_interfaces[l->type]->set_menu_selection ( l, selection );
+}
+
+guint16 vik_layer_get_menu_items_selection(VikLayer *l)
+{
+ if ( vik_layer_interfaces[l->type]->get_menu_selection )
+ return(vik_layer_interfaces[l->type]->get_menu_selection (l));
+ else
+ return(vik_layer_interfaces[l->type]->menu_items_selection);
+}
+
void vik_layer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp )
{
if ( vik_layer_interfaces[l->type]->add_menu_items )
return FALSE;
}
-void vik_layer_post_read ( VikLayer *layer, gpointer vp )
+void vik_layer_post_read ( VikLayer *layer, VikViewport *vp, gboolean from_file )
{
if ( vik_layer_interfaces[layer->type]->post_read )
- vik_layer_interfaces[layer->type]->post_read ( layer, vp );
+ vik_layer_interfaces[layer->type]->post_read ( layer, vp, from_file );
}
static GtkWidget *properties_widget_new_widget ( VikLayerParam *param, VikLayerParamData data )
{
- GtkWidget *rv;
+ GtkWidget *rv = NULL;
switch ( param->widget_type )
{
case VIK_LAYER_WIDGET_COLOR:
break;
#endif
case VIK_LAYER_WIDGET_RADIOGROUP:
+ /* widget_data and extra_widget_data are GList */
+ if ( param->type == VIK_LAYER_PARAM_UINT && param->widget_data )
+ {
+ rv = vik_radio_group_new ( param->widget_data );
+ if ( param->extra_widget_data ) /* map of alternate uint values for options */
+ {
+ int i;
+ int nb_elem = g_list_length(param->widget_data);
+ for ( i = 0; i < nb_elem; i++ )
+ if ( (guint32)g_list_nth_data(param->extra_widget_data, i) == data.u )
+ {
+ vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv), i );
+ break;
+ }
+ }
+ else if ( data.u ) /* zero is already default */
+ vik_radio_group_set_selected ( VIK_RADIO_GROUP(rv), data.u );
+ }
+ break;
+ case VIK_LAYER_WIDGET_RADIOGROUP_STATIC:
if ( param->type == VIK_LAYER_PARAM_UINT && param->widget_data )
{
- rv = vik_radio_group_new ( (const gchar **) param->widget_data );
+ rv = vik_radio_group_new_static ( (const gchar **) param->widget_data );
if ( param->extra_widget_data ) /* map of alternate uint values for options */
{
int i;
vik_file_entry_set_filename ( VIK_FILE_ENTRY(rv), data.s );
}
break;
+ case VIK_LAYER_WIDGET_FILELIST:
+ if ( param->type == VIK_LAYER_PARAM_STRING_LIST )
+ {
+ rv = vik_file_list_new ( param->title );
+ vik_file_list_set_files ( VIK_FILE_LIST(rv), data.sl );
+ }
+ break;
case VIK_LAYER_WIDGET_HSCALE:
if ( (param->type == VIK_LAYER_PARAM_DOUBLE || param->type == VIK_LAYER_PARAM_UINT
|| param->type == VIK_LAYER_PARAM_INT) && param->widget_data )
break;
#endif
case VIK_LAYER_WIDGET_RADIOGROUP:
+ case VIK_LAYER_WIDGET_RADIOGROUP_STATIC:
rv.u = vik_radio_group_get_selected(VIK_RADIO_GROUP(widget));
if ( param->extra_widget_data )
- rv.u = ((guint *)param->extra_widget_data)[rv.u];
+ rv.u = (guint32)g_list_nth_data(param->extra_widget_data, rv.u);
break;
case VIK_LAYER_WIDGET_SPINBUTTON:
if ( param->type == VIK_LAYER_PARAM_UINT )
case VIK_LAYER_WIDGET_FILEENTRY:
rv.s = vik_file_entry_get_filename ( VIK_FILE_ENTRY(widget) );
break;
+ case VIK_LAYER_WIDGET_FILELIST:
+ rv.sl = vik_file_list_get_files ( VIK_FILE_LIST(widget) );
+ break;
case VIK_LAYER_WIDGET_HSCALE:
if ( param->type == VIK_LAYER_PARAM_UINT )
rv.u = (guint32) gtk_range_get_value ( GTK_RANGE(widget) );
/* false if cancel, true if OK */
/* some would claim this wasn't written to be human-readable. */
-static gboolean layer_properties_factory ( VikLayer *vl, gpointer vp )
+static gboolean layer_properties_factory ( VikLayer *vl, VikViewport *vp )
{
VikLayerParam *params = vik_layer_interfaces[vl->type]->params;
guint16 params_count = vik_layer_interfaces[vl->type]->params_count;
j++;
}
}
- vik_layer_post_read ( vl, vp ); /* update any gc's */
+ vik_layer_post_read ( vl, vp, FALSE ); /* update any gc's */
gtk_widget_destroy ( dialog ); /* hide before redrawing. */
g_free ( widgets );