--- trunk/src/osm-gps-map-osd-classic.c 2009/09/16 13:45:10 113 +++ trunk/src/osm-gps-map-osd-classic.c 2009/09/16 20:04:38 114 @@ -52,6 +52,7 @@ cairo_surface_t *surface; int orientation, offset_x, offset_y; + gboolean just_created; float lat, lon; OsmGpsMapRect_t rect; @@ -272,7 +273,7 @@ /* return true if balloon is being displayed and if */ /* the given coordinate is within this balloon */ static gboolean -osd_balloon_check(osm_gps_map_osd_t *osd, gint x, gint y) +osd_balloon_check(osm_gps_map_osd_t *osd, gboolean down, gint x, gint y) { osd_priv_t *priv = (osd_priv_t*)osd->priv; @@ -287,9 +288,21 @@ xs += priv->balloon.rect.x + priv->balloon.offset_x; ys += priv->balloon.rect.y + priv->balloon.offset_y; - return (priv->balloon.surface && - (x > xs) && (x < xs + priv->balloon.rect.w) && - (y > ys) && (y < ys + priv->balloon.rect.h)); + /* handle the fact that the balloon may have been created by the */ + /* button down event */ + + gboolean is_in = + (x > xs) && (x < xs + priv->balloon.rect.w) && + (y > ys) && (y < ys + priv->balloon.rect.h); + + if(!is_in && !down && !priv->balloon.just_created) { + /* the user actually clicked outside the balloon */ + + /* close the balloon! */ + osm_gps_map_osd_clear_balloon (OSM_GPS_MAP(osd->widget)); + } + + return is_in; } void osm_gps_map_osd_clear_balloon (OsmGpsMap *map) { @@ -301,8 +314,6 @@ osd_priv_t *priv = (osd_priv_t*)osd->priv; g_return_if_fail (priv); - printf("request to clear balloon\n"); - if(priv->balloon.surface) { cairo_surface_destroy(priv->balloon.surface); priv->balloon.surface = NULL; @@ -325,8 +336,6 @@ osm_gps_map_osd_clear_balloon (map); - printf("request to draw balloon at %f %f\n", latitude, longitude); - /* allocate balloon surface */ priv->balloon.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, @@ -336,6 +345,7 @@ priv->balloon.lon = longitude; priv->balloon.cb = cb; priv->balloon.data = data; + priv->balloon.just_created = TRUE; priv->balloon.orientation = -1; @@ -856,7 +866,7 @@ /* check if the user clicked inside the source selection area */ static osd_button_t -osd_source_check(osm_gps_map_osd_t *osd, gint x, gint y) { +osd_source_check(osm_gps_map_osd_t *osd, gboolean down, gint x, gint y) { osd_priv_t *priv = (osd_priv_t*)osd->priv; if(!priv->source_sel.expanded) @@ -874,7 +884,8 @@ /* really within puller shape? */ if(x > Z_RAD || osm_gps_map_in_circle(x, y, Z_RAD, Z_RAD, Z_RAD)) { /* expand source selector */ - osd_source_toggle(osd); + if(down) + osd_source_toggle(osd); /* tell upper layers that user clicked some background element */ /* of the OSD */ @@ -900,16 +911,18 @@ y /= step; y += 1; - gint old = 0; - g_object_get(osd->widget, "map-source", &old, NULL); - - if(y > OSM_GPS_MAP_SOURCE_NULL && - y <= OSM_GPS_MAP_SOURCE_LAST && - old != y) { - g_object_set(osd->widget, "map-source", y, NULL); - - osd_render_source_sel(osd, TRUE); - osm_gps_map_repaint(OSM_GPS_MAP(osd->widget)); + if(down) { + gint old = 0; + g_object_get(osd->widget, "map-source", &old, NULL); + + if(y > OSM_GPS_MAP_SOURCE_NULL && + y <= OSM_GPS_MAP_SOURCE_LAST && + old != y) { + g_object_set(osd->widget, "map-source", y, NULL); + + osd_render_source_sel(osd, TRUE); + osm_gps_map_repaint(OSM_GPS_MAP(osd->widget)); + } } /* return "clicked in OSD background" to prevent further */ @@ -923,42 +936,52 @@ #endif // OSD_SOURCE_SEL static osd_button_t -osd_check(osm_gps_map_osd_t *osd, gint x, gint y) { +osd_check(osm_gps_map_osd_t *osd, gboolean down, gint x, gint y) { osd_button_t but = OSD_NONE; #ifdef OSD_BALLOON - /* check if user clicked into balloon */ - if(osd_balloon_check(osd, x, y)) - return OSD_BG; + if(down) { + /* needed to handle balloons that are created at click */ + osd_priv_t *priv = (osd_priv_t*)osd->priv; + priv->balloon.just_created = FALSE; + } #endif #ifdef OSD_SOURCE_SEL /* the source selection area is handles internally */ - but = osd_source_check(osd, x, y); - if(but != OSD_NONE) - return but; + but = osd_source_check(osd, down, x, y); #endif - - x -= OSD_X; - y -= OSD_Y; - - if(OSD_X < 0) - x -= (osd->widget->allocation.width - OSD_W); - - if(OSD_Y < 0) - y -= (osd->widget->allocation.height - OSD_H); - - /* first do a rough test for the OSD area. */ - /* this is just to avoid an unnecessary detailed test */ - if(x > 0 && x < OSD_W && y > 0 && y < OSD_H) { + + if(but == OSD_NONE) { + x -= OSD_X; + y -= OSD_Y; + + if(OSD_X < 0) + x -= (osd->widget->allocation.width - OSD_W); + + if(OSD_Y < 0) + y -= (osd->widget->allocation.height - OSD_H); + + /* first do a rough test for the OSD area. */ + /* this is just to avoid an unnecessary detailed test */ + if(x > 0 && x < OSD_W && y > 0 && y < OSD_H) { #ifndef OSD_NO_DPAD - but = osd_check_dpad(x, y); + but = osd_check_dpad(x, y); #endif + } if(but == OSD_NONE) but = osd_check_zoom(x, y); } +#ifdef OSD_BALLOON + if(but == OSD_NONE) { + /* check if user clicked into balloon */ + if(osd_balloon_check(osd, down, x, y)) + but = OSD_BG; + } +#endif + return but; } @@ -1745,5 +1768,5 @@ osm_gps_map_osd_t *osd = osm_gps_map_osd_get(map); g_return_val_if_fail (osd, OSD_NONE); - return osd_check(osd, x, y); + return osd_check(osd, TRUE, x, y); }