/** * Some common things to do on completion of a datasource process * . Update layer * . Update dialog info * . Update main dsisplay */ static void on_complete_process (w_and_interface_t *wi) { if (wi->w->running) { gtk_label_set_text ( GTK_LABEL(wi->w->status), _("Done.") ); if ( wi->creating_new_layer ) { /* Only create the layer if it actually contains anything useful */ // TODO: create function for this operation to hide detail: if ( ! vik_trw_layer_is_empty ( wi->vtl ) ) { vik_layer_post_read ( VIK_LAYER(wi->vtl), wi->w->vvp, TRUE ); vik_aggregate_layer_add_layer( vik_layers_panel_get_top_layer(wi->w->vlp), VIK_LAYER(wi->vtl)); } else gtk_label_set_text ( GTK_LABEL(wi->w->status), _("No data.") ); } /* View this data if available and is desired */ if ( wi->vtl && wi->w->source_interface->autoview ) { vik_trw_layer_auto_set_view ( wi->vtl, vik_layers_panel_get_viewport(wi->w->vlp) ); } if ( wi->w->source_interface->keep_dialog_open ) { gtk_dialog_set_response_sensitive ( GTK_DIALOG(wi->w->dialog), GTK_RESPONSE_ACCEPT, TRUE ); gtk_dialog_set_response_sensitive ( GTK_DIALOG(wi->w->dialog), GTK_RESPONSE_REJECT, FALSE ); } else { gtk_dialog_response ( GTK_DIALOG(wi->w->dialog), GTK_RESPONSE_ACCEPT ); } // Main display update if ( wi->vtl ) vik_layers_panel_emit_update ( wi->w->vlp ); } else { /* cancelled */ if ( wi->creating_new_layer ) g_object_unref(wi->vtl); } }
static void aggregate_layer_track_list_dialog ( gpointer data[2] ) { VikAggregateLayer *val = VIK_AGGREGATE_LAYER(data[0]); gchar *title = g_strdup_printf ( _("%s: Track and Route List"), VIK_LAYER(val)->name ); vik_trw_layer_track_list_show_dialog ( title, VIK_LAYER(val), NULL, aggregate_layer_track_create_list, TRUE ); g_free ( title ); }
/* returns 0 == we're good, 1 == didn't find any layers, 2 == got rejected */ guint vik_aggregate_layer_tool ( VikAggregateLayer *val, VikLayerTypeEnum layer_type, VikToolInterfaceFunc tool_func, GdkEventButton *event, VikViewport *vvp ) { GList *iter = val->children; gboolean found_rej = FALSE; if (!iter) return FALSE; while (iter->next) iter = iter->next; while ( iter ) { /* if this layer "accepts" the tool call */ if ( VIK_LAYER(iter->data)->visible && VIK_LAYER(iter->data)->type == layer_type ) { if ( tool_func ( VIK_LAYER(iter->data), event, vvp ) ) return 0; else found_rej = TRUE; } /* recursive -- try the same for the child aggregate layer. */ else if ( VIK_LAYER(iter->data)->visible && VIK_LAYER(iter->data)->type == VIK_LAYER_AGGREGATE ) { gint rv = vik_aggregate_layer_tool(VIK_AGGREGATE_LAYER(iter->data), layer_type, tool_func, event, vvp); if ( rv == 0 ) return 0; else if ( rv == 2 ) found_rej = TRUE; } iter = iter->prev; } return found_rej ? 2 : 1; /* no one wanted to accept the tool call in this layer */ }
static void aggregate_layer_track_list_dialog ( menu_array_values values ) { VikAggregateLayer *val = VIK_AGGREGATE_LAYER ( values[MA_VAL] ); gchar *title = g_strdup_printf ( _("%s: Track and Route List"), VIK_LAYER(val)->name ); vik_trw_layer_track_list_show_dialog ( title, VIK_LAYER(val), NULL, aggregate_layer_track_create_list, TRUE ); g_free ( title ); }
static void aggregate_layer_marshall( VikAggregateLayer *val, guint8 **data, gint *datalen ) { GList *child = val->children; VikLayer *child_layer; guint8 *ld; gint ll; GByteArray* b = g_byte_array_new (); gint len; #define alm_append(obj, sz) \ len = (sz); \ g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \ g_byte_array_append ( b, (guint8 *)(obj), len ); vik_layer_marshall_params(VIK_LAYER(val), &ld, &ll); alm_append(ld, ll); g_free(ld); while (child) { child_layer = VIK_LAYER(child->data); vik_layer_marshall ( child_layer, &ld, &ll ); if (ld) { alm_append(ld, ll); g_free(ld); } child = child->next; } *data = b->data; *datalen = b->len; g_byte_array_free(b, FALSE); #undef alm_append }
static void layers_item_toggled (VikLayersPanel *vlp, GtkTreeIter *iter) { gboolean visible; gpointer p; gint type; /* get type and data */ type = vik_treeview_item_get_type ( vlp->vt, iter ); p = vik_treeview_item_get_pointer ( vlp->vt, iter ); switch ( type ) { case VIK_TREEVIEW_TYPE_LAYER: visible = (VIK_LAYER(p)->visible ^= 1); vik_layer_emit_update_although_invisible ( VIK_LAYER(p) ); /* set trigger for half-drawn */ break; case VIK_TREEVIEW_TYPE_SUBLAYER: visible = vik_layer_sublayer_toggle_visible ( VIK_LAYER(vik_treeview_item_get_parent(vlp->vt, iter)), vik_treeview_item_get_data(vlp->vt, iter), p); vik_layer_emit_update_although_invisible ( VIK_LAYER(vik_treeview_item_get_parent(vlp->vt, iter)) ); break; default: return; } vik_treeview_item_set_visible ( vlp->vt, iter, visible ); }
static VikGeorefLayer *georef_layer_new ( VikViewport *vvp ) { VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) ); vik_layer_set_type ( VIK_LAYER(vgl), VIK_LAYER_GEOREF ); // Since GeoRef layer doesn't use uibuilder // initializing this way won't do anything yet.. vik_layer_set_defaults ( VIK_LAYER(vgl), vvp ); // Make these defaults based on the current view vgl->mpp_northing = vik_viewport_get_ympp ( vvp ); vgl->mpp_easting = vik_viewport_get_xmpp ( vvp ); vik_coord_to_utm ( vik_viewport_get_center ( vvp ), &(vgl->corner) ); vgl->image = NULL; vgl->pixbuf = NULL; vgl->click_x = -1; vgl->click_y = -1; vgl->scaled = NULL; vgl->scaled_width = 0; vgl->scaled_height = 0; vgl->ll_br.lat = 0.0; vgl->ll_br.lon = 0.0; vgl->alpha = 255; return vgl; }
gboolean vik_aggregate_layer_delete ( VikAggregateLayer *val, GtkTreeIter *iter ) { VikLayer *l = VIK_LAYER( vik_treeview_item_get_pointer ( VIK_LAYER(val)->vt, iter ) ); gboolean was_visible = l->visible; vik_treeview_item_delete ( VIK_LAYER(val)->vt, iter ); aggregate_layer_delete_common ( val, l ); return was_visible; }
static VikCoordLayer *coord_layer_new ( VikViewport *vvp ) { VikCoordLayer *vcl = VIK_COORD_LAYER ( g_object_new ( VIK_COORD_LAYER_TYPE, NULL ) ); vik_layer_set_type ( VIK_LAYER(vcl), VIK_LAYER_COORD ); vik_layer_set_defaults ( VIK_LAYER(vcl), vvp ); vcl->gc = NULL; return vcl; }
gboolean vik_aggregate_layer_delete ( VikAggregateLayer *val, GtkTreeIter *iter ) { VikLayer *l = VIK_LAYER( vik_treeview_item_get_pointer ( VIK_LAYER(val)->vt, iter ) ); gboolean was_visible = l->visible; vik_treeview_item_delete ( VIK_LAYER(val)->vt, iter ); val->children = g_list_remove ( val->children, l ); g_assert(DISCONNECT_UPDATE_SIGNAL(l,val)==1); g_object_unref ( l ); return was_visible; }
/* * Foreach entry we copy the various individual waypoint properties into the tree store * formatting & converting the internal values into something for display */ static void trw_layer_waypoint_list_add ( vik_trw_waypoint_list_t *vtdl, GtkTreeStore *store, vik_units_height_t height_units ) { GtkTreeIter t_iter; VikWaypoint *wpt = vtdl->wpt; VikTrwLayer *vtl = vtdl->vtl; // Get start date gchar time_buf[32]; time_buf[0] = '\0'; if ( wpt->has_timestamp ) { #if GLIB_CHECK_VERSION(2,26,0) GDateTime* gdt = g_date_time_new_from_unix_utc ( wpt->timestamp ); gchar *time = g_date_time_format ( gdt, WAYPOINT_LIST_DATE_FORMAT ); strncpy ( time_buf, time, sizeof(time_buf) ); g_free ( time ); g_date_time_unref ( gdt); #else GDate* gdate_start = g_date_new (); g_date_set_time_t ( gdate_start, wpt->timestamp ); g_date_strftime ( time_buf, sizeof(time_buf), WAYPOINT_LIST_DATE_FORMAT, gdate_start ); g_date_free ( gdate_start ); #endif } // NB: doesn't include aggegrate visibility gboolean visible = VIK_LAYER(vtl)->visible && wpt->visible; visible = visible && vik_trw_layer_get_waypoints_visibility(vtl); gdouble alt = wpt->altitude; switch (height_units) { case VIK_UNITS_HEIGHT_FEET: alt = VIK_METERS_TO_FEET(alt); break; default: // VIK_UNITS_HEIGHT_METRES: no need to convert break; } gtk_tree_store_append ( store, &t_iter, NULL ); gtk_tree_store_set ( store, &t_iter, 0, VIK_LAYER(vtl)->name, 1, wpt->name, 2, time_buf, 3, visible, 4, wpt->comment, 5, (gint)round(alt), 6, get_wp_sym_small (wpt->symbol), TRW_COL_NUM, vtl, WPT_COL_NUM, wpt, -1 ); }
/** * vik_layers_panel_add_layer: * @l: existing layer * * Add an existing layer to panel. */ void vik_layers_panel_add_layer ( VikLayersPanel *vlp, VikLayer *l ) { GtkTreeIter iter; GtkTreeIter *replace_iter = NULL; /* could be something different so we have to do this */ vik_layer_change_coord_mode ( l, vik_viewport_get_coord_mode(vlp->vvp) ); if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) ) vik_aggregate_layer_add_layer ( vlp->toplayer, l ); else { VikAggregateLayer *addtoagg; if (vik_treeview_item_get_type ( vlp->vt, &iter ) == VIK_TREEVIEW_TYPE_LAYER ) { if ( IS_VIK_AGGREGATE_LAYER(vik_treeview_item_get_pointer ( vlp->vt, &iter )) ) addtoagg = VIK_AGGREGATE_LAYER(vik_treeview_item_get_pointer ( vlp->vt, &iter )); else { VikLayer *vl = VIK_LAYER(vik_treeview_item_get_parent ( vlp->vt, &iter )); while ( ! IS_VIK_AGGREGATE_LAYER(vl) ) { iter = vl->iter; vl = VIK_LAYER(vik_treeview_item_get_parent ( vlp->vt, &vl->iter )); g_assert ( vl->realized ); } addtoagg = VIK_AGGREGATE_LAYER(vl); replace_iter = &iter; } } else { /* a sublayer is selected, first get its parent (layer), then find the layer's parent (aggr. layer) */ VikLayer *vl = VIK_LAYER(vik_treeview_item_get_parent ( vlp->vt, &iter )); replace_iter = &(vl->iter); g_assert ( vl->realized ); VikLayer *grandpa = (vik_treeview_item_get_parent ( vlp->vt, &(vl->iter) ) ); if (IS_VIK_AGGREGATE_LAYER(grandpa)) addtoagg = VIK_AGGREGATE_LAYER(grandpa); else { addtoagg = vlp->toplayer; replace_iter = &grandpa->iter; } } if ( replace_iter ) vik_aggregate_layer_insert_layer ( addtoagg, l, replace_iter ); else vik_aggregate_layer_add_layer ( addtoagg, l ); } vik_layers_panel_emit_update ( vlp ); }
static void aggregate_layer_analyse ( menu_array_values values ) { VikAggregateLayer *val = VIK_AGGREGATE_LAYER ( values[MA_VAL] ); // There can only be one! if ( val->tracks_analysis_dialog ) return; val->tracks_analysis_dialog = vik_trw_layer_analyse_this ( VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(val)), VIK_LAYER(val)->name, VIK_LAYER(val), NULL, aggregate_layer_track_create_list, aggregate_layer_analyse_close ); }
static void aggregate_layer_analyse ( gpointer data[2] ) { VikAggregateLayer *val = VIK_AGGREGATE_LAYER(data[0]); // There can only be one! if ( val->tracks_analysis_dialog ) return; val->tracks_analysis_dialog = vik_trw_layer_analyse_this ( VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(val)), VIK_LAYER(val)->name, VIK_LAYER(val), NULL, aggregate_layer_track_create_list, aggregate_layer_analyse_close ); }
static VikAggregateLayer *aggregate_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ) { #define alm_size (*(gint *)data) #define alm_next \ len -= sizeof(gint) + alm_size; \ data += sizeof(gint) + alm_size; VikAggregateLayer *rv = vik_aggregate_layer_new(); VikLayer *child_layer; vik_layer_unmarshall_params ( VIK_LAYER(rv), data+sizeof(gint), alm_size, vvp ); alm_next; while (len>0) { child_layer = vik_layer_unmarshall ( data + sizeof(gint), alm_size, vvp ); if (child_layer) { rv->children = g_list_append ( rv->children, child_layer ); g_signal_connect_swapped ( G_OBJECT(child_layer), "update", G_CALLBACK(vik_layer_emit_update_secondary), rv ); } alm_next; } // g_print("aggregate_layer_unmarshall ended with len=%d\n", len); return rv; #undef alm_size #undef alm_next }
/** * vik_aggregate_layer_add_layer: * @allow_reordering: should be set for GUI interactions, * whereas loading from a file needs strict ordering and so should be FALSE */ void vik_aggregate_layer_add_layer ( VikAggregateLayer *val, VikLayer *l, gboolean allow_reordering ) { GtkTreeIter iter; VikLayer *vl = VIK_LAYER(val); // By default layers go to the top gboolean put_above = TRUE; if ( allow_reordering ) { // These types are 'base' types in that you what other information on top if ( l->type == VIK_LAYER_MAPS || l->type == VIK_LAYER_DEM || l->type == VIK_LAYER_GEOREF ) put_above = FALSE; } if ( vl->realized ) { vik_treeview_add_layer ( vl->vt, &(vl->iter), &iter, l->name, val, put_above, l, l->type, l->type); if ( ! l->visible ) vik_treeview_item_set_visible ( vl->vt, &iter, FALSE ); vik_layer_realize ( l, vl->vt, &iter ); if ( val->children == NULL ) vik_treeview_expand ( vl->vt, &(vl->iter) ); } if ( put_above ) val->children = g_list_append ( val->children, l ); else val->children = g_list_prepend ( val->children, l ); g_signal_connect_swapped ( G_OBJECT(l), "update", G_CALLBACK(vik_layer_emit_update_secondary), val ); }
static VikCoordLayer *coord_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ) { VikCoordLayer *rv = coord_layer_new ( vvp ); vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp ); coord_layer_update_gc ( rv, vvp ); return rv; }
VikAggregateLayer *vik_aggregate_layer_new () { VikAggregateLayer *val = VIK_AGGREGATE_LAYER ( g_object_new ( VIK_AGGREGATE_LAYER_TYPE, NULL ) ); vik_layer_set_type ( VIK_LAYER(val), VIK_LAYER_AGGREGATE ); val->children = NULL; return val; }
static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp ) { if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF) return FALSE; if ( event->button == 1 ) { if ( vgl->mpp_easting < (VIK_VIEWPORT_MAX_ZOOM / 1.05) && vgl->mpp_northing < (VIK_VIEWPORT_MAX_ZOOM / 1.05) ) { vgl->mpp_easting *= 1.01; vgl->mpp_northing *= 1.01; } } else { if ( vgl->mpp_easting > (VIK_VIEWPORT_MIN_ZOOM * 1.05) && vgl->mpp_northing > (VIK_VIEWPORT_MIN_ZOOM * 1.05) ) { vgl->mpp_easting /= 1.01; vgl->mpp_northing /= 1.01; } } vik_viewport_set_xmpp ( vvp, vgl->mpp_easting ); vik_viewport_set_ympp ( vvp, vgl->mpp_northing ); vik_layer_emit_update ( VIK_LAYER(vgl) ); return TRUE; }
static void layers_panel_finalize ( GObject *gob ) { VikLayersPanel *vlp = VIK_LAYERS_PANEL ( gob ); g_object_unref ( VIK_LAYER(vlp->toplayer) ); g_object_unref ( G_OBJECT(vlp->popup_factory) ); G_OBJECT_CLASS(parent_class)->finalize(gob); }
void vik_aggregate_layer_insert_layer ( VikAggregateLayer *val, VikLayer *l, GtkTreeIter *replace_iter ) { GtkTreeIter iter; VikLayer *vl = VIK_LAYER(val); if ( vl->realized ) { vik_treeview_insert_layer ( vl->vt, &(vl->iter), &iter, l->name, val, l, l->type, l->type, replace_iter ); if ( ! l->visible ) vik_treeview_item_set_visible ( vl->vt, &iter, FALSE ); vik_layer_realize ( l, vl->vt, &iter ); if ( val->children == NULL ) vik_treeview_expand ( vl->vt, &(vl->iter) ); } if (replace_iter) { GList *theone = g_list_find ( val->children, vik_treeview_item_get_pointer ( vl->vt, replace_iter ) ); val->children = g_list_insert ( val->children, l, g_list_position(val->children,theone)+1 ); } else { // Effectively insert at 'end' of the list to match how displayed in the treeview // - but since it is drawn from 'bottom first' it is actually the first in the child list // This ordering is especially important if it is a map or similar type, // which needs be drawn first for the layering draw method to work properly. // ATM this only happens when a layer is drag/dropped to the end of an aggregate layer val->children = g_list_prepend ( val->children, l ); } g_signal_connect_swapped ( G_OBJECT(l), "update", G_CALLBACK(vik_layer_emit_update_secondary), val ); }
/** * Run geotagging process in a separate thread */ static int trw_layer_geotag_thread ( geotag_options_t *options, gpointer threaddata ) { guint total = g_list_length(options->files), done = 0; // TODO decide how to report any issues to the user ... // Foreach file attempt to geotag it while ( options->files ) { options->image = (gchar *) ( options->files->data ); trw_layer_geotag_process ( options ); options->files = options->files->next; // Update thread progress and detect stop requests int result = a_background_thread_progress ( threaddata, ((gdouble) ++done) / total ); if ( result != 0 ) return -1; /* Abort thread */ } if ( options->redraw ) { if ( IS_VIK_LAYER(options->vtl) ) { // Ensure any new images get shown trw_layer_verify_thumbnails ( options->vtl, NULL ); // NB second parameter not used ATM // Force redraw as verify only redraws if there are new thumbnails (they may already exist) vik_layer_emit_update ( VIK_LAYER(options->vtl), TRUE ); // Update from background } } return 0; }
void vik_aggregate_layer_realize ( VikAggregateLayer *val, VikTreeview *vt, GtkTreeIter *layer_iter ) { GList *i = val->children; GtkTreeIter iter; VikLayer *vl = VIK_LAYER(val); VikLayer *vli; while ( i ) { vli = VIK_LAYER(i->data); vik_treeview_add_layer ( vl->vt, layer_iter, &iter, vli->name, val, TRUE, vli, vli->type, vli->type ); if ( ! vli->visible ) vik_treeview_item_set_visible ( vl->vt, &iter, FALSE ); vik_layer_realize ( vli, vl->vt, &iter ); i = i->next; } }
GList *vik_aggregate_layer_get_all_layers_of_type(VikAggregateLayer *val, GList *layers, VikLayerTypeEnum type, gboolean include_invisible) { GList *l = layers; GList *children = val->children; VikLayer *vl; if (!children) return layers; // Where appropriate *don't* include non-visible layers while (children) { vl = VIK_LAYER(children->data); if (vl->type == VIK_LAYER_AGGREGATE ) { // Don't even consider invisible aggregrates, unless told to if (vl->visible || include_invisible) l = vik_aggregate_layer_get_all_layers_of_type(VIK_AGGREGATE_LAYER(children->data), l, type, include_invisible); } else if (vl->type == type) { if (vl->visible || include_invisible) l = g_list_prepend(l, children->data); /* now in top down order */ } else if (type == VIK_LAYER_TRW) { /* GPS layers contain TRW layers. cf with usage in file.c */ if (VIK_LAYER(children->data)->type == VIK_LAYER_GPS) { if (VIK_LAYER(children->data)->visible || include_invisible) { if (!vik_gps_layer_is_empty(VIK_GPS_LAYER(children->data))) { /* can not use g_list_concat due to wrong copy method - crashes if used a couple times !! l = g_list_concat (l, vik_gps_layer_get_children (VIK_GPS_LAYER(children->data))); */ /* create own copy method instead :( */ GList *gps_trw_layers = (GList *)vik_gps_layer_get_children (VIK_GPS_LAYER(children->data)); int n_layers = g_list_length (gps_trw_layers); int layer = 0; for ( layer = 0; layer < n_layers; layer++) { l = g_list_prepend(l, gps_trw_layers->data); gps_trw_layers = gps_trw_layers->next; } g_list_free(gps_trw_layers); } } } } children = children->next; } return l; }
static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ) { VikGeorefLayer *rv = georef_layer_new ( vvp ); vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp ); if (rv->image) { georef_layer_load_image ( rv, vvp, TRUE ); } return rv; }
static void aggregate_layer_change_coord_mode ( VikAggregateLayer *val, VikCoordMode mode ) { GList *iter = val->children; while ( iter ) { vik_layer_change_coord_mode ( VIK_LAYER(iter->data), mode ); iter = iter->next; } }
static void aggregate_layer_child_visible_toggle ( menu_array_values values ) { VikAggregateLayer *val = VIK_AGGREGATE_LAYER ( values[MA_VAL] ); VikLayersPanel *vlp = VIK_LAYERS_PANEL ( values[MA_VLP] ); VikLayer *vl; // Loop around all (child) layers applying visibility setting // This does not descend the tree if there are aggregates within aggregrate - just the first level of layers held GList *iter = val->children; while ( iter ) { vl = VIK_LAYER ( iter->data ); vl->visible = !vl->visible; // Also set checkbox on/off vik_treeview_item_toggle_visible ( vik_layers_panel_get_treeview ( vlp ), &(vl->iter) ); iter = iter->next; } // Redraw as view may have changed vik_layer_emit_update ( VIK_LAYER ( val ) ); }
/** * Delete a child layer from the aggregate layer */ gboolean vik_aggregate_layer_delete_layer ( VikAggregateLayer *val, VikLayer *vl ) { gboolean was_visible = vl->visible; if ( vl->realized && &vl->iter ) vik_treeview_item_delete ( VIK_LAYER(val)->vt, &vl->iter ); aggregate_layer_delete_common ( val, vl ); return was_visible; }
static VikDEMLayer *dem_layer_new ( VikViewport *vvp ) { VikDEMLayer *vdl = VIK_DEM_LAYER ( g_object_new ( VIK_DEM_LAYER_TYPE, NULL ) ); vik_layer_set_type ( VIK_LAYER(vdl), VIK_LAYER_DEM ); vdl->files = NULL; vdl->gcs = g_malloc(sizeof(GdkGC *)*DEM_N_HEIGHT_COLORS); vdl->gcsgradient = g_malloc(sizeof(GdkGC *)*DEM_N_GRADIENT_COLORS); /* make new gcs only if we need it (copy layer -> use old) */ // Ensure the base GC is available so the default colour can be applied if ( vvp ) vdl->gcs[0] = vik_viewport_new_gc ( vvp, "#0000FF", 1 ); vik_layer_set_defaults ( VIK_LAYER(vdl), vvp ); return vdl; }
VikLayer *vik_layers_panel_get_layer_of_type ( VikLayersPanel *vlp, gint type ) { VikLayer *rv = vik_layers_panel_get_selected ( vlp ); if ( rv == NULL || rv->type != type ) if ( VIK_LAYER(vlp->toplayer)->visible ) return vik_aggregate_layer_get_top_visible_layer_of_type ( vlp->toplayer, type ); else return NULL; else return rv; }