--- trunk/src/osm-gps-map.c 2009/08/17 10:51:56 58 +++ trunk/src/osm-gps-map.c 2009/08/18 14:32:45 61 @@ -107,6 +107,17 @@ gpointer data; } balloon; +#ifdef ENABLE_OSD + //the osd controls + struct { + GdkPixmap *backup; + gint backup_x, backup_y; + + + // GdkPixbuf *pixbuf; + } osd; +#endif + //additional images or tracks added to the map GSList *tracks; GSList *images; @@ -644,7 +655,7 @@ /* most visual effects are hardcoded by now, but may be made */ /* available via properties later */ -#define BALLOON_AREA_WIDTH 250 +#define BALLOON_AREA_WIDTH 290 #define BALLOON_AREA_HEIGHT 75 #define BALLOON_CORNER_RADIUS 20 @@ -693,7 +704,6 @@ cairo_close_path (cr); } -/* http://cairographics.org/samples/ */ static void osm_gps_map_draw_balloon_int (OsmGpsMap *map) { @@ -801,6 +811,8 @@ priv->balloon.cb(cr, &priv->balloon.rect, priv->balloon.data); } + cairo_destroy(cr); + gtk_widget_queue_draw_area (GTK_WIDGET(map), x0, y0, BALLOON_WIDTH, BALLOON_HEIGHT + POINTER_HEIGHT); @@ -816,8 +828,6 @@ { OsmGpsMapPrivate *priv = map->priv; - printf("clocked at %d %d\n", x, y); - if (!priv->balloon.valid) return; @@ -1397,6 +1407,147 @@ g_hash_table_foreach_remove(priv->tile_cache, osm_gps_map_purge_cache_check, priv); } +#ifdef ENABLE_OSD +/* position and extent of bounding box */ +#define OSD_X (10) +#define OSD_Y (10) +#define OSD_W (80+5) +#define OSD_H (120+5) + +static void +osm_gps_map_draw_osd_controls (OsmGpsMap *map, gint xoffset, gint yoffset) +{ + /* xyz */ + OsmGpsMapPrivate *priv = map->priv; + + /* backup previous contents */ + if(!priv->osd.backup) + priv->osd.backup = gdk_pixmap_new(priv->pixmap, OSD_W, OSD_H, -1); + + gint x = OSD_X + EXTRA_BORDER + xoffset; + gint y = OSD_Y + EXTRA_BORDER + yoffset; + + /* create backup of background */ + gdk_draw_drawable(priv->osd.backup, + GTK_WIDGET(map)->style->fg_gc[GTK_WIDGET_STATE(GTK_WIDGET(map))], + priv->pixmap, x, y, 0, 0, OSD_W, OSD_H); + priv->osd.backup_x = x; + priv->osd.backup_y = y; + +#if 0 + /* create pixbuf for osd */ + if(!priv->osd.pixbuf) + priv->osd.pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, + TRUE, 8, OSD_W, OSD_H); + cairo_surface_t *surface = + cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W, OSD_H); + + /* fill with transparency */ + { + cairo_t *cr = cairo_create(surface); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0); + cairo_paint(cr); + cairo_destroy(cr); + } +#endif + + +#ifdef USE_CAIRO + // cairo_t *cr = cairo_create(surface); + cairo_t *cr = gdk_cairo_create(priv->pixmap); + +#define RAD 40 +#define TIP 35 +#define LEN 15 +#define WID 15 + + /* --------- the direction "pad" shape and shadow ----------- */ + cairo_arc (cr, x+RAD+5, y+RAD+5, RAD, 0, 2 * M_PI); + cairo_set_source_rgba (cr, 0, 0, 0, 0.2); + cairo_fill (cr); + cairo_stroke (cr); + + cairo_arc (cr, x+RAD, y+RAD, RAD, 0, 2 * M_PI); + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_fill_preserve (cr); + cairo_set_source_rgb (cr, 0.6, 0.6, 1); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + + /* ---------- the zoom pad shape and shadow -------------- */ + cairo_move_to (cr, x, y+2*RAD); + cairo_line_to (cr, x+2*RAD-10, y+2*RAD); + cairo_curve_to (cr, x+2*RAD, y+2*RAD, + x+2*RAD, y+3*RAD, + x+2*RAD-10, y+3*RAD); + cairo_close_path (cr); + + + cairo_set_source_rgba (cr, 1, 1, 1, 1.0); + cairo_fill (cr); + cairo_stroke (cr); + + + /* left arrow/triangle */ + cairo_move_to (cr, x+RAD-TIP, y+RAD); + cairo_rel_line_to (cr, +LEN, -WID/2); + cairo_rel_line_to (cr, 0, +WID); + cairo_rel_line_to (cr, -LEN, -WID/2); + cairo_close_path (cr); + + /* right arrow/triangle */ + cairo_move_to (cr, x+RAD+TIP, y+RAD); + cairo_rel_line_to (cr, -LEN, -WID/2); + cairo_rel_line_to (cr, 0, +WID); + cairo_rel_line_to (cr, +LEN, -WID/2); + cairo_close_path (cr); + + /* top arrow/triangle */ + cairo_move_to (cr, x+RAD, y+RAD-TIP); + cairo_rel_line_to (cr, -WID/2, +LEN); + cairo_rel_line_to (cr, +WID, 0); + cairo_rel_line_to (cr, -WID/2, -LEN); + cairo_close_path (cr); + + /* bottom arrow/triangle */ + cairo_move_to (cr, x+RAD, y+RAD+TIP); + cairo_rel_line_to (cr, -WID/2, -LEN); + cairo_rel_line_to (cr, +WID, 0); + cairo_rel_line_to (cr, -WID/2, +LEN); + cairo_close_path (cr); + + cairo_set_source_rgb (cr, 0.6, 0.6, 1); + cairo_fill_preserve (cr); + cairo_set_line_width (cr, 0); + cairo_set_source_rgba (cr, 0, 0, 0, 1); + cairo_stroke (cr); + + + cairo_destroy(cr); + +#else +#warning "OSD control display lacks a non-cairo implementation!" +#endif +} + +static void +osm_gps_map_osd_restore (OsmGpsMap *map) +{ + OsmGpsMapPrivate *priv = map->priv; + + /* restore backup of previous contents */ + if(priv->osd.backup) { + /* create backup of background */ + gdk_draw_drawable(priv->pixmap, + GTK_WIDGET(map)->style->fg_gc[GTK_WIDGET_STATE(GTK_WIDGET(map))], + priv->osd.backup, 0, 0, + priv->osd.backup_x, priv->osd.backup_y, OSD_W, OSD_H); + } +} + +#endif + static gboolean osm_gps_map_map_redraw (OsmGpsMap *map) { @@ -1428,6 +1579,9 @@ osm_gps_map_draw_gps_point(map); osm_gps_map_print_images(map); osm_gps_map_draw_balloon_int(map); +#ifdef ENABLE_OSD + osm_gps_map_draw_osd_controls(map, 0, 0); +#endif //osm_gps_map_osd_speed(map, 1.5); osm_gps_map_purge_cache(map); @@ -1463,6 +1617,10 @@ priv->balloon.valid = FALSE; priv->balloon.cb = NULL; +#ifdef ENABLE_OSD + priv->osd.backup = NULL; +#endif + priv->tracks = NULL; priv->images = NULL; @@ -1623,6 +1781,11 @@ g_free(priv->gps); g_free(priv->balloon.coo); +#ifdef ENABLE_OSD + if (priv->osd.backup) + g_object_unref(priv->osd.backup); +#endif + G_OBJECT_CLASS (osm_gps_map_parent_class)->dispose (object); } @@ -1934,6 +2097,16 @@ priv->drag_mouse_dx = x - priv->drag_start_mouse_x; priv->drag_mouse_dy = y - priv->drag_start_mouse_y; +#ifdef ENABLE_OSD + /* undo OSD */ + osm_gps_map_osd_restore (OSM_GPS_MAP(widget)); + + /* draw new OSD */ + osm_gps_map_draw_osd_controls (OSM_GPS_MAP(widget), + -priv->drag_mouse_dx, + -priv->drag_mouse_dy); +#endif + gdk_draw_drawable ( widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], @@ -2027,6 +2200,17 @@ event->area.x, event->area.y, event->area.width, event->area.height); +#ifdef ENABLE_OSD_OVL + /* TODO: intersect with area */ + if (priv->osd.pixbuf) + { + // gdk_draw_drawable (widget->window, + // widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + // priv->osd.pixbuf, 0, 0, + // OSD_X, OSD_Y, OSD_W, OSD_H); + } +#endif + return FALSE; }