From c01f1643593dafccac25226b0ac0a8e388799369 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Tue, 29 Apr 2008 18:43:28 +0300 Subject: [PATCH] Some more widget work --- src/gtkmap.c | 414 +++++++++++++++++++++++++++++++++++---------------- src/gtkmap.h | 89 +++-------- 2 files changed, 306 insertions(+), 197 deletions(-) diff --git a/src/gtkmap.c b/src/gtkmap.c index 36c0924..6a8dd86 100644 --- a/src/gtkmap.c +++ b/src/gtkmap.c @@ -17,13 +17,16 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include + +#include + #ifdef WITH_GL #include #include #endif -#include -#include #include "image-cache.h" #include "gtkmap.h" @@ -37,82 +40,131 @@ #define BUF_HEIGHT_PIXELS (768) #define MAP_CACHE_DEFAULT (64) -/* Tile cache, this might need some adjustment */ G_DEFINE_TYPE(GtkMap, gtk_map, GTK_TYPE_WIDGET); +#define GTK_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_MAP_TYPE, GtkMapPriv)) + typedef struct _GtkMapPriv GtkMapPriv; struct _GtkMapPriv { -gint mark_x1; -gint mark_x2; -gint mark_y1; -gint mark_y2; -gint mark_minx; -gint mark_miny; -gint mark_width; -gint mark_height; + GdkPixmap *buffer; + + PangoContext *context; + PangoLayout *layout; + PangoFontDescription *fontdesc; + + PangoContext *speed_context; + PangoLayout *speed_layout; + PangoFontDescription *speed_font; -guint buf_width_tiles; -guint buf_height_tiles; -guint buf_width_pixels; -guint buf_height_pixels; + PangoContext *scale_context; + PangoLayout *scale_layout; + PangoFontDescription *scale_font; -GTimer *timer; + GdkGC *gc_h; + GdkGC *gc_w; + GdkGC *gc_d; -GtkMapCenterMode center_mode; + GdkGC *speed_gc1; + GdkGC *speed_gc2; -GdkPixmap *buffer; -ImageCache *icache; + GdkRectangle scale_rect; + + GTimer *timer; + ImageCache *icache; #ifdef WITH_GL -GdkGLConfig* gl_config; + GdkGLConfig* gl_config; #endif -gboolean gl; -PangoContext *context; -PangoLayout *layout; -PangoFontDescription *fontdesc; + gint mark_x1; + gint mark_x2; + gint mark_y1; + gint mark_y2; + gint mark_minx; + gint mark_miny; + gint mark_width; + gint mark_height; -PangoLayout *speed_layout; -PangoLayout *scale_layout; -gint zoom; -gint offsetx; -gint offsety; -}; + guint buf_width_tiles; + guint buf_height_tiles; + guint buf_width_pixels; + guint buf_height_pixels; + + gboolean gl; -#define GTK_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_MAP, GtkMapPriv)) + GtkMapCenterMode center_mode; + + Point min_center; + Point max_center; + + Point focus; + Point center; + + guint lead_ratio; + guint center_ratio; + + guint base_tile_x; + guint base_tile_y; + + gint zoom; + gint max_zoom; + gint min_zoom; + + gint offsetx; + gint offsety; + + guint screen_grids_halfwidth; + guint screen_grids_halfheight; + guint screen_width_pixels; + guint screen_height_pixels; + + guint focus_unitwidth; + guint focus_unitheight; + guint world_size_tiles; + + gint show_paths; + gboolean show_scale; + gboolean show_velvec; + gboolean show_markers; + + guint draw_width; + + guint key_zoom_new; + guint key_zoom_timeout_sid; +}; #define tile2grid(tile) ((tile) << 3) #define grid2tile(grid) ((grid) >> 3) #define tile2pixel(tile) ((tile) << 8) #define pixel2tile(pixel) ((pixel) >> 8) -#define tile2unit(tile) ((tile) << (8 + _zoom)) -#define unit2tile(unit) ((unit) >> (8 + _zoom)) +#define tile2unit(tile) ((tile) << (8 + priv->zoom)) +#define unit2tile(unit) ((unit) >> (8 + priv->zoom)) #define tile2zunit(tile, zoom) ((tile) << (8 + zoom)) #define unit2ztile(unit, zoom) ((unit) >> (8 + zoom)) #define grid2pixel(grid) ((grid) << 5) #define pixel2grid(pixel) ((pixel) >> 5) -#define grid2unit(grid) ((grid) << (5 + _zoom)) -#define unit2grid(unit) ((unit) >> (5 + _zoom)) +#define grid2unit(grid) ((grid) << (5 + priv->zoom)) +#define unit2grid(unit) ((unit) >> (5 + priv->zoom)) -#define pixel2unit(pixel) ((pixel) << _zoom) -#define unit2pixel(pixel) ((pixel) >> _zoom) +#define pixel2unit(pixel) ((pixel) << priv->zoom) +#define unit2pixel(pixel) ((pixel) >> priv->zoom) #define pixel2zunit(pixel, zoom) ((pixel) << (zoom)) -#define unit2bufx(unit) (unit2pixel(unit) - tile2pixel(_base_tilex)) -#define bufx2unit(x) (pixel2unit(x) + tile2unit(_base_tilex)) -#define unit2bufy(unit) (unit2pixel(unit) - tile2pixel(_base_tiley)) -#define bufy2unit(y) (pixel2unit(y) + tile2unit(_base_tiley)) +#define unit2bufx(unit) (unit2pixel(unit) - tile2pixel(priv->base_tilex)) +#define bufx2unit(x) (pixel2unit(x) + tile2unit(priv->base_tilex)) +#define unit2bufy(unit) (unit2pixel(unit) - tile2pixel(priv->base_tiley)) +#define bufy2unit(y) (pixel2unit(y) + tile2unit(priv->base_tiley)) -#define unit2x(unit) (unit2pixel(unit) - tile2pixel(_base_tilex) - _offsetx) -#define x2unit(x) (pixel2unit(x + _offsetx) + tile2unit(_base_tilex)) -#define unit2y(unit) (unit2pixel(unit) - tile2pixel(_base_tiley) - _offsety) -#define y2unit(y) (pixel2unit(y + _offsety) + tile2unit(_base_tiley)) +#define unit2x(unit) (unit2pixel(unit) - tile2pixel(priv->base_tilex) - priv->offsetx) +#define x2unit(x) (pixel2unit(x + priv->offsetx) + tile2unit(priv->base_tilex)) +#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 + (_lead_ratio) * pixel2unit(mgps.vel_offsetx)) -#define leady2unit(mgps) (mgps.unity + (0.6f*_lead_ratio)*pixel2unit(mgps.vel_offsety)) +#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)) static void gtk_map_finalize(GObject *object); @@ -125,6 +177,23 @@ static void gtk_map_realize(GtkWidget *widget); 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); +/* Signal IDs */ +enum { + MAP_LOCATION_CHANGED, + + MAP_ZOOMED_IN, + MAP_ZOOMED_OUT, + + LAST_SIGNAL +}; + +/* Property IDs */ +enum { + LAST_PROP +}; + +static guint gtk_map_signals[LAST_SIGNAL] = { 0 }; + static void gtk_map_class_init (GtkMapClass *class) { @@ -146,6 +215,73 @@ widget_class->size_allocate = gtk_map_size_allocate; g_type_class_add_private (object_class, sizeof(GtkMapPriv)); } +static void +gtk_map_init(GtkMap *map) +{ +GtkMapPriv *priv; +GdkColor color; + +g_debug("MAP: Init"); +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->icache=image_cache_new(64); + +priv->scale_context=gtk_widget_get_pango_context(GTK_WIDGET(map)); +priv->scale_layout=pango_layout_new(priv->scale_context); +priv->scale_font=pango_font_description_new(); +pango_font_description_set_size(priv->scale_font, 12 * PANGO_SCALE); +pango_layout_set_font_description(priv->scale_layout, priv->scale_font); + +/* Speed limit, over limit color */ +priv->speed_gc1=gdk_gc_new(GTK_WIDGET(map)->window); +color.red=0xffff; +color.green=0; +color.blue=0; +gdk_gc_set_rgb_fg_color(priv->speed_gc1, &color); + +/* Speed limit, under limit color */ +priv->speed_gc2=gdk_gc_new(GTK_WIDGET(map)->window); +color.red=0; +color.green=0x1000; +color.blue=0; +gdk_gc_set_rgb_fg_color(priv->speed_gc2, &color); + +priv->speed_context=gtk_widget_get_pango_context(GTK_WIDGET(map)); +priv->speed_layout=pango_layout_new(priv->speed_context); +priv->speed_font=pango_font_description_new(); +pango_font_description_set_size(priv->speed_font, 48 * PANGO_SCALE); +pango_layout_set_font_description(priv->speed_layout, priv->speed_font); +pango_layout_set_alignment(priv->speed_layout, PANGO_ALIGN_LEFT); + +priv->gl=FALSE; + +#ifdef WITH_GL +priv->gl_config=gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH); +if (priv->gl_config) { + g_print("OpenGL version: %s\n", glGetString (GL_VERSION)); + g_print("OpenGL vendor: %s\n", glGetString (GL_VENDOR)); + g_print("OpenGL renderer: %s\n", glGetString (GL_RENDERER)); + gtk_widget_set_gl_capability(map->widget, priv->gl_config, NULL, TRUE, GDK_GL_RGBA_TYPE); + priv->gl=TRUE; +} +#endif + +gtk_widget_set_extension_events(GTK_WIDGET(map), GDK_EXTENSION_EVENTS_ALL); + +gtk_widget_add_events(GTK_WIDGET(map), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); + +#if 0 +g_signal_connect(G_OBJECT(map), "button_press_event", G_CALLBACK(gtk_map_cb_button_press), NULL); +#endif + +} + static void gtk_map_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -172,31 +308,10 @@ switch (prop_id) { } } -static void -gtk_map_init(GtkMap *map) -{ -GtkMapPriv *priv; - -priv=GTK_MAP_GET_PRIVATE(map); -} - GtkWidget* gtk_map_new(void) { -GtkMap *map; -GtkMapPriv *priv; -GtkWidget *widget; - -map=g_object_new(GTK_MAP_TYPE, NULL); -widget=GTK_WIDGET(map); -priv=GTK_MAP_GET_PRIVATE(map); -map->heading=0; - -#if 0 -g_signal_connect(G_OBJECT(widget), "button_press_event", G_CALLBACK(gtk_map_cb_button_press), NULL); -#endif - -return widget; +return g_object_new(GTK_MAP_TYPE, NULL); } static void @@ -253,6 +368,7 @@ gtk_map_expose(GtkWidget *widget, GdkEventExpose *event) { GtkMap *map; GtkMapPriv *priv; +GtkStyle *style; g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); @@ -260,12 +376,17 @@ g_return_val_if_fail(event != NULL, FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); -gdk_draw_drawable(GDK_DRAWABLE(map->widget->window), - priv->gc[COLORABLE_MARK], - priv->pixmap, - event->area.x + priv->offsetx, event->area.y + priv->offsety, - event->area.x, event->area.y, - event->area.width, event->area.height); +style=widget->style; + +gdk_draw_drawable(GDK_DRAWABLE(map->map), + style->fg_gc[GTK_STATE_NORMAL], + priv->buffer, + event->area.x + priv->offsetx, + event->area.y + priv->offsety, + event->area.x, + event->area.y, + event->area.width, + event->area.height); return TRUE; } @@ -285,26 +406,26 @@ map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); pango_layout_set_text(priv->scale_layout, "0", -1); -pango_layout_get_pixel_size(priv->scale_layout, NULL, &scale_rect.height); -scale_rect.y = priv->screen_height_pixels - scale_rect.height - 1; +pango_layout_get_pixel_size(priv->scale_layout, NULL, &priv->scale_rect.height); +priv->scale_rect.y = priv->screen_height_pixels - priv->scale_rect.height - 1; -gdk_rectangle_intersect(&event->area, &scale_rect, &event->area); +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)], - TRUE, scale_rect.x, scale_rect.y, - scale_rect.width, - scale_rect.height); - gdk_draw_rectangle(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - FALSE, scale_rect.x, scale_rect.y, - scale_rect.width, - scale_rect.height); + gdk_draw_rectangle(map->widget->window, + map->widget->style->bg_gc[GTK_WIDGET_STATE(map->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)], + FALSE, priv->scale_rect.x, priv->scale_rect.y, + priv->scale_rect.width, + priv->scale_rect.height); /* Now calculate and draw the distance. */ - unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat1, lon1); - unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat2, lon2); + 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]; if (distance < 1.f) @@ -318,36 +439,36 @@ if (event->area.width && event->area.height) { pango_layout_get_pixel_size(scale_layout, &width, NULL); /* Draw the layout itself. */ - gdk_draw_layout(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + (scale_rect.width - width) / 2, - scale_rect.y, scale_layout); + gdk_draw_layout(map->widget->window, + map->widget->style->fg_gc[GTK_WIDGET_STATE(map->widget)], + priv->scale_rect.x + (priv->scale_rect.width - width) / 2, + priv->scale_rect.y, scale_layout); /* Draw little hashes on the ends. */ - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + 4, - scale_rect.y + scale_rect.height / 2 - 4, - scale_rect.x + 4, - scale_rect.y + scale_rect.height / 2 + 4); - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + 4, - scale_rect.y + scale_rect.height / 2, - scale_rect.x + (scale_rect.width - width) / 2 - 4, - scale_rect.y + scale_rect.height / 2); - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + scale_rect.width - 4, - scale_rect.y + scale_rect.height / 2 - 4, - scale_rect.x + scale_rect.width - 4, - scale_rect.y + scale_rect.height / 2 + 4); - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + scale_rect.width - 4, - scale_rect.y + scale_rect.height / 2, - scale_rect.x + (scale_rect.width + width) / 2 + 4, - scale_rect.y + scale_rect.height / 2); + 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); } } @@ -364,26 +485,28 @@ 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(map->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(map->widget->window, gc, x, y, speed_layout); gdk_window_process_all_updates(); } static void map_speed_draw(GtkWidget *widget, gfloat speed, gboolean overspeed) { +GtkMap *map; +GtkMapPriv *priv; GdkGC *gc; gfloat cur_speed; -gchar *buffer; +gchar buffer[32]; g_return_if_fail(GTK_IS_MAP(widget)); map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); -gc=(overspeed) ? speed_gc1 : speed_gc2; -buffer = g_strdup_printf("%0.0f", speed); +gc=(overspeed) ? priv->speed_gc1 : priv->speed_gc2; +buffer=g_snprintf(buffer, sizeof(buffer), "%0.0f", speed); map_information_text(10, 10, gc, buffer); -g_free(buffer); } /** @@ -394,7 +517,7 @@ g_free(buffer); static void map_pixbuf_scale_inplace(GdkPixbuf *pixbuf, guint ratio_p2, guint src_x, guint src_y) { -guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS; +guint dest_x = 0, dest_y = 0, dest_dim = GTK_MAP_TILE_SIZE_PIXELS; guint rowstride = gdk_pixbuf_get_rowstride(pixbuf); guint n_channels = gdk_pixbuf_get_n_channels(pixbuf); guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); @@ -453,25 +576,40 @@ map=GTK_MAP(widget); gtk_widget_queue_draw_area(widget, 0, 0, map->width, map->height); } +gint gtk_map_get_zoom(GtkWidget *map) +{ +GtkMap *map; +GtkMapPriv *priv; + +g_return_val_if_fail(GTK_IS_MAP(widget), -1); + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +return priv->zoom; +} + gint -map_zoom(GtkWidget *widget, gint zdir) +gtk_map_zoom(GtkWidget *widget, gint zdir) { gint nzoom; GtkMap *map; +GtkMapPriv *priv; g_return_val_if_fail(GTK_IS_MAP(widget), -1); map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); -nzoom=map->zoom+zdir; -if ((nzoom >= 0) && (nzoom < map->max_zoom - 1)) { - map_set_zoom(widget, nzoom); +nzoom=priv->zoom+zdir; +if ((nzoom >= 0) && (nzoom < priv->max_zoom - 1)) { + gtk_map_set_zoom(widget, nzoom); } return nzoom; } gboolean -map_zoom_in(GtkWidget *widget) +gtk_map_zoom_in(GtkWidget *widget) { g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map_zoom(widget, -1); @@ -479,9 +617,23 @@ return FALSE; } gboolean -map_zoom_out(GtkWidget *widget) +gtk_map_zoom_out(GtkWidget *widget) { g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map_zoom(widget, 1); return FALSE; } + +void +gtk_map_set_cache_size(GtkWidget *widget, guint cache_size) +{ +GtkMap *map; +GtkMapPriv *priv; + +g_return_if_fail(GTK_IS_MAP(widget)); +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); +if (cache_size>512) + cache_size=512; +image_cache_set_size(priv->icache, cache_size); +} diff --git a/src/gtkmap.h b/src/gtkmap.h index db2ccce..22478bc 100644 --- a/src/gtkmap.h +++ b/src/gtkmap.h @@ -23,8 +23,6 @@ #include #include "path.h" -G_BEGIN_DECLS - typedef enum { CENTER_WAS_LATLON = -2, CENTER_WAS_LEAD = -1, @@ -48,106 +46,58 @@ typedef enum { #define GTK_MAP_MACRO_RECALC_CENTER(center_mode, center, mgps, center_unitx, center_unity) { \ switch(center_mode) { \ case CENTER_LEAD: \ - center_unitx = leadx2unit(mgps); \ - center_unity = leady2unit(mgps); \ + priv->center_unitx = leadx2unit(mgps); \ + priv->center_unity = leady2unit(mgps); \ break; \ case CENTER_LATLON: \ - center_unitx = mgps.unitx; \ - center_unity = mgps.unity; \ + priv->center_unitx = mgps.unitx; \ + priv->center_unity = mgps.unity; \ break; \ default: \ - center_unitx = center.unitx; \ - center_unity = center.unity; \ + priv->center_unitx = center.unitx; \ + priv->center_unity = center.unity; \ break; \ } \ }; -#define GTK_MAP_RECALC_OFFSET(map, center) { \ - map->offsetx = grid2pixel(unit2grid(center.unitx) - map->screen_grids_halfwidth - tile2grid(map->base_tilex)); \ - map->offsety = grid2pixel(unit2grid(center.unity) - map->screen_grids_halfheight - tile2grid(map->base_tiley)); \ +#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(map, sens) { \ - map->focus.unitx = x2unit(map->screen_width_pixels * sens / 20); \ - map->focus.unity = y2unit(map->screen_height_pixels * sens / 20); \ +#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; struct _GtkMap { - GtkDrawingArea widget; + GtkDrawingArea map; - GdkGC *gc_h; - GdkGC *gc_w; - GdkGC *gc_d; guint width, height; guint size; guint xoffset, yoffset; - PangoContext *context; - PangoLayout *layout; - PangoFontDescription *fontdesc; - - Point min_center; - Point max_center; - Point focus; - /** The "base tile" is the upper-left tile in the pixmap. */ - guint base_tilex; - guint base_tiley; - - Point center; /* current center location, X. */ - GtkMapCenterMode center_mode; - guint lead_ratio; - guint center_ratio; gfloat heading; gfloat speed; - - guint zoom; /* zoom level, from 0 to MAX_ZOOM. */ - - /** The "offset" defines the upper-left corner of the visible portion of the buffer pixmap. */ - guint offsetx; - guint offsety; - - /** CACHED SCREEN INFORMATION THAT IS DEPENDENT ON THE CURRENT VIEW. */ - guint screen_grids_halfwidth; - guint screen_grids_halfheight; - guint screen_width_pixels; - guint screen_height_pixels; - - guint focus_unitwidth; - guint focus_unitheight; - guint world_size_tiles; - - gint show_paths; - gboolean show_scale; - gboolean show_velvec; - gboolean show_markers; - - guint draw_width; - - guint key_zoom_new; - guint key_zoom_timeout_sid; }; struct _GtkMapClass { - GtkWidgetClass parent_class; + GtkDrawingAreaClass parent_class; }; +G_BEGIN_DECLS + GType gtk_map_get_type(void); GtkWidget* gtk_map_new(void); void gtk_map_refresh(GtkWidget *widget); gboolean gtk_map_key_zoom_timeout(GtkWidget *map); -gint gtk_map_zoom(gint zdir); -guint gtk_map_get_zoom(GtkWidget *map); -gboolean gtk_map_set_zoom(guint zoom); - -gboolean gtk_map_zoom_in(GtkWidget *map); -gboolean gtk_map_zoom_out(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); @@ -162,9 +112,16 @@ void gtk_map_force_redraw(GtkWidget *map); void gtk_map_draw_position_icon(GtkWidget *map, Position *pos, const gchar *icon); GdkPixmap *gtk_map_pixmap_get(GtkWidget *map); +void gtk_map_set_cache_size(GtkWidget *widget, guint cache_size); + void gtk_map_center_unit(GtkWidget *map, guint new_center_unitx, guint new_center_unity); void gtk_map_center_latlon(GtkWidget *map, gdouble lat, gdouble lon); +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); + gboolean gtk_map_goto_position(GtkWidget *map, Position *pos); gboolean gtk_map_update_location_from_center(GtkWidget *map); -- 2.39.5