diff --git a/examples/Makefile.am b/examples/Makefile.am index fafab85..1148ef5 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -13,7 +13,7 @@ OSMGPSMAP_LIBS = \ $(SOUP24_LIBS) ## Demo Application -noinst_PROGRAMS = mapviewer polygon editable_track +noinst_PROGRAMS = mapviewer polygon editable_track clickable_track editable_clickable_track mapviewer_SOURCES = \ mapviewer.c @@ -62,6 +62,36 @@ editable_track_LDADD = \ $(GTHREAD_LIBS) \ $(top_builddir)/src/libosmgpsmap-1.0.la +clickable_track_SOURCES = \ + clickable_track.c + +clickable_track_CFLAGS = \ + -I$(top_srcdir)/src \ + $(WARN_CFLAGS) \ + $(DISABLE_DEPRECATED) \ + $(OSMGPSMAP_CFLAGS) \ + $(GTHREAD_CFLAGS) + +clickable_track_LDADD = \ + $(OSMGPSMAP_LIBS) \ + $(GTHREAD_LIBS) \ + $(top_builddir)/src/libosmgpsmap-1.0.la + +editable_clickable_track_SOURCES = \ + editable_clickable_track.c + +editable_clickable_track_CFLAGS = \ + -I$(top_srcdir)/src \ + $(WARN_CFLAGS) \ + $(DISABLE_DEPRECATED) \ + $(OSMGPSMAP_CFLAGS) \ + $(GTHREAD_CFLAGS) + +editable_clickable_track_LDADD = \ + $(OSMGPSMAP_LIBS) \ + $(GTHREAD_LIBS) \ + $(top_builddir)/src/libosmgpsmap-1.0.la + ## Misc EXTRA_DIST = poi.png mapviewer.ui mapviewer.js README diff --git a/examples/clickable_track.c b/examples/clickable_track.c new file mode 100644 index 0000000..26f2de1 --- /dev/null +++ b/examples/clickable_track.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */ +/* vim:set et sw=4 ts=4 cino=t0,(0: */ +/* + * clickable_track.c + * Copyright (C) Martijn Goedhart 2014 + * + * This is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include "osm-gps-map.h" +#include "converter.h" + +void point_clicked(OsmGpsMapTrack *osmgpsmaptrack, OsmGpsMapPoint *point, gpointer user_data); + +void +point_clicked(OsmGpsMapTrack *osmgpsmaptrack, OsmGpsMapPoint *point, gpointer user_data) +{ + printf("point at latitude: %.4f and longitude %.4f clicked\n", rad2deg(point->rlat), rad2deg(point->rlon)); + osm_gps_map_track_set_highlight_point(osmgpsmaptrack, point); +} + +int +main (int argc, char *argv[]) +{ + OsmGpsMap *map; + GtkWidget *window; + + gtk_init(&argc, &argv); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), "Window"); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + + map = g_object_new(OSM_TYPE_GPS_MAP, NULL); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(map)); + + OsmGpsMapTrack* track = osm_gps_map_track_new(); + + OsmGpsMapPoint* p1, *p2, *p3, *p4; + p1 = osm_gps_map_point_new_radians(1.25663706, -0.488692191); + p2 = osm_gps_map_point_new_radians(1.06465084, -0.750491578); + p3 = osm_gps_map_point_new_radians(1.17245321, -0.685401453); + p4 = osm_gps_map_point_new_radians(1.04543154, -0.105454354); + + osm_gps_map_track_add_point(track, p1); + osm_gps_map_track_add_point(track, p2); + osm_gps_map_track_add_point(track, p3); + osm_gps_map_track_add_point(track, p4); + + osm_gps_map_point_free(p1); + osm_gps_map_point_free(p2); + osm_gps_map_point_free(p3); + osm_gps_map_point_free(p4); + + g_object_set(track, "clickable", TRUE, NULL); + g_signal_connect(track, "point-clicked", G_CALLBACK(point_clicked), NULL); + + osm_gps_map_track_add(map, track); + + gtk_widget_show(GTK_WIDGET(map)); + gtk_widget_show(window); + + gtk_main(); + + return 0; +} diff --git a/examples/editable_clickable_track.c b/examples/editable_clickable_track.c new file mode 100644 index 0000000..997b28c --- /dev/null +++ b/examples/editable_clickable_track.c @@ -0,0 +1,86 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */ +/* vim:set et sw=4 ts=4 cino=t0,(0: */ +/* + * clickable_track.c + * Copyright (C) Martijn Goedhart 2014 + * + * This is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include "osm-gps-map.h" +#include "converter.h" + +void point_clicked(OsmGpsMapTrack *osmgpsmaptrack, OsmGpsMapPoint *point, gpointer user_data); +void point_changed(OsmGpsMapTrack *osmgpsmaptrack, gpointer user_data); + +void +point_clicked(OsmGpsMapTrack *osmgpsmaptrack, OsmGpsMapPoint *point, gpointer user_data) +{ + printf("point at latitude: %.4f and longitude %.4f clicked\n", rad2deg(point->rlat), rad2deg(point->rlon)); + osm_gps_map_track_set_highlight_point(osmgpsmaptrack, point); +} + +void +point_changed(OsmGpsMapTrack *osmgpsmaptrack, gpointer user_data) +{ + printf("point has changed\n"); +} + +int +main (int argc, char *argv[]) +{ + OsmGpsMap *map; + GtkWidget *window; + + gtk_init(&argc, &argv); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), "Window"); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + + map = g_object_new(OSM_TYPE_GPS_MAP, NULL); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(map)); + + OsmGpsMapTrack* track = osm_gps_map_track_new(); + + OsmGpsMapPoint* p1, *p2, *p3, *p4; + p1 = osm_gps_map_point_new_radians(1.25663706, -0.488692191); + p2 = osm_gps_map_point_new_radians(1.06465084, -0.750491578); + p3 = osm_gps_map_point_new_radians(1.17245321, -0.685401453); + p4 = osm_gps_map_point_new_radians(1.04543154, -0.105454354); + + osm_gps_map_track_add_point(track, p1); + osm_gps_map_track_add_point(track, p2); + osm_gps_map_track_add_point(track, p3); + osm_gps_map_track_add_point(track, p4); + + osm_gps_map_point_free(p1); + osm_gps_map_point_free(p2); + osm_gps_map_point_free(p3); + osm_gps_map_point_free(p4); + + g_object_set(track, "clickable", TRUE, NULL); + g_object_set(track, "editable", TRUE, NULL); + g_signal_connect(track, "point-clicked", G_CALLBACK(point_clicked), NULL); + g_signal_connect(track, "point-changed", G_CALLBACK(point_changed), NULL); + + osm_gps_map_track_add(map, track); + + gtk_widget_show(GTK_WIDGET(map)); + gtk_widget_show(window); + + gtk_main(); + + return 0; +} diff --git a/src/osm-gps-map-polygon.c b/src/osm-gps-map-polygon.c index c290a56..923dcaa 100644 --- a/src/osm-gps-map-polygon.c +++ b/src/osm-gps-map-polygon.c @@ -29,6 +29,7 @@ enum PROP_SHADED, PROP_EDITABLE, PROP_SHADE_ALPHA, + PROP_CLICKABLE, PROP_BREAKABLE }; @@ -38,6 +39,7 @@ struct _OsmGpsMapPolygonPrivate gboolean visible; gboolean editable; gboolean shaded; + gboolean clickable; gfloat shade_alpha; gboolean breakable; }; @@ -74,6 +76,9 @@ osm_gps_map_polygon_get_property (GObject *object, case PROP_SHADE_ALPHA: g_value_set_float(value, priv->shade_alpha); break; + case PROP_CLICKABLE: + g_value_set_boolean(value, priv->clickable); + break; case PROP_BREAKABLE: g_value_set_boolean(value, priv->breakable); break; @@ -107,6 +112,9 @@ osm_gps_map_polygon_set_property (GObject *object, case PROP_SHADE_ALPHA: priv->shade_alpha = g_value_get_float(value); break; + case PROP_CLICKABLE: + priv->clickable = g_value_get_boolean(value); + break; case PROP_BREAKABLE: priv->breakable = g_value_get_boolean(value); break; @@ -191,6 +199,13 @@ osm_gps_map_polygon_class_init (OsmGpsMapPolygonClass *klass) TRUE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_CLICKABLE, + g_param_spec_boolean ("clickable", + "clickable", + "should this polygon be clickable", + FALSE, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); } static void diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 06ab0dc..3536ddc 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -42,7 +42,10 @@ enum PROP_LINE_WIDTH, PROP_ALPHA, PROP_COLOR, - PROP_EDITABLE + PROP_EDITABLE, + PROP_CLICKABLE, + PROP_HIGHLIGHT_POINT, + PROP_HIGHLIGHT_COLOR }; enum @@ -51,6 +54,7 @@ enum POINT_CHANGED, POINT_INSERTED, POINT_REMOVED, + POINT_CLICKED, LAST_SIGNAL }; @@ -64,6 +68,16 @@ struct _OsmGpsMapTrackPrivate gfloat alpha; GdkRGBA color; gboolean editable; + gboolean clickable; + + /* + * Properties for highlighted points. + * highlight_point - Must be a pointer to a element in the list of points + * associated with this track or NULL. + * highlight_color - The color used to indicate this point as highlighted. + */ + OsmGpsMapPoint *highlight_point; + GdkRGBA highlight_color; }; G_DEFINE_TYPE_WITH_PRIVATE(OsmGpsMapTrack, osm_gps_map_track, G_TYPE_OBJECT) @@ -73,6 +87,11 @@ G_DEFINE_TYPE_WITH_PRIVATE(OsmGpsMapTrack, osm_gps_map_track, G_TYPE_OBJECT) #define DEFAULT_B (0) #define DEFAULT_A (0.6) +#define DEFAULT_HIGHLIGHT_R (0) +#define DEFAULT_HIGHLIGHT_G (0) +#define DEFAULT_HIGHLIGHT_B (0.6) +#define DEFAULT_HIGHLIGHT_A (0.6) + static void osm_gps_map_track_get_property (GObject *object, guint property_id, @@ -101,6 +120,15 @@ osm_gps_map_track_get_property (GObject *object, case PROP_EDITABLE: g_value_set_boolean(value, priv->editable); break; + case PROP_CLICKABLE: + g_value_set_boolean(value, priv->clickable); + break; + case PROP_HIGHLIGHT_POINT: + g_value_set_pointer(value, priv->highlight_point); + break; + case PROP_HIGHLIGHT_COLOR: + g_value_set_boxed(value, &priv->highlight_color); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -137,6 +165,20 @@ osm_gps_map_track_set_property (GObject *object, case PROP_EDITABLE: priv->editable = g_value_get_boolean(value); break; + case PROP_CLICKABLE: + priv->clickable = g_value_get_boolean(value); + break; + case PROP_HIGHLIGHT_POINT: + priv->highlight_point = g_value_get_pointer(value); + break; + case PROP_HIGHLIGHT_COLOR: { + GdkRGBA *c = g_value_get_boxed (value); + priv->highlight_color.red = c->red; + priv->highlight_color.green = c->green; + priv->highlight_color.blue = c->blue; + printf("\n%f %f %f\n", c->red, c->green, c->blue); + fflush(stdout); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -224,6 +266,29 @@ osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass) FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_CLICKABLE, + g_param_spec_boolean ("clickable", + "clickable", + "should this track be clickable", + FALSE, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_HIGHLIGHT_POINT, + g_param_spec_pointer ("highlight-point", + "highlight point", + "point in this track that must be highlighted", + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property (object_class, + PROP_HIGHLIGHT_COLOR, + g_param_spec_boxed ("highlight-color", + "highlight color", + "color used to mark a highlighted point", + GDK_TYPE_COLOR, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + /** * OsmGpsMapTrack::point-added: * @self: A #OsmGpsMapTrack @@ -275,6 +340,22 @@ osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass) G_TYPE_NONE, 1, G_TYPE_INT); + + /* + * This signal is emitted when a point on the map is clicked/selected. The + * callback(s) connected to this signal will receive a pointer to the point + * which was clicked (hence the G_SIGNAL_TYPE_STATIC_SCOPE flag). + */ + signals [POINT_CLICKED] = g_signal_new ("point-clicked", + OSM_TYPE_GPS_MAP_TRACK, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + OSM_TYPE_GPS_MAP_POINT | G_SIGNAL_TYPE_STATIC_SCOPE); } static void @@ -285,6 +366,12 @@ osm_gps_map_track_init (OsmGpsMapTrack *self) self->priv->color.red = DEFAULT_R; self->priv->color.green = DEFAULT_G; self->priv->color.blue = DEFAULT_B; + + self->priv->highlight_color.red = DEFAULT_HIGHLIGHT_R; + self->priv->highlight_color.green = DEFAULT_HIGHLIGHT_G; + self->priv->highlight_color.blue = DEFAULT_HIGHLIGHT_B; + + self->priv->highlight_point = NULL; } void @@ -351,6 +438,24 @@ osm_gps_map_track_get_color (OsmGpsMapTrack *track, GdkRGBA *color) color->blue = track->priv->color.blue; } +void +osm_gps_map_track_set_highlight_color (OsmGpsMapTrack *track, GdkRGBA *color) +{ + g_return_if_fail (OSM_GPS_MAP_IS_TRACK (track)); + track->priv->highlight_color.red = color->red; + track->priv->highlight_color.green = color->green; + track->priv->highlight_color.blue = color->blue; +} + +void +osm_gps_map_track_get_highlight_color (OsmGpsMapTrack *track, GdkRGBA *color) +{ + g_return_if_fail (OSM_GPS_MAP_IS_TRACK (track)); + color->red = track->priv->highlight_color.red; + color->green = track->priv->highlight_color.green; + color->blue = track->priv->highlight_color.blue; +} + double osm_gps_map_track_get_length(OsmGpsMapTrack* track) { @@ -373,6 +478,23 @@ osm_gps_map_track_get_length(OsmGpsMapTrack* track) return ret; } +void +osm_gps_map_track_set_highlight_point(OsmGpsMapTrack* track, OsmGpsMapPoint *point) +{ + g_return_if_fail (OSM_GPS_MAP_IS_TRACK (track)); + track->priv->highlight_point = point; + /* Notify ourself of the new highlight point. + * When a map object is listening it will update the map. */ + g_object_notify (G_OBJECT (track), "highlight-point"); +} + +OsmGpsMapPoint * +osm_gps_map_track_get_highlight_point(OsmGpsMapTrack* track) +{ + g_return_val_if_fail (OSM_GPS_MAP_IS_TRACK (track), NULL); + return track->priv->highlight_point; +} + OsmGpsMapTrack * osm_gps_map_track_new (void) diff --git a/src/osm-gps-map-track.h b/src/osm-gps-map-track.h index 1195df3..fdbe58c 100644 --- a/src/osm-gps-map-track.h +++ b/src/osm-gps-map-track.h @@ -110,6 +110,8 @@ void osm_gps_map_track_set_color (OsmGpsMapTrack *track, GdkR * Since: 0.7.0 **/ void osm_gps_map_track_get_color (OsmGpsMapTrack *track, GdkRGBA *color); +void osm_gps_map_track_set_highlight_color (OsmGpsMapTrack *track, GdkRGBA *color); +void osm_gps_map_track_get_highlight_color (OsmGpsMapTrack *track, GdkRGBA *color); /** * osm_gps_map_track_remove_point: @@ -168,6 +170,13 @@ OsmGpsMapPoint* osm_gps_map_track_get_point(OsmGpsMapTrack* track, int pos); **/ double osm_gps_map_track_get_length(OsmGpsMapTrack* track); +/** + * osm_gps_map_track_set_highlight_point: + * Mark the given point as highlighted on this track. + * @note The point must match a point in the list of points associated with the given track. + */ +void osm_gps_map_track_set_highlight_point(OsmGpsMapTrack* track, OsmGpsMapPoint *point); +OsmGpsMapPoint * osm_gps_map_track_get_highlight_point(OsmGpsMapTrack* track); G_END_DECLS diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 2d3eb8d..6d52ceb 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -229,10 +229,17 @@ struct _OsmGpsMapPrivate int drag_limit; guint drag_expose_source; - /* Properties for dragging a point with right mouse button. */ + /* Properties for dragging and clicking a point. */ OsmGpsMapPoint* drag_point; OsmGpsMapTrack* drag_track; + /* + * Last location where a click is received, so a click and move can be + * distinguished from a click. + */ + int clicked_x; + int clicked_y; + /* for customizing the redering of the gps track */ int ui_gps_point_inner_radius; int ui_gps_point_outer_radius; @@ -256,6 +263,7 @@ struct _OsmGpsMapPrivate guint is_fullscreen : 1; guint is_google : 1; guint is_dragging_point : 1; + guint is_clicked_point : 1; }; typedef struct @@ -1144,24 +1152,29 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) OsmGpsMapPrivate *priv = map->priv; GSList *pt,*points; + OsmGpsMapPoint *highlight_point; int x,y; int min_x = 0,min_y = 0,max_x = 0,max_y = 0; gfloat lw, alpha; int map_x0, map_y0; - GdkRGBA color; + GdkRGBA color, highlight_color; g_object_get (track, "track", &points, "line-width", &lw, "alpha", &alpha, + "highlight_point", &highlight_point, NULL); osm_gps_map_track_get_color(track, &color); + osm_gps_map_track_get_highlight_color(track, &highlight_color); if (points == NULL) return; gboolean path_editable = FALSE; + gboolean path_clickable = FALSE; g_object_get(track, "editable", &path_editable, NULL); + g_object_get(track, "clickable", &path_clickable, NULL); cairo_set_line_width (cr, lw); cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha); @@ -1215,12 +1228,21 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) cairo_line_to(cr, x, y); cairo_stroke(cr); - if(path_editable) + if(path_editable || path_clickable) { - cairo_arc (cr, x, y, DOT_RADIUS, 0.0, 2 * M_PI); + if(tp == highlight_point) + { + cairo_set_source_rgba (cr, highlight_color.red, highlight_color.green, highlight_color.blue, alpha); + cairo_arc (cr, x, y, DOT_RADIUS, 0.0, 2 * M_PI); + cairo_stroke(cr); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha); + } + else + cairo_arc (cr, x, y, DOT_RADIUS, 0.0, 2 * M_PI); cairo_stroke(cr); - if(pt != points) + /* This draws the breaker point, do this only when the track is editable. */ + if(pt != points && path_editable) { cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha*0.75); cairo_arc(cr, (last_x + x)/2.0, (last_y+y)/2.0, DOT_RADIUS, 0.0, 2*M_PI); @@ -1299,9 +1321,11 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) return; gboolean path_editable = FALSE; + gboolean path_clickable = FALSE; gboolean poly_shaded = FALSE; gboolean breakable = TRUE; g_object_get(poly, "editable", &path_editable, NULL); + g_object_get(poly, "clickable", &path_clickable, NULL); g_object_get(poly, "shaded", &poly_shaded, NULL); g_object_get(poly, "shade_alpha", &shade_alpha, NULL); g_object_get(poly, "breakable", &breakable, NULL); @@ -1335,7 +1359,7 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) cairo_line_to(cr, first_x, first_y); cairo_stroke(cr); - if(path_editable) + if(path_editable || path_clickable) { int last_x = 0, last_y = 0; for(pt = points; pt != NULL; pt = pt->next) @@ -1348,7 +1372,8 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) cairo_arc (cr, x, y, DOT_RADIUS, 0.0, 2 * M_PI); cairo_stroke(cr); - if((pt != points) && (breakable)) + /* This draws the breaker point, do this only when the track is editable. */ + if((pt != points) && (breakable || path_editable)) { cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha*0.75); cairo_arc(cr, (last_x + x)/2.0, (last_y+y)/2.0, DOT_RADIUS, 0.0, 2*M_PI); @@ -2197,12 +2222,16 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) if(event->button == 1) { GSList* tracks = priv->tracks; + priv->clicked_x = event->x; + priv->clicked_y = event->y; while(tracks) { OsmGpsMapTrack* track = tracks->data; gboolean path_editable = FALSE; + gboolean path_clickable = FALSE; g_object_get(track, "editable", &path_editable, NULL); - if(path_editable) + g_object_get(track, "clickable", &path_clickable, NULL); + if(path_editable || path_clickable) { GSList* points = osm_gps_map_track_get_points(track); int ctr = 0; @@ -2221,11 +2250,28 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) priv->is_button_down = TRUE; priv->drag_point = point; priv->drag_track = track; - priv->is_dragging_point = TRUE; + /* + * If the track is clickable mark this point as clicked + * and track if the mouse is not moved (too far). When + * this track is only editable mark this point as + * dragging right away. + */ + if(path_clickable) priv->is_clicked_point = TRUE; + else priv->is_dragging_point = TRUE; osm_gps_map_map_redraw(map); return FALSE; } + /* When the path is not editable go to the next interation, + * because the rest of this loop is only used in the case + * the path is editable. + */ + if(!path_editable) + { + points = points->next; + continue; + } + //add a new point if a 'breaker' has been clicked if(ctr != 0) { @@ -2237,6 +2283,13 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) OsmGpsMapPoint* newpoint = malloc(sizeof(OsmGpsMapPoint)); osm_gps_map_convert_screen_to_geographic(map, ptx, pty, newpoint); osm_gps_map_track_insert_point(track, newpoint, ctr); + /* + * Also emit the point-clicked signal when a + * breaker has been clicked, but after the new + * point has been created. + */ + if(path_clickable) + g_signal_emit_by_name(track, "point-clicked", newpoint); osm_gps_map_map_redraw(map); return FALSE; } @@ -2257,10 +2310,12 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) OsmGpsMapPolygon* poly = polys->data; gboolean path_editable = FALSE; gboolean breakable = TRUE; + gboolean path_clickable = FALSE; OsmGpsMapTrack* track = osm_gps_map_polygon_get_track(poly); g_object_get(poly, "editable", &path_editable, NULL); g_object_get(poly, "breakable", &breakable, NULL); - if(path_editable) + g_object_get(poly, "clickable", &path_clickable, NULL); + if(path_editable || path_clickable) { GSList* points = osm_gps_map_track_get_points(track); int ctr = 0; @@ -2280,11 +2335,28 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) priv->is_button_down = TRUE; priv->drag_point = point; priv->drag_track = track; - priv->is_dragging_point = TRUE; + /* + * If the polygon is clickable mark this point as + * clicked and track if the mouse is not moved (too + * far). When this track is only editable mark this + * point as dragging right away. + */ + if(path_clickable) priv->is_clicked_point = TRUE; + else priv->is_dragging_point = TRUE; osm_gps_map_map_redraw(map); return FALSE; } + /* When the path is not editable go to the next interation, + * because the rest of this loop is only used in the case + * the path is editable. + */ + if(!path_editable) + { + points = points->next; + continue; + } + //add a new point if a 'breaker' has been clicked if((ctr != 0) && (breakable)) { @@ -2296,6 +2368,13 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) OsmGpsMapPoint* newpoint = malloc(sizeof(OsmGpsMapPoint)); osm_gps_map_convert_screen_to_geographic(map, ptx, pty, newpoint); osm_gps_map_track_insert_point(track, newpoint, ctr); + /* + * Also emit the point-clicked signal when a + * breaker has been clicked, but after the new + * point has been created. + */ + if(path_clickable) + g_signal_emit_by_name(track, "point-clicked", newpoint); osm_gps_map_map_redraw(map); return FALSE; } @@ -2319,6 +2398,13 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) OsmGpsMapPoint* newpoint = malloc(sizeof(OsmGpsMapPoint)); osm_gps_map_convert_screen_to_geographic(map, ptx, pty, newpoint); osm_gps_map_track_insert_point(track, newpoint, ctr); + /* + * Also emit the point-clicked signal when a + * breaker has been clicked, but after the new + * point has been created. + */ + if(path_clickable) + g_signal_emit_by_name(track, "point-clicked", newpoint); osm_gps_map_map_redraw(map); return FALSE; } @@ -2361,13 +2447,19 @@ osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event) osm_gps_map_map_redraw_idle(map); } - if( priv->is_dragging_point) + if(priv->is_dragging_point) { priv->is_dragging_point = FALSE; osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, priv->drag_point); g_signal_emit_by_name(priv->drag_track, "point-changed"); } + if(priv->is_clicked_point) + { + priv->is_clicked_point = FALSE; + g_signal_emit_by_name(priv->drag_track, "point-clicked", priv->drag_point); + } + priv->drag_counter = -1; priv->is_button_down = FALSE; @@ -2394,6 +2486,21 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion *event) if(!priv->is_button_down) return FALSE; + if(priv->is_clicked_point) + { + gboolean path_editable = FALSE; + g_object_get(priv->drag_track, "editable", &path_editable, NULL); + /* + * If the track is also editable and the mouse is moved away from its + * initial position, then mark this point as dragging. + */ + if(priv->is_clicked_point && path_editable && (priv->clicked_x != event->x || priv->clicked_y != event->y)) + { + priv->is_dragging_point = TRUE; + priv->is_clicked_point = FALSE; + } + } + if(priv->is_dragging_point) { osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, priv->drag_point);