Diff of /trunk/src/map.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 161 by harbaum, Sat Apr 11 11:28:56 2009 UTC revision 234 by harbaum, Mon Jul 20 20:15:10 2009 UTC
# Line 55  static void map_statusbar(map_t *map, ma Line 55  static void map_statusbar(map_t *map, ma
55    
56    gboolean collision = FALSE;    gboolean collision = FALSE;
57    tag_t *tags = tag;    tag_t *tags = tag;
58      while(tag) {
59    if(id == ID_ILLEGAL)      if(!collision && info_tag_key_collision(tags, tag))
60      str = g_strdup_printf(_("Unknown item"));        collision = TRUE;
61    else {      tag = tag->next;
     str = g_strdup_printf("%s #" ITEM_ID_FORMAT, 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;  
   
       /* we don't have much space, so ignore created_by tag */  
       if(!osm_is_creator_tag(tag)) {  
         char *old = str;  
         str = g_strdup_printf("%s, %s=%s", old, tag->key, tag->value);  
         g_free(old);  
       }  
       tag = tag->next;  
     }  
62    }    }
63    
64      str = osm_object_get_speaking_name(&map_item->object);
65    statusbar_set(map->appdata, str, collision);    statusbar_set(map->appdata, str, collision);
66    g_free(str);    g_free(str);
67  }  }
# Line 167  static void map_node_select(appdata_t *a Line 144  static void map_node_select(appdata_t *a
144      gint h = gdk_pixbuf_get_height(map_item->object.node->icon_buf);      gint h = gdk_pixbuf_get_height(map_item->object.node->icon_buf);
145      /* icons are technically square, so a radius slightly bigger */      /* icons are technically square, so a radius slightly bigger */
146      /* than sqrt(2)*MAX(w,h) should fit nicely */      /* than sqrt(2)*MAX(w,h) should fit nicely */
147      radius =  0.75 * map->style->icon.scale * ((w>h)?w:h);      radius = 0.75 * map->style->icon.scale * ((w>h)?w:h);
148    }    }
149    
150      radius *= map->state->detail;
151    map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,    map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,
152                      x, y, radius, map->style->highlight.color);                      x, y, radius, map->style->highlight.color);
153    
# Line 198  void map_way_select(appdata_t *appdata, Line 176  void map_way_select(appdata_t *appdata,
176    map_statusbar(map, map_item);    map_statusbar(map, map_item);
177    icon_bar_map_item_selected(appdata, map_item, TRUE);    icon_bar_map_item_selected(appdata, map_item, TRUE);
178    gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, TRUE);    gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, TRUE);
179    
180    gint arrow_width = (map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)?    gint arrow_width = ((map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)?
181      map->style->highlight.width + map_item->object.way->draw.bg.width/2:                        map->style->highlight.width + map_item->object.way->draw.bg.width/2:
182      map->style->highlight.width + map_item->object.way->draw.width/2;                        map->style->highlight.width + map_item->object.way->draw.width/2)
183        * map->state->detail;
184    
185    node_chain_t *node_chain = map_item->object.way->node_chain;    node_chain_t *node_chain = map_item->object.way->node_chain;
186    node_t *last = NULL;    node_t *last = NULL;
# Line 259  void map_way_select(appdata_t *appdata, Line 238  void map_way_select(appdata_t *appdata,
238        gint y = node_chain->node->lpos.y;        gint y = node_chain->node->lpos.y;
239    
240        map_hl_circle_new(map, CANVAS_GROUP_NODES_IHL, new_map_item,        map_hl_circle_new(map, CANVAS_GROUP_NODES_IHL, new_map_item,
241                          x, y, map->style->node.radius,                          x, y, map->style->node.radius * map->state->detail,
242                          map->style->highlight.node_color);                          map->style->highlight.node_color);
243      }      }
244    
# Line 287  void map_way_select(appdata_t *appdata, Line 266  void map_way_select(appdata_t *appdata,
266      new_map_item->highlight = TRUE;      new_map_item->highlight = TRUE;
267    
268      map_hl_polyline_new(map, CANVAS_GROUP_WAYS_HL, new_map_item, points,      map_hl_polyline_new(map, CANVAS_GROUP_WAYS_HL, new_map_item, points,
269                  (map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)?                   ((map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)?
270                  2*map->style->highlight.width + map_item->object.way->draw.bg.width:                   2*map->style->highlight.width + map_item->object.way->draw.bg.width:
271                  2*map->style->highlight.width + map_item->object.way->draw.width,                   2*map->style->highlight.width + map_item->object.way->draw.width)
272                  map->style->highlight.color);                  * map->state->detail, map->style->highlight.color);
273    
274      canvas_points_free(points);      canvas_points_free(points);
275    }    }
276  }  }
# Line 400  void map_item_deselect(appdata_t *appdat Line 379  void map_item_deselect(appdata_t *appdat
379        osm_tags_free(appdata->map->last_node_tags);        osm_tags_free(appdata->map->last_node_tags);
380    
381      appdata->map->last_node_tags =      appdata->map->last_node_tags =
382        osm_tags_copy(appdata->map->selected.object.node->tag, FALSE);        osm_tags_copy(appdata->map->selected.object.node->tag);
383    } else if(appdata->map->selected.object.type == WAY) {    } else if(appdata->map->selected.object.type == WAY) {
384      if(appdata->map->last_way_tags)      if(appdata->map->last_way_tags)
385        osm_tags_free(appdata->map->last_way_tags);        osm_tags_free(appdata->map->last_way_tags);
386    
387      appdata->map->last_way_tags =      appdata->map->last_way_tags =
388        osm_tags_copy(appdata->map->selected.object.way->tag, FALSE);        osm_tags_copy(appdata->map->selected.object.way->tag);
389    }    }
390    
391    /* remove statusbar message */    /* remove statusbar message */
# Line 472  static canvas_item_t *map_node_new(map_t Line 451  static canvas_item_t *map_node_new(map_t
451    else    else
452      map_item->item = canvas_image_new(map->canvas, CANVAS_GROUP_NODES,      map_item->item = canvas_image_new(map->canvas, CANVAS_GROUP_NODES,
453        node->icon_buf,        node->icon_buf,
454        node->lpos.x - map->style->icon.scale/2 *        node->lpos.x - map->style->icon.scale/2 * map->state->detail *
455                        gdk_pixbuf_get_width(node->icon_buf),                        gdk_pixbuf_get_width(node->icon_buf),
456        node->lpos.y - map->style->icon.scale/2 *        node->lpos.y - map->style->icon.scale/2 * map->state->detail *
457                        gdk_pixbuf_get_height(node->icon_buf),                        gdk_pixbuf_get_height(node->icon_buf),
458                map->style->icon.scale,map->style->icon.scale);                        map->state->detail * map->style->icon.scale,
459                          map->state->detail * map->style->icon.scale);
460    
461    canvas_item_set_zoom_max(map_item->item, node->zoom_max);    canvas_item_set_zoom_max(map_item->item,
462                               node->zoom_max / (2 * map->state->detail));
463    
464    /* attach map_item to nodes map_item_chain */    /* attach map_item to nodes map_item_chain */
465    map_item_chain_t **chain = &node->map_item_chain;    map_item_chain_t **chain = &node->map_item_chain;
# Line 540  static canvas_item_t *map_way_new(map_t Line 521  static canvas_item_t *map_way_new(map_t
521      map_item->item = canvas_polyline_new(map->canvas, group, points, width, color);      map_item->item = canvas_polyline_new(map->canvas, group, points, width, color);
522    }    }
523    
524    canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max);    canvas_item_set_zoom_max(map_item->item,
525                               way->draw.zoom_max / (2 * map->state->detail));
526    
527    /* a ways outline itself is never dashed */    /* a ways outline itself is never dashed */
528    if (group != CANVAS_GROUP_WAYS_OL)    if (group != CANVAS_GROUP_WAYS_OL)
# Line 590  void map_way_draw(map_t *map, way_t *way Line 572  void map_way_draw(map_t *map, way_t *way
572      }      }
573    
574      /* draw way */      /* draw way */
575        float width = way->draw.width * map->state->detail;
576    
577      if(way->draw.flags & OSM_DRAW_FLAG_AREA) {      if(way->draw.flags & OSM_DRAW_FLAG_AREA) {
578        map_way_new(map, CANVAS_GROUP_POLYGONS, way, points,        map_way_new(map, CANVAS_GROUP_POLYGONS, way, points,
579                    way->draw.width, way->draw.color, way->draw.area.color);                    width, way->draw.color, way->draw.area.color);
580      } else {      } else {
581    
582        if(way->draw.flags & OSM_DRAW_FLAG_BG) {        if(way->draw.flags & OSM_DRAW_FLAG_BG) {
583          map_way_new(map, CANVAS_GROUP_WAYS_INT, way, points,          map_way_new(map, CANVAS_GROUP_WAYS_INT, way, points,
584                      way->draw.width, way->draw.color, NO_COLOR);                      width, way->draw.color, NO_COLOR);
585    
586          map_way_new(map, CANVAS_GROUP_WAYS_OL, way, points,          map_way_new(map, CANVAS_GROUP_WAYS_OL, way, points,
587                      way->draw.bg.width, way->draw.bg.color, NO_COLOR);                      way->draw.bg.width * map->state->detail,
588                        way->draw.bg.color, NO_COLOR);
589    
590        } else        } else
591          map_way_new(map, CANVAS_GROUP_WAYS, way, points,          map_way_new(map, CANVAS_GROUP_WAYS, way, points,
592                      way->draw.width, way->draw.color, NO_COLOR);                      width, way->draw.color, NO_COLOR);
593      }      }
594      canvas_points_free(points);      canvas_points_free(points);
595    }    }
# Line 617  void map_node_draw(map_t *map, node_t *n Line 602  void map_node_draw(map_t *map, node_t *n
602    
603    if(!node->ways)    if(!node->ways)
604      map_node_new(map, node,      map_node_new(map, node,
605                   map->style->node.radius,                   map->style->node.radius * map->state->detail,
606                   map->style->node.border_radius,                   map->style->node.border_radius * map->state->detail,
607                   map->style->node.fill_color,                   map->style->node.fill_color,
608                   map->style->node.color);                   map->style->node.color);
609    
610    else if(map->style->node.show_untagged || osm_node_has_tag(node))    else if(map->style->node.show_untagged || osm_node_has_tag(node))
611      map_node_new(map, node,      map_node_new(map, node,
612                   map->style->node.radius, 0,                   map->style->node.radius * map->state->detail, 0,
613                   map->style->node.color, 0);                   map->style->node.color, 0);
614  }  }
615    
# Line 677  static void map_item_init(style_t *style Line 662  static void map_item_init(style_t *style
662  void map_item_redraw(appdata_t *appdata, map_item_t *map_item) {  void map_item_redraw(appdata_t *appdata, map_item_t *map_item) {
663    map_item_t item = *map_item;    map_item_t item = *map_item;
664    
665      /* a relation cannot be redraws as it doesn't have a visual */
666      /* representation */
667      if(map_item->object.type == RELATION)
668        return;
669    
670    /* check if the item to be redrawn is the selected one */    /* check if the item to be redrawn is the selected one */
671    gboolean is_selected = FALSE;    gboolean is_selected = FALSE;
672    if(map_item->object.ptr == appdata->map->selected.object.ptr) {    if(map_item->object.ptr == appdata->map->selected.object.ptr) {
# Line 1007  static gboolean map_limit_zoom(map_t *ma Line 997  static gboolean map_limit_zoom(map_t *ma
997          }          }
998      }      }
999      if (*zoom != oldzoom) {      if (*zoom != oldzoom) {
1000          printf("Can't zoom further out\n");          printf("Can't zoom further out (%f)\n", *zoom);
1001          return 1;          return 1;
1002      }      }
1003      return 0;      return 0;
# Line 1366  static void map_touchnode_update(appdata Line 1356  static void map_touchnode_update(appdata
1356      /* don't highlight the dragged node itself and don't highlight */      /* don't highlight the dragged node itself and don't highlight */
1357      /* deleted ones */      /* deleted ones */
1358      if((node != cur_node) && (!(node->flags & OSM_FLAG_DELETED))) {      if((node != cur_node) && (!(node->flags & OSM_FLAG_DELETED))) {
1359        gint nx = x - node->lpos.x;        gint nx = abs(x - node->lpos.x);
1360        gint ny = y - node->lpos.y;        gint ny = abs(y - node->lpos.y);
1361    
1362        if((nx < map->style->node.radius) && (ny < map->style->node.radius) &&        if((nx < map->style->node.radius) && (ny < map->style->node.radius) &&
1363           (nx*nx + ny*ny < map->style->node.radius * map->style->node.radius))           (nx*nx + ny*ny < map->style->node.radius * map->style->node.radius))
# Line 1381  static void map_touchnode_update(appdata Line 1371  static void map_touchnode_update(appdata
1371    if(!map->touchnode && map->action.way) {    if(!map->touchnode && map->action.way) {
1372      node_chain_t *chain = map->action.way->node_chain;      node_chain_t *chain = map->action.way->node_chain;
1373      while(!map->touchnode && chain && chain->next) {      while(!map->touchnode && chain && chain->next) {
1374        gint nx = x - chain->node->lpos.x;        gint nx = abs(x - chain->node->lpos.x);
1375        gint ny = y - chain->node->lpos.y;        gint ny = abs(y - chain->node->lpos.y);
1376    
1377        if((nx < map->style->node.radius) && (ny < map->style->node.radius) &&        if((nx < map->style->node.radius) && (ny < map->style->node.radius) &&
1378           (nx*nx + ny*ny < map->style->node.radius * map->style->node.radius))           (nx*nx + ny*ny < map->style->node.radius * map->style->node.radius))
# Line 1740  gboolean map_key_press_event(appdata_t * Line 1730  gboolean map_key_press_event(appdata_t *
1730    return FALSE;    return FALSE;
1731  }  }
1732    
1733    void map_state_reset(map_state_t *state) {
1734      if(!state) return;
1735    
1736      state->zoom = 0.25;
1737      state->detail = 1.0;
1738    
1739      /* todo: try to scroll to center of screen */
1740      state->scroll_offset.x = 0;
1741      state->scroll_offset.y = 0;
1742    }
1743    
1744    map_state_t *map_state_new(void) {
1745      map_state_t *state = g_new0(map_state_t, 1);
1746      map_state_reset(state);
1747      return state;
1748    }
1749    
1750  GtkWidget *map_new(appdata_t *appdata) {  GtkWidget *map_new(appdata_t *appdata) {
1751    map_t *map = appdata->map = g_new0(map_t, 1);    map_t *map = appdata->map = g_new0(map_t, 1);
1752    
# Line 1755  GtkWidget *map_new(appdata_t *appdata) { Line 1762  GtkWidget *map_new(appdata_t *appdata) {
1762      map->state = appdata->project->map_state;      map->state = appdata->project->map_state;
1763    } else {    } else {
1764      printf("Creating new map state\n");      printf("Creating new map state\n");
1765      map->state = g_new0(map_state_t, 1);      map->state = map_state_new();
     map->state->zoom = 0.25;  
1766    }    }
1767    
1768    map->state->refcount++;    map->state->refcount++;
# Line 1766  GtkWidget *map_new(appdata_t *appdata) { Line 1772  GtkWidget *map_new(appdata_t *appdata) {
1772    map->appdata = appdata;    map->appdata = appdata;
1773    map->action.type = MAP_ACTION_IDLE;    map->action.type = MAP_ACTION_IDLE;
1774    
1775    map->canvas = canvas_new(map->style->background.color);    map->canvas = canvas_new();
   canvas_set_antialias(map->canvas, !appdata->settings->no_antialias);  
1776    
1777    GtkWidget *canvas_widget = canvas_get_widget(map->canvas);    GtkWidget *canvas_widget = canvas_get_widget(map->canvas);
1778    
# Line 1796  GtkWidget *map_new(appdata_t *appdata) { Line 1801  GtkWidget *map_new(appdata_t *appdata) {
1801  void map_init(appdata_t *appdata) {  void map_init(appdata_t *appdata) {
1802    map_t *map = appdata->map;    map_t *map = appdata->map;
1803    
1804      /* update canvas background color */
1805      canvas_set_background(map->canvas, map->style->background.color);
1806    
1807    /* set initial zoom */    /* set initial zoom */
1808    map_set_zoom(map, map->state->zoom, FALSE);    map_set_zoom(map, map->state->zoom, FALSE);
1809    josm_elemstyles_colorize_world(map->style, appdata->osm);    josm_elemstyles_colorize_world(map->style, appdata->osm);
# Line 1835  void map_clear(appdata_t *appdata, gint Line 1843  void map_clear(appdata_t *appdata, gint
1843  void map_paint(appdata_t *appdata) {  void map_paint(appdata_t *appdata) {
1844    map_t *map = appdata->map;    map_t *map = appdata->map;
1845    
   /* user may have changed antialias settings */  
   canvas_set_antialias(map->canvas, !appdata->settings->no_antialias);  
   
1846    josm_elemstyles_colorize_world(map->style, appdata->osm);    josm_elemstyles_colorize_world(map->style, appdata->osm);
1847    map_draw(map, appdata->osm);    map_draw(map, appdata->osm);
1848  }  }
# Line 1945  void map_action_ok(appdata_t *appdata) { Line 1950  void map_action_ok(appdata_t *appdata) {
1950      /* save changes to bg_offset in project */      /* save changes to bg_offset in project */
1951      appdata->project->wms_offset.x = map->bg.offset.x;      appdata->project->wms_offset.x = map->bg.offset.x;
1952      appdata->project->wms_offset.y = map->bg.offset.y;      appdata->project->wms_offset.y = map->bg.offset.y;
     appdata->project->dirty = TRUE;  
1953      break;      break;
1954    
1955    default:    default:
# Line 2372  void map_show_all(appdata_t *appdata) { Line 2376  void map_show_all(appdata_t *appdata) {
2376    gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);    gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);
2377  }  }
2378    
2379    static void map_detail_change(map_t *map, float detail) {
2380      appdata_t *appdata = map->appdata;
2381    
2382      /* deselecting anything allows us not to care about automatic deselection */
2383      /* as well as items becoming invisible by the detail change */
2384      map_item_deselect(appdata);
2385    
2386      map->state->detail = detail;
2387      printf("changing detail factor to %f\n", map->state->detail);
2388    
2389      banner_busy_start(appdata, 1, _("Redrawing"));
2390      map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
2391      map_paint(appdata);
2392      banner_busy_stop(appdata);
2393    }
2394    
2395    #define DETAIL_STEP 1.5
2396    
2397    void map_detail_increase(map_t *map) {
2398      if(!map) return;
2399      map_detail_change(map, map->state->detail * DETAIL_STEP);
2400    }
2401    
2402    void map_detail_decrease(map_t *map) {
2403      if(!map) return;
2404      map_detail_change(map, map->state->detail / DETAIL_STEP);
2405    }
2406    
2407    void map_detail_normal(map_t *map) {
2408      if(!map) return;
2409      map_detail_change(map, 1.0);
2410    }
2411    
2412  // vim:et:ts=8:sw=2:sts=2:ai  // vim:et:ts=8:sw=2:sts=2:ai

Legend:
Removed from v.161  
changed lines
  Added in v.234