Diff of /trunk/src/map.c

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

revision 54 by harbaum, Fri Feb 6 12:06:30 2009 UTC revision 153 by harbaum, Mon Mar 30 11:14:20 2009 UTC
# Line 43  static void map_statusbar(map_t *map, ma Line 43  static void map_statusbar(map_t *map, ma
43      tag = map_item->way->tag;      tag = map_item->way->tag;
44      break;      break;
45    
46      case MAP_TYPE_RELATION:
47        item_str = "Relation";
48        id = map_item->relation->id;
49        tag = map_item->relation->tag;
50        break;
51    
52    default:    default:
53      break;      break;
54    }    }
# Line 166  static void map_node_select(appdata_t *a Line 172  static void map_node_select(appdata_t *a
172    
173    map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,    map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,
174                      x, y, radius, map->style->highlight.color);                      x, y, radius, map->style->highlight.color);
175    
176    if(!map_item->item) {    if(!map_item->item) {
177      /* and draw a fake node */      /* and draw a fake node */
178      new_map_item = g_new0(map_item_t, 1);      new_map_item = g_new0(map_item_t, 1);
179      memcpy(new_map_item, map_item, sizeof(map_item_t));      memcpy(new_map_item, map_item, sizeof(map_item_t));
180      new_map_item->highlight = TRUE;      new_map_item->highlight = TRUE;
181      map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,      map_hl_circle_new(map, CANVAS_GROUP_NODES_IHL, new_map_item,
182                        x, y, map->style->node.radius,                        x, y, map->style->node.radius,
183                        map->style->highlight.node_color);                        map->style->highlight.node_color);
184    }    }
# Line 234  void map_way_select(appdata_t *appdata, Line 240  void map_way_select(appdata_t *appdata,
240          points->coords[2*2+0] = center.x - diff.y - diff.x;          points->coords[2*2+0] = center.x - diff.y - diff.x;
241          points->coords[2*2+1] = center.y + diff.x - diff.y;          points->coords[2*2+1] = center.y + diff.x - diff.y;
242    
243          map_hl_polygon_new(map, CANVAS_GROUP_NODES_HL, new_map_item,          map_hl_polygon_new(map, CANVAS_GROUP_WAYS_DIR, new_map_item,
244                             points, map->style->highlight.arrow_color);                             points, map->style->highlight.arrow_color);
245    
246          canvas_points_free(points);          canvas_points_free(points);
# Line 252  void map_way_select(appdata_t *appdata, Line 258  void map_way_select(appdata_t *appdata,
258        gint x = node_chain->node->lpos.x;        gint x = node_chain->node->lpos.x;
259        gint y = node_chain->node->lpos.y;        gint y = node_chain->node->lpos.y;
260    
261        map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item,        map_hl_circle_new(map, CANVAS_GROUP_NODES_IHL, new_map_item,
262                          x, y, map->style->node.radius,                          x, y, map->style->node.radius,
263                          map->style->highlight.node_color);                          map->style->highlight.node_color);
264      }      }
# Line 290  void map_way_select(appdata_t *appdata, Line 296  void map_way_select(appdata_t *appdata,
296    }    }
297  }  }
298    
299    void map_relation_select(appdata_t *appdata, relation_t *relation) {
300      map_t *map = appdata->map;
301    
302      printf("highlighting relation %ld\n", relation->id);
303    
304      g_assert(!map->highlight);
305      map_highlight_t **hl = &map->highlight;
306    
307      map_item_t *map_item = &map->selected;
308      map_item->type      = MAP_TYPE_RELATION;
309      map_item->relation  = relation;
310      map_item->highlight = FALSE;
311      map_item->item      = NULL;
312    
313      map_statusbar(map, map_item);
314      icon_bar_map_item_selected(appdata, map_item, TRUE);
315    
316      /* process all members */
317      member_t *member = relation->member;
318      while(member) {
319        canvas_item_t *item = NULL;
320    
321        switch(member->type) {
322    
323        case NODE: {
324          node_t *node = member->node;
325          printf("  -> node %ld\n", node->id);
326    
327          item = canvas_circle_new(map->canvas, CANVAS_GROUP_NODES_HL,
328                            node->lpos.x, node->lpos.y,
329                            map->style->highlight.width + map->style->node.radius,
330                            0, map->style->highlight.color, NO_COLOR);
331          } break;
332    
333        case WAY: {
334          way_t *way = member->way;
335          /* a way needs at least 2 points to be drawn */
336          guint nodes = osm_way_number_of_nodes(way);
337          if(nodes > 1) {
338    
339            /* allocate space for nodes */
340            canvas_points_t *points = canvas_points_new(nodes);
341    
342            int node = 0;
343            node_chain_t *node_chain = way->node_chain;
344            while(node_chain) {
345              canvas_point_set_pos(points, node++, &node_chain->node->lpos);
346              node_chain = node_chain->next;
347            }
348    
349            if(way->draw.flags & OSM_DRAW_FLAG_AREA)
350              item = canvas_polygon_new(map->canvas, CANVAS_GROUP_WAYS_HL, points, 0, 0,
351                                        map->style->highlight.color);
352            else
353              item = canvas_polyline_new(map->canvas, CANVAS_GROUP_WAYS_HL, points,
354                                  (way->draw.flags & OSM_DRAW_FLAG_BG)?
355                                  2*map->style->highlight.width + way->draw.bg.width:
356                                  2*map->style->highlight.width + way->draw.width,
357                                  map->style->highlight.color);
358    
359            canvas_points_free(points);
360          } } break;
361    
362        default:
363          break;
364        }
365    
366        /* attach item to item chain */
367        if(item) {
368          *hl = g_new0(map_highlight_t, 1);
369          (*hl)->item = item;
370          hl = &(*hl)->next;
371        }
372    
373        member = member->next;
374      }
375    }
376    
377  static void map_item_select(appdata_t *appdata, map_item_t *map_item) {  static void map_item_select(appdata_t *appdata, map_item_t *map_item) {
378    switch(map_item->type) {    switch(map_item->type) {
379    case MAP_TYPE_NODE:    case MAP_TYPE_NODE:
# Line 379  static canvas_item_t *map_node_new(map_t Line 463  static canvas_item_t *map_node_new(map_t
463    map_item->node = node;    map_item->node = node;
464    
465    if(!node->icon_buf || !map->style->icon.enable ||    if(!node->icon_buf || !map->style->icon.enable ||
466       map->appdata->settings->no_icons)       map->appdata->settings->no_icons)
467      map_item->item = canvas_circle_new(map, CANVAS_GROUP_NODES,      map_item->item = canvas_circle_new(map->canvas, CANVAS_GROUP_NODES,
468         node->lpos.x, node->lpos.y, radius, width, fill, border);         node->lpos.x, node->lpos.y, radius, width, fill, border);
469    else    else
470      map_item->item = canvas_image_new(map, CANVAS_GROUP_NODES,      map_item->item = canvas_image_new(map->canvas, CANVAS_GROUP_NODES,
471        node->icon_buf,        node->icon_buf,
472        node->lpos.x - map->style->icon.scale/2 *        node->lpos.x - map->style->icon.scale/2 *
473                        gdk_pixbuf_get_width(node->icon_buf),                        gdk_pixbuf_get_width(node->icon_buf),
# Line 415  static canvas_item_t *map_way_single_new Line 499  static canvas_item_t *map_way_single_new
499    map_item_t *map_item = g_new0(map_item_t, 1);    map_item_t *map_item = g_new0(map_item_t, 1);
500    map_item->type = MAP_TYPE_WAY;    map_item->type = MAP_TYPE_WAY;
501    map_item->way = way;    map_item->way = way;
502    map_item->item = canvas_circle_new(map, CANVAS_GROUP_WAYS,    map_item->item = canvas_circle_new(map->canvas, CANVAS_GROUP_WAYS,
503            way->node_chain->node->lpos.x, way->node_chain->node->lpos.y,            way->node_chain->node->lpos.x, way->node_chain->node->lpos.y,
504                                       radius, width, fill, border);                                       radius, width, fill, border);
505    
# Line 444  static canvas_item_t *map_way_new(map_t Line 528  static canvas_item_t *map_way_new(map_t
528    
529    if(way->draw.flags & OSM_DRAW_FLAG_AREA) {    if(way->draw.flags & OSM_DRAW_FLAG_AREA) {
530      if(map->style->area.color & 0xff)      if(map->style->area.color & 0xff)
531        map_item->item = canvas_polygon_new(map, group, points,        map_item->item = canvas_polygon_new(map->canvas, group, points,
532                                            width, color, fill_color);                                            width, color, fill_color);
533      else      else
534        map_item->item = canvas_polyline_new(map, group, points,        map_item->item = canvas_polyline_new(map->canvas, group, points,
535                                             width, color);                                             width, color);
536    } else {    } else {
537      map_item->item = canvas_polyline_new(map, group, points, width, color);      map_item->item = canvas_polyline_new(map->canvas, group, points, width, color);
538    }    }
539    
540    canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max);    canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max);
541    
542      /* a ways outline itself is never dashed */
543    if (group != CANVAS_GROUP_WAYS_OL)    if (group != CANVAS_GROUP_WAYS_OL)
544      if (way->draw.dashed)      if (way->draw.dashed)
545        canvas_item_set_dashed(map_item->item, width, way->draw.dash_length);        canvas_item_set_dashed(map_item->item, width, way->draw.dash_length);
# Line 506  void map_way_draw(map_t *map, way_t *way Line 591  void map_way_draw(map_t *map, way_t *way
591        map_way_new(map, CANVAS_GROUP_POLYGONS, way, points,        map_way_new(map, CANVAS_GROUP_POLYGONS, way, points,
592                    way->draw.width, way->draw.color, way->draw.area.color);                    way->draw.width, way->draw.color, way->draw.area.color);
593      } else {      } else {
       map_way_new(map, CANVAS_GROUP_WAYS, way, points,  
                   way->draw.width, way->draw.color, NO_COLOR);  
594    
595        if(way->draw.flags & OSM_DRAW_FLAG_BG)        if(way->draw.flags & OSM_DRAW_FLAG_BG) {
596            map_way_new(map, CANVAS_GROUP_WAYS_INT, way, points,
597                        way->draw.width, way->draw.color, NO_COLOR);
598    
599          map_way_new(map, CANVAS_GROUP_WAYS_OL, way, points,          map_way_new(map, CANVAS_GROUP_WAYS_OL, way, points,
600                      way->draw.bg.width, way->draw.bg.color, NO_COLOR);                      way->draw.bg.width, way->draw.bg.color, NO_COLOR);
601    
602          } else
603            map_way_new(map, CANVAS_GROUP_WAYS, way, points,
604                        way->draw.width, way->draw.color, NO_COLOR);
605      }      }
606      canvas_points_free(points);      canvas_points_free(points);
607    }    }
# Line 622  void map_frisket_draw(map_t *map, bounds Line 712  void map_frisket_draw(map_t *map, bounds
712      /* top rectangle */      /* top rectangle */
713      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,
714                            mult*bounds->min.y, bounds->min.y);                            mult*bounds->min.y, bounds->min.y);
715      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
716                           1, NO_COLOR, color);
717    
718      /* bottom rectangle */      /* bottom rectangle */
719      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,      map_frisket_rectangle(points, mult*bounds->min.x, mult*bounds->max.x,
720                            bounds->max.y, mult*bounds->max.y);                            bounds->max.y, mult*bounds->max.y);
721      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
722                           1, NO_COLOR, color);
723    
724      /* left rectangle */      /* left rectangle */
725      map_frisket_rectangle(points, mult*bounds->min.x, bounds->min.x,      map_frisket_rectangle(points, mult*bounds->min.x, bounds->min.x,
726                            mult*bounds->min.y, mult*bounds->max.y);                            mult*bounds->min.y, mult*bounds->max.y);
727      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
728                           1, NO_COLOR, color);
729    
730      /* right rectangle */      /* right rectangle */
731      map_frisket_rectangle(points, bounds->max.x, mult*bounds->max.x,      map_frisket_rectangle(points, bounds->max.x, mult*bounds->max.x,
732                            mult*bounds->min.y, mult*bounds->max.y);                            mult*bounds->min.y, mult*bounds->max.y);
733      canvas_polygon_new(map, CANVAS_GROUP_NODES, points, 1, NO_COLOR, color);      canvas_polygon_new(map->canvas, CANVAS_GROUP_FRISKET, points,
734                           1, NO_COLOR, color);
735    
736    }    }
737    
# Line 648  void map_frisket_draw(map_t *map, bounds Line 742  void map_frisket_draw(map_t *map, bounds
742                            bounds->min.x-ew2, bounds->max.x+ew2,                            bounds->min.x-ew2, bounds->max.x+ew2,
743                            bounds->min.y-ew2, bounds->max.y+ew2);                            bounds->min.y-ew2, bounds->max.y+ew2);
744    
745      canvas_polyline_new(map, CANVAS_GROUP_NODES, points,      canvas_polyline_new(map->canvas, CANVAS_GROUP_FRISKET, points,
746                          map->style->frisket.border.width,                          map->style->frisket.border.width,
747                          map->style->frisket.border.color);                          map->style->frisket.border.color);
748    
# Line 839  map_item_t *map_real_item_at(map_t *map, Line 933  map_item_t *map_real_item_at(map_t *map,
933    return map_item;    return map_item;
934  }  }
935    
   
   
 #ifdef USE_GOOCANVAS  
   
936  /* 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
937   * map visible at all times */   * map visible at all times */
938  static void map_limit_scroll(map_t *map, gint *sx, gint *sy) {  static void map_limit_scroll(map_t *map, canvas_unit_t unit,
939      gdouble zoom = goo_canvas_get_scale(GOO_CANVAS(map->canvas));                               gint *sx, gint *sy) {
   
     gint sx_cu = *sx / zoom;  
     gint sy_cu = *sy / zoom;  
   
     // Canvas viewport dimensions  
     GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;  
     gint aw_cu = a->width / zoom;  
     gint ah_cu = a->height / zoom;  
   
     // Data rect minimum and maximum  
     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;  
940    
941      // limit stops - prevent scrolling beyond these    /* get scale factor for pixel->meter conversion. set to 1 if */
942      gint min_sy_cu = 0.95*(min_y - ah_cu);    /* given coordinates are already in meters */
943      gint min_sx_cu = 0.95*(min_x - aw_cu);    gdouble scale = (unit == CANVAS_UNIT_METER)?1.0:canvas_get_zoom(map->canvas);
944      gint max_sy_cu = 0.95*(max_y);  
945      gint max_sx_cu = 0.95*(max_x);    /* convert pixels to meters if necessary */
946      if (sy_cu < min_sy_cu) { *sy = min_sy_cu*zoom; }    gdouble sx_cu = *sx / scale;
947      if (sx_cu < min_sx_cu) { *sx = min_sx_cu*zoom; }    gdouble sy_cu = *sy / scale;
948      if (sy_cu > max_sy_cu) { *sy = max_sy_cu*zoom; }  
949      if (sx_cu > max_sx_cu) { *sx = max_sx_cu*zoom; }    /* get size of visible area in canvas units (meters) */
950      gint aw_cu = canvas_get_viewport_width(map->canvas, CANVAS_UNIT_METER);
951      gint ah_cu = canvas_get_viewport_height(map->canvas, CANVAS_UNIT_METER);
952    
953      // Data rect minimum and maximum
954      gint min_x, min_y, max_x, max_y;
955      min_x = map->appdata->osm->bounds->min.x;
956      min_y = map->appdata->osm->bounds->min.y;
957      max_x = map->appdata->osm->bounds->max.x;
958      max_y = map->appdata->osm->bounds->max.y;
959    
960      // limit stops - prevent scrolling beyond these
961      gint min_sy_cu = 0.95*(min_y - ah_cu);
962      gint min_sx_cu = 0.95*(min_x - aw_cu);
963      gint max_sy_cu = 0.95*(max_y);
964      gint max_sx_cu = 0.95*(max_x);
965      if (sy_cu < min_sy_cu) { *sy = min_sy_cu * scale; }
966      if (sx_cu < min_sx_cu) { *sx = min_sx_cu * scale; }
967      if (sy_cu > max_sy_cu) { *sy = max_sy_cu * scale; }
968      if (sx_cu > max_sx_cu) { *sx = max_sx_cu * scale; }
969  }  }
970    
971    
# Line 885  static gboolean map_limit_zoom(map_t *ma Line 979  static gboolean map_limit_zoom(map_t *ma
979      max_x = map->appdata->osm->bounds->max.x;      max_x = map->appdata->osm->bounds->max.x;
980      max_y = map->appdata->osm->bounds->max.y;      max_y = map->appdata->osm->bounds->max.y;
981    
982      // Canvas viewport dimensions      /* get size of visible area in pixels and convert to meters of intended */
983      GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;      /* zoom by deviding by zoom (which is basically pix/m) */
984      gint ah_cu = a->height / *zoom;      gint aw_cu =
985      gint aw_cu = a->width / *zoom;        canvas_get_viewport_width(map->canvas, CANVAS_UNIT_PIXEL) / *zoom;
986        gint ah_cu =
987          canvas_get_viewport_height(map->canvas, CANVAS_UNIT_PIXEL) / *zoom;
988    
989      gdouble oldzoom = *zoom;      gdouble oldzoom = *zoom;
990      if (ah_cu < aw_cu) {      if (ah_cu < aw_cu) {
# Line 913  static gboolean map_limit_zoom(map_t *ma Line 1009  static gboolean map_limit_zoom(map_t *ma
1009  }  }
1010    
1011    
 #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  
   
1012  /*  /*
1013   * Scroll the map to a point if that point is currently offscreen.   * Scroll the map to a point if that point is currently offscreen.
1014   */   */
# Line 1007  void map_scroll_to_if_offscreen(map_t *m Line 1031  void map_scroll_to_if_offscreen(map_t *m
1031    }    }
1032    
1033    // Viewport dimensions in canvas space    // Viewport dimensions in canvas space
1034    gdouble zoom = goo_canvas_get_scale(GOO_CANVAS(map->canvas));  
1035    GtkAllocation *a = &GTK_WIDGET(map->canvas)->allocation;    /* get size of visible area in canvas units (meters) */
1036    gdouble aw = a->width / zoom;    gdouble pix_per_meter = canvas_get_zoom(map->canvas);
1037    gdouble ah = a->height / zoom;    gdouble aw = canvas_get_viewport_width(map->canvas, CANVAS_UNIT_METER);
1038      gdouble ah = canvas_get_viewport_height(map->canvas, CANVAS_UNIT_METER);
1039    
1040    // Is the point still onscreen?    // Is the point still onscreen?
1041    gboolean vert_recentre_needed = FALSE;    gboolean vert_recentre_needed = FALSE;
1042    gboolean horiz_recentre_needed = FALSE;    gboolean horiz_recentre_needed = FALSE;
1043    gint sx, sy;    gint sx, sy;
1044    canvas_get_scroll_offsets(map->canvas, &sx, &sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1045    gint viewport_left   = (sx/zoom);    gint viewport_left   = (sx/pix_per_meter);
1046    gint viewport_right  = (sx/zoom)+aw;    gint viewport_right  = (sx/pix_per_meter)+aw;
1047    gint viewport_top    = (sy/zoom);    gint viewport_top    = (sy/pix_per_meter);
1048    gint viewport_bottom = (sy/zoom)+ah;    gint viewport_bottom = (sy/pix_per_meter)+ah;
1049    if (lpos->x > viewport_right) {    if (lpos->x > viewport_right) {
1050      printf("** off right edge (%d > %d)\n", lpos->x, viewport_right);      printf("** off right edge (%d > %d)\n", lpos->x, viewport_right);
1051      horiz_recentre_needed = TRUE;      horiz_recentre_needed = TRUE;
# Line 1040  void map_scroll_to_if_offscreen(map_t *m Line 1065  void map_scroll_to_if_offscreen(map_t *m
1065    
1066    if (horiz_recentre_needed || vert_recentre_needed) {    if (horiz_recentre_needed || vert_recentre_needed) {
1067      gint new_sx, new_sy;      gint new_sx, new_sy;
1068  #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  
1069      // Just centre both at once      // Just centre both at once
1070      new_sx = zoom * (lpos->x - (aw/2));      new_sx = pix_per_meter * (lpos->x - (aw/2));
1071      new_sy = zoom * (lpos->y - (ah/2));      new_sy = pix_per_meter * (lpos->y - (ah/2));
1072  #endif  
1073      map_limit_scroll(map, &new_sx, &new_sy);      map_limit_scroll(map, CANVAS_UNIT_PIXEL, &new_sx, &new_sy);
1074      canvas_scroll_to(map->canvas, new_sx, new_sy);      canvas_scroll_to(map->canvas, CANVAS_UNIT_PIXEL, new_sx, new_sy);
1075    }    }
1076  }  }
1077    
 #endif // #ifdef USE_GOOCANVAS  
   
1078  /* Deselects the current way or node if its zoom_max  /* Deselects the current way or node if its zoom_max
1079   * 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. */
1080  void map_deselect_if_zoom_below_zoom_max(map_t *map) {  void map_deselect_if_zoom_below_zoom_max(map_t *map) {
# Line 1081  void map_deselect_if_zoom_below_zoom_max Line 1099  void map_deselect_if_zoom_below_zoom_max
1099  void map_set_zoom(map_t *map, double zoom,  void map_set_zoom(map_t *map, double zoom,
1100                    gboolean update_scroll_offsets) {                    gboolean update_scroll_offsets) {
1101    gboolean at_zoom_limit = 0;    gboolean at_zoom_limit = 0;
 #ifdef USE_GOOCANVAS  
1102    at_zoom_limit = map_limit_zoom(map, &zoom);    at_zoom_limit = map_limit_zoom(map, &zoom);
1103  #endif  
1104    map->state->zoom = zoom;    map->state->zoom = zoom;
1105    canvas_set_zoom(map->canvas, map->state->zoom);    canvas_set_zoom(map->canvas, map->state->zoom);
1106    
1107    map_deselect_if_zoom_below_zoom_max(map);    map_deselect_if_zoom_below_zoom_max(map);
1108    
1109    if (update_scroll_offsets) {    if(update_scroll_offsets) {
1110      if (!at_zoom_limit) {      if (!at_zoom_limit) {
1111        /* zooming affects the scroll offsets */        /* zooming affects the scroll offsets */
1112        gint sx, sy;        gint sx, sy;
1113        canvas_get_scroll_offsets(map->canvas, &sx, &sy);        canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1114  #ifdef USE_GOOCANVAS        map_limit_scroll(map, CANVAS_UNIT_PIXEL, &sx, &sy);
1115        map_limit_scroll(map, &sx, &sy);  
1116        canvas_scroll_to(map->canvas, sx, sy);  // keep the map visible        // keep the map visible
1117  #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);  
1118      }      }
1119  #endif  
1120        canvas_scroll_get(map->canvas, CANVAS_UNIT_METER,
1121                          &map->state->scroll_offset.x,
1122                          &map->state->scroll_offset.y);
1123    }    }
1124  }  }
1125    
# Line 1130  static gboolean map_scroll_event(GtkWidg Line 1144  static gboolean map_scroll_event(GtkWidg
1144  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) {
1145    gint sx, sy;    gint sx, sy;
1146    
 #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  
1147    /* add offsets generated by mouse within map and map scrolling */    /* add offsets generated by mouse within map and map scrolling */
1148    sx = (x-map->pen_down.at.x);    sx = (x-map->pen_down.at.x);
1149    sy = (y-map->pen_down.at.y);    sy = (y-map->pen_down.at.y);
 #endif  
1150    
1151    return(sx*sx + sy*sy > limit*limit);    return(sx*sx + sy*sy > limit*limit);
1152  }  }
# Line 1149  static gboolean distance_above(map_t *ma Line 1155  static gboolean distance_above(map_t *ma
1155  static void map_do_scroll(map_t *map, gint x, gint y) {  static void map_do_scroll(map_t *map, gint x, gint y) {
1156    gint sx, sy;    gint sx, sy;
1157    
1158    canvas_get_scroll_offsets(map->canvas, &sx, &sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1159    sx -= x-map->pen_down.at.x;    sx -= x-map->pen_down.at.x;
1160    sy -= y-map->pen_down.at.y;    sy -= y-map->pen_down.at.y;
1161  #ifdef USE_GOOCANVAS    map_limit_scroll(map, CANVAS_UNIT_PIXEL, &sx, &sy);
1162    map_limit_scroll(map, &sx, &sy);    canvas_scroll_to(map->canvas, CANVAS_UNIT_PIXEL, sx, sy);
1163  #endif  
1164    canvas_scroll_to(map->canvas, sx, sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_METER,
1165    map->state->scroll_offset.x = sx;                      &map->state->scroll_offset.x,
1166    map->state->scroll_offset.y = sy;                      &map->state->scroll_offset.y);
1167  }  }
1168    
1169    
1170  /* scroll a certain step */  /* scroll a certain step */
1171  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) {
1172    gint sx, sy;    gint sx, sy;
1173    canvas_get_scroll_offsets(map->canvas, &sx, &sy);    canvas_scroll_get(map->canvas, CANVAS_UNIT_PIXEL, &sx, &sy);
1174    sx += x;    sx += x;
1175    sy += y;    sy += y;
1176  #ifdef USE_GOOCANVAS    map_limit_scroll(map, CANVAS_UNIT_PIXEL, &sx, &sy);
1177    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;  
 }  
1178    
1179      canvas_scroll_get(map->canvas, CANVAS_UNIT_METER,
1180                        &map->state->scroll_offset.x,
1181                        &map->state->scroll_offset.y);
1182    }
1183    
1184  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) {
1185    printf("check if item is a selected node\n");    printf("check if item is a selected node\n");
# Line 1393  static void map_button_press(map_t *map, Line 1398  static void map_button_press(map_t *map,
1398    map->pen_down.at.y = y;    map->pen_down.at.y = y;
1399    map->pen_down.drag = FALSE;     // don't assume drag yet    map->pen_down.drag = FALSE;     // don't assume drag yet
1400    
 #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  
   
1401    /* determine wether this press was on an item */    /* determine wether this press was on an item */
1402    map->pen_down.on_item = map_real_item_at(map, x, y);    map->pen_down.on_item = map_real_item_at(map, x, y);
1403    
# Line 1598  static gboolean map_motion_notify_event( Line 1597  static gboolean map_motion_notify_event(
1597    if(!map->pen_down.is)    if(!map->pen_down.is)
1598      return FALSE;      return FALSE;
1599    
1600  #ifdef USE_GNOMECANVAS  #ifndef USE_GOOCANVAS
1601    /* handle hints, hints are handled by goocanvas directly */    /* handle hints, hints are handled by goocanvas directly */
1602    if(event->is_hint)    if(event->is_hint)
1603      gdk_window_get_pointer(event->window, &x, &y, &state);      gdk_window_get_pointer(event->window, &x, &y, &state);
# Line 1643  static gboolean map_motion_notify_event( Line 1642  static gboolean map_motion_notify_event(
1642    
1643    case MAP_ACTION_WAY_NODE_ADD:    case MAP_ACTION_WAY_NODE_ADD:
1644      map_hl_cursor_clear(map);      map_hl_cursor_clear(map);
1645      map_item_t *item = map_real_item_at(map, x, y);      map_item_t *item = map_item_at(map, x, y);
1646      if(item) map_edit_way_node_add_highlight(map, item, x, y);      if(item) map_edit_way_node_add_highlight(map, item, x, y);
1647      break;      break;
1648    
1649    case MAP_ACTION_WAY_CUT:    case MAP_ACTION_WAY_CUT:
1650      map_hl_cursor_clear(map);      map_hl_cursor_clear(map);
1651      item = map_real_item_at(map, x, y);      item = map_item_at(map, x, y);
1652      if(item) map_edit_way_cut_highlight(map, item, x, y);      if(item) map_edit_way_cut_highlight(map, item, x, y);
1653      break;      break;
1654    
# Line 1762  GtkWidget *map_new(appdata_t *appdata) { Line 1761  GtkWidget *map_new(appdata_t *appdata) {
1761    map->appdata = appdata;    map->appdata = appdata;
1762    map->action.type = MAP_ACTION_IDLE;    map->action.type = MAP_ACTION_IDLE;
1763    
1764  #ifdef USE_GNOMECANVAS    map->canvas = canvas_new(map->style->background.color);
1765    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);  
1766    
1767    gtk_widget_modify_bg(map->canvas, GTK_STATE_NORMAL,    GtkWidget *canvas_widget = canvas_get_widget(map->canvas);
                        &map->canvas->style->white);  
1768    
1769  #else    gtk_widget_set_events(canvas_widget,
   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 >> 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;  
   for(group = 0; group < CANVAS_GROUPS; group++)  
     map->group[group] = goo_canvas_group_new(root, NULL);  
   
 #endif  
   
   gtk_widget_set_events(map->canvas,  
1770                            GDK_BUTTON_PRESS_MASK                            GDK_BUTTON_PRESS_MASK
1771                          | GDK_BUTTON_RELEASE_MASK                          | GDK_BUTTON_RELEASE_MASK
1772                          | GDK_SCROLL_MASK                          | GDK_SCROLL_MASK
1773                          | GDK_POINTER_MOTION_MASK                          | GDK_POINTER_MOTION_MASK
1774                          | GDK_POINTER_MOTION_HINT_MASK);                          | GDK_POINTER_MOTION_HINT_MASK);
1775    
1776    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1777       "button_press_event", G_CALLBACK(map_button_event), appdata);       "button_press_event", G_CALLBACK(map_button_event), appdata);
1778    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1779       "button_release_event", G_CALLBACK(map_button_event), appdata);       "button_release_event", G_CALLBACK(map_button_event), appdata);
1780    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1781       "motion_notify_event", G_CALLBACK(map_motion_notify_event), appdata);       "motion_notify_event", G_CALLBACK(map_motion_notify_event), appdata);
1782    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1783       "scroll_event", G_CALLBACK(map_scroll_event), appdata);       "scroll_event", G_CALLBACK(map_scroll_event), appdata);
1784    
1785    gtk_signal_connect(GTK_OBJECT(map->canvas),    gtk_signal_connect(GTK_OBJECT(canvas_widget),
1786       "destroy", G_CALLBACK(map_destroy_event), appdata);       "destroy", G_CALLBACK(map_destroy_event), appdata);
1787    
1788    return map->canvas;    return canvas_widget;
1789  }  }
1790    
1791  void map_init(appdata_t *appdata) {  void map_init(appdata_t *appdata) {
# Line 1833  void map_init(appdata_t *appdata) { Line 1804  void map_init(appdata_t *appdata) {
1804                      mult*appdata->osm->bounds->max.x,                      mult*appdata->osm->bounds->max.x,
1805                      mult*appdata->osm->bounds->max.y);                      mult*appdata->osm->bounds->max.y);
1806    
1807    printf("restore scroll offsets %d/%d\n",    printf("restore scroll position %d/%d\n",
1808           map->state->scroll_offset.x, map->state->scroll_offset.y);           map->state->scroll_offset.x, map->state->scroll_offset.y);
1809    
1810    canvas_scroll_to(map->canvas,    map_limit_scroll(map, CANVAS_UNIT_METER,
1811                     map->state->scroll_offset.x, map->state->scroll_offset.y);             &map->state->scroll_offset.x, &map->state->scroll_offset.y);
1812      canvas_scroll_to(map->canvas, CANVAS_UNIT_METER,
1813               map->state->scroll_offset.x, map->state->scroll_offset.y);
1814  }  }
1815    
1816    
# Line 1854  void map_item_set_flags(map_item_t *map_ Line 1827  void map_item_set_flags(map_item_t *map_
1827      map_item->way->flags &= ~clr;      map_item->way->flags &= ~clr;
1828      break;      break;
1829    
1830      case MAP_TYPE_RELATION:
1831        map_item->relation->flags |=  set;
1832        map_item->relation->flags &= ~clr;
1833        break;
1834    
1835    default:    default:
1836      g_assert(0);      g_assert(0);
1837      break;      break;
1838    }    }
1839  }  }
1840    
1841  void map_clear(appdata_t *appdata, gint layer_mask) {  void map_clear(appdata_t *appdata, gint group_mask) {
1842    map_t *map = appdata->map;    map_t *map = appdata->map;
1843    
1844    printf("freeing map contents\n");    printf("freeing map contents\n");
# Line 1870  void map_clear(appdata_t *appdata, gint Line 1848  void map_clear(appdata_t *appdata, gint
1848    /* remove a possibly existing highlight */    /* remove a possibly existing highlight */
1849    map_item_deselect(appdata);    map_item_deselect(appdata);
1850    
1851    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  
   }  
1852  }  }
1853    
1854  void map_paint(appdata_t *appdata) {  void map_paint(appdata_t *appdata) {
1855    map_t *map = appdata->map;    map_t *map = appdata->map;
1856    
1857    /* user may have changes antialias settings */    /* user may have changed antialias settings */
1858    GooCanvasItem *root = goo_canvas_get_root_item(GOO_CANVAS(map->canvas));    canvas_set_antialias(map->canvas, !appdata->settings->no_antialias);
   g_object_set(G_OBJECT(root), "antialias",  
                appdata->settings->no_antialias?CAIRO_ANTIALIAS_NONE:  
                CAIRO_ANTIALIAS_DEFAULT, NULL);  
1859    
1860    josm_elemstyles_colorize_world(map->style, appdata->osm);    josm_elemstyles_colorize_world(map->style, appdata->osm);
1861    map_draw(map, appdata->osm);    map_draw(map, appdata->osm);
# Line 2119  void map_track_draw_seg(map_t *map, trac Line 2074  void map_track_draw_seg(map_t *map, trac
2074    if(pnum == 1) {    if(pnum == 1) {
2075      g_assert(!seg->item);      g_assert(!seg->item);
2076    
2077      seg->item = canvas_circle_new(map, CANVAS_GROUP_TRACK,      seg->item = canvas_circle_new(map->canvas, CANVAS_GROUP_TRACK,
2078            seg->track_point->lpos.x, seg->track_point->lpos.y,            seg->track_point->lpos.x, seg->track_point->lpos.y,
2079            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);
2080    }    }
# Line 2141  void map_track_draw_seg(map_t *map, trac Line 2096  void map_track_draw_seg(map_t *map, trac
2096      if(seg->item)      if(seg->item)
2097        canvas_item_destroy(seg->item);        canvas_item_destroy(seg->item);
2098    
2099      seg->item = canvas_polyline_new(map, CANVAS_GROUP_TRACK,      seg->item = canvas_polyline_new(map->canvas, CANVAS_GROUP_TRACK,
2100            points, map->style->track.width, map->style->track.color);            points, map->style->track.width, map->style->track.color);
2101    
2102      canvas_points_free(points);      canvas_points_free(points);
# Line 2207  void map_track_pos(appdata_t *appdata, l Line 2162  void map_track_pos(appdata_t *appdata, l
2162    }    }
2163    
2164    if(lpos)    if(lpos)
2165      appdata->track.gps_item = canvas_circle_new(appdata->map, CANVAS_GROUP_GPS,      appdata->track.gps_item =
2166          canvas_circle_new(appdata->map->canvas, CANVAS_GROUP_GPS,
2167          lpos->x, lpos->y, appdata->map->style->track.width/2.0, 0,          lpos->x, lpos->y, appdata->map->style->track.width/2.0, 0,
2168                          appdata->map->style->track.gps_color, NO_COLOR);                          appdata->map->style->track.gps_color, NO_COLOR);
2169  }  }
# Line 2250  void map_set_bg_image(map_t *map, char * Line 2206  void map_set_bg_image(map_t *map, char *
2206    map->bg.scale.y = (float)(bounds->max.y - bounds->min.y)/    map->bg.scale.y = (float)(bounds->max.y - bounds->min.y)/
2207      (float)gdk_pixbuf_get_height(map->bg.pix);      (float)gdk_pixbuf_get_height(map->bg.pix);
2208    
2209    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,
2210            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);
2211    
2212    canvas_item_destroy_connect(map->bg.item,    canvas_item_destroy_connect(map->bg.item,
# Line 2295  void map_show_all(appdata_t *appdata) { Line 2251  void map_show_all(appdata_t *appdata) {
2251    
2252    gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);    gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);
2253  }  }
2254    
2255  // vim:et:ts=8:sw=2:sts=2:ai  // vim:et:ts=8:sw=2:sts=2:ai

Legend:
Removed from v.54  
changed lines
  Added in v.153