From 580150e69ea547f74d7da21b37460d9f7a7024eb Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 26 Aug 2014 13:11:09 +0200 Subject: [PATCH 01/11] add clickable property and point-clicked signal to OsmGpsMapTrack --- src/osm-gps-map-track.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 06ab0dc..8d95680 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -42,7 +42,8 @@ enum PROP_LINE_WIDTH, PROP_ALPHA, PROP_COLOR, - PROP_EDITABLE + PROP_EDITABLE, + PROP_CLICKABLE }; enum @@ -51,6 +52,7 @@ enum POINT_CHANGED, POINT_INSERTED, POINT_REMOVED, + POINT_CLICKED, LAST_SIGNAL }; @@ -64,6 +66,7 @@ struct _OsmGpsMapTrackPrivate gfloat alpha; GdkRGBA color; gboolean editable; + gboolean clickable; }; G_DEFINE_TYPE_WITH_PRIVATE(OsmGpsMapTrack, osm_gps_map_track, G_TYPE_OBJECT) @@ -101,6 +104,9 @@ 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; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -137,6 +143,9 @@ 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; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -224,6 +233,14 @@ 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)); + /** * OsmGpsMapTrack::point-added: * @self: A #OsmGpsMapTrack @@ -275,6 +292,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 From 9245c81b4ada9c9132e0cfc0036bf5ed57017232 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 10:05:41 +0200 Subject: [PATCH 02/11] add clickable property to OsmGpsMapPolygon --- src/osm-gps-map-polygon.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 From 657908fb2b549ff9519daa1220dd10a8d4b1e673 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 10:19:30 +0200 Subject: [PATCH 03/11] make tracks with the clickable property set clickable --- src/osm-gps-map-widget.c | 88 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 2d3eb8d..18e8b18 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 @@ -1161,7 +1169,9 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) 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 +1225,13 @@ 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); 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); @@ -2197,12 +2208,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 +2236,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) { @@ -2257,10 +2289,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 +2314,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)) { @@ -2361,13 +2412,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 +2451,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); From 9db095c7511cc327fd7851df0f52cbc370025c02 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 10:20:18 +0200 Subject: [PATCH 04/11] add clickable_track example to give a simple idea of the use of clickable points --- examples/Makefile.am | 17 ++++++++- examples/clickable_track.c | 76 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 examples/clickable_track.c diff --git a/examples/Makefile.am b/examples/Makefile.am index fafab85..09f7c58 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 mapviewer_SOURCES = \ mapviewer.c @@ -62,6 +62,21 @@ 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 + ## 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..17474ee --- /dev/null +++ b/examples/clickable_track.c @@ -0,0 +1,76 @@ +/* -*- 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)); +} + +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; +} From 5f2f19926bf31bc9f3d86d9b7086f5abc0f837d7 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 10:27:20 +0200 Subject: [PATCH 05/11] add editable_clickable_track example for an impression of those two features used together --- examples/Makefile.am | 17 +++++- examples/editable_clickable_track.c | 85 +++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 examples/editable_clickable_track.c diff --git a/examples/Makefile.am b/examples/Makefile.am index 09f7c58..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 clickable_track +noinst_PROGRAMS = mapviewer polygon editable_track clickable_track editable_clickable_track mapviewer_SOURCES = \ mapviewer.c @@ -77,6 +77,21 @@ clickable_track_LDADD = \ $(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/editable_clickable_track.c b/examples/editable_clickable_track.c new file mode 100644 index 0000000..5cc954b --- /dev/null +++ b/examples/editable_clickable_track.c @@ -0,0 +1,85 @@ +/* -*- 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)); +} + +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; +} From b49ac088e08b988e3f30d7c028d25acf69af32b8 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 11:02:37 +0200 Subject: [PATCH 06/11] emit the point-clicked signal also after a breaker has been clicked --- src/osm-gps-map-widget.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 18e8b18..0f88720 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -2269,6 +2269,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; } @@ -2347,6 +2354,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; } @@ -2370,6 +2384,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; } From 5fa4f8b7304ceea6cc112782f2a8ec07a8bfd5ab Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 11:24:55 +0200 Subject: [PATCH 07/11] also make polylines draw dots when the clickable property is set --- src/osm-gps-map-widget.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 0f88720..bde3676 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1310,9 +1310,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); @@ -1346,7 +1348,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) @@ -1359,7 +1361,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); From 57a5ad9a11d47bb6c7740da723accbd149ce49a2 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 17 Aug 2014 16:42:21 +0200 Subject: [PATCH 08/11] add highlight point and color property to the track type --- src/osm-gps-map-track.c | 91 ++++++++++++++++++++++++++++++++++++++++- src/osm-gps-map-track.h | 9 ++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 8d95680..3536ddc 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -43,7 +43,9 @@ enum PROP_ALPHA, PROP_COLOR, PROP_EDITABLE, - PROP_CLICKABLE + PROP_CLICKABLE, + PROP_HIGHLIGHT_POINT, + PROP_HIGHLIGHT_COLOR }; enum @@ -67,6 +69,15 @@ struct _OsmGpsMapTrackPrivate 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) @@ -76,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, @@ -107,6 +123,12 @@ osm_gps_map_track_get_property (GObject *object, 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); } @@ -146,6 +168,17 @@ osm_gps_map_track_set_property (GObject *object, 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); } @@ -241,6 +274,21 @@ 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_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 @@ -318,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 @@ -384,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) { @@ -406,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 From 34379ccf1adce539d8c7ec2a932a2d9e257e34bb Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 10:48:26 +0200 Subject: [PATCH 09/11] draw highlighted point with highlight color --- src/osm-gps-map-widget.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index bde3676..6d52ceb 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1152,18 +1152,21 @@ 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; @@ -1227,7 +1230,15 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) cairo_stroke(cr); 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); /* This draws the breaker point, do this only when the track is editable. */ From b57d513e619d55eabce95e8c24c56accf82782a8 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 17 Aug 2014 16:48:42 +0200 Subject: [PATCH 10/11] extend the clickable_track example to also highlight the clicked point --- examples/clickable_track.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/clickable_track.c b/examples/clickable_track.c index 17474ee..26f2de1 100644 --- a/examples/clickable_track.c +++ b/examples/clickable_track.c @@ -27,6 +27,7 @@ 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 From acd6c091c18bc8116e526d6a5cfdc0516bd0420a Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 11:00:42 +0200 Subject: [PATCH 11/11] extend the editable_clickable_track example to also highlight the clicked point --- examples/editable_clickable_track.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/editable_clickable_track.c b/examples/editable_clickable_track.c index 5cc954b..997b28c 100644 --- a/examples/editable_clickable_track.c +++ b/examples/editable_clickable_track.c @@ -28,6 +28,7 @@ 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