From df81704f2f5569786c63c23666bd0c836838657d Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Tue, 6 May 2008 16:00:53 +0300 Subject: [PATCH] Map widget: - Start to add drawing of paths and points --- src/gtkmap.c | 177 +++++++++++++++++++++++++++++++++++++++++++++------ src/gtkmap.h | 36 ++++++----- 2 files changed, 179 insertions(+), 34 deletions(-) diff --git a/src/gtkmap.c b/src/gtkmap.c index 14661da..2e59188 100644 --- a/src/gtkmap.c +++ b/src/gtkmap.c @@ -82,30 +82,32 @@ struct _GtkMapPriv PangoLayout *scale_layout; PangoFontDescription *scale_font; - GdkGC *gc_h; - GdkGC *gc_w; - GdkGC *gc_d; + GdkGC *gc_track; + GdkGC *gc_route; + GdkGC *gc_waypoint; + GdkGC *gc_break; + + GdkGC *gc_mark; + GdkGC *gc_velvec; GdkGC *speed_gc1; GdkGC *speed_gc2; GdkGC *speed_gc; + /* OpenGL data */ +#ifdef WITH_GL + GdkGLConfig* gl_config; +#endif + gboolean gl; + GdkRectangle scale_rect; RepoData *curr_repo; GTimer *timer; ImageCache *icache; - GList *markers; - /* OpenGL data */ -#ifdef WITH_GL - GdkGLConfig* gl_config; -#endif - gboolean gl; - - GdkGC *gc_mark; - GdkGC *gc_velvec; + GSList *markers; /* Cached Location dot x,y values */ gint mark_x1; @@ -115,7 +117,6 @@ struct _GtkMapPriv GdkRectangle mark_rect; GtkMapCenterMode center_mode; - Point center; Point min_center; Point max_center; @@ -169,6 +170,11 @@ struct _GtkMapPriv guint key_zoom_new; guint key_zoom_timeout_sid; + + /* Paths */ + GSList *paths; /* A list with paths to draw (tracks, routes, friends) */ + Path *current_track; /* Pointer to main track */ + Path *current_route; /* Pointer to main route */ }; #define tile2grid(tile) ((tile) << 3) @@ -456,7 +462,7 @@ priv=GTK_MAP_GET_PRIVATE(map); tw=GTK_MAP_TILE_SIZE_PIXELS*((width/GTK_MAP_TILE_SIZE_PIXELS)+2); th=GTK_MAP_TILE_SIZE_PIXELS*((height/GTK_MAP_TILE_SIZE_PIXELS)+2); -gtk_map_update_buffer_size(GTK_MAP(widget), tw, th); +gtk_map_update_buffer_size(widget, tw, th); if (!priv->buffer) { return; } @@ -510,11 +516,8 @@ g_return_if_fail(requisition != NULL); map=GTK_MAP(widget); -g_debug("GTKMAP: Size request"); - requisition->width=GTK_MAP_TILE_SIZE_PIXELS/2; requisition->height=GTK_MAP_TILE_SIZE_PIXELS/2; -/* gtk_map_update_size(widget, requisition->width, requisition->height); */ } static gboolean @@ -622,6 +625,30 @@ color.green=0x1000; color.blue=0; gdk_gc_set_rgb_fg_color(priv->speed_gc2, &color); +priv->gc_track=gdk_gc_new(widget->window); +color.red=0xffff; +color.green=0; +color.blue=0; +gdk_gc_set_rgb_fg_color(priv->gc_track, &color); + +priv->gc_route=gdk_gc_new(widget->window); +color.red=0; +color.green=0xffff; +color.blue=0; +gdk_gc_set_rgb_fg_color(priv->gc_route, &color); + +priv->gc_waypoint=gdk_gc_new(widget->window); +color.red=0xffff; +color.green=0xffff; +color.blue=0; +gdk_gc_set_rgb_fg_color(priv->gc_waypoint, &color); + +priv->gc_break=gdk_gc_new(widget->window); +color.red=0xffff; +color.green=0; +color.blue=0xffff; +gdk_gc_set_rgb_fg_color(priv->gc_break, &color); + priv->speed_context=gtk_widget_get_pango_context(widget); priv->speed_layout=pango_layout_new(priv->speed_context); priv->speed_font=pango_font_description_new(); @@ -683,6 +710,107 @@ priv->ct=NULL; return TRUE; } +static void +gtk_map_render_waypoint(GtkWidget *widget, guint x1, guint y1) +{ +GtkMap *map; +GtkMapPriv *priv; +GdkGC *gc; + +g_return_if_fail(GTK_IS_MAP(widget)); + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +if ((x1 > priv->buf_width_pixels) || (y1 > priv->buf_height_pixels)) + return; +gdk_draw_arc(widget->window, gc, FALSE, x1 - priv->draw_width, y1 - priv->draw_width, 2 * priv->draw_width, 2 * priv->draw_width, 0, 360 * 64); +} + +static void +gtk_map_render_path_segment(GtkWidget *widget, guint unitx1, guint unity1, guint unitx2, guint unity2) +{ +GtkMap *map; +GtkMapPriv *priv; +GdkGC *gc; +gint x1, y1, x2, y2; + +g_return_if_fail(GTK_IS_MAP(widget)); + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +x1=unit2bufx(unitx1); +y1=unit2bufy(unity1); +x2=unit2bufx(unitx2); +y2=unit2bufy(unity2); + +/* Make sure this line could possibly be visible. */ +if (!((x1 > priv->buf_width_pixels && x2 > priv->buf_width_pixels) || (x1 < 0 && x2 < 0) + || (y1 > priv->buf_height_pixels && y2 > priv->buf_height_pixels) || (y1 < 0 && y2 < 0))) { + gc=priv->gc_track; + gdk_draw_line(widget->window, gc, x1, y1, x2, y2); +} +} + +static void +gtk_map_render_path(GtkWidget *widget, Path *path, GdkEventExpose *event) +{ +GtkMap *map; +GtkMapPriv *priv; +Point *curr; +WayPoint *wcurr; + +g_return_if_fail(path); + +if (path->head==path->tail) + return; + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +for (curr = path->head, wcurr = path->whead; curr++ != path->tail;) { + /* Draw the line from (curr - 1) to (curr). */ + + gtk_map_render_segment(widget, curr[-1].unitx, curr[-1].unity, curr->unitx, curr->unity); + /* Now, check if curr is a waypoint. */ + if (wcurr && wcurr <= path->wtail && wcurr->point == curr) { + guint x1 = unit2bufx(wcurr->point->unitx); + guint y1 = unit2bufy(wcurr->point->unity); + + gtk_map_render_waypoint(widget, x1, y1); + wcurr++; + } +} +if (path->type==PATH_TYPE_ROUTE) + gtk_map_render_next_waypoint(widget, path); +} + +static void +gtk_map_render_paths(GtkWidget *widget, GdkEventExpose *event) +{ +GtkMap *map; +GtkMapPriv *priv; +GSList *iter; + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +/* No paths defined so return */ +if (!priv->paths) + return; + +for (iter=priv->paths; iter!=NULL; iter=iter->next) { + Path *p=(Path *)iter->data; + + if ( (!(priv->show_paths & ROUTES_MASK) && p->type==PATH_TYPE_ROUTE) || + (!(priv->show_paths & TRACKS_MASK) && p->type==PATH_TYPE_ROUTE) ) + continue; + + gtk_map_render_path(widget, p, event); +} +} + static void gtk_map_mark_draw(GtkWidget *widget, GdkEventExpose *event) { @@ -1078,7 +1206,7 @@ gdk_draw_rectangle(priv->buffer, return TRUE; } -gboolean +void gtk_map_set_center(GtkWidget *widget, guint unitx, guint unity) { GtkMap *map; @@ -1172,6 +1300,15 @@ gtk_map_refresh(widget); g_signal_emit(widget, gtk_map_signals[MAP_LOCATION_CHANGED], 0, priv->zoom); } +void +gtk_map_set_center_latlon(GtkWidget *widget, gdouble lat, gdouble lon) +{ +guint unitx, unity; + +latlon2unit(lat, lon, unitx, unity); +gtk_map_set_center(widget, unitx, unity); +} + void gtk_map_pan(GtkWidget *widget, gint delta_x, gint delta_y) { @@ -1318,6 +1455,10 @@ if (cache_size>512) image_cache_set_size(priv->icache, cache_size); } +/******************************************************************************/ +/* Internal widget callback handlers */ +/******************************************************************************/ + /** * Mouse scroller zoom in/out callback */ diff --git a/src/gtkmap.h b/src/gtkmap.h index 360a828..958f3ff 100644 --- a/src/gtkmap.h +++ b/src/gtkmap.h @@ -32,6 +32,10 @@ typedef enum { CENTER_LATLON = 2 } GtkMapCenterMode; +#define TRACKS_MASK 0x00000001 +#define ROUTES_MASK 0x00000002 +#define FRIENDS_MASK 0x00000004 + #define GTK_MAP_TYPE (gtk_map_get_type ()) #define GTK_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_MAP_TYPE, GtkMap)) #define GTK_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_MAP_TYPE, GtkMapClass)) @@ -58,41 +62,41 @@ G_BEGIN_DECLS GType gtk_map_get_type(void); GtkWidget* gtk_map_new(void); + void gtk_map_refresh(GtkWidget *map); +/* Map repository handling */ void gtk_map_set_tile_repository(GtkWidget *map, RepoData *rd); -gboolean gtk_map_key_zoom_timeout(GtkWidget *map); -void gtk_map_render_path(GtkWidget *map, Path *path, GdkGC ** gc); - +/* */ void gtk_map_set_mark(GtkWidget *map); void gtk_map_move_mark(GtkWidget *map); -void gtk_map_render_data(GtkWidget *map); -void gtk_map_render_waypoint(GtkWidget *map, guint x1, guint y1, GdkGC *gc); -void gtk_map_render_paths(GtkWidget *map); -void gtk_map_force_redraw(GtkWidget *map); -void gtk_map_draw_position_icon(GtkWidget *map, Position *pos, const gchar *icon); +/* Path functions */ +void gtk_map_set_path(GtkWidget *map, Path *path, PathType type, gint id); +gboolean gtk_map_remove_path(GtkWidget *map, Path *path); +gboolean gtk_map_remove_path_by_id(GtkWidget *map, gint id); + +/* Get copy of map buffer */ GdkPixmap *gtk_map_pixmap_get(GtkWidget *map); +/* Tile cache config */ void gtk_map_set_cache_size(GtkWidget *widget, guint cache_size); /* 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_set_center(GtkWidget *map, guint unitx, guint unity); +void gtk_map_set_center_latlon(GtkWidget *map, gdouble lat, gdouble lon); +void gtk_map_get_center_latlon(GtkWidget *map); 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); +gint gtk_map_zoom(GtkWidget *map, gint zdir); +gboolean gtk_map_zoom_out(GtkWidget *map); +gboolean gtk_map_zoom_in(GtkWidget *map); 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); - G_END_DECLS #endif /* __GTK_MAP_H__ */ -- 2.39.5