X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/4c77d5e0aec3c7aab32965ca4e02abb17bb6108f..9552af08b0de8cf0de6b8d253d5a77173f35259b:/src/viklayer.c?ds=sidebyside diff --git a/src/viklayer.c b/src/viklayer.c index 94b961e6..926b9390 100644 --- a/src/viklayer.c +++ b/src/viklayer.c @@ -1,7 +1,8 @@ /* * viking -- GPS Data and Topo Analyzer, Explorer, and Manager * - * Copyright (C) 2003-2005, Evan Battaglia + * Copyright (C) 2005, Alex Foobarian + * Copyright (C) 2003-2007, Evan Battaglia * * 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 @@ -94,28 +95,49 @@ static void layer_class_init (VikLayerClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } -void vik_layer_emit_update ( VikLayer *vl ) +/** + * Invoke the actual drawing via signal method + */ +static gboolean idle_draw ( VikLayer *vl ) +{ + g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 ); + return FALSE; // Nothing else to do +} + +/** + * Draw specified layer + */ +void vik_layer_emit_update ( VikLayer *vl, gboolean from_background ) { if ( vl->visible ) { vik_window_set_redraw_trigger(vl); - g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 ); + + // Only ever draw when there is time to do so + if ( from_background ) + // Drawing requested from background thread, so handle via the gdk thread method + gdk_threads_add_idle ( (GSourceFunc) idle_draw, vl ); + else + g_idle_add ( (GSourceFunc) idle_draw, vl ); } } -/* should only be done by VikLayersPanel -- need to redraw and record trigger - * when we make a layer invisible. +/** + * should only be done by VikLayersPanel (hence never used from the background) + * need to redraw and record trigger when we make a layer invisible. */ void vik_layer_emit_update_although_invisible ( VikLayer *vl ) { vik_window_set_redraw_trigger(vl); - g_signal_emit ( G_OBJECT(vl), layer_signals[VL_UPDATE_SIGNAL], 0 ); + g_idle_add ( (GSourceFunc) idle_draw, vl ); } /* 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 ); + // TODO: this can used from the background - eg in acquire + // so will need to flow background update status through too + g_idle_add ( (GSourceFunc) idle_draw, vl ); } static VikLayerInterface *vik_layer_interfaces[VIK_LAYER_NUM_TYPES] = { @@ -259,7 +281,8 @@ void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count; for ( i = 0; i < params_count; i++ ) { - d = get_param(vl, i); + g_debug("%s: %s", __FUNCTION__, params[i].name); + d = get_param(vl, i, FALSE); switch ( params[i].type ) { case VIK_LAYER_PARAM_STRING: @@ -323,6 +346,7 @@ void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, Vik guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count; for ( i = 0; i < params_count; i++ ) { + g_debug("%s: %s", __FUNCTION__, params[i].name); switch ( params[i].type ) { case VIK_LAYER_PARAM_STRING: @@ -330,7 +354,7 @@ void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, Vik s[vlm_size]=0; vlm_read(s); d.s = s; - set_param(vl, i, d, vvp); + set_param(vl, i, d, vvp, FALSE); g_free(s); break; case VIK_LAYER_PARAM_STRING_LIST: { @@ -346,14 +370,14 @@ void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, Vik list = g_list_append ( list, s ); } d.sl = list; - set_param ( vl, i, d, vvp ); + set_param(vl, i, d, vvp, FALSE); /* don't free -- string list is responsibility of the layer */ break; } default: vlm_read(&d); - set_param(vl, i, d, vvp); + set_param(vl, i, d, vvp, FALSE); break; } } @@ -391,6 +415,14 @@ gboolean vik_layer_sublayer_toggle_visible ( VikLayer *l, gint subtype, gpointer return TRUE; /* if unknown, will always be visible */ } +gboolean vik_layer_selected ( VikLayer *l, gint subtype, gpointer sublayer, gint type, gpointer vlp ) +{ + if ( vik_layer_interfaces[l->type]->layer_selected ) + return vik_layer_interfaces[l->type]->layer_selected ( l, subtype, sublayer, type, vlp ); + /* Since no 'layer_selected' function explicitly turn off here */ + return vik_window_clear_highlight ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(l) ); +} + void vik_layer_realize ( VikLayer *l, VikTreeview *vt, GtkTreeIter *layer_iter ) { l->vt = vt; @@ -420,10 +452,10 @@ void vik_layer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp ) vik_layer_interfaces[l->type]->add_menu_items ( l, menu, vlp ); } -gboolean vik_layer_sublayer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter ) +gboolean vik_layer_sublayer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter, VikViewport *vvp ) { if ( vik_layer_interfaces[l->type]->sublayer_add_menu_items ) - return vik_layer_interfaces[l->type]->sublayer_add_menu_items ( l, menu, vlp, subtype, sublayer, iter ); + return vik_layer_interfaces[l->type]->sublayer_add_menu_items ( l, menu, vlp, subtype, sublayer, iter, vvp ); return FALSE; } @@ -435,6 +467,20 @@ const gchar *vik_layer_sublayer_rename_request ( VikLayer *l, const gchar *newna return NULL; } +const gchar* vik_layer_sublayer_tooltip ( VikLayer *l, gint subtype, gpointer sublayer ) +{ + if ( vik_layer_interfaces[l->type]->sublayer_tooltip ) + return vik_layer_interfaces[l->type]->sublayer_tooltip ( l, subtype, sublayer ); + return NULL; +} + +const gchar* vik_layer_layer_tooltip ( VikLayer *l ) +{ + if ( vik_layer_interfaces[l->type]->layer_tooltip ) + return vik_layer_interfaces[l->type]->layer_tooltip ( l ); + return NULL; +} + GdkPixbuf *vik_layer_load_icon ( gint type ) { g_assert ( type < VIK_LAYER_NUM_TYPES ); @@ -443,10 +489,10 @@ GdkPixbuf *vik_layer_load_icon ( gint type ) return NULL; } -gboolean vik_layer_set_param ( VikLayer *layer, guint16 id, VikLayerParamData data, gpointer vp ) +gboolean vik_layer_set_param ( VikLayer *layer, guint16 id, VikLayerParamData data, gpointer vp, gboolean is_file_operation ) { if ( vik_layer_interfaces[layer->type]->set_param ) - return vik_layer_interfaces[layer->type]->set_param ( layer, id, data, vp ); + return vik_layer_interfaces[layer->type]->set_param ( layer, id, data, vp, is_file_operation ); return FALSE; } @@ -458,16 +504,20 @@ void vik_layer_post_read ( VikLayer *layer, VikViewport *vp, gboolean from_file static gboolean layer_properties_factory ( VikLayer *vl, VikViewport *vp ) { - switch ( a_uibuilder_properties_factory ( VIK_GTK_WINDOW_FROM_WIDGET(vp), - vik_layer_interfaces[vl->type]->params, - vik_layer_interfaces[vl->type]->params_count, - vik_layer_interfaces[vl->type]->params_groups, - vik_layer_interfaces[vl->type]->params_groups_count, - vik_layer_interfaces[vl->type]->set_param, vl, vp, - vik_layer_interfaces[vl->type]->get_param, vl) ) { + switch ( a_uibuilder_properties_factory ( _("Layer Properties"), + VIK_GTK_WINDOW_FROM_WIDGET(vp), + vik_layer_interfaces[vl->type]->params, + vik_layer_interfaces[vl->type]->params_count, + vik_layer_interfaces[vl->type]->params_groups, + vik_layer_interfaces[vl->type]->params_groups_count, + (gpointer) vik_layer_interfaces[vl->type]->set_param, + vl, + vp, + (gpointer) vik_layer_interfaces[vl->type]->get_param, + vl) ) { case 0: - return FALSE; case 3: + return FALSE; /* redraw (?) */ case 2: vik_layer_post_read ( vl, vp, FALSE ); /* update any gc's */ @@ -476,54 +526,3 @@ static gboolean layer_properties_factory ( VikLayer *vl, VikViewport *vp ) } } -static GdkCursor ***layers_cursors; - -GdkCursor *vik_layer_get_tool_cursor ( gint layer_id, gint tool_id ) -{ - if ( layer_id >= VIK_LAYER_NUM_TYPES ) - return NULL; - if ( tool_id >= vik_layer_interfaces[layer_id]->tools_count ) - return NULL; - return layers_cursors[layer_id][tool_id]; -} - -void vik_layer_cursors_init() -{ - gint i, j; - layers_cursors = g_malloc ( sizeof(GdkCursor **) * VIK_LAYER_NUM_TYPES ); - for ( i = 0 ; i < VIK_LAYER_NUM_TYPES; i++ ) { - if ( vik_layer_interfaces[i]->tools_count ) { - layers_cursors[i] = g_malloc ( sizeof(GdkCursor *) * vik_layer_interfaces[i]->tools_count ); - for ( j = 0; j < vik_layer_interfaces[i]->tools_count; j++ ) { - if ( vik_layer_interfaces[i]->tools[j].cursor ) { - const GdkPixdata *cursor_pixdata = vik_layer_interfaces[i]->tools[j].cursor; - GError *cursor_load_err = NULL; - GdkPixbuf *cursor_pixbuf = gdk_pixbuf_from_pixdata (cursor_pixdata, FALSE, &cursor_load_err); - /* TODO: settable offeset */ - GdkCursor *cursor = gdk_cursor_new_from_pixbuf ( gdk_display_get_default(), cursor_pixbuf, 3, 3 ); - layers_cursors[i][j] = cursor; - - g_object_unref ( G_OBJECT(cursor_pixbuf) ); - } - else - layers_cursors[i][j] = NULL; - } - } else - layers_cursors[i] = NULL; - } -} - -void vik_layer_cursors_uninit() -{ - gint i, j; - for ( i = 0 ; i < VIK_LAYER_NUM_TYPES; i++ ) { - if ( vik_layer_interfaces[i]->tools_count ) { - for ( j = 0; j < vik_layer_interfaces[i]->tools_count; j++ ) { - if ( layers_cursors[i][j] ) - gdk_cursor_unref ( layers_cursors[i][j] ); - } - g_free ( layers_cursors[i] ); - } - } - g_free ( layers_cursors ); -}