From: Kaj-Michael Lang Date: Wed, 30 Apr 2008 10:10:18 +0000 (+0300) Subject: More map widget work X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe995717e3963b1108a5fa163ee9b8af4ec0f67e;p=mapper More map widget work --- diff --git a/src/gtkmap.c b/src/gtkmap.c index c16b639..f2a738c 100644 --- a/src/gtkmap.c +++ b/src/gtkmap.c @@ -19,7 +19,7 @@ #include #include - +#include #include #ifdef WITH_GL @@ -28,6 +28,8 @@ #endif #include "image-cache.h" +#include "map-repo.h" +#include "latlon.h" #include "gtkmap.h" #define MAP_THUMB_MARGIN_X (100) @@ -39,6 +41,8 @@ #define BUF_WIDTH_PIXELS (1024) #define BUF_HEIGHT_PIXELS (768) +#define SCALE_WIDTH (300) + #define MAP_CACHE_DEFAULT (64) G_DEFINE_TYPE(GtkMap, gtk_map, GTK_TYPE_WIDGET); @@ -48,6 +52,7 @@ G_DEFINE_TYPE(GtkMap, gtk_map, GTK_TYPE_WIDGET); typedef struct _GtkMapPriv GtkMapPriv; struct _GtkMapPriv { + /* Map image buffer */ GdkPixmap *buffer; PangoContext *context; @@ -68,11 +73,15 @@ struct _GtkMapPriv GdkGC *speed_gc1; GdkGC *speed_gc2; + GdkGC *speed_gc; GdkRectangle scale_rect; + RepoData *curr_repo; + GTimer *timer; ImageCache *icache; + GList *markers; #ifdef WITH_GL GdkGLConfig* gl_config; @@ -96,22 +105,28 @@ struct _GtkMapPriv GtkMapCenterMode center_mode; + Point center; Point min_center; Point max_center; - Point focus; - Point center; + + Point location; guint lead_ratio; guint center_ratio; - guint base_tile_x; - guint base_tile_y; + guint base_tilex; + guint base_tiley; gint zoom; gint max_zoom; gint min_zoom; + gfloat units_conv; + gchar *units_str; + + gfloat speed; + gint offsetx; gint offsety; @@ -131,6 +146,8 @@ struct _GtkMapPriv guint draw_width; + gboolean fast_render; + guint key_zoom_new; guint key_zoom_timeout_sid; }; @@ -163,16 +180,61 @@ struct _GtkMapPriv #define unit2y(unit) (unit2pixel(unit) - tile2pixel(priv->base_tiley) - priv->offsety) #define y2unit(y) (pixel2unit(y + priv->offsety) + tile2unit(priv->base_tiley)) -#define leadx2unit(mgps) (mgps.unitx + (priv->lead_ratio) * pixel2unit(mgps.vel_offsetx)) -#define leady2unit(mgps) (mgps.unity + (0.6f*priv->lead_ratio)*pixel2unit(mgps.vel_offsety)) +#define leadx2unit (location->unitx + (priv->lead_ratio) * pixel2unit(priv->vel_offsetx)) +#define leady2unit (location->unity + (0.6f*priv->lead_ratio) * pixel2unit(priv->vel_offsety)) + +#define GTK_MAP_TILE_SIZE_PIXELS (256) +#define GTK_MAP_TILE_SIZE_P2 (8) +#define GTK_MAP_WORLD_SIZE_UNITS(max_zoom) (2 << (max_zoom + GTK_MAP_TILE_SIZE_P2)) + +/* Pans are done two "grids" at a time, or 64 pixels. */ +#define GTK_MAP_PAN_UNITS (grid2unit(2)) + +#define GTK_MAP_MACRO_RECALC_CENTER(center_unitx, center_unity) { \ + switch(priv->center_mode) { \ + case CENTER_LEAD: \ + priv->center.unitx = leadx2unit; \ + priv->center.unity = leady2unit; \ + break; \ + case CENTER_LATLON: \ + priv->center.unitx = priv->location.unitx; \ + priv->center.unity = priv->location.unity; \ + break; \ + default: \ + priv->center.unitx = center_unitx; \ + priv->center.unity = center_unity; \ + break; \ + } \ +}; + +#define GTK_MAP_RECALC_OFFSET(center) { \ + priv->offsetx = grid2pixel(unit2grid(center.unitx) - priv->screen_grids_halfwidth - tile2grid(priv->base_tilex)); \ + priv->offsety = grid2pixel(unit2grid(center.unity) - priv->screen_grids_halfheight - tile2grid(priv->base_tiley)); \ +} + +#define GTK_MAP_RECALC_FOCUS_BASE(sens) { \ + priv->focus.unitx = x2unit(priv->screen_width_pixels * sens / 20); \ + priv->focus.unity = y2unit(priv->screen_height_pixels * sens / 20); \ +} + +#define BOUND(x, a, b) { \ + if((x) < (a)) \ + (x) = (a); \ + else if((x) > (b)) \ + (x) = (b); \ +} static void gtk_map_finalize(GObject *object); static void gtk_map_size_request(GtkWidget *widget, GtkRequisition *requisition); static void gtk_map_size_allocate(GtkWidget *widget, GtkAllocation *allocate); - -static gboolean gtk_map_expose(GtkWidget *widget, GdkEventExpose *event); static void gtk_map_realize(GtkWidget *widget); +static gboolean gtk_map_expose(GtkWidget *widget, GdkEventExpose *event); +static gboolean gtk_map_configure(GtkWidget *widget, GdkEventConfigure *event); + +static void gtk_map_scale_draw(GtkWidget *widget, GdkEventExpose *event); + +static void gtk_map_update_buffer_size(GtkMap *map, gint new_width, gint new_height); static void gtk_map_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gtk_map_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -213,6 +275,7 @@ object_class->get_property = gtk_map_get_property; widget_class->size_request = gtk_map_size_request; widget_class->expose_event = gtk_map_expose; +widget_class->configure_event = gtk_map_configure; widget_class->realize = gtk_map_realize; widget_class->size_allocate = gtk_map_size_allocate; @@ -230,8 +293,12 @@ priv=GTK_MAP_GET_PRIVATE(map); priv->zoom=3; priv->center_mode=CENTER_LATLON; -priv->base_tile_x=-5; -priv->base_tile_y=-5; +priv->base_tilex=-5; +priv->base_tiley=-5; +priv->draw_width=4; + +priv->speed=-1; +priv->speed_gc=priv->speed_gc1; priv->icache=image_cache_new(64); @@ -288,6 +355,49 @@ g_signal_connect(G_OBJECT(map), "button_press_event", G_CALLBACK(gtk_map_cb_butt } +static gboolean +gtk_map_configure(GtkWidget *widget, GdkEventConfigure *event) +{ +guint tw, th; +GtkMap *map; +GtkMapPriv *priv; + +g_return_val_if_fail(GTK_IS_MAP(widget), TRUE); +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +tw=GTK_MAP_TILE_SIZE_PIXELS*((widget->allocation.width/GTK_MAP_TILE_SIZE_PIXELS)+2); +th=GTK_MAP_TILE_SIZE_PIXELS*((widget->allocation.height/GTK_MAP_TILE_SIZE_PIXELS)+2); + +gtk_map_update_buffer_size(GTK_MAP(widget), tw, th); +g_assert(priv->buffer); + +priv->buf_width_pixels=tw; +priv->buf_height_pixels=th; +priv->buf_width_tiles=priv->buf_width_pixels/GTK_MAP_TILE_SIZE_PIXELS; +priv->buf_height_tiles=priv->buf_height_pixels/GTK_MAP_TILE_SIZE_PIXELS; + +priv->screen_width_pixels = widget->allocation.width; +priv->screen_height_pixels = widget->allocation.height; +priv->screen_grids_halfwidth = pixel2grid(priv->screen_width_pixels) / 2; +priv->screen_grids_halfheight = pixel2grid(priv->screen_height_pixels) / 2; + +/* Set scale_rect. */ +priv->scale_rect.x = (priv->screen_width_pixels - SCALE_WIDTH) / 2; +priv->scale_rect.width = SCALE_WIDTH; + +GTK_MAP_MACRO_RECALC_FOCUS_BASE(priv->center_ratio); +GTK_MAP_MACRO_RECALC_FOCUS_SIZE(priv->center_ratio); + +priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth)); +priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight)); +priv->max_center.unitx = GTK_MAP_WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfwidth) - 1; +priv->max_center.unity = GTK_MAP_WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfheight) - 1; + +return TRUE; +} + + static void gtk_map_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -360,6 +470,23 @@ map->width=512; map->height=256; } +static void +gtk_map_update_buffer_size(GtkMap *map, gint new_width, gint new_height) +{ +priv=GTK_MAP_GET_PRIVATE(map); + +if (priv->buffer==NULL) { + priv->buffer=gdk_pixmap_new(GTK_WIDGET(map)->window, new_width, new_height, -1); + return TRUE; +} else if (new_width>priv->buf_width_pixels || new_height>priv->buf_height_pixels) || + new_widthbuffer); + priv->buffer=gdk_pixmap_new(GTK_WIDGET(map)->window, new_width, new_height, -1); + return TRUE; +} +return FALSE; +} + static void gtk_map_realize(GtkWidget *widget) { @@ -396,11 +523,23 @@ gdk_draw_drawable(GDK_DRAWABLE(map), event->area.width, event->area.height); +#if 0 +gtk_map_paths_draw(widget, event); + +gtk_map_markers_draw(widget, event); + +gtk_map_mark_draw(widget, event); + +gtk_map_speed_draw(widget, event); +#endif + +gtk_map_scale_draw(widget, event); + return TRUE; } static void -map_scale_draw(GtkWidget *widget, GdkEventExpose *event) +gtk_map_scale_draw(GtkWidget *widget, GdkEventExpose *event) { GtkMap *map; GtkMapPriv *priv; @@ -420,13 +559,13 @@ priv->scale_rect.y = priv->screen_height_pixels - priv->scale_rect.height - 1; gdk_rectangle_intersect(&event->area, &priv->scale_rect, &event->area); if (event->area.width && event->area.height) { - gdk_draw_rectangle(map->widget->window, - map->widget->style->bg_gc[GTK_WIDGET_STATE(map->widget)], + gdk_draw_rectangle(widget->window, + widget->style->bg_gc[GTK_WIDGET_STATE(widget)], TRUE, priv->scale_rect.x, priv->scale_rect.y, priv->scale_rect.width, priv->scale_rect.height); - gdk_draw_rectangle(map->widget->window, - map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], + gdk_draw_rectangle(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], FALSE, priv->scale_rect.x, priv->scale_rect.y, priv->scale_rect.width, priv->scale_rect.height); @@ -434,54 +573,54 @@ if (event->area.width && event->area.height) { /* Now calculate and draw the distance. */ unit2latlon(priv->center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4), priv->center.unity, lat1, lon1); unit2latlon(priv->center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4), priv->center.unity, lat2, lon2); - distance=calculate_distance(lat1, lon1, lat2, lon2) * UNITS_CONVERT[_units]; + distance=calculate_distance(lat1, lon1, lat2, lon2) * priv->units_conv; if (distance < 1.f) - g_snprintf(buffer, sizeof(buffer), "%0.2f %s", distance, UNITS_TEXT[_units]); + g_snprintf(buffer, sizeof(buffer), "%0.2f %s", distance, priv->units_str); else if (distance < 10.f) - g_snprintf(buffer, sizeof(buffer), "%0.1f %s", distance, UNITS_TEXT[_units]); + g_snprintf(buffer, sizeof(buffer), "%0.1f %s", distance, priv->units_str); else - g_snprintf(buffer, sizeof(buffer), "%0.f %s", distance, UNITS_TEXT[_units]); + g_snprintf(buffer, sizeof(buffer), "%0.f %s", distance, priv->units_str); - pango_layout_set_text(scale_layout, buffer, -1); - pango_layout_get_pixel_size(scale_layout, &width, NULL); + pango_layout_set_text(priv->scale_layout, buffer, -1); + pango_layout_get_pixel_size(priv->scale_layout, &width, NULL); /* Draw the layout itself. */ - gdk_draw_layout(map->widget->window, - map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], + gdk_draw_layout(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], priv->scale_rect.x + (priv->scale_rect.width - width) / 2, - priv->scale_rect.y, scale_layout); + priv->scale_rect.y, priv->scale_layout); /* Draw little hashes on the ends. */ - gdk_draw_line(map->widget->window, - map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], - priv->scale_rect.x + 4, - priv->scale_rect.y + priv->scale_rect.height / 2 - 4, - priv->scale_rect.x + 4, - priv->scale_rect.y + priv->scale_rect.height / 2 + 4); - gdk_draw_line(map->widget->window, - map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], - priv->scale_rect.x + 4, - priv->scale_rect.y + priv->scale_rect.height / 2, - priv->scale_rect.x + (priv->scale_rect.width - width) / 2 - 4, - priv->scale_rect.y + priv->scale_rect.height / 2); - gdk_draw_line(map->widget->window, - map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], - priv->scale_rect.x + priv->scale_rect.width - 4, - priv->scale_rect.y + priv->scale_rect.height / 2 - 4, - priv->scale_rect.x + priv->scale_rect.width - 4, - priv->scale_rect.y + priv->scale_rect.height / 2 + 4); - gdk_draw_line(map->widget->window, - map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], - priv->scale_rect.x + priv->scale_rect.width - 4, - priv->scale_rect.y + priv->scale_rect.height / 2, - priv->scale_rect.x + (priv->scale_rect.width + width) / 2 + 4, - priv->scale_rect.y + priv->scale_rect.height / 2); + gdk_draw_line(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], + priv->scale_rect.x + 4, + priv->scale_rect.y + priv->scale_rect.height / 2 - 4, + priv->scale_rect.x + 4, + priv->scale_rect.y + priv->scale_rect.height / 2 + 4); + gdk_draw_line(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], + priv->scale_rect.x + 4, + priv->scale_rect.y + priv->scale_rect.height / 2, + priv->scale_rect.x + (priv->scale_rect.width - width) / 2 - 4, + priv->scale_rect.y + priv->scale_rect.height / 2); + gdk_draw_line(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], + priv->scale_rect.x + priv->scale_rect.width - 4, + priv->scale_rect.y + priv->scale_rect.height / 2 - 4, + priv->scale_rect.x + priv->scale_rect.width - 4, + priv->scale_rect.y + priv->scale_rect.height / 2 + 4); + gdk_draw_line(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], + priv->scale_rect.x + priv->scale_rect.width - 4, + priv->scale_rect.y + priv->scale_rect.height / 2, + priv->scale_rect.x + (priv->scale_rect.width + width) / 2 + 4, + priv->scale_rect.y + priv->scale_rect.height / 2); } } static void -map_information_text(GtkWidget *widget, guint x, guint y, GdkGC *gc, gchar *msg) +gtk_map_information_text(GtkWidget *widget, guint x, guint y, GdkGC *gc, gchar *msg) { GtkMap *map; GtkMapPriv *priv; @@ -493,28 +632,42 @@ priv=GTK_MAP_GET_PRIVATE(map); pango_layout_set_text(priv->speed_layout, msg, -1); pango_layout_get_pixel_size(priv->speed_layout, &width, &height); -gtk_widget_queue_draw_area(map->widget, x - 5, y - 5, width * 3 + 15, height + 5); +gtk_widget_queue_draw_area(widget, x - 5, y - 5, width * 3 + 15, height + 5); gdk_window_process_all_updates(); -gdk_draw_layout(map->widget->window, gc, x, y, speed_layout); +gdk_draw_layout(widget->window, gc, x, y, priv->speed_layout); gdk_window_process_all_updates(); } static void -map_speed_draw(GtkWidget *widget, gfloat speed, gboolean overspeed) +gtk_map_speed_draw(GtkWidget *widget, GdkEventExpose *event) { GtkMap *map; GtkMapPriv *priv; -GdkGC *gc; -gfloat cur_speed; -gchar buffer[32]; +gchar buffer[16]; g_return_if_fail(GTK_IS_MAP(widget)); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); -gc=(overspeed) ? priv->speed_gc1 : priv->speed_gc2; -buffer=g_snprintf(buffer, sizeof(buffer), "%0.0f", speed); -map_information_text(10, 10, gc, buffer); +if (priv->speed<0) + return; + +buffer=g_snprintf(buffer, sizeof(buffer), "%0.0f %s", priv->speed * priv->units_conv, priv->units_str); +map_information_text(10, 10, priv->speed_gc, buffer); +} + +void +gtk_map_set_speed(GtkWidget *widget, gfloat speed, gboolean overspeed) +{ +GtkMap *map; +GtkMapPriv *priv; + +g_return_if_fail(GTK_IS_MAP(widget)); +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +priv->speed_gc=(overspeed) ? priv->speed_gc1 : priv->speed_gc2; +priv->speed=speed; } /** @@ -523,7 +676,7 @@ map_information_text(10, 10, gc, buffer); * this method, but I guess it's not general-purpose enough. */ static void -map_pixbuf_scale_inplace(GdkPixbuf *pixbuf, guint ratio_p2, guint src_x, guint src_y) +gtk_map_pixbuf_scale_inplace(GdkPixbuf *pixbuf, guint ratio_p2, guint src_x, guint src_y) { guint dest_x = 0, dest_y = 0, dest_dim = GTK_MAP_TILE_SIZE_PIXELS; guint rowstride = gdk_pixbuf_get_rowstride(pixbuf); @@ -581,11 +734,12 @@ GtkMapPriv *priv; GdkPixbuf *pixbuf=NULL; gint zoff; -g_return_if_fail(GTK_IS_MAP(widget)); +g_return_if_val_fail(GTK_IS_MAP(widget), FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); g_return_val_if_fail(priv->buffer, FALSE); +g_return_val_if_fail(priv->curr_repo, FALSE); if (destx > priv->buf_width_pixels || desty > priv->buf_height_pixels) return FALSE; @@ -596,7 +750,7 @@ if (tilex > priv->world_size_tiles || tiley > priv->world_size_tiles) /* g_debug("MAP RT: %u %u (%u) %u %u (%u, %u)", tilex, tiley, priv->world_size_tiles, destx, desty, buf_width_tiles, buf_height_tiles); */ /* The tile is possible. */ -for (zoff = (_curr_repo->double_size ? 1 : 0); !pixbuf && (priv->zoom + zoff) <= priv->max_zoom && zoff <= TILE_SIZE_P2; zoff += 1) { +for (zoff = (priv->curr_repo->double_size ? 1 : 0); !pixbuf && (priv->zoom + zoff) <= priv->max_zoom && zoff <= GTK_MAP_TILE_SIZE_P2; zoff += 1) { pixbuf=gtk_map_tile_load(map, tilex, tiley, zoff, !fast_fail); if (!pixbuf) { if (!fast_fail) @@ -605,32 +759,43 @@ for (zoff = (_curr_repo->double_size ? 1 : 0); !pixbuf && (priv->zoom + zoff) <= /* Check if we need to blit. */ if (zoff) { gtk_map_pixbuf_scale_inplace(pixbuf, zoff, - (tilex - ((tilex >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff), - (tiley - ((tiley >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff)); + (tilex - ((tilex >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff), + (tiley - ((tiley >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff)); image_cache_invalidate_by_image(priv->icache, pixbuf); } } } if (pixbuf) { - gdk_draw_pixbuf(priv->buffer, _gc[COLORABLE_MARK], pixbuf, 0, 0, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0); + gdk_draw_pixbuf(priv->buffer, + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], + pixbuf, 0, 0, destx, desty, + GTK_MAP_TILE_SIZE_PIXELS, + GTK_MAP_TILE_SIZE_PIXELS, + GDK_RGB_DITHER_NONE, 0, 0); g_object_unref(pixbuf); return TRUE; } -gdk_draw_rectangle(priv->buffer, map->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS); +gdk_draw_rectangle(priv->buffer, + widget->style->black_gc, TRUE, + destx, desty, + GTK_MAP_TILE_SIZE_PIXELS, + GTK_MAP_TILE_SIZE_PIXELS); return TRUE; } gboolean -gtk_map_set_center(GtkWidget *map, guint new_center_unitx, guint new_center_unity) +gtk_map_set_center(GtkWidget *widget, guint new_center_unitx, guint new_center_unity) { GtkMap *map; GtkMapPriv *priv; +GtkStyle *style; g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +style=widget->style; gint new_base_tilex, new_base_tiley; guint new_x, new_y; @@ -655,7 +820,7 @@ if (new_base_tilex != priv->base_tilex || new_base_tiley != priv->base_tiley) { * new_y, old_x, old_y, iox, and ioy with that in mind. */ if (new_base_tiley < priv->base_tiley) { /* New is lower than old - start at bottom and go up. */ - new_y = buf_height_tiles - 1; + new_y = priv->buf_height_tiles - 1; ioy = -1; } else { /* New is higher than old - start at top and go down. */ @@ -664,7 +829,7 @@ if (new_base_tilex != priv->base_tilex || new_base_tiley != priv->base_tiley) { } if (new_base_tilex < priv->base_tilex) { /* New is righter than old - start at right and go left. */ - base_new_x = buf_width_tiles - 1; + base_new_x = priv->buf_width_tiles - 1; iox = -1; } else { /* New is lefter than old - start at left and go right. */ @@ -678,39 +843,40 @@ if (new_base_tilex != priv->base_tilex || new_base_tiley != priv->base_tiley) { priv->base_tilex = new_base_tilex; priv->base_tiley = new_base_tiley; - for (j = 0; j < buf_height_tiles; ++j, new_y += ioy, old_y += ioy) { + for (j = 0; j < priv->buf_height_tiles; ++j, new_y += ioy, old_y += ioy) { new_x = base_new_x; old_x = base_old_x; /* Iterate over the x tile values. */ - for (k = 0; k < buf_width_tiles; ++k, new_x += iox, old_x += iox) { + for (k = 0; k < priv->buf_width_tiles; ++k, new_x += iox, old_x += iox) { /* Can we get this grid block from the old buffer?. */ - if (old_x >= 0 && old_x < buf_width_tiles && old_y >= 0 && old_y < buf_height_tiles) { + if (old_x >= 0 && old_x < priv->buf_width_tiles && old_y >= 0 && old_y < priv->buf_height_tiles) { /* Copy from old buffer to new buffer. */ gdk_draw_drawable(priv->buffer, - _gc[COLORABLE_MARK], - priv->buffer, - old_x * TILE_SIZE_PIXELS, - old_y * TILE_SIZE_PIXELS, - new_x * TILE_SIZE_PIXELS, - new_y * TILE_SIZE_PIXELS, - TILE_SIZE_PIXELS, - TILE_SIZE_PIXELS); + widget->style->fg_gc[GTK_WIDGET_STATE(widget)], + priv->buffer, + old_x * GTK_MAP_TILE_SIZE_PIXELS, + old_y * GTK_MAP_TILE_SIZE_PIXELS, + new_x * GTK_MAP_TILE_SIZE_PIXELS, + new_y * GTK_MAP_TILE_SIZE_PIXELS, + GTK_MAP_TILE_SIZE_PIXELS, + GTK_MAP_TILE_SIZE_PIXELS); } else { - gtk_map_render_tile(map, new_base_tilex + new_x, + gtk_map_render_tile(map, + new_base_tilex + new_x, new_base_tiley + new_y, - new_x * TILE_SIZE_PIXELS, - new_y * TILE_SIZE_PIXELS, - map_drag_id!=0 ? TRUE : FALSE); + new_x * GTK_MAP_TILE_SIZE_PIXELS, + new_y * GTK_MAP_TILE_SIZE_PIXELS, + priv->fast_render); } } } - gtk_map_render_data(map); } -MACRO_RECALC_OFFSET(); -MACRO_RECALC_FOCUS_BASE(priv->center_ratio); +GTK_MAP_MACRO_RECALC_OFFSET(); +GTK_MAP_MACRO_RECALC_FOCUS_BASE(priv->center_ratio); + +/* gtk_map_set_mark(&_gps->data); */ -gtk_map_set_mark(&_gps->data); gtk_map_refresh(map); } @@ -726,7 +892,7 @@ gtk_widget_queue_draw_area(widget, 0, 0, map->width, map->height); } gint -gtk_map_get_zoom(GtkWidget *map) +gtk_map_get_zoom(GtkWidget *widget) { GtkMap *map; GtkMapPriv *priv; @@ -740,7 +906,7 @@ return priv->zoom; } gboolean -gtk_map_set_zoom(GtkWidget *map, gint new_zoom) +gtk_map_set_zoom(GtkWidget *widget, gint new_zoom) { GtkMap *map; GtkMapPriv *priv; @@ -757,16 +923,16 @@ if (new_zoom == priv->zoom) return FALSE; priv->zoom = new_zoom / _curr_repo->view_zoom_steps * _curr_repo->view_zoom_steps; -priv->world_size_tiles = unit2tile(WORLD_SIZE_UNITS); +priv->world_size_tiles = unit2tile(GTK_MAP_WORLD_SIZE_UNITS(priv->max_zoom)); /* If we're leading, update the center to reflect new zoom level. */ -MACRO_RECALC_CENTER(_gps->data, priv->center.unitx, priv->center.unity); +GTK_MAP_MACRO_RECALC_CENTER(priv->center.unitx, priv->center.unity); /* Update center bounds to reflect new zoom level. */ priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth)); priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight)); -priv->max_center.unitx = WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfwidth) - 1; -priv->max_center.unity = WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfheight) - 1; +priv->max_center.unitx = GTK_MAP_WORLD_SIZE_UNITS(priv->max_zoom) - grid2unit(priv->screen_grids_halfwidth) - 1; +priv->max_center.unity = GTK_MAP_WORLD_SIZE_UNITS(priv->max_zoom) - grid2unit(priv->screen_grids_halfheight) - 1; BOUND(priv->center.unitx, priv->min_center.unitx, priv->max_center.unitx); BOUND(priv->center.unity, priv->min_center.unity, priv->max_center.unity); @@ -776,11 +942,11 @@ priv->base_tiley = grid2tile(pixel2grid(unit2pixel(priv->center.unity)) - priv-> /* New zoom level, so we can't reuse the old buffer's pixels. */ /* Update state variables. */ -MACRO_RECALC_OFFSET(); -MACRO_RECALC_FOCUS_BASE(priv->center_ratio); -MACRO_RECALC_FOCUS_SIZE(priv->center_ratio); +GTK_MAP_MACRO_RECALC_OFFSET(); +GTK_MAP_MACRO_RECALC_FOCUS_BASE(priv->center_ratio); +GTK_MAP_MACRO_RECALC_FOCUS_SIZE(priv->center_ratio); -gtk_map_set_mark(&_gps->data); +/* gtk_map_set_mark(&_gps->data); */ gtk_map_refresh(map); return TRUE; @@ -810,7 +976,7 @@ gboolean gtk_map_zoom_in(GtkWidget *widget) { g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); -map_zoom(widget, -1); +gtk_map_zoom(widget, -1); return FALSE; } @@ -818,7 +984,7 @@ gboolean gtk_map_zoom_out(GtkWidget *widget) { g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); -map_zoom(widget, 1); +gtk_map_zoom(widget, 1); return FALSE; } diff --git a/src/gtkmap.h b/src/gtkmap.h index 22478bc..9163a63 100644 --- a/src/gtkmap.h +++ b/src/gtkmap.h @@ -36,40 +36,6 @@ typedef enum { #define GTK_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_MAP_TYPE, GtkMapClass)) #define GTK_IS_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_MAP_TYPE)) -#define GTK_MAP_TILE_SIZE_PIXELS (256) -#define GTK_MAP_TILE_SIZE_P2 (8) -#define GTK_MAP_WORLD_SIZE_UNITS(max_zoom) (2 << (max_zoom + TILE_SIZE_P2)) - -/* Pans are done two "grids" at a time, or 64 pixels. */ -#define GTK_MAP_PAN_UNITS (grid2unit(2)) - -#define GTK_MAP_MACRO_RECALC_CENTER(center_mode, center, mgps, center_unitx, center_unity) { \ - switch(center_mode) { \ - case CENTER_LEAD: \ - priv->center_unitx = leadx2unit(mgps); \ - priv->center_unity = leady2unit(mgps); \ - break; \ - case CENTER_LATLON: \ - priv->center_unitx = mgps.unitx; \ - priv->center_unity = mgps.unity; \ - break; \ - default: \ - priv->center_unitx = center.unitx; \ - priv->center_unity = center.unity; \ - break; \ - } \ -}; - -#define GTK_MAP_RECALC_OFFSET(center) { \ - priv->offsetx = grid2pixel(unit2grid(center.unitx) - priv->screen_grids_halfwidth - tile2grid(priv->base_tilex)); \ - priv->offsety = grid2pixel(unit2grid(center.unity) - priv->screen_grids_halfheight - tile2grid(priv->base_tiley)); \ -} - -#define GTK_MAP_RECALC_FOCUS_BASE(sens) { \ - priv->focus.unitx = x2unit(priv->screen_width_pixels * sens / 20); \ - priv->focus.unity = y2unit(priv->screen_height_pixels * sens / 20); \ -} - typedef struct _GtkMap GtkMap; typedef struct _GtkMapClass GtkMapClass; @@ -80,8 +46,6 @@ struct _GtkMap { guint size; guint xoffset, yoffset; - /** The "base tile" is the upper-left tile in the pixmap. */ - gfloat heading; gfloat speed; }; @@ -98,13 +62,11 @@ void gtk_map_refresh(GtkWidget *widget); gboolean gtk_map_key_zoom_timeout(GtkWidget *map); -void gtk_map_set_autozoom(GtkWidget *map, gboolean az, gfloat speed); void gtk_map_render_path(Path *path, GdkGC ** gc); void gtk_map_pan(GtkWidget *map, gint delta_unitx, gint delta_unity); void gtk_map_move_mark(GtkWidget *map); void gtk_map_set_mark(GtkWidget *map); void gtk_map_render_data(GtkWidget *map); -gboolean gtk_map_render_tile(GtkWidget *map, guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail); void gtk_map_render_waypoint(GtkWidget *map, guint x1, guint y1, GdkGC *gc); void gtk_map_render_paths(GtkWidget *map); @@ -121,6 +83,7 @@ gint gtk_map_get_zoom(GtkWidget *map); gint gtk_map_zoom(GtkWidget *widget, gint zdir); gboolean gtk_map_zoom_out(GtkWidget *widget); gboolean gtk_map_zoom_in(GtkWidget *widget); +void gtk_map_set_autozoom(GtkWidget *map, gboolean az, gfloat speed); gboolean gtk_map_goto_position(GtkWidget *map, Position *pos); gboolean gtk_map_update_location_from_center(GtkWidget *map);