X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/0e6076a1a298736d20a92607e5617c47a3a4490b..78af40635535da56ceb0b83ca15a7f6c8fc615bd:/src/viklayer.c?ds=sidebyside diff --git a/src/viklayer.c b/src/viklayer.c index 522be1f8..897fbe5d 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 @@ -47,45 +48,18 @@ static guint layer_signals[VL_LAST_SIGNAL] = { 0 }; static GObjectClass *parent_class; -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, VikViewport *vp ); +static void vik_layer_finalize ( VikLayer *vl ); +static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ); +G_DEFINE_TYPE (VikLayer, vik_layer, G_TYPE_OBJECT) -/* TODO longone: rename vik_layer_init -> set_type */ - -GType vik_layer_get_type () -{ - static GType vl_type = 0; - - if (!vl_type) - { - static const GTypeInfo vl_info = - { - sizeof (VikLayerClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) layer_class_init, /* class init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (VikLayer), - 0, - (GInstanceInitFunc) layer_init /* instance init */ - }; - vl_type = g_type_register_static ( G_TYPE_OBJECT, "VikLayer", &vl_info, 0 ); - } - - return vl_type; -} - -static void layer_class_init (VikLayerClass *klass) +static void vik_layer_class_init (VikLayerClass *klass) { GObjectClass *object_class; object_class = G_OBJECT_CLASS (klass); - object_class->finalize = (GObjectFinalizeFunc) layer_finalize; + object_class->finalize = (GObjectFinalizeFunc) vik_layer_finalize; parent_class = g_type_class_peek_parent (klass); @@ -94,28 +68,49 @@ static void layer_class_init (VikLayerClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } +/** + * 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 ) { - if ( vl->visible ) { + if ( vl->visible && vl->realized ) { 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 ( g_thread_self() != vik_window_get_thread (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl))) ) + // Drawing requested from another (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] = { @@ -134,14 +129,14 @@ VikLayerInterface *vik_layer_get_interface ( gint type ) return vik_layer_interfaces[type]; } -static void layer_init ( VikLayer *vl ) +static void vik_layer_init ( VikLayer *vl ) { vl->visible = TRUE; vl->name = NULL; vl->realized = FALSE; } -void vik_layer_init ( VikLayer *vl, gint type ) +void vik_layer_set_type ( VikLayer *vl, gint type ) { vl->type = type; } @@ -198,7 +193,7 @@ gboolean vik_layer_properties ( VikLayer *layer, gpointer vp ) { if ( vik_layer_interfaces[layer->type]->properties ) return vik_layer_interfaces[layer->type]->properties ( layer, vp ); - return layer_properties_factory ( layer, vp ); + return vik_layer_properties_factory ( layer, vp ); } void vik_layer_draw ( VikLayer *l, gpointer data ) @@ -375,7 +370,7 @@ VikLayer *vik_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp ) } } -static void layer_finalize ( VikLayer *vl ) +static void vik_layer_finalize ( VikLayer *vl ) { g_assert ( vl != NULL ); if ( vik_layer_interfaces[vl->type]->free ) @@ -393,6 +388,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; @@ -422,10 +425,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; } @@ -437,6 +440,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 ); @@ -458,7 +475,7 @@ void vik_layer_post_read ( VikLayer *layer, VikViewport *vp, gboolean from_file vik_layer_interfaces[layer->type]->post_read ( layer, vp, from_file ); } -static gboolean layer_properties_factory ( VikLayer *vl, VikViewport *vp ) +static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ) { switch ( a_uibuilder_properties_factory ( _("Layer Properties"), VIK_GTK_WINDOW_FROM_WIDGET(vp),