--- trunk/src/map-tool.c 2009/10/27 08:38:31 144 +++ trunk/src/map-tool.c 2009/11/03 08:38:23 155 @@ -22,6 +22,13 @@ * http://topo.geofabrik.de/trail/${z}/${x}/${y}.png 8-15 */ +/* + * TODO: + * - draw caches only once + * - prefer duplicates from selected files + * - make semi-transparent caches selectable + */ + #include "gpxview.h" #include "converter.h" #include // for isnan @@ -109,14 +116,18 @@ static gboolean map_gps_update(gpointer data) { map_context_t *context = (map_context_t*)data; + static gboolean goto_is_enabled = FALSE; /* get reference position ... */ pos_t *refpos = get_pos(context->appdata); gboolean ok = (refpos!= NULL) && !isnan(refpos->lat) && !isnan(refpos->lon); /* ... and enable "goto" button if it's valid */ - osm_gps_map_osd_enable_gps (OSM_GPS_MAP(context->widget), - OSM_GPS_MAP_OSD_CALLBACK(ok?cb_map_gps:NULL), context); + if(ok != goto_is_enabled) { + osm_gps_map_osd_enable_gps (OSM_GPS_MAP(context->widget), + OSM_GPS_MAP_OSD_CALLBACK(ok?cb_map_gps:NULL), context); + goto_is_enabled = ok; + } if(ok) { float heading = NAN; @@ -131,6 +142,8 @@ radius = dist2pixel(context, eph/1000, refpos->lat); } + /* TODO: in order to save energy: only draw if state actually changed */ + g_object_set(context->widget, "gps-track-highlight-radius", radius, NULL); osm_gps_map_draw_gps(OSM_GPS_MAP(context->widget), refpos->lat, refpos->lon, heading); @@ -140,8 +153,9 @@ return TRUE; } -static void map_draw_cache(GtkWidget *map, cache_t *cache) { - GdkPixbuf *icon = icon_get(ICON_CACHE_TYPE, cache->type); +static void map_draw_cache(GtkWidget *map, cache_t *cache, gboolean semi) { + GdkPixbuf *icon = icon_get(semi?ICON_CACHE_TYPE_SEMI:ICON_CACHE_TYPE, + cache->type); /* check if there's also an overwritten coordinate */ if(cache->notes && cache->notes->override) { @@ -159,7 +173,9 @@ } } -static void map_draw_gpx(appdata_t *appdata, GtkWidget *map, gpx_t *gpx) { +static void map_draw_gpx(appdata_t *appdata, cache_display_t *caches, + GtkWidget *map, gpx_t *gpx, + cache_t *nav, gboolean semi) { if(!gpx->notes_loaded) { notes_load_all(appdata, gpx); gpx->notes_loaded = TRUE; @@ -167,7 +183,18 @@ cache_t *cache = gpx->cache; while(cache) { - map_draw_cache(map, cache); + /* search if we have that cache already in our list/displayed */ + int i=0; + while(caches[i].id && (strcmp(caches[i].id, cache->id) != 0)) + i++; + + if(!caches[i].id) { + /* if nav is given draw all other caches semitransparent. */ + /* if nav is not given do what semi sais */ + map_draw_cache(map, cache, nav?(cache != nav):semi); + caches[i].id = cache->id; + } + cache = cache->next; } } @@ -176,6 +203,23 @@ static void map_setup(map_context_t *context) { char *name = NULL; + int cache_num = gpx_total_caches_global(context->appdata->gpx); + + if(context->caches_displayed && (cache_num != context->cache_list_len)) { + // printf("re-alloc because %p %d/%d\n", context->caches_displayed, + // cache_num, context->cache_list_len); + g_free(context->caches_displayed); + context->caches_displayed = NULL; + context->cache_list_len = 0; + } + + /* allocate buffer */ + if(cache_num && !context->caches_displayed) { + context->cache_list_len = cache_num; + context->caches_displayed = g_new0(cache_display_t, cache_num+1); + printf("allocated space to handle %d map icons\n", cache_num); + } + if(!context->appdata->cur_gpx && !context->appdata->cur_cache) { if(context->state != MAP_ALL) { printf("map_setup(ALL)\n"); @@ -185,15 +229,25 @@ osm_gps_map_osd_clear_nav (OSM_GPS_MAP(context->widget)); #endif - /* clear all existing ccahe images */ + /* clear all existing cache images */ osm_gps_map_clear_images (OSM_GPS_MAP(context->widget)); + memset(context->caches_displayed, 0, + (cache_num+1) * sizeof(cache_display_t)); - /* draw all geocaches */ + /* draw all geocaches and none is semi-transparent */ gpx_t *gpx = context->appdata->gpx; while(gpx) { - map_draw_gpx(context->appdata, context->widget, gpx); + map_draw_gpx(context->appdata, context->caches_displayed, + context->widget, gpx, NULL, FALSE); gpx = gpx->next; } + + { + int i=0; + while(context->caches_displayed[i].id) i++; + printf("number of caches actually displayed: %d\n", i); + } + name = g_strdup(_("all")); context->state = MAP_ALL; } @@ -208,16 +262,29 @@ /* clear all existing ccahe images */ osm_gps_map_clear_images (OSM_GPS_MAP(context->widget)); + memset(context->caches_displayed, 0, + (cache_num+1) * sizeof(cache_display_t)); + + /* draw all geocaches and all other gpx files are semi-transparent */ + map_draw_gpx(context->appdata, context->caches_displayed, + context->widget, context->appdata->cur_gpx, NULL, FALSE); + + gpx_t *gpx = context->appdata->gpx; + while(gpx) { + if(gpx != context->appdata->cur_gpx) + map_draw_gpx(context->appdata, context->caches_displayed, + context->widget, gpx, NULL, TRUE); + + gpx = gpx->next; + } - map_draw_gpx(context->appdata, context->widget, - context->appdata->cur_gpx); name = g_strdup(context->appdata->cur_gpx->name); context->state = MAP_GPX; } } else { cache_t *cache = context->appdata->cur_cache; - printf("map_setp(CACHE)\n"); + printf("map_setup(CACHE)\n"); /* no balloons in this mode */ context->balloon = NULL; @@ -225,8 +292,17 @@ /* clear all existing ccahe images */ osm_gps_map_clear_images (OSM_GPS_MAP(context->widget)); + memset(context->caches_displayed, 0, + (cache_num+1) * sizeof(cache_display_t)); - map_draw_cache(context->widget, cache); + /* draw all geocaches and all but selected one are semi-transparent */ + gpx_t *gpx = context->appdata->gpx; + while(gpx) { + map_draw_gpx(context->appdata, context->caches_displayed, + context->widget, gpx, cache, FALSE); + gpx = gpx->next; + } + name = g_strdup(cache->name); context->state = MAP_CACHE; @@ -402,6 +478,7 @@ gdk_pixbuf_get_height(buf)); // Create the new Context for the ImageSurface + g_assert(image_surface); cairo_t *context = cairo_create(image_surface); // Draw the image on the new Context @@ -664,6 +741,12 @@ #endif gtk_timeout_remove(context->handler_id); + gps_unregister_callback(appdata, context->cb_id); + + if(context->caches_displayed) { + g_free(context->caches_displayed); + context->caches_displayed = NULL; + } g_free(context); appdata->map.context = NULL; @@ -707,6 +790,12 @@ #endif } +/* callback called by the gps layer whenever gps state changes */ +static void +gps_callback(struct gps_state *state, gpointer data) { + printf("map: gps callback\n"); +} + void map(appdata_t *appdata) { map_context_t *context = NULL; @@ -797,6 +886,7 @@ /* install handler for timed updates of the gps button */ context->handler_id = gtk_timeout_add(1000, map_gps_update, context); + context->cb_id = gps_register_callback(appdata, gps_callback, context); #if MAEMO_VERSION_MAJOR == 5 /* prevent some of the main screen things */