--- src/map.c 2008/12/09 20:06:06 1 +++ trunk/src/map.c 2009/02/06 12:06:30 54 @@ -56,6 +56,15 @@ str = g_strdup_printf("%s #%ld", item_str, id); /* add some tags ... */ + /* + * XXX Should we just try to present only the name or the ref (or the + * alt_name, old_name, whatever) here? Hurling a load of tags in the + * user's face in some unpredictable, uninformative order isn't very + * friendly. + * + * Actually, a tag_short_desc() function would be useful in dialogs + * nd user messages too. + */ while(tag) { if(!collision && info_tag_key_collision(tags, tag)) collision = TRUE; @@ -146,7 +155,8 @@ float radius = map->style->highlight.width + map->style->node.radius; if(!node->ways) radius += map->style->node.border_radius; - if(node->icon_buf && map->style->icon.enable) { + if(node->icon_buf && map->style->icon.enable && + !appdata->settings->no_icons) { gint w = gdk_pixbuf_get_width(map_item->node->icon_buf); gint h = gdk_pixbuf_get_height(map_item->node->icon_buf); /* icons are technically square, so a radius slightly bigger */ @@ -208,6 +218,8 @@ diff.x = node_chain->node->lpos.x - last->lpos.x; diff.y = node_chain->node->lpos.y - last->lpos.y; + /* only draw arrow if there's sufficient space */ + /* TODO: what if there's not enough space anywhere? */ float len = sqrt(pow(diff.x, 2)+pow(diff.y, 2)); if(len > map->style->highlight.arrow_limit*arrow_width) { len /= arrow_width; @@ -366,7 +378,8 @@ map_item->type = MAP_TYPE_NODE; map_item->node = node; - if(!node->icon_buf || !map->style->icon.enable) + if(!node->icon_buf || !map->style->icon.enable || + map->appdata->settings->no_icons) map_item->item = canvas_circle_new(map, CANVAS_GROUP_NODES, node->lpos.x, node->lpos.y, radius, width, fill, border); else @@ -430,7 +443,7 @@ map_item->way = way; if(way->draw.flags & OSM_DRAW_FLAG_AREA) { - if(map->style->area.opaque) + if(map->style->area.color & 0xff) map_item->item = canvas_polygon_new(map, group, points, width, color, fill_color); else @@ -442,6 +455,10 @@ canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max); + if (group != CANVAS_GROUP_WAYS_OL) + if (way->draw.dashed) + canvas_item_set_dashed(map_item->item, width, way->draw.dash_length); + /* attach map_item to ways map_item_chain */ map_item_chain_t **chain = &way->map_item_chain; while(*chain) chain = &(*chain)->next; @@ -458,7 +475,7 @@ void map_show_node(map_t *map, node_t *node) { map_node_new(map, node, map->style->node.radius, 0, - RGB2CANVAS(map->style->node.color), 0); + map->style->node.color, 0); } void map_way_draw(map_t *map, way_t *way) { @@ -473,7 +490,7 @@ if(nodes == 1) { /* draw a single dot where this single node is */ map_way_single_new(map, way, map->style->node.radius, 0, - RGB2CANVAS(map->style->node.color), 0); + map->style->node.color, 0); } else { canvas_points_t *points = canvas_points_new(nodes); @@ -509,14 +526,13 @@ map_node_new(map, node, map->style->node.radius, map->style->node.border_radius, - RGBA2CANVAS(map->style->node.fill_color, - map->style->node.has_fill_color?0xff:0x00), - RGB2CANVAS(map->style->node.color)); + map->style->node.fill_color, + map->style->node.color); else if(map->style->node.show_untagged || osm_node_has_tag(node)) map_node_new(map, node, map->style->node.radius, 0, - RGB2CANVAS(map->style->node.color), 0); + map->style->node.color, 0); } static void map_item_draw(map_t *map, map_item_t *map_item) { @@ -598,9 +614,8 @@ canvas_points_t *points = canvas_points_new(5); /* don't draw frisket at all if it's completely transparent */ - if(map->style->frisket.opaque) { - elemstyle_color_t color = - (map->style->background.color<<8) | map->style->frisket.opaque; + if(map->style->frisket.color & 0xff) { + elemstyle_color_t color = map->style->frisket.color; float mult = map->style->frisket.mult; @@ -765,7 +780,7 @@ return NULL; } - if(map_item->highlight) + if(map_item->highlight) printf(" item is highlight\n"); switch(map_item->type) { @@ -784,7 +799,7 @@ } /* get the real item (no highlight) at x, y */ -static map_item_t *map_real_item_at(map_t *map, gint x, gint y) { +map_item_t *map_real_item_at(map_t *map, gint x, gint y) { map_item_t *map_item = map_item_at(map, x, y); /* no item or already a real one */ @@ -969,6 +984,77 @@ map->state->scroll_offset.y = sy; } #endif // #if 0 + +/* + * Scroll the map to a point if that point is currently offscreen. + */ +void map_scroll_to_if_offscreen(map_t *map, lpos_t *lpos) { + + // Ignore anything outside the working area + if (!(map && map->appdata && map->appdata->osm)) { + return; + } + gint min_x, min_y, max_x, max_y; + min_x = map->appdata->osm->bounds->min.x; + min_y = map->appdata->osm->bounds->min.y; + max_x = map->appdata->osm->bounds->max.x; + max_y = map->appdata->osm->bounds->max.y; + if ( (lpos->x > max_x) || (lpos->x < min_x) + || (lpos->y > max_y) || (lpos->y < min_y)) { + printf("cannot scroll to (%d, %d): outside the working area\n", + lpos->x, lpos->y); + return; + } + + // Viewport dimensions in canvas space + gdouble zoom = goo_canvas_get_scale(GOO_CANVAS(map->canvas)); + GtkAllocation *a = >K_WIDGET(map->canvas)->allocation; + gdouble aw = a->width / zoom; + gdouble ah = a->height / zoom; + + // Is the point still onscreen? + gboolean vert_recentre_needed = FALSE; + gboolean horiz_recentre_needed = FALSE; + gint sx, sy; + canvas_get_scroll_offsets(map->canvas, &sx, &sy); + gint viewport_left = (sx/zoom); + gint viewport_right = (sx/zoom)+aw; + gint viewport_top = (sy/zoom); + gint viewport_bottom = (sy/zoom)+ah; + if (lpos->x > viewport_right) { + printf("** off right edge (%d > %d)\n", lpos->x, viewport_right); + horiz_recentre_needed = TRUE; + } + if (lpos->x < viewport_left) { + printf("** off left edge (%d < %d)\n", lpos->x, viewport_left); + horiz_recentre_needed = TRUE; + } + if (lpos->y > viewport_bottom) { + printf("** off bottom edge (%d > %d)\n", lpos->y, viewport_bottom); + vert_recentre_needed = TRUE; + } + if (lpos->y < viewport_top) { + printf("** off top edge (%d < %d)\n", lpos->y, viewport_top); + vert_recentre_needed = TRUE; + } + + if (horiz_recentre_needed || vert_recentre_needed) { + gint new_sx, new_sy; +#if 0 + // Only recentre the drifting axis. + new_sx = horiz_recentre_needed ? zoom*(lpos->x - (aw/2)) : sx; + new_sy = vert_recentre_needed ? zoom*(lpos->y - (ah/2)) : sy; + // Not sure about this. I don't think it really buys us anything. +#else + // Just centre both at once + new_sx = zoom * (lpos->x - (aw/2)); + new_sy = zoom * (lpos->y - (ah/2)); +#endif + map_limit_scroll(map, &new_sx, &new_sy); + canvas_scroll_to(map->canvas, new_sx, new_sy); + } +} + #endif // #ifdef USE_GOOCANVAS /* Deselects the current way or node if its zoom_max @@ -1505,7 +1591,7 @@ /* reduce update frequency on hildon to keep screen update fluid */ static guint32 last_time = 0; - if(event->time - last_time < 100) return FALSE; + if(event->time - last_time < 250) return FALSE; last_time = event->time; #endif @@ -1549,7 +1635,7 @@ case MAP_ACTION_NODE_ADD: map_hl_cursor_draw(map, x, y, FALSE, map->style->node.radius); break; - + case MAP_ACTION_WAY_ADD: map_hl_cursor_draw(map, x, y, FALSE, map->style->node.radius); map_touchnode_update(appdata, x, y); @@ -1557,13 +1643,13 @@ case MAP_ACTION_WAY_NODE_ADD: map_hl_cursor_clear(map); - map_item_t *item = map_item_at(map, x, y); + map_item_t *item = map_real_item_at(map, x, y); if(item) map_edit_way_node_add_highlight(map, item, x, y); break; case MAP_ACTION_WAY_CUT: map_hl_cursor_clear(map); - item = map_item_at(map, x, y); + item = map_real_item_at(map, x, y); if(item) map_edit_way_cut_highlight(map, item, x, y); break; @@ -1654,6 +1740,11 @@ map_t *map = appdata->map = g_new0(map_t, 1); map->style = style_load(appdata, appdata->settings->style); + if(!map->style) { + errorf(NULL, _("Unable to load valid style, terminating.")); + g_free(map); + return NULL; + } if(appdata->project && appdata->project->map_state) { printf("Using projects map state\n"); @@ -1690,9 +1781,12 @@ g_object_set(G_OBJECT(map->canvas), "anchor", GTK_ANCHOR_CENTER, NULL); g_object_set(G_OBJECT(map->canvas), "background-color-rgb", - map->style->background.color, NULL); + map->style->background.color >> 8, NULL); GooCanvasItem *root = goo_canvas_get_root_item(GOO_CANVAS(map->canvas)); + g_object_set(G_OBJECT(root), "antialias", + appdata->settings->no_antialias?CAIRO_ANTIALIAS_NONE: + CAIRO_ANTIALIAS_DEFAULT, NULL); /* create the groups */ canvas_group_t group; @@ -1802,6 +1896,12 @@ void map_paint(appdata_t *appdata) { map_t *map = appdata->map; + /* user may have changes antialias settings */ + GooCanvasItem *root = goo_canvas_get_root_item(GOO_CANVAS(map->canvas)); + g_object_set(G_OBJECT(root), "antialias", + appdata->settings->no_antialias?CAIRO_ANTIALIAS_NONE: + CAIRO_ANTIALIAS_DEFAULT, NULL); + josm_elemstyles_colorize_world(map->style, appdata->osm); map_draw(map, appdata->osm); } @@ -1933,6 +2033,8 @@ /* deleting the selected item de-selects it ... */ map_item_deselect(appdata); + undo_remember_delete(appdata, item.type, item.ptr); + switch(item.type) { case MAP_TYPE_NODE: printf("request to delete node #%ld\n", item.node->id); @@ -2107,7 +2209,7 @@ if(lpos) appdata->track.gps_item = canvas_circle_new(appdata->map, CANVAS_GROUP_GPS, lpos->x, lpos->y, appdata->map->style->track.width/2.0, 0, - RGB2CANVAS(appdata->map->style->track.gps_color), NO_COLOR); + appdata->map->style->track.gps_color, NO_COLOR); } /* ------------------- map background ------------------ */ @@ -2193,3 +2295,4 @@ gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE); } +// vim:et:ts=8:sw=2:sts=2:ai