From c9c39986be6062546f846067c1fbf6fabf5c0d99 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Mon, 5 May 2008 14:36:20 +0300 Subject: [PATCH] Add pan and zoom control to map widget test application. Add missing pan function to widget, combine some ifs --- src/gtkmap.c | 87 ++++++++++++++++++++++++++----------------- src/gtkmap.h | 6 ++- src/map-widget-test.c | 71 +++++++++++++++++++++++++++++++++-- 3 files changed, 124 insertions(+), 40 deletions(-) diff --git a/src/gtkmap.c b/src/gtkmap.c index b0b7446..3c3afde 100644 --- a/src/gtkmap.c +++ b/src/gtkmap.c @@ -42,7 +42,7 @@ #define BUF_WIDTH_PIXELS (1024) #define BUF_HEIGHT_PIXELS (768) -#define SCALE_WIDTH (300) +#define SCALE_WIDTH (256) #define MAP_CACHE_DEFAULT (64) @@ -342,12 +342,19 @@ priv=GTK_MAP_GET_PRIVATE(map); priv->ct=gdk_cairo_create(GTK_WIDGET(map)->window); #endif -priv->zoom=3; -priv->center_mode=CENTER_LATLON; priv->base_tilex=-5; priv->base_tiley=-5; + priv->draw_width=4; +priv->zoom=3; +priv->min_zoom=0; +priv->max_zoom=17; + +priv->center_mode=CENTER_LATLON; +priv->center.unitx=0; +priv->center.unity=0; + priv->speed=-1; priv->speed_gc=priv->speed_gc1; @@ -471,14 +478,6 @@ if (!priv->buffer) { return; } -map->width=width; -map->height=height; - -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 = width; priv->screen_height_pixels = height; priv->screen_grids_halfwidth = pixel2grid(priv->screen_width_pixels) / 2; @@ -547,15 +546,16 @@ priv=GTK_MAP_GET_PRIVATE(map); g_debug("GTKMAP: %s (%d, %d)", __PRETTY_FUNCTION__, new_width, new_height); -if (priv->buffer==NULL) { - priv->buffer=gdk_pixmap_new(widget->window, - new_widthpriv->buf_width_pixels || new_height>priv->buf_height_pixels || - new_widthbuf_width_pixels-(GTK_MAP_TILE_SIZE_PIXELS*2) || new_heightbuf_height_pixels-(GTK_MAP_TILE_SIZE_PIXELS*2) ) { - g_object_unref(priv->buffer); - priv->buffer=gdk_pixmap_new(widget->window, new_width, new_height, -1); +if ( (priv->buffer==NULL) || (new_width>priv->buf_width_pixels || new_height>priv->buf_height_pixels || new_widthbuf_width_pixels-(GTK_MAP_TILE_SIZE_PIXELS*2) || new_heightbuf_height_pixels-(GTK_MAP_TILE_SIZE_PIXELS*2) )) { + priv->buf_width_pixels=new_widthbuf_height_pixels=new_heightbuf_width_tiles=priv->buf_width_pixels/GTK_MAP_TILE_SIZE_PIXELS; + priv->buf_height_tiles=priv->buf_height_pixels/GTK_MAP_TILE_SIZE_PIXELS; + if (priv->buffer) + g_object_unref(priv->buffer); + priv->buffer=gdk_pixmap_new(widget->window, priv->buf_width_pixels, priv->buf_height_pixels, -1); + if (priv->buffer) + gdk_draw_rectangle(priv->buffer, widget->style->black_gc, TRUE, 0, 0, priv->buf_width_pixels, priv->buf_height_pixels); return TRUE; } return FALSE; @@ -924,6 +924,8 @@ g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +g_debug("LOAD: %u, %u @ (%d+%d)", tilex, tiley, priv->zoom, zoff); + return NULL; } @@ -939,6 +941,9 @@ g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +g_debug("RT: %u %u (%u) %u %u (%u, %u)", tilex, tiley, + priv->world_size_tiles, destx, desty, priv->buf_width_tiles, priv->buf_height_tiles); + g_return_val_if_fail(priv->buffer, FALSE); g_return_val_if_fail(priv->curr_repo, FALSE); @@ -948,8 +953,6 @@ if (destx > priv->buf_width_pixels || desty > priv->buf_height_pixels) if (tilex > priv->world_size_tiles || tiley > priv->world_size_tiles) return FALSE; -/* 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); */ - 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) { @@ -985,11 +988,14 @@ return TRUE; } gboolean -gtk_map_set_center(GtkWidget *widget, guint new_center_unitx, guint new_center_unity) +gtk_map_set_center(GtkWidget *widget, guint unitx, guint unity) { GtkMap *map; GtkMapPriv *priv; GtkStyle *style; +gint new_base_tilex, new_base_tiley; +guint new_x, new_y; +guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy; g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); @@ -997,16 +1003,12 @@ 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; -guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy; - /* Assure that _center.unitx/y are bounded. */ -BOUND(new_center_unitx, priv->min_center.unitx, priv->max_center.unitx); -BOUND(new_center_unity, priv->min_center.unity, priv->max_center.unity); +BOUND(unitx, priv->min_center.unitx, priv->max_center.unitx); +BOUND(unity, priv->min_center.unity, priv->max_center.unity); -priv->center.unitx = new_center_unitx; -priv->center.unity = new_center_unity; +priv->center.unitx = unitx; +priv->center.unity = unity; new_base_tilex = grid2tile((gint) pixel2grid((gint)unit2pixel((gint) priv->center.unitx)) - (gint)priv->screen_grids_halfwidth); new_base_tiley = grid2tile(pixel2grid(unit2pixel(priv->center.unity)) - priv->screen_grids_halfheight); @@ -1078,14 +1080,23 @@ gtk_map_refresh(map); } void -gtk_map_refresh(GtkWidget *widget) +gtk_map_pan(GtkWidget *widget, gint delta_x, gint delta_y) { GtkMap *map; +GtkMapPriv *priv; g_return_if_fail(GTK_IS_MAP(widget)); - map=GTK_MAP(widget); -gtk_widget_queue_draw_area(widget, 0, 0, map->width, map->height); +priv=GTK_MAP_GET_PRIVATE(map); + +gtk_map_set_center(widget, priv->center.unitx + delta_x, priv->center.unity + delta_y); +} + +void +gtk_map_refresh(GtkWidget *widget) +{ +g_return_if_fail(GTK_IS_MAP(widget)); +gtk_widget_queue_draw_area(widget, 0, 0, widget->allocation.width, widget->allocation.height); } gint @@ -1113,13 +1124,19 @@ g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +g_debug("GTKMAP: zoom %d", new_zoom); + if (new_zoom > (priv->max_zoom - 1)) return FALSE; if (new_zoom == priv->zoom) return FALSE; -priv->zoom = new_zoom / priv->curr_repo->view_zoom_steps * priv->curr_repo->view_zoom_steps; +if (priv->curr_repo) + priv->zoom = new_zoom / priv->curr_repo->view_zoom_steps * priv->curr_repo->view_zoom_steps; +else + priv->zoom = new_zoom; + priv->world_size_tiles = unit2tile(GTK_MAP_WORLD_SIZE_UNITS); /* If we're leading, update the center to reflect new zoom level. */ diff --git a/src/gtkmap.h b/src/gtkmap.h index 9163a63..faf252c 100644 --- a/src/gtkmap.h +++ b/src/gtkmap.h @@ -76,10 +76,14 @@ 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); +/* Location functions */ +void gtk_map_center_unit(GtkWidget *map, guint unitx, guint unity); void gtk_map_center_latlon(GtkWidget *map, gdouble lat, gdouble lon); +void gtk_map_pan(GtkWidget *map, gint delta_unitx, gint delta_unity); +/* Zoom functions */ gint gtk_map_get_zoom(GtkWidget *map); +gint gtk_map_set_zoom(GtkWidget *map, gint zoom); gint gtk_map_zoom(GtkWidget *widget, gint zdir); gboolean gtk_map_zoom_out(GtkWidget *widget); gboolean gtk_map_zoom_in(GtkWidget *widget); diff --git a/src/map-widget-test.c b/src/map-widget-test.c index aae6639..0706796 100644 --- a/src/map-widget-test.c +++ b/src/map-widget-test.c @@ -2,11 +2,48 @@ #include #include "gtkmap.h" +GtkWidget *map; + +static gboolean +map_zoom(GtkWidget *widget, gpointer data) +{ +gtk_map_set_zoom(map, (gint)gtk_range_get_value(widget)); +return TRUE; +} + +static gboolean +map_pan_up(GtkWidget *widget, gpointer data) +{ +gtk_map_pan(map, -1, 0); +return TRUE; +} + +static gboolean +map_pan_down(GtkWidget *widget, gpointer data) +{ +gtk_map_pan(map, 1, 0); +return TRUE; +} + +static gboolean +map_pan_left(GtkWidget *widget, gpointer data) +{ +gtk_map_pan(map, 0, -1); +return TRUE; +} + +static gboolean +map_pan_right(GtkWidget *widget, gpointer data) +{ +gtk_map_pan(map, 0, 1); +return TRUE; +} + int main (int argc, char **args) { GtkDialog *dialog; -GtkWidget *map; +GtkWidget *hbox, *zoomer, *btn_left, *btn_right, *btn_up, *btn_down, *vbox; gtk_init (&argc, &args); @@ -14,11 +51,37 @@ dialog=GTK_DIALOG(gtk_dialog_new ()); gtk_window_set_title(GTK_WINDOW(dialog), "Map test"); gtk_dialog_add_button (dialog, "Close", GTK_RESPONSE_CLOSE); +hbox=gtk_hbox_new(FALSE, 3); +vbox=gtk_vbox_new(FALSE, 3); + map=gtk_map_new(); -gtk_box_pack_start(GTK_BOX (dialog->vbox), map, TRUE, TRUE, 0); +gtk_box_pack_start(GTK_BOX(hbox), map, TRUE, TRUE, 0); + +zoomer=gtk_vscale_new_with_range(0,17,1); +g_signal_connect(G_OBJECT(zoomer), "value-changed", G_CALLBACK(map_zoom), NULL); +gtk_box_pack_start(GTK_BOX(hbox), zoomer, FALSE, FALSE, 0); + +btn_left=gtk_button_new_with_label("L"); +btn_right=gtk_button_new_with_label("R"); +btn_up=gtk_button_new_with_label("U"); +btn_down=gtk_button_new_with_label("D"); + +g_signal_connect(G_OBJECT(btn_up), "clicked", G_CALLBACK(map_pan_up), NULL); +g_signal_connect(G_OBJECT(btn_down), "clicked", G_CALLBACK(map_pan_down), NULL); +g_signal_connect(G_OBJECT(btn_left), "clicked", G_CALLBACK(map_pan_left), NULL); +g_signal_connect(G_OBJECT(btn_right), "clicked", G_CALLBACK(map_pan_right), NULL); + +gtk_box_pack_start(GTK_BOX(vbox), btn_left, FALSE, FALSE, 0); +gtk_box_pack_start(GTK_BOX(vbox), btn_right, FALSE, FALSE, 0); +gtk_box_pack_start(GTK_BOX(vbox), btn_up, FALSE, FALSE, 0); +gtk_box_pack_start(GTK_BOX(vbox), btn_down, FALSE, FALSE, 0); + +gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); + +gtk_box_pack_start(GTK_BOX(dialog->vbox), hbox, TRUE, TRUE, 0); -gtk_widget_show_all(GTK_WIDGET (dialog)); -gtk_dialog_run (dialog); +gtk_widget_show_all(GTK_WIDGET(dialog)); +gtk_dialog_run(dialog); return 0; } -- 2.39.5