Diff of /trunk/src/map.c

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

revision 13 by achadwick, Mon Dec 15 14:17:29 2008 UTC revision 105 by harbaum, Tue Mar 3 15:27:55 2009 UTC
# Line 56  static void map_statusbar(map_t *map, ma Line 56  static void map_statusbar(map_t *map, ma
56      str = g_strdup_printf("%s #%ld", item_str, id);      str = g_strdup_printf("%s #%ld", item_str, id);
57    
58      /* add some tags ... */      /* add some tags ... */
59        /*
60         *  XXX Should we just try to present only the name or the ref (or the
61         *  alt_name, old_name, whatever) here?  Hurling a load of tags in the
62         *  user's face in some unpredictable, uninformative order isn't very
63         *  friendly.
64         *
65         *  Actually, a tag_short_desc() function would be useful in dialogs
66         *  nd user messages too.
67         */
68      while(tag) {      while(tag) {
69        if(!collision && info_tag_key_collision(tags, tag))        if(!collision && info_tag_key_collision(tags, tag))
70          collision = TRUE;          collision = TRUE;
# Line 146  static void map_node_select(appdata_t *a Line 155  static void map_node_select(appdata_t *a
155    
156    float radius = map->style->highlight.width + map->style->node.radius;    float radius = map->style->highlight.width + map->style->node.radius;
157    if(!node->ways) radius += map->style->node.border_radius;    if(!node->ways) radius += map->style->node.border_radius;
158    if(node->icon_buf && map->style->icon.enable) {    if(node->icon_buf && map->style->icon.enable &&
159         !appdata->settings->no_icons) {
160      gint w = gdk_pixbuf_get_width(map_item->node->icon_buf);      gint w = gdk_pixbuf_get_width(map_item->node->icon_buf);
161      gint h = gdk_pixbuf_get_height(map_item->node->icon_buf);      gint h = gdk_pixbuf_get_height(map_item->node->icon_buf);
162      /* icons are technically square, so a radius slightly bigger */      /* icons are technically square, so a radius slightly bigger */
# Line 156  static void map_node_select(appdata_t *a Line 166  static void map_node_select(appdata_t *a
166    
167    map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,    map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,
168                      x, y, radius, map->style->highlight.color);                      x, y, radius, map->style->highlight.color);
169    
170    if(!map_item->item) {    if(!map_item->item) {
171      /* and draw a fake node */      /* and draw a fake node */
172      new_map_item = g_new0(map_item_t, 1);      new_map_item = g_new0(map_item_t, 1);
# Line 208  void map_way_select(appdata_t *appdata, Line 218  void map_way_select(appdata_t *appdata,
218        diff.x = node_chain->node->lpos.x - last->lpos.x;        diff.x = node_chain->node->lpos.x - last->lpos.x;
219        diff.y = node_chain->node->lpos.y - last->lpos.y;        diff.y = node_chain->node->lpos.y - last->lpos.y;
220    
221          /* only draw arrow if there's sufficient space */
222          /* TODO: what if there's not enough space anywhere? */
223        float len = sqrt(pow(diff.x, 2)+pow(diff.y, 2));        float len = sqrt(pow(diff.x, 2)+pow(diff.y, 2));
224        if(len > map->style->highlight.arrow_limit*arrow_width) {        if(len > map->style->highlight.arrow_limit*arrow_width) {
225          len /= arrow_width;          len /= arrow_width;
# Line 222  void map_way_select(appdata_t *appdata, Line 234  void map_way_select(appdata_t *appdata,
234          points->coords[2*2+0] = center.x - diff.y - diff.x;          points->coords[2*2+0] = center.x - diff.y - diff.x;
235          points->coords[2*2+1] = center.y + diff.x - diff.y;          points->coords[2*2+1] = center.y + diff.x - diff.y;
236    
237          map_hl_polygon_new(map, CANVAS_GROUP_NODES_HL, new_map_item,          map_hl_polygon_new(map, CANVAS_GROUP_WAYS_DIR, new_map_item,
238                             points, map->style->highlight.arrow_color);                             points, map->style->highlight.arrow_color);
239    
240          canvas_points_free(points);          canvas_points_free(points);
# Line 366  static canvas_item_t *map_node_new(map_t Line 378  static canvas_item_t *map_node_new(map_t
378    map_item->type = MAP_TYPE_NODE;    map_item->type = MAP_TYPE_NODE;
379    map_item->node = node;    map_item->node = node;
380    
381    if(!node->icon_buf || !map->style->icon.enable)    if(!node->icon_buf || !map->style->icon.enable ||
382      map_item->item = canvas_circle_new(map, CANVAS_GROUP_NODES,       map->appdata->settings->no_icons)
383        map_item->item = canvas_circle_new(map->canvas, CANVAS_GROUP_NODES,
384         node->lpos.x, node->lpos.y, radius, width, fill, border);         node->lpos.x, node->lpos.y, radius, width, fill, border);
385    else    else
386      map_item->item = canvas_image_new(map, CANVAS_GROUP_NODES,      map_item->item = canvas_image_new(map->canvas, CANVAS_GROUP_NODES,
387        node->icon_buf,        node->icon_buf,
388        node->lpos.x - map->style->icon.scale/2 *        node->lpos.x - map->style->icon.scale/2 *
389                        gdk_pixbuf_get_width(node->icon_buf),                        gdk_pixbuf_get_width(node->icon_buf),
# Line 402  static canvas_item_t *map_way_single_new Line 415  static canvas_item_t *map_way_single_new
415    map_item_t *map_item = g_new0(map_item_t, 1);    map_item_t *map_item = g_new0(map_item_t, 1);
416    map_item->type = MAP_TYPE_WAY;    map_item->type = MAP_TYPE_WAY;
417    map_item->way = way;    map_item->way = way;
418    map_item->item = canvas_circle_new(map, CANVAS_GROUP_WAYS,    map_item->item = canvas_circle_new(map->canvas, CANVAS_GROUP_WAYS,
419            way->node_chain->node->lpos.x, way->node_chain->node->lpos.y,            way->node_chain->node->lpos.x, way->node_chain->node->lpos.y,
420                                       radius, width, fill, border);                                       radius, width, fill, border);
421    
# Line 430  static canvas_item_t *map_way_new(map_t Line 443  static canvas_item_t *map_way_new(map_t
443    map_item->way = way;    map_item->way = way;
444    
445    if(way->draw.flags & OSM_DRAW_FLAG_AREA) {    if(way->draw.flags & OSM_DRAW_FLAG_AREA) {
446      if(map->style->area.opaque)      if(map->style->area.color & 0xff)
447        map_item->item = canvas_polygon_new(map, group, points,        map_item->item = canvas_polygon_new(map->canvas, group, points,
448                                            width, color, fill_color);                                            width, color, fill_color);
449      else      else
450        map_item->item = canvas_polyline_new(map, group, points,        map_item->item = canvas_polyline_new(map->canvas, group, points,
451                                             width, color);                                             width, color);
452    } else {    } else {
453      map_item->item = canvas_polyline_new(map, group, points, width, color);      map_item->item = canvas_polyline_new(map->canvas, group, points, width, color);
454    }    }
455    
456    canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max);    canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max);
457    
458    if (group != CANVAS_GROUP_WAYS_OL)    if (group != CANVAS_GROUP_WAYS_OL)
459      if (way->draw.dashed)      if (way->draw.dashed)
460        canvas_item_set_dashed(map_item->item);        canvas_item_set_dashed(map_item->item, width, way->draw.dash_length);
461    
462    /* attach map_item to ways map_item_chain */    /* attach map_item to ways map_item_chain */
463    map_item_chain_t **chain = &way->map_item_chain;    map_item_chain_t **chain = &way->map_item_chain;
# Line 462  static canvas_item_t *map_way_new(map_t Line 475  static canvas_item_t *map_way_new(map_t
475    
476  void map_show_node(map_t *map, node_t *node) {  void map_show_node(map_t *map, node_t *node) {
477    map_node_new(map, node, map->style->node.radius, 0,    map_node_new(map, node, map->style->node.radius, 0,
478                 RGB2CANVAS(map->style->node.color), 0);                 map->style->node.color, 0);
479  }  }
480    
481  void map_way_draw(map_t *map, way_t *way) {  void map_way_draw(map_t *map, way_t *way) {
# Line 477  void map_way_draw(map_t *map, way_t *way Line 490  void map_way_draw(map_t *map, way_t *way
490    if(nodes == 1) {    if(nodes == 1) {
491      /* draw a single dot where this single node is */      /* draw a single dot where this single node is */
492      map_way_single_new(map, way, map->style->node.radius, 0,      map_way_single_new(map, way, map->style->node.radius, 0,
493                         RGB2CANVAS(map->style->node.color), 0);                         map->style->node.color, 0);
494    } else {    } else {
495      canvas_points_t *points = canvas_points_new(nodes);      canvas_points_t *points = canvas_points_new(nodes);
496    
# Line 513  void map_node_draw(map_t *map, node_t *n Line 526  void map_node_draw(map_t *map, node_t *n
526      map_node_new(map, node,      map_node_new(map, node,
527                   map->style->node.radius,                   map->style->node.radius,
528                   map->style->node.border_radius,                   map->style->node.border_radius,
529                   RGBA2CANVAS(map->style->node.fill_color,                   map->style->node.fill_color,
530                               map->style->node.has_fill_color?0xff:0x00),                   map->style->node.color);
                  RGB2CANVAS(map->style->node.color));  
531    
532    else if(map->style->node.show_untagged || osm_node_has_tag(node))    else if(map->style->node.show_untagged || osm_node_has_tag(node))
533      map_node_new(map, node,      map_node_new(map, node,
534                   map->style->node.radius, 0,                   map->style->node.radius, 0,
535                   RGB2CANVAS(map->style->node.color), 0);                   map->style->node.color, 0);
536  }  }
537    
538  static void map_item_draw(map_t *map, map_item_t *map_item) {  static void map_item_draw(map_t *map, map_item_t *map_item) {
# Line 602  void map_frisket_draw(map_t *map, bounds Line 614  void map_frisket_draw(map_t *map, bounds
614    canvas_points_t *points = canvas_points_new(5);    canvas_points_t *points = canvas_points_new(5);
615    
616    /* don't draw frisket at all if it's completely transparent */    /* don't draw frisket at all if it's completely transparent */
617    if(map->style->frisket.opaque) {    if(map->style->frisket.color & 0xff) {
618      elemstyle_color_t color =      elemstyle_color_t color = map->style->frisket.color;
       (map->style->background.color<<8) | map->style->frisket.opaque;  
619    
620      float mult = map->style->frisket.mult;      float mult = map->style->frisket.mult;
621    
622      /* top rectangle */      /* top rectangle */
623      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,
624                            mult*bounds->min.y, bounds->min.y);                            mult*bounds->min.y, bounds->min.y);
625      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
626                           1, NO_COLOR, color);
627    
628      /* bottom rectangle */      /* bottom rectangle */
629      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,
630                            bounds->max.y, mult*bounds->max.y);                            bounds->max.y, mult*bounds->max.y);
631      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
632                           1, NO_COLOR, color);
633    
634      /* left rectangle */      /* left rectangle */
635      map_frisket_rectangle(points, mult*bounds->min.x, bounds->min.x,      map_frisket_rectangle(points, mult*bounds->min.x, bounds->min.x,
636                            mult*bounds->min.y, mult*bounds->max.y);                            mult*bounds->min.y, mult*bounds->max.y);
637      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
638                           1, NO_COLOR, color);
639    
640      /* right rectangle */      /* right rectangle */
641      map_frisket_rectangle(points, bounds->max.x, mult*bounds->max.x,      map_frisket_rectangle(points, bounds->max.x, mult*bounds->max.x,
642                            mult*bounds->min.y, mult*bounds->max.y);                            mult*bounds->min.y, mult*bounds->max.y);
643      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
644                           1, NO_COLOR, color);
645    
646    }    }
647    
# Line 637  void map_frisket_draw(map_t *map, bounds Line 652  void map_frisket_draw(map_t *map, bounds
652                            bounds->min.x-ew2, bounds->max.x+ew2,                            bounds->min.x-ew2, bounds->max.x+ew2,
653                            bounds->min.y-ew2, bounds->max.y+ew2);                            bounds->min.y-ew2, bounds->max.y+ew2);
654    
655      canvas_polyline_new(map, CANVAS_GROUP_NODES, points,      canvas_polyline_new(map->canvas, CANVAS_GROUP_FRISKET, points,
656                          map->style->frisket.border.width,                          map->style->frisket.border.width,
657                          map->style->frisket.border.color);                          map->style->frisket.border.color);
658    
# Line 769  map_item_t *map_item_at(map_t *map, gint Line 784  map_item_t *map_item_at(map_t *map, gint
784      return NULL;      return NULL;
785    }    }
786    
787    if(map_item->highlight)    if(map_item->highlight)
788      printf("  item is highlight\n");      printf("  item is highlight\n");
789    
790    switch(map_item->type) {    switch(map_item->type) {
# Line 788  map_item_t *map_item_at(map_t *map, gint Line 803  map_item_t *map_item_at(map_t *map, gint
803  }  }
804    
805  /* get the real item (no highlight) at x, y */  /* get the real item (no highlight) at x, y */
806  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) {
807    map_item_t *map_item = map_item_at(map, x, y);    map_item_t *map_item = map_item_at(map, x, y);
808    
809    /* no item or already a real one */    /* no item or already a real one */
# Line 828  static map_item_t *map_real_item_at(map_ Line 843  static map_item_t *map_real_item_at(map_
843    return map_item;    return map_item;
844  }  }
845    
   
   
 #ifdef USE_GOOCANVAS  
   
846  /* Limitations on the amount by which we can scroll. Keeps part of the  /* Limitations on the amount by which we can scroll. Keeps part of the
847   * map visible at all times */   * map visible at all times */
848  static void map_limit_scroll(map_t *map, gint *sx, gint *sy) {  static void map_limit_scroll(map_t *map, canvas_unit_t unit,
849      gdouble zoom = goo_canvas_get_scale(GOO_CANVAS(map->canvas));                               gint *sx, gint *sy) {
850    
851      gint sx_cu = *sx / zoom;    /* get scale factor for pixel->meter conversion. set to 1 if */
852      gint sy_cu = *sy / zoom;    /* given coordinates are already in meters */
853      gdouble scale = (unit == CANVAS_UNIT_METER)?1.0:canvas_get_zoom(map->canvas);
854      // Canvas viewport dimensions  
855      GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;    /* convert pixels to meters if necessary */
856      gint aw_cu = a->width / zoom;    gdouble sx_cu = *sx / scale;
857      gint ah_cu = a->height / zoom;    gdouble sy_cu = *sy / scale;
858    
859      // Data rect minimum and maximum    /* get size of visible area in canvas units (meters) */
860      gint min_x, min_y, max_x, max_y;    gint aw_cu = canvas_get_viewport_width(map->canvas, CANVAS_UNIT_METER);
861      min_x = map->appdata->osm->bounds->min.x;    gint ah_cu = canvas_get_viewport_height(map->canvas, CANVAS_UNIT_METER);
862      min_y = map->appdata->osm->bounds->min.y;  
863      max_x = map->appdata->osm->bounds->max.x;    // Data rect minimum and maximum
864      max_y = map->appdata->osm->bounds->max.y;    gint min_x, min_y, max_x, max_y;
865      min_x = map->appdata->osm->bounds->min.x;
866      // limit stops - prevent scrolling beyond these    min_y = map->appdata->osm->bounds->min.y;
867      gint min_sy_cu = 0.95*(min_y - ah_cu);    max_x = map->appdata->osm->bounds->max.x;
868      gint min_sx_cu = 0.95*(min_x - aw_cu);    max_y = map->appdata->osm->bounds->max.y;
869      gint max_sy_cu = 0.95*(max_y);  
870      gint max_sx_cu = 0.95*(max_x);    // limit stops - prevent scrolling beyond these
871      if (sy_cu < min_sy_cu) { *sy = min_sy_cu*zoom; }    gint min_sy_cu = 0.95*(min_y - ah_cu);
872      if (sx_cu < min_sx_cu) { *sx = min_sx_cu*zoom; }    gint min_sx_cu = 0.95*(min_x - aw_cu);
873      if (sy_cu > max_sy_cu) { *sy = max_sy_cu*zoom; }    gint max_sy_cu = 0.95*(max_y);
874      if (sx_cu > max_sx_cu) { *sx = max_sx_cu*zoom; }    gint max_sx_cu = 0.95*(max_x);
875      if (sy_cu < min_sy_cu) { *sy = min_sy_cu * scale; }
876      if (sx_cu < min_sx_cu) { *sx = min_sx_cu * scale; }
877      if (sy_cu > max_sy_cu) { *sy = max_sy_cu * scale; }
878      if (sx_cu > max_sx_cu) { *sx = max_sx_cu * scale; }
879  }  }
880    
881    
# Line 874  static gboolean map_limit_zoom(map_t *ma Line 889  static gboolean map_limit_zoom(map_t *ma
889      max_x = map->appdata->osm->bounds->max.x;      max_x = map->appdata->osm->bounds->max.x;
890      max_y = map->appdata->osm->bounds->max.y;      max_y = map->appdata->osm->bounds->max.y;
891    
892      // Canvas viewport dimensions      /* get size of visible area in pixels and convert to meters of intended */
893      GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;      /* zoom by deviding by zoom (which is basically pix/m) */
894      gint ah_cu = a->height / *zoom;      gint aw_cu =
895      gint aw_cu = a->width / *zoom;        canvas_get_viewport_width(map->canvas, CANVAS_UNIT_PIXEL) / *zoom;
896        gint ah_cu =
897          canvas_get_viewport_height(map->canvas, CANVAS_UNIT_PIXEL) / *zoom;
898    
899      gdouble oldzoom = *zoom;      gdouble oldzoom = *zoom;
900      if (ah_cu < aw_cu) {      if (ah_cu < aw_cu) {
# Line 902  static gboolean map_limit_zoom(map_t *ma Line 919  static gboolean map_limit_zoom(map_t *ma
919  }  }
920    
921    
 #if 0  
 /* Scroll the map a little towards the centre from where it is right now.  
  * This is used as a cute recentring trick when the map is at its outer  
  * scroll limit. */  
 static void map_scroll_towards_centre(map_t *map, gdouble amt) {  
     gint sx, sy, sx_orig, sy_orig;  
     canvas_get_scroll_offsets(map->canvas, &sx, &sy);  
     gdouble zoom = goo_canvas_get_scale(GOO_CANVAS(map->canvas));  
     sx_orig=sx;  
     sy_orig=sy;  
   
     // Work in canvas units  
     gdouble sx_cu = sx / zoom;  
     gdouble sy_cu = sy / zoom;  
   
     // Map bounds  
     gdouble bmin_x_cu, bmin_y_cu, bmax_x_cu, bmax_y_cu;  
     bmin_x_cu = map->appdata->osm->bounds->min.x;  
     bmin_y_cu = map->appdata->osm->bounds->min.y;  
     bmax_x_cu = map->appdata->osm->bounds->max.x;  
     bmax_y_cu = map->appdata->osm->bounds->max.y;  
   
     // Canvas viewport dimensions  
     GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;  
     gdouble ah_cu = a->height / zoom;  
     gdouble aw_cu = a->width / zoom;  
   
     // Scroll offsets that would recentre the map  
     gdouble centre_sx_cu, centre_sy_cu;  
     centre_sx_cu = - (aw_cu/2);  
     centre_sy_cu = - (ah_cu/2);  
   
     // Move towards centre by a given fraction of the whole map  
     if (sx_cu > centre_sx_cu) {  
         sx_cu -= ((bmax_x_cu - bmin_x_cu) * amt);  
         if (sx_cu < centre_sx_cu) {  
             printf("force-centre-x\n");  
             sx_cu = centre_sx_cu;  
         }  
     }  
     if (sx_cu < centre_sx_cu) {  
         sx_cu += ((bmax_x_cu - bmin_x_cu) * amt);  
         if (sx_cu > centre_sx_cu) {  
             printf("force-centre-x\n");  
             sx_cu = centre_sx_cu;  
         }  
     }  
   
     if (sy_cu > centre_sy_cu) {  
         sy_cu -= ((bmax_y_cu - bmin_y_cu) * amt);  
         if (sy_cu < centre_sy_cu) {  
             printf("force-centre-y\n");  
             sy_cu = centre_sy_cu;  
         }  
     }  
     if (sy_cu < centre_sy_cu) {  
         sy_cu += ((bmax_y_cu - bmin_y_cu) * amt);  
         if (sy_cu > centre_sy_cu) {  
             printf("force-centre-y\n");  
             sy_cu = centre_sy_cu;  
         }  
     }  
   
     // Back to pixels for setting the scroll  
     sx = (gint)(sx_cu * zoom);  
     sy = (gint)(sy_cu * zoom);  
     canvas_scroll_to(map->canvas, sx, sy);  
     map->state->scroll_offset.x = sx;  
     map->state->scroll_offset.y = sy;  
 }  
 #endif // #if 0  
   
922  /*  /*
923   * Scroll the map to a point if that point is currently offscreen.   * Scroll the map to a point if that point is currently offscreen.
924   */   */
# Line 990  void map_scroll_to_if_offscreen(map_t *m Line 935  void map_scroll_to_if_offscreen(map_t *m
935    max_y = map->appdata->osm->bounds->max.y;    max_y = map->appdata->osm->bounds->max.y;
936    if (   (lpos->x > max_x) || (lpos->x < min_x)    if (   (lpos->x > max_x) || (lpos->x < min_x)
937        || (lpos->y > max_y) || (lpos->y < min_y)) {        || (lpos->y > max_y) || (lpos->y < min_y)) {
938      printf("cannot scroll to (%d, %d): outside the working area\n");      printf("cannot scroll to (%d, %d): outside the working area\n",
939               lpos->x, lpos->y);
940      return;      return;
941    }    }
942    
943    // Viewport dimensions in canvas space    // Viewport dimensions in canvas space
944    gdouble zoom = goo_canvas_get_scale(GOO_CANVAS(map->canvas));  
945    GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;    /* get size of visible area in canvas units (meters) */
946    gdouble aw = a->width / zoom;    gdouble pix_per_meter = canvas_get_zoom(map->canvas);
947    gdouble ah = a->height / zoom;    gdouble aw = canvas_get_viewport_width(map->canvas, CANVAS_UNIT_METER);
948      gdouble ah = canvas_get_viewport_height(map->canvas, CANVAS_UNIT_METER);
949    
950    // Is the point still onscreen?    // Is the point still onscreen?
951    gboolean vert_recentre_needed = FALSE;    gboolean vert_recentre_needed = FALSE;
952    gboolean horiz_recentre_needed = FALSE;    gboolean horiz_recentre_needed = FALSE;
953    gint sx, sy;    gint sx, sy;
954    canvas_get_scroll_offsets(map->canvas, &sx, &sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
955    gint viewport_left   = (sx/zoom);    gint viewport_left   = (sx/pix_per_meter);
956    gint viewport_right  = (sx/zoom)+aw;    gint viewport_right  = (sx/pix_per_meter)+aw;
957    gint viewport_top    = (sy/zoom);    gint viewport_top    = (sy/pix_per_meter);
958    gint viewport_bottom = (sy/zoom)+ah;    gint viewport_bottom = (sy/pix_per_meter)+ah;
959    if (lpos->x > viewport_right) {    if (lpos->x > viewport_right) {
960      printf("** off right edge (%d > %d)\n", lpos->x, viewport_right);      printf("** off right edge (%d > %d)\n", lpos->x, viewport_right);
961      horiz_recentre_needed = TRUE;      horiz_recentre_needed = TRUE;
# Line 1028  void map_scroll_to_if_offscreen(map_t *m Line 975  void map_scroll_to_if_offscreen(map_t *m
975    
976    if (horiz_recentre_needed || vert_recentre_needed) {    if (horiz_recentre_needed || vert_recentre_needed) {
977      gint new_sx, new_sy;      gint new_sx, new_sy;
978  #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  
979      // Just centre both at once      // Just centre both at once
980      new_sx = zoom * (lpos->x - (aw/2));      new_sx = pix_per_meter * (lpos->x - (aw/2));
981      new_sy = zoom * (lpos->y - (ah/2));      new_sy = pix_per_meter * (lpos->y - (ah/2));
982  #endif  
983      map_limit_scroll(map, &new_sx, &new_sy);      map_limit_scroll(map, CANVAS_UNIT_PIXEL, &new_sx, &new_sy);
984      canvas_scroll_to(map->canvas, new_sx, new_sy);      canvas_scroll_to(map->canvas, CANVAS_UNIT_PIXEL, new_sx, new_sy);
985    }    }
986  }  }
987    
 #endif // #ifdef USE_GOOCANVAS  
   
988  /* Deselects the current way or node if its zoom_max  /* Deselects the current way or node if its zoom_max
989   * means that it's not going to render at the current map zoom. */   * means that it's not going to render at the current map zoom. */
990  void map_deselect_if_zoom_below_zoom_max(map_t *map) {  void map_deselect_if_zoom_below_zoom_max(map_t *map) {
# Line 1069  void map_deselect_if_zoom_below_zoom_max Line 1009  void map_deselect_if_zoom_below_zoom_max
1009  void map_set_zoom(map_t *map, double zoom,  void map_set_zoom(map_t *map, double zoom,
1010                    gboolean update_scroll_offsets) {                    gboolean update_scroll_offsets) {
1011    gboolean at_zoom_limit = 0;    gboolean at_zoom_limit = 0;
 #ifdef USE_GOOCANVAS  
1012    at_zoom_limit = map_limit_zoom(map, &zoom);    at_zoom_limit = map_limit_zoom(map, &zoom);
1013  #endif  
1014    map->state->zoom = zoom;    map->state->zoom = zoom;
1015    canvas_set_zoom(map->canvas, map->state->zoom);    canvas_set_zoom(map->canvas, map->state->zoom);
1016    
1017    map_deselect_if_zoom_below_zoom_max(map);    map_deselect_if_zoom_below_zoom_max(map);
1018    
1019    if (update_scroll_offsets) {    if(update_scroll_offsets) {
1020      if (!at_zoom_limit) {      if (!at_zoom_limit) {
1021        /* zooming affects the scroll offsets */        /* zooming affects the scroll offsets */
1022        gint sx, sy;        gint sx, sy;
1023        canvas_get_scroll_offsets(map->canvas, &sx, &sy);        canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1024  #ifdef USE_GOOCANVAS        map_limit_scroll(map, CANVAS_UNIT_PIXEL, &sx, &sy);
1025        map_limit_scroll(map, &sx, &sy);  
1026        canvas_scroll_to(map->canvas, sx, sy);  // keep the map visible        // keep the map visible
1027  #endif        canvas_scroll_to(map->canvas, CANVAS_UNIT_PIXEL, sx, sy);
       map->state->scroll_offset.x = sx;  
       map->state->scroll_offset.y = sy;  
     }  
 #ifdef USE_GOOCANVAS  
     else {  
       //      map_scroll_towards_centre(map, 0.20);  
1028      }      }
1029  #endif  
1030        canvas_scroll_get(map->canvas, CANVAS_UNIT_METER,
1031                          &map->state->scroll_offset.x,
1032                          &map->state->scroll_offset.y);
1033    }    }
1034  }  }
1035    
# Line 1118  static gboolean map_scroll_event(GtkWidg Line 1054  static gboolean map_scroll_event(GtkWidg
1054  static gboolean distance_above(map_t *map, gint x, gint y, gint limit) {  static gboolean distance_above(map_t *map, gint x, gint y, gint limit) {
1055    gint sx, sy;    gint sx, sy;
1056    
 #ifdef USE_GNOMECANVAS  
   gnome_canvas_get_scroll_offsets(GNOME_CANVAS(map->canvas), &sx, &sy);  
   
   /* add offsets generated by mouse within map and map scrolling */  
   sx = (x-map->pen_down.at.x) + (map->pen_down.so.x-sx);  
   sy = (y-map->pen_down.at.y) + (map->pen_down.so.y-sy);  
 #else  
1057    /* add offsets generated by mouse within map and map scrolling */    /* add offsets generated by mouse within map and map scrolling */
1058    sx = (x-map->pen_down.at.x);    sx = (x-map->pen_down.at.x);
1059    sy = (y-map->pen_down.at.y);    sy = (y-map->pen_down.at.y);
 #endif  
1060    
1061    return(sx*sx + sy*sy > limit*limit);    return(sx*sx + sy*sy > limit*limit);
1062  }  }
# Line 1137  static gboolean distance_above(map_t *ma Line 1065  static gboolean distance_above(map_t *ma
1065  static void map_do_scroll(map_t *map, gint x, gint y) {  static void map_do_scroll(map_t *map, gint x, gint y) {
1066    gint sx, sy;    gint sx, sy;
1067    
1068    canvas_get_scroll_offsets(map->canvas, &sx, &sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1069    sx -= x-map->pen_down.at.x;    sx -= x-map->pen_down.at.x;
1070    sy -= y-map->pen_down.at.y;    sy -= y-map->pen_down.at.y;
1071  #ifdef USE_GOOCANVAS    map_limit_scroll(map, CANVAS_UNIT_PIXEL, &sx, &sy);
1072    map_limit_scroll(map, &sx, &sy);    canvas_scroll_to(map->canvas, CANVAS_UNIT_PIXEL, sx, sy);
1073  #endif  
1074    canvas_scroll_to(map->canvas, sx, sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_METER,
1075    map->state->scroll_offset.x = sx;                      &map->state->scroll_offset.x,
1076    map->state->scroll_offset.y = sy;                      &map->state->scroll_offset.y);
1077  }  }
1078    
1079    
1080  /* scroll a certain step */  /* scroll a certain step */
1081  static void map_do_scroll_step(map_t *map, gint x, gint y) {  static void map_do_scroll_step(map_t *map, gint x, gint y) {
1082    gint sx, sy;    gint sx, sy;
1083    canvas_get_scroll_offsets(map->canvas, &sx, &sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1084    sx += x;    sx += x;
1085    sy += y;    sy += y;
1086  #ifdef USE_GOOCANVAS    map_limit_scroll(map, CANVAS_UNIT_PIXEL, &sx, &sy);
1087    map_limit_scroll(map, &sx, &sy);    canvas_scroll_to(map->canvas, CANVAS_UNIT_PIXEL, sx, sy);
 #endif  
   canvas_scroll_to(map->canvas, sx, sy);  
   map->state->scroll_offset.x = sx;  
   map->state->scroll_offset.y = sy;  
 }  
1088    
1089      canvas_scroll_get(map->canvas, CANVAS_UNIT_METER,
1090                        &map->state->scroll_offset.x,
1091                        &map->state->scroll_offset.y);
1092    }
1093    
1094  gboolean map_item_is_selected_node(map_t *map, map_item_t *map_item) {  gboolean map_item_is_selected_node(map_t *map, map_item_t *map_item) {
1095    printf("check if item is a selected node\n");    printf("check if item is a selected node\n");
# Line 1381  static void map_button_press(map_t *map, Line 1308  static void map_button_press(map_t *map,
1308    map->pen_down.at.y = y;    map->pen_down.at.y = y;
1309    map->pen_down.drag = FALSE;     // don't assume drag yet    map->pen_down.drag = FALSE;     // don't assume drag yet
1310    
 #ifdef USE_GNOMECANVAS  
   /* save initial scroll offset */  
   gnome_canvas_get_scroll_offsets(GNOME_CANVAS(map->canvas),  
                   &map->pen_down.so.x, &map->pen_down.so.y);  
 #endif  
   
1311    /* determine wether this press was on an item */    /* determine wether this press was on an item */
1312    map->pen_down.on_item = map_real_item_at(map, x, y);    map->pen_down.on_item = map_real_item_at(map, x, y);
1313    
# Line 1579  static gboolean map_motion_notify_event( Line 1500  static gboolean map_motion_notify_event(
1500    /* reduce update frequency on hildon to keep screen update fluid */    /* reduce update frequency on hildon to keep screen update fluid */
1501    static guint32 last_time = 0;    static guint32 last_time = 0;
1502    
1503    if(event->time - last_time < 100) return FALSE;    if(event->time - last_time < 250) return FALSE;
1504    last_time = event->time;    last_time = event->time;
1505  #endif  #endif
1506    
1507    if(!map->pen_down.is)    if(!map->pen_down.is)
1508      return FALSE;      return FALSE;
1509    
1510  #ifdef USE_GNOMECANVAS  #ifndef USE_GOOCANVAS
1511    /* handle hints, hints are handled by goocanvas directly */    /* handle hints, hints are handled by goocanvas directly */
1512    if(event->is_hint)    if(event->is_hint)
1513      gdk_window_get_pointer(event->window, &x, &y, &state);      gdk_window_get_pointer(event->window, &x, &y, &state);
# Line 1623  static gboolean map_motion_notify_event( Line 1544  static gboolean map_motion_notify_event(
1544    case MAP_ACTION_NODE_ADD:    case MAP_ACTION_NODE_ADD:
1545      map_hl_cursor_draw(map, x, y, FALSE, map->style->node.radius);      map_hl_cursor_draw(map, x, y, FALSE, map->style->node.radius);
1546      break;      break;
1547    
1548    case MAP_ACTION_WAY_ADD:    case MAP_ACTION_WAY_ADD:
1549      map_hl_cursor_draw(map, x, y, FALSE, map->style->node.radius);      map_hl_cursor_draw(map, x, y, FALSE, map->style->node.radius);
1550      map_touchnode_update(appdata, x, y);      map_touchnode_update(appdata, x, y);
# Line 1728  GtkWidget *map_new(appdata_t *appdata) { Line 1649  GtkWidget *map_new(appdata_t *appdata) {
1649    map_t *map = appdata->map = g_new0(map_t, 1);    map_t *map = appdata->map = g_new0(map_t, 1);
1650    
1651    map->style = style_load(appdata, appdata->settings->style);    map->style = style_load(appdata, appdata->settings->style);
1652      if(!map->style) {
1653        errorf(NULL, _("Unable to load valid style, terminating."));
1654        g_free(map);
1655        return NULL;
1656      }
1657    
1658    if(appdata->project && appdata->project->map_state) {    if(appdata->project && appdata->project->map_state) {
1659      printf("Using projects map state\n");      printf("Using projects map state\n");
# Line 1745  GtkWidget *map_new(appdata_t *appdata) { Line 1671  GtkWidget *map_new(appdata_t *appdata) {
1671    map->appdata = appdata;    map->appdata = appdata;
1672    map->action.type = MAP_ACTION_IDLE;    map->action.type = MAP_ACTION_IDLE;
1673    
1674  #ifdef USE_GNOMECANVAS    map->canvas = canvas_new(map->style->background.color);
1675    map->canvas = gnome_canvas_new_aa();  // _aa    canvas_set_antialias(map->canvas, !appdata->settings->no_antialias);
   
   /* create the groups */  
   canvas_group_t group;  
   for(group = 0; group < CANVAS_GROUPS; group++)  
     map->group[group] = gnome_canvas_item_new(  
                 gnome_canvas_root(GNOME_CANVAS(map->canvas)),  
                 GNOME_TYPE_CANVAS_GROUP,  
                 NULL);  
   
   gtk_widget_modify_bg(map->canvas, GTK_STATE_NORMAL,  
                        &map->canvas->style->white);  
   
 #else  
   map->canvas = goo_canvas_new();  
   
   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);  
   
   GooCanvasItem *root = goo_canvas_get_root_item(GOO_CANVAS(map->canvas));  
   
   /* create the groups */  
   canvas_group_t group;  
   for(group = 0; group < CANVAS_GROUPS; group++)  
     map->group[group] = goo_canvas_group_new(root, NULL);  
1676    
1677  #endif    GtkWidget *canvas_widget = canvas_get_widget(map->canvas);
1678    
1679    gtk_widget_set_events(map->canvas,    gtk_widget_set_events(canvas_widget,
1680                            GDK_BUTTON_PRESS_MASK                            GDK_BUTTON_PRESS_MASK
1681                          | GDK_BUTTON_RELEASE_MASK                          | GDK_BUTTON_RELEASE_MASK
1682                          | GDK_SCROLL_MASK                          | GDK_SCROLL_MASK
1683                          | GDK_POINTER_MOTION_MASK                          | GDK_POINTER_MOTION_MASK
1684                          | GDK_POINTER_MOTION_HINT_MASK);                          | GDK_POINTER_MOTION_HINT_MASK);
1685    
1686    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1687       "button_press_event", G_CALLBACK(map_button_event), appdata);       "button_press_event", G_CALLBACK(map_button_event), appdata);
1688    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1689       "button_release_event", G_CALLBACK(map_button_event), appdata);       "button_release_event", G_CALLBACK(map_button_event), appdata);
1690    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1691       "motion_notify_event", G_CALLBACK(map_motion_notify_event), appdata);       "motion_notify_event", G_CALLBACK(map_motion_notify_event), appdata);
1692    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1693       "scroll_event", G_CALLBACK(map_scroll_event), appdata);       "scroll_event", G_CALLBACK(map_scroll_event), appdata);
1694    
1695    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1696       "destroy", G_CALLBACK(map_destroy_event), appdata);       "destroy", G_CALLBACK(map_destroy_event), appdata);
1697    
1698    return map->canvas;    return canvas_widget;
1699  }  }
1700    
1701  void map_init(appdata_t *appdata) {  void map_init(appdata_t *appdata) {
# Line 1813  void map_init(appdata_t *appdata) { Line 1714  void map_init(appdata_t *appdata) {
1714                      mult*appdata->osm->bounds->max.x,                      mult*appdata->osm->bounds->max.x,
1715                      mult*appdata->osm->bounds->max.y);                      mult*appdata->osm->bounds->max.y);
1716    
1717    printf("restore scroll offsets %d/%d\n",    printf("restore scroll position %d/%d\n",
1718           map->state->scroll_offset.x, map->state->scroll_offset.y);           map->state->scroll_offset.x, map->state->scroll_offset.y);
1719    
1720    canvas_scroll_to(map->canvas,    map_limit_scroll(map, CANVAS_UNIT_METER,
1721                     map->state->scroll_offset.x, map->state->scroll_offset.y);             &map->state->scroll_offset.x, &map->state->scroll_offset.y);
1722      canvas_scroll_to(map->canvas, CANVAS_UNIT_METER,
1723               map->state->scroll_offset.x, map->state->scroll_offset.y);
1724  }  }
1725    
1726    
# Line 1840  void map_item_set_flags(map_item_t *map_ Line 1743  void map_item_set_flags(map_item_t *map_
1743    }    }
1744  }  }
1745    
1746  void map_clear(appdata_t *appdata, gint layer_mask) {  void map_clear(appdata_t *appdata, gint group_mask) {
1747    map_t *map = appdata->map;    map_t *map = appdata->map;
1748    
1749    printf("freeing map contents\n");    printf("freeing map contents\n");
# Line 1850  void map_clear(appdata_t *appdata, gint Line 1753  void map_clear(appdata_t *appdata, gint
1753    /* remove a possibly existing highlight */    /* remove a possibly existing highlight */
1754    map_item_deselect(appdata);    map_item_deselect(appdata);
1755    
1756    canvas_group_t group;    canvas_erase(map->canvas, group_mask);
   for(group=0;group<CANVAS_GROUPS;group++) {  
   
 #ifdef USE_GNOMECANVAS  
     /* destroy the entire group */  
     canvas_item_destroy(map->group[group]);  
   
     /* and create an empty new one */  
     map->group[group] = gnome_canvas_item_new(  
                       gnome_canvas_root(GNOME_CANVAS(map->canvas)),  
                       GNOME_TYPE_CANVAS_GROUP,  
                       NULL);  
 #else  
     if(layer_mask & (1<<group)) {  
       gint children = goo_canvas_item_get_n_children(map->group[group]);  
       printf("Removing %d children from layer %d\n", children, group);  
       while(children--)  
         goo_canvas_item_remove_child(map->group[group], children);  
     }  
 #endif  
   }  
1757  }  }
1758    
1759  void map_paint(appdata_t *appdata) {  void map_paint(appdata_t *appdata) {
1760    map_t *map = appdata->map;    map_t *map = appdata->map;
1761    
1762      /* user may have changed antialias settings */
1763      canvas_set_antialias(map->canvas, !appdata->settings->no_antialias);
1764    
1765    josm_elemstyles_colorize_world(map->style, appdata->osm);    josm_elemstyles_colorize_world(map->style, appdata->osm);
1766    map_draw(map, appdata->osm);    map_draw(map, appdata->osm);
1767  }  }
# Line 2007  void map_delete_selected(appdata_t *appd Line 1893  void map_delete_selected(appdata_t *appd
1893    /* deleting the selected item de-selects it ... */    /* deleting the selected item de-selects it ... */
1894    map_item_deselect(appdata);    map_item_deselect(appdata);
1895    
1896      undo_remember_delete(appdata, item.type, item.ptr);
1897    
1898    switch(item.type) {    switch(item.type) {
1899    case MAP_TYPE_NODE:    case MAP_TYPE_NODE:
1900      printf("request to delete node #%ld\n", item.node->id);      printf("request to delete node #%ld\n", item.node->id);
# Line 2091  void map_track_draw_seg(map_t *map, trac Line 1979  void map_track_draw_seg(map_t *map, trac
1979    if(pnum == 1) {    if(pnum == 1) {
1980      g_assert(!seg->item);      g_assert(!seg->item);
1981    
1982      seg->item = canvas_circle_new(map, CANVAS_GROUP_TRACK,      seg->item = canvas_circle_new(map->canvas, CANVAS_GROUP_TRACK,
1983            seg->track_point->lpos.x, seg->track_point->lpos.y,            seg->track_point->lpos.x, seg->track_point->lpos.y,
1984            map->style->track.width/2.0, 0, map->style->track.color, NO_COLOR);            map->style->track.width/2.0, 0, map->style->track.color, NO_COLOR);
1985    }    }
# Line 2113  void map_track_draw_seg(map_t *map, trac Line 2001  void map_track_draw_seg(map_t *map, trac
2001      if(seg->item)      if(seg->item)
2002        canvas_item_destroy(seg->item);        canvas_item_destroy(seg->item);
2003    
2004      seg->item = canvas_polyline_new(map, CANVAS_GROUP_TRACK,      seg->item = canvas_polyline_new(map->canvas, CANVAS_GROUP_TRACK,
2005            points, map->style->track.width, map->style->track.color);            points, map->style->track.width, map->style->track.color);
2006    
2007      canvas_points_free(points);      canvas_points_free(points);
# Line 2179  void map_track_pos(appdata_t *appdata, l Line 2067  void map_track_pos(appdata_t *appdata, l
2067    }    }
2068    
2069    if(lpos)    if(lpos)
2070      appdata->track.gps_item = canvas_circle_new(appdata->map, CANVAS_GROUP_GPS,      appdata->track.gps_item =
2071          canvas_circle_new(appdata->map->canvas, CANVAS_GROUP_GPS,
2072          lpos->x, lpos->y, appdata->map->style->track.width/2.0, 0,          lpos->x, lpos->y, appdata->map->style->track.width/2.0, 0,
2073                          RGB2CANVAS(appdata->map->style->track.gps_color), NO_COLOR);                          appdata->map->style->track.gps_color, NO_COLOR);
2074  }  }
2075    
2076  /* ------------------- map background ------------------ */  /* ------------------- map background ------------------ */
# Line 2222  void map_set_bg_image(map_t *map, char * Line 2111  void map_set_bg_image(map_t *map, char *
2111    map->bg.scale.y = (float)(bounds->max.y - bounds->min.y)/    map->bg.scale.y = (float)(bounds->max.y - bounds->min.y)/
2112      (float)gdk_pixbuf_get_height(map->bg.pix);      (float)gdk_pixbuf_get_height(map->bg.pix);
2113    
2114    map->bg.item = canvas_image_new(map, CANVAS_GROUP_BG, map->bg.pix,    map->bg.item = canvas_image_new(map->canvas, CANVAS_GROUP_BG, map->bg.pix,
2115            bounds->min.x, bounds->min.y, map->bg.scale.x, map->bg.scale.y);            bounds->min.x, bounds->min.y, map->bg.scale.x, map->bg.scale.y);
2116    
2117    canvas_item_destroy_connect(map->bg.item,    canvas_item_destroy_connect(map->bg.item,

Legend:
Removed from v.13  
changed lines
  Added in v.105