From 580150e69ea547f74d7da21b37460d9f7a7024eb Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 26 Aug 2014 13:11:09 +0200 Subject: [PATCH 01/47] 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/47] 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/47] 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/47] 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/47] 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/47] 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/47] 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/47] 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/47] 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/47] 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/47] 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 From f200189a61fd63bd39a07c6c5d36722af668a841 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Thu, 17 Mar 2022 21:19:28 +0100 Subject: [PATCH 12/47] add callback functionality for the tile loader --- src/osm-gps-map-widget.c | 100 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 2d3eb8d..0d3da28 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -196,6 +196,9 @@ struct _OsmGpsMapPrivate char *image_format; int uri_format; + //callback for map tiles + void (*map_tile_callback)(int zoom, int x, int y, void (*)(GdkPixbuf *, gpointer), gpointer); + //gps tracking state GSList *trip_history; float gps_heading; @@ -302,6 +305,7 @@ enum PROP_GPS_POINT_R1, PROP_GPS_POINT_R2, PROP_MAP_SOURCE, + PROP_MAP_TILE_CALLBACK, PROP_IMAGE_FORMAT, PROP_DRAG_LIMIT, PROP_AUTO_CENTER_THRESHOLD, @@ -731,6 +735,88 @@ osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, cairo_t *cr, int offset } } +static void +osm_gps_map_tile_callback_complete (GdkPixbuf *pixbuf, gpointer user_data) +{ + OsmTileDownload *dl = (OsmTileDownload *)user_data; + OsmGpsMap *map = OSM_GPS_MAP(dl->map); + OsmGpsMapPrivate *priv = map->priv; + + if (G_LIKELY (pixbuf)) { + /* save tile into cachedir if one has been specified */ + if (priv->cache_dir) { + if (g_mkdir_with_parents(dl->folder,0700) == 0) { + char *extension = strrchr (dl->filename, '.'); + gdk_pixbuf_save (pixbuf, dl->filename, extension+1, NULL, NULL); + + g_debug("Wrote tile to %s", dl->filename); + } else { + g_warning("Error creating tile download directory: %s", dl->folder); + } + } + + if (dl->redraw) { + /* Store the tile into the cache */ + OsmCachedTile *tile = g_slice_new (OsmCachedTile); + tile->pixbuf = pixbuf; + tile->redraw_cycle = priv->redraw_cycle; + /* if the tile is already in the cache (it could be one + * rendered from another zoom level), it will be + * overwritten */ + g_hash_table_insert (priv->tile_cache, dl->filename, tile); + /* NULL-ify dl->filename so that it won't be freed, as + * we are using it as a key in the hash table */ + dl->filename = NULL; + + osm_gps_map_map_redraw_idle (map); + } + } + g_hash_table_remove(priv->tile_queue, dl->uri); + g_object_notify(G_OBJECT(map), "tiles-queued"); + + g_free(dl->folder); + g_free(dl->filename); + g_free(dl); +} + +static void +osm_gps_map_callback_tile (OsmGpsMap *map, int zoom, int x, int y, gboolean redraw) +{ + OsmGpsMapPrivate *priv = map->priv; + OsmTileDownload *dl = g_new0(OsmTileDownload,1); + + //calculate the uri to download + dl->uri = replace_map_uri(map, priv->repo_uri, zoom, x, y); + + //check the tile has not already been queued for retrieval, + //or has been attempted, and its missing + if (g_hash_table_lookup_extended(priv->tile_queue, dl->uri, NULL, NULL) || + g_hash_table_lookup_extended(priv->missing_tiles, dl->uri, NULL, NULL) ) + { + g_debug("Tile already in progress (or missing)"); + g_free(dl->uri); + g_free(dl); + } else { + dl->folder = g_strdup_printf("%s%c%d%c%d%c", + priv->cache_dir, G_DIR_SEPARATOR, + zoom, G_DIR_SEPARATOR, + x, G_DIR_SEPARATOR); + dl->filename = g_strdup_printf("%s%d.%s", + dl->folder, + y, + priv->image_format); + dl->map = map; + dl->redraw = redraw; + + g_debug("retrieve tile: %d,%d z:%d\n\t%s --> %s", x, y, zoom, dl->uri, dl->filename); + + g_hash_table_insert (priv->tile_queue, dl->uri, NULL); + g_object_notify (G_OBJECT (map), "tiles-queued"); + + (priv->map_tile_callback)(zoom, x, y, osm_gps_map_tile_callback_complete, dl); + } +} + #define MSG_RESPONSE_BODY(a) ((a)->response_body->data) #define MSG_RESPONSE_LEN(a) ((a)->response_body->length) #define MSG_RESPONSE_LEN_FORMAT "%"G_GOFFSET_FORMAT @@ -1067,6 +1153,8 @@ osm_gps_map_load_tile (OsmGpsMap *map, cairo_t *cr, int zoom, int x, int y, int } else { if (priv->map_auto_download_enabled) { osm_gps_map_download_tile(map, zoom, x, y, TRUE); + } else if (priv->map_tile_callback != NULL) { + osm_gps_map_callback_tile(map, zoom, x, y, TRUE); } /* try to render the tile by scaling cached tiles from other zoom @@ -1696,6 +1784,8 @@ osm_gps_map_init (OsmGpsMap *object) priv->map_source = 0; + priv->map_tile_callback = NULL; + priv->keybindings_enabled = FALSE; for (i = 0; i < OSM_GPS_MAP_KEY_MAX; i++) priv->keybindings[i] = 0; @@ -2029,6 +2119,9 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G osm_gps_map_setup(map); } } break; + case PROP_MAP_TILE_CALLBACK: + priv->map_tile_callback = g_value_get_pointer (value); + break; case PROP_IMAGE_FORMAT: g_free(priv->image_format); priv->image_format = g_value_dup_string (value); @@ -2897,6 +2990,13 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) 0, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_MAP_TILE_CALLBACK, + g_param_spec_pointer ("map-tile-callback", + "map tile callback", + "The map tile callback function", + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_IMAGE_FORMAT, g_param_spec_string ("image-format", From a85bb4c6a97de463070a694eea17ed739212668c Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 17 Aug 2014 17:44:21 +0200 Subject: [PATCH 13/47] Use the alpha field from GdkRGBA instead of a separate one; remove the alpha field and mark the alpha property as deprecated. Conflicts: src/osm-gps-map-widget.c --- src/osm-gps-map-track.c | 19 ++++++++++++------- src/osm-gps-map-widget.c | 26 ++++++++++++-------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 3536ddc..92d691c 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -40,7 +40,7 @@ enum PROP_VISIBLE, PROP_TRACK, PROP_LINE_WIDTH, - PROP_ALPHA, + PROP_ALPHA, /* The alpha property can be considered obsolete as GdkRGBA also provides an alpha field */ PROP_COLOR, PROP_EDITABLE, PROP_CLICKABLE, @@ -65,7 +65,6 @@ struct _OsmGpsMapTrackPrivate GSList *track; gboolean visible; gfloat linewidth; - gfloat alpha; GdkRGBA color; gboolean editable; gboolean clickable; @@ -112,7 +111,7 @@ osm_gps_map_track_get_property (GObject *object, g_value_set_float(value, priv->linewidth); break; case PROP_ALPHA: - g_value_set_float(value, priv->alpha); + g_value_set_float(value, priv->color.alpha); break; case PROP_COLOR: g_value_set_boxed(value, &priv->color); @@ -154,13 +153,14 @@ osm_gps_map_track_set_property (GObject *object, priv->linewidth = g_value_get_float (value); break; case PROP_ALPHA: - priv->alpha = g_value_get_float (value); + priv->color.alpha = g_value_get_float (value); break; case PROP_COLOR: { GdkRGBA *c = g_value_get_boxed (value); priv->color.red = c->red; priv->color.green = c->green; priv->color.blue = c->blue; + priv->color.alpha = c->alpha; } break; case PROP_EDITABLE: priv->editable = g_value_get_boolean(value); @@ -176,8 +176,7 @@ osm_gps_map_track_set_property (GObject *object, 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); + priv->highlight_color.alpha = c->alpha; } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -248,7 +247,7 @@ osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass) 0.0, /* minimum property value */ 1.0, /* maximum property value */ DEFAULT_A, - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT | G_PARAM_DEPRECATED)); g_object_class_install_property (object_class, PROP_COLOR, @@ -366,10 +365,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->color.alpha = DEFAULT_A; 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_color.alpha = DEFAULT_HIGHLIGHT_A; self->priv->highlight_point = NULL; } @@ -427,6 +428,7 @@ osm_gps_map_track_set_color (OsmGpsMapTrack *track, GdkRGBA *color) track->priv->color.red = color->red; track->priv->color.green = color->green; track->priv->color.blue = color->blue; + track->priv->color.alpha = color->alpha; } void @@ -436,6 +438,7 @@ osm_gps_map_track_get_color (OsmGpsMapTrack *track, GdkRGBA *color) color->red = track->priv->color.red; color->green = track->priv->color.green; color->blue = track->priv->color.blue; + color->alpha = track->priv->color.alpha; } void @@ -445,6 +448,7 @@ osm_gps_map_track_set_highlight_color (OsmGpsMapTrack *track, GdkRGBA *color) track->priv->highlight_color.red = color->red; track->priv->highlight_color.green = color->green; track->priv->highlight_color.blue = color->blue; + track->priv->highlight_color.alpha = color->alpha; } void @@ -454,6 +458,7 @@ osm_gps_map_track_get_highlight_color (OsmGpsMapTrack *track, GdkRGBA *color) color->red = track->priv->highlight_color.red; color->green = track->priv->highlight_color.green; color->blue = track->priv->highlight_color.blue; + color->alpha = track->priv->highlight_color.alpha; } double diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 6d52ceb..e5facf2 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1155,14 +1155,13 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) OsmGpsMapPoint *highlight_point; int x,y; int min_x = 0,min_y = 0,max_x = 0,max_y = 0; - gfloat lw, alpha; + gfloat lw; int map_x0, map_y0; 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); @@ -1177,7 +1176,7 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) 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); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); @@ -1232,10 +1231,10 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) { if(tp == highlight_point) { - cairo_set_source_rgba (cr, highlight_color.red, highlight_color.green, highlight_color.blue, alpha); + cairo_set_source_rgba (cr, highlight_color.red, highlight_color.green, highlight_color.blue, highlight_color.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); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); } else cairo_arc (cr, x, y, DOT_RADIUS, 0.0, 2 * M_PI); @@ -1244,10 +1243,10 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) /* 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_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha * 0.75); cairo_arc(cr, (last_x + x)/2.0, (last_y+y)/2.0, DOT_RADIUS, 0.0, 2*M_PI); cairo_stroke(cr); - cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); } } @@ -1301,7 +1300,7 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) GSList *pt,*points; int x,y; int min_x = 0,min_y = 0,max_x = 0,max_y = 0; - gfloat lw, alpha; + gfloat lw; int map_x0, map_y0; GdkRGBA color; gfloat shade_alpha; @@ -1313,7 +1312,6 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) g_object_get (track, "track", &points, "line-width", &lw, - "alpha", &alpha, NULL); osm_gps_map_track_get_color(track, &color); @@ -1331,7 +1329,7 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) g_object_get(poly, "breakable", &breakable, NULL); cairo_set_line_width (cr, lw); - cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); @@ -1375,10 +1373,10 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) /* 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_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha * 0.75); cairo_arc(cr, (last_x + x)/2.0, (last_y+y)/2.0, DOT_RADIUS, 0.0, 2*M_PI); cairo_stroke(cr); - cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); } last_x = x; last_y = y; } @@ -1386,11 +1384,11 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) x = first_x; y = first_y; if(breakable) { - cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha*0.75); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha*0.75); cairo_arc(cr, (last_x + x)/2.0, (last_y+y)/2.0, DOT_RADIUS, 0.0, 2*M_PI); cairo_stroke(cr); } - cairo_set_source_rgba (cr, color.red, color.green, color.blue, alpha); + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); } if(poly_shaded) From 4bd561973375302c36a8ced206d2e36ae9809f5d Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 27 Aug 2014 12:05:30 +0200 Subject: [PATCH 14/47] change the type of the color and highlight-color to GDK_TYPE_RGBA so it matches the internal used type and is able to pass the alpha channel as wel --- src/osm-gps-map-track.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 92d691c..e0a0312 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -285,7 +285,7 @@ osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass) g_param_spec_boxed ("highlight-color", "highlight color", "color used to mark a highlighted point", - GDK_TYPE_COLOR, + GDK_TYPE_RGBA, G_PARAM_READABLE | G_PARAM_WRITABLE)); /** From caaada607344d7161799730598a8526ce597f2e8 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 3 Apr 2022 11:13:32 +0200 Subject: [PATCH 15/47] update requirements --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 94439d6..759bfb3 100644 --- a/configure.ac +++ b/configure.ac @@ -22,9 +22,9 @@ AM_PROG_LIBTOOL AM_SILENT_RULES([yes]) # Library dependencies -PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16]) -PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.0]) -PKG_CHECK_MODULES(CAIRO, [cairo >= 1.8]) +PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.66]) +PKG_CHECK_MODULES(GTK, [gtk4 >= 4.6]) +PKG_CHECK_MODULES(CAIRO, [cairo >= 1.14]) PKG_CHECK_MODULES(SOUP24, [libsoup-2.4 >= 2.42]) # The mapviewer demo also calls g_thread_init, so it needs to link against From b219fee4bae1407a3fc4ef17203bb86fd2a9692a Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 3 Apr 2022 11:30:42 +0200 Subject: [PATCH 16/47] it seems g_cclosure_marshal_VOID__INT is beter for the point-changed signal; this removes critical error message: g_cclosure_marshal_VOID__VOID: assertion 'n_param_values == 1' failed --- src/osm-gps-map-track.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index e0a0312..74b2234 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -313,7 +313,7 @@ osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); From 98589e2eb4c1f929941e761786ff8ee0c92ba3ec Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 3 Apr 2022 13:16:51 +0200 Subject: [PATCH 17/47] fix error; g_value_get_pointer: assertion 'G_VALUE_HOLDS_POINTER (value)' failed; by changing to generic poiner type --- src/osm-gps-map-track.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 74b2234..3a2530c 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -354,7 +354,7 @@ osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass) g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, - OSM_TYPE_GPS_MAP_POINT | G_SIGNAL_TYPE_STATIC_SCOPE); + G_TYPE_POINTER | G_SIGNAL_TYPE_STATIC_SCOPE); } static void From 17f6644e0356c10c9d521f863ca419cc10be2e8b Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 14 Jun 2022 19:07:42 +0200 Subject: [PATCH 18/47] compile with warnings for deprecated symbols --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index 32bbc59..6fa138c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ libosmgpsmap_1_0_la_CFLAGS = \ $(WARN_CFLAGS) \ $(DISABLE_DEPRECATED) \ $(OSMGPSMAP_CFLAGS) \ + -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED \ -DG_LOG_DOMAIN=\"OsmGpsMap\" if OS_WIN32 From b02f24a7c011060ccccebbb75127c5a8f77622c2 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Wed, 15 Jun 2022 22:18:14 +0200 Subject: [PATCH 19/47] enable warnings for deprecated symbols for example programs --- examples/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/Makefile.am b/examples/Makefile.am index 1148ef5..c8dc212 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,6 +1,7 @@ ## Process this file with automake to produce Makefile.in OSMGPSMAP_CFLAGS = \ + -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED \ $(GLIB_CFLAGS) \ $(GTK_CFLAGS) \ $(CAIRO_CFLAGS) \ From 48986bfe246307eb0871facefee4dfa8cfe39a32 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 20:58:53 +0200 Subject: [PATCH 20/47] replace gtk_widget_queue_draw_area with gtk_widget_queue_draw --- src/osm-gps-map-widget.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 6a10fd0..9e27ba5 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -644,11 +644,7 @@ osm_gps_map_print_images (OsmGpsMap *map, cairo_t *cr) min_y = MIN(loc.y - loc.height, min_y); } - gtk_widget_queue_draw_area ( - GTK_WIDGET(map), - min_x + EXTRA_BORDER, min_y + EXTRA_BORDER, - max_x + EXTRA_BORDER, max_y + EXTRA_BORDER); - + gtk_widget_queue_draw (GTK_WIDGET(map)); } static void @@ -711,11 +707,7 @@ osm_gps_map_draw_gps_point (OsmGpsMap *map, cairo_t *cr) cairo_stroke(cr); } - gtk_widget_queue_draw_area (GTK_WIDGET(map), - x-mr, - y-mr, - mr*2, - mr*2); + gtk_widget_queue_draw (GTK_WIDGET(map)); } static void @@ -1350,12 +1342,7 @@ osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track, cairo_t *cr) last_lon = tp->rlon; } - gtk_widget_queue_draw_area ( - GTK_WIDGET(map), - min_x - lw, - min_y - lw, - max_x + (lw * 2), - max_y + (lw * 2)); + gtk_widget_queue_draw (GTK_WIDGET(map)); cairo_stroke(cr); } @@ -1505,13 +1492,7 @@ osm_gps_map_print_polygon (OsmGpsMap *map, OsmGpsMapPolygon *poly, cairo_t *cr) cairo_fill(cr); } - gtk_widget_queue_draw_area ( - GTK_WIDGET(map), - min_x - lw, - min_y - lw, - max_x + (lw * 2), - max_y + (lw * 2)); - + gtk_widget_queue_draw (GTK_WIDGET(map)); } static void From 0ee6145c2ecf55bb2ea64cbac75f377300575a93 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 21:13:02 +0200 Subject: [PATCH 21/47] switch to GtkEventControllerMotion for mouse movement events --- src/osm-gps-map-widget.c | 49 ++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 9e27ba5..da51a39 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -322,6 +322,11 @@ enum G_DEFINE_TYPE_WITH_PRIVATE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); +/* + * event handle function forward defintions + */ +static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); + /* * Drawing function forward defintions */ @@ -1818,11 +1823,15 @@ osm_gps_map_init (OsmGpsMap *object) gtk_widget_add_events (GTK_WIDGET (object), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK | + GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); #ifdef HAVE_GDK_EVENT_GET_SCROLL_DELTAS gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) #endif + + GtkEventController* controller_motion = gtk_event_controller_motion_new (); + gtk_widget_add_controller (GTK_WIDGET (object), controller_motion); + gtk_widget_set_can_focus (GTK_WIDGET (object), TRUE); g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL); @@ -1830,6 +1839,8 @@ osm_gps_map_init (OsmGpsMap *object) /* setup signal handlers */ g_signal_connect(object, "key_press_event", G_CALLBACK(on_window_key_press), priv); + + g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); } static char* @@ -2548,12 +2559,11 @@ osm_gps_map_idle_expose (GtkWidget *widget) } static gboolean -osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion *event) +osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data) { - GdkModifierType state; - OsmGpsMap *map = OSM_GPS_MAP(widget); + GdkModifierType state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER(self)); + OsmGpsMap *map = OSM_GPS_MAP(gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); OsmGpsMapPrivate *priv = map->priv; - gint x, y; if(!priv->is_button_down) return FALSE; @@ -2566,7 +2576,7 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion *event) * 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)) + if(priv->is_clicked_point && path_editable && (priv->clicked_x != x || priv->clicked_y != y)) { priv->is_dragging_point = TRUE; priv->is_clicked_point = FALSE; @@ -2575,31 +2585,11 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion *event) if(priv->is_dragging_point) { - osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, priv->drag_point); + osm_gps_map_convert_screen_to_geographic(map, x, y, priv->drag_point); osm_gps_map_map_redraw_idle(map); return FALSE; } - if (event->is_hint) - { - // gdk_window_get_pointer (event->window, &x, &y, &state); - -#if GTK_CHECK_VERSION(3, 20, 0) - // TODO: check if we can use gtk_widget_get_display(widget) instead of default - GdkDevice* pointer = gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default())); -#else - GdkDevice* pointer = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager( gdk_display_get_default())); -#endif - - gdk_window_get_device_position( event->window, pointer, &x, &y, &state); - } - else - { - x = event->x; - y = event->y; - state = event->state; - } - // are we being dragged if (!(state & GDK_BUTTON1_MASK)) return FALSE; @@ -2619,7 +2609,7 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion *event) priv->is_dragging = TRUE; if (priv->map_auto_center_enabled) - g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL); + g_object_set(G_OBJECT(map), "auto-center", FALSE, NULL); priv->drag_mouse_dx = x - priv->drag_start_mouse_x; priv->drag_mouse_dy = y - priv->drag_start_mouse_y; @@ -2627,7 +2617,7 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion *event) /* instead of redrawing directly just add an idle function */ if (!priv->drag_expose_source) priv->drag_expose_source = - g_idle_add ((GSourceFunc)osm_gps_map_idle_expose, widget); + g_idle_add ((GSourceFunc)osm_gps_map_idle_expose, GTK_WIDGET(map)); return FALSE; } @@ -2712,7 +2702,6 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) widget_class->configure_event = osm_gps_map_configure; widget_class->button_press_event = osm_gps_map_button_press; widget_class->button_release_event = osm_gps_map_button_release; - widget_class->motion_notify_event = osm_gps_map_motion_notify; widget_class->scroll_event = osm_gps_map_scroll_event; //widget_class->get_preferred_width = osm_gps_map_get_preferred_width; //widget_class->get_preferred_height = osm_gps_map_get_preferred_height; From 98c3ac15dcbd61d5680041767644eaeeb3bd0a20 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 21:21:21 +0200 Subject: [PATCH 22/47] use gtk3 code to register eventController --- src/osm-gps-map-widget.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index da51a39..288100e 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1829,8 +1829,7 @@ osm_gps_map_init (OsmGpsMap *object) gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) #endif - GtkEventController* controller_motion = gtk_event_controller_motion_new (); - gtk_widget_add_controller (GTK_WIDGET (object), controller_motion); + GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); gtk_widget_set_can_focus (GTK_WIDGET (object), TRUE); From 3198151dee23ab263bb5a3d60bbfcb5b4d4be733 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 21:22:38 +0200 Subject: [PATCH 23/47] temporarly disable draw motion (click-move) to drag the map around; TODO: see if this can be enabled in GTK3 --- src/osm-gps-map-widget.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 288100e..66a81c6 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -2560,7 +2560,6 @@ osm_gps_map_idle_expose (GtkWidget *widget) static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data) { - GdkModifierType state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER(self)); OsmGpsMap *map = OSM_GPS_MAP(gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); OsmGpsMapPrivate *priv = map->priv; @@ -2590,7 +2589,7 @@ osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, } // are we being dragged - if (!(state & GDK_BUTTON1_MASK)) + if (!(0 & GDK_BUTTON1_MASK)) return FALSE; if (priv->drag_counter < 0) From d6402ba45ffd141cd726923c3f2a5bb8d3a0ef52 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 21:35:43 +0200 Subject: [PATCH 24/47] switch to GtkEventControllerScroll for scroll (zoom) events --- src/osm-gps-map-widget.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 66a81c6..fca926b 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -221,6 +221,9 @@ struct _OsmGpsMapPrivate //A list of OsmGpsMapLayer* layers, such as the OSD GSList *layers; + //Track the mouse movement + gdouble mouse_x; + gdouble mouse_y; //For tracking click and drag int drag_counter; int drag_mouse_dx; @@ -325,6 +328,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); /* * event handle function forward defintions */ +static gboolean osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); /* @@ -1782,6 +1786,9 @@ osm_gps_map_init (OsmGpsMap *object) priv->images = NULL; priv->layers = NULL; + priv->mouse_x = 0; + priv->mouse_y = 0; + priv->drag_counter = 0; priv->drag_mouse_dx = 0; priv->drag_mouse_dy = 0; @@ -1823,7 +1830,6 @@ osm_gps_map_init (OsmGpsMap *object) gtk_widget_add_events (GTK_WIDGET (object), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); #ifdef HAVE_GDK_EVENT_GET_SCROLL_DELTAS gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) @@ -1831,6 +1837,8 @@ osm_gps_map_init (OsmGpsMap *object) GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); + GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_WIDGET (object), GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); + gtk_widget_set_can_focus (GTK_WIDGET (object), TRUE); g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL); @@ -1838,7 +1846,7 @@ osm_gps_map_init (OsmGpsMap *object) /* setup signal handlers */ g_signal_connect(object, "key_press_event", G_CALLBACK(on_window_key_press), priv); - + g_signal_connect (controller_scroll, "scroll", G_CALLBACK (osm_gps_map_scroll_event), priv); g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); } @@ -2251,29 +2259,27 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS } static gboolean -osm_gps_map_scroll_event (GtkWidget *widget, GdkEventScroll *event) +osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy, gpointer user_data) { OsmGpsMap *map; OsmGpsMapPoint *pt; float lat, lon, c_lat, c_lon; - map = OSM_GPS_MAP(widget); + map = OSM_GPS_MAP(gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); pt = osm_gps_map_point_new_degrees(0.0,0.0); /* arguably we could use get_event_location here, but I'm not convinced it is forward compatible to cast between GdkEventScroll and GtkEventButton */ - osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, pt); + osm_gps_map_convert_screen_to_geographic(map, map->priv->mouse_x, map->priv->mouse_y, pt); osm_gps_map_point_get_degrees (pt, &lat, &lon); c_lat = rad2deg(map->priv->center_rlat); c_lon = rad2deg(map->priv->center_rlon); - - - if ((event->direction == GDK_SCROLL_UP) && (map->priv->map_zoom < map->priv->max_zoom)) { + if ((dy > 0) && (map->priv->map_zoom < map->priv->max_zoom)) { lat = c_lat + ((lat - c_lat)/2.0); lon = c_lon + ((lon - c_lon)/2.0); osm_gps_map_set_center_and_zoom(map, lat, lon, map->priv->map_zoom+1); - } else if ((event->direction == GDK_SCROLL_DOWN) && (map->priv->map_zoom > map->priv->min_zoom)) { + } else if ((dy < 0) && (map->priv->map_zoom > map->priv->min_zoom)) { lat = c_lat + ((c_lat - lat)*1.0); lon = c_lon + ((c_lon - lon)*1.0); osm_gps_map_set_center_and_zoom(map, lat, lon, map->priv->map_zoom-1); @@ -2562,6 +2568,8 @@ osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, { OsmGpsMap *map = OSM_GPS_MAP(gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); OsmGpsMapPrivate *priv = map->priv; + priv->mouse_x = x; + priv->mouse_y = y; if(!priv->is_button_down) return FALSE; From 0003bafd56f822da506662031c75cdd844e4d52d Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 22:09:47 +0200 Subject: [PATCH 25/47] also remove old event registration --- src/osm-gps-map-widget.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index fca926b..0e732a6 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -2708,7 +2708,6 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) widget_class->configure_event = osm_gps_map_configure; widget_class->button_press_event = osm_gps_map_button_press; widget_class->button_release_event = osm_gps_map_button_release; - widget_class->scroll_event = osm_gps_map_scroll_event; //widget_class->get_preferred_width = osm_gps_map_get_preferred_width; //widget_class->get_preferred_height = osm_gps_map_get_preferred_height; From 5065769d49c251e70e4fefa8e10a60609e075cb5 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 22:10:33 +0200 Subject: [PATCH 26/47] fix whitespaces --- src/osm-gps-map-widget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 0e732a6..3bd70e7 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1837,7 +1837,7 @@ osm_gps_map_init (OsmGpsMap *object) GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); - GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_WIDGET (object), GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); + GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_WIDGET (object), GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); gtk_widget_set_can_focus (GTK_WIDGET (object), TRUE); From cea8c4875b2726b65f22c965cad4aac6888995eb Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 22:12:49 +0200 Subject: [PATCH 27/47] Fix: revert zoom direction --- src/osm-gps-map-widget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 3bd70e7..b76c7b4 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -2275,11 +2275,11 @@ osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy c_lat = rad2deg(map->priv->center_rlat); c_lon = rad2deg(map->priv->center_rlon); - if ((dy > 0) && (map->priv->map_zoom < map->priv->max_zoom)) { + if ((dy < 0) && (map->priv->map_zoom < map->priv->max_zoom)) { lat = c_lat + ((lat - c_lat)/2.0); lon = c_lon + ((lon - c_lon)/2.0); osm_gps_map_set_center_and_zoom(map, lat, lon, map->priv->map_zoom+1); - } else if ((dy < 0) && (map->priv->map_zoom > map->priv->min_zoom)) { + } else if ((dy > 0) && (map->priv->map_zoom > map->priv->min_zoom)) { lat = c_lat + ((c_lat - lat)*1.0); lon = c_lon + ((c_lon - lon)*1.0); osm_gps_map_set_center_and_zoom(map, lat, lon, map->priv->map_zoom-1); From 7e3a785911b9a6c379f224285130f3a8a7c37fa5 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Mon, 20 Jun 2022 19:42:54 +0200 Subject: [PATCH 28/47] apparently gtk_widget_add_events is still needed with GtkEventController --- src/osm-gps-map-widget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index b76c7b4..2eeed3d 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1830,6 +1830,7 @@ osm_gps_map_init (OsmGpsMap *object) gtk_widget_add_events (GTK_WIDGET (object), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); #ifdef HAVE_GDK_EVENT_GET_SCROLL_DELTAS gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) From e413e991003866cddf2515eb4ccce8bcfe854ae9 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 22:03:18 +0200 Subject: [PATCH 29/47] switch to GtkEventControllerKey for key press events --- src/osm-gps-map-widget.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 2eeed3d..2065936 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1674,13 +1674,14 @@ maybe_autocenter_map (OsmGpsMap *map) } static gboolean -on_window_key_press(GtkWidget *widget, GdkEventKey *event, OsmGpsMapPrivate *priv) +on_window_key_press (GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, OsmGpsMap *map) { int i; int step; gboolean handled; GtkAllocation allocation; - OsmGpsMap *map = OSM_GPS_MAP(widget); + GtkWidget *widget = GTK_WIDGET(map); + OsmGpsMapPrivate *priv = map->priv; /* if no keybindings are set, let the app handle them... */ if (!priv->keybindings_enabled) @@ -1693,7 +1694,7 @@ on_window_key_press(GtkWidget *widget, GdkEventKey *event, OsmGpsMapPrivate *pri /* the map handles some keys on its own */ for (i = 0; i < OSM_GPS_MAP_KEY_MAX; i++) { /* not the key we have a binding for */ - if (map->priv->keybindings[i] != event->keyval) + if (map->priv->keybindings[i] != keyval) continue; switch(i) { @@ -1836,6 +1837,8 @@ osm_gps_map_init (OsmGpsMap *object) gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) #endif + GtkEventController* controller_key = gtk_event_controller_key_new (GTK_WIDGET (object)); + GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_WIDGET (object), GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); @@ -1845,8 +1848,7 @@ osm_gps_map_init (OsmGpsMap *object) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL); /* setup signal handlers */ - g_signal_connect(object, "key_press_event", - G_CALLBACK(on_window_key_press), priv); + g_signal_connect (controller_key, "key-pressed", G_CALLBACK (on_window_key_press), priv); g_signal_connect (controller_scroll, "scroll", G_CALLBACK (osm_gps_map_scroll_event), priv); g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); } From 6602e3f2ed6deebc72a921dde7d32a98cb5dc6a5 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Mon, 20 Jun 2022 20:01:19 +0200 Subject: [PATCH 30/47] fix whitespaces --- src/osm-gps-map-widget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 2065936..6aa652a 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1837,7 +1837,7 @@ osm_gps_map_init (OsmGpsMap *object) gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) #endif - GtkEventController* controller_key = gtk_event_controller_key_new (GTK_WIDGET (object)); + GtkEventController* controller_key = gtk_event_controller_key_new (GTK_WIDGET (object)); GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); From 6eff0c930193c30cf4c0235d1ff9ab21820810f4 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Mon, 20 Jun 2022 20:09:44 +0200 Subject: [PATCH 31/47] fix: wrong parameter usage --- src/osm-gps-map-widget.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 6aa652a..286fe3c 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -328,6 +328,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); /* * event handle function forward defintions */ +static gboolean on_window_key_press (GtkEventControllerKey *self, guint keyval, guint keycode, GdkModifierType state, gpointer user_data); static gboolean osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); @@ -1674,13 +1675,13 @@ maybe_autocenter_map (OsmGpsMap *map) } static gboolean -on_window_key_press (GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, OsmGpsMap *map) +on_window_key_press (GtkEventControllerKey *self, guint keyval, guint keycode, GdkModifierType state, gpointer user_data) { int i; int step; gboolean handled; GtkAllocation allocation; - GtkWidget *widget = GTK_WIDGET(map); + OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); OsmGpsMapPrivate *priv = map->priv; /* if no keybindings are set, let the app handle them... */ @@ -1699,7 +1700,7 @@ on_window_key_press (GtkEventControllerKey *controller, guint keyval, guint keyc switch(i) { case OSM_GPS_MAP_KEY_FULLSCREEN: { - GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(widget)); + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (map)); if(!priv->is_fullscreen) gtk_window_fullscreen(GTK_WINDOW(toplevel)); else From 9c65cd89095625a0e6bb390fb03cc8a6eb969ed9 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 21:47:50 +0200 Subject: [PATCH 32/47] switch to GtkGestureMultiPress for (mouse) button click events --- src/osm-gps-map-layer.c | 4 ++-- src/osm-gps-map-layer.h | 10 ++++++--- src/osm-gps-map-osd.c | 12 ++++++----- src/osm-gps-map-widget.c | 46 +++++++++++++++++++++++----------------- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/osm-gps-map-layer.c b/src/osm-gps-map-layer.c index 3da68ee..cca414f 100644 --- a/src/osm-gps-map-layer.c +++ b/src/osm-gps-map-layer.c @@ -66,8 +66,8 @@ osm_gps_map_layer_busy (OsmGpsMapLayer *self) } gboolean -osm_gps_map_layer_button_press (OsmGpsMapLayer *self, OsmGpsMap *map, GdkEventButton *event) +osm_gps_map_layer_button_press (OsmGpsMapLayer *self, OsmGpsMap *map, GtkGestureSingle *event, gint n_press, gdouble x, gdouble y, gpointer user_data) { - return OSM_GPS_MAP_LAYER_GET_INTERFACE (self)->button_press (self, map, event); + return OSM_GPS_MAP_LAYER_GET_INTERFACE (self)->button_press (self, map, event, n_press, x, y, user_data); } diff --git a/src/osm-gps-map-layer.h b/src/osm-gps-map-layer.h index a2d248c..029305b 100644 --- a/src/osm-gps-map-layer.h +++ b/src/osm-gps-map-layer.h @@ -48,7 +48,7 @@ struct _OsmGpsMapLayerIface { void (*render) (OsmGpsMapLayer *self, OsmGpsMap *map); void (*draw) (OsmGpsMapLayer *self, OsmGpsMap *map, cairo_t *cr); gboolean (*busy) (OsmGpsMapLayer *self); - gboolean (*button_press) (OsmGpsMapLayer *self, OsmGpsMap *map, GdkEventButton *event); + gboolean (*button_press) (OsmGpsMapLayer *self, OsmGpsMap *map, GtkGestureSingle *event, gint n_press, gdouble x, gdouble y, gpointer user_data); }; /** @@ -99,14 +99,18 @@ gboolean osm_gps_map_layer_busy (OsmGpsMapLayer *self); * osm_gps_map_layer_button_press: * @self: (in): a #OsmGpsMapLayer object * @map: (in): a #OsmGpsMap widget - * @event: (in): a #GdkEventButton event + * @event: (in): a GtkGestureClick event + * @n_press: (in): How many touch/button presses happened with this one. + * @x: (in): The X coordinate, in widget allocation coordinates. + * @y: (in): The Y coordinate, in widget allocation coordinates. + * @user_data: (in): pointer to user data * * Handle button event * * Returns: whether even had been handled * Since: 0.6.0 **/ -gboolean osm_gps_map_layer_button_press (OsmGpsMapLayer *self, OsmGpsMap *map, GdkEventButton *event); +gboolean osm_gps_map_layer_button_press (OsmGpsMapLayer *self, OsmGpsMap *map, GtkGestureSingle *event, gint n_press, gdouble x, gdouble y, gpointer user_data); G_END_DECLS diff --git a/src/osm-gps-map-osd.c b/src/osm-gps-map-osd.c index 635defd..ca3008e 100644 --- a/src/osm-gps-map-osd.c +++ b/src/osm-gps-map-osd.c @@ -108,7 +108,7 @@ G_DEFINE_TYPE_WITH_CODE (OsmGpsMapOsd, osm_gps_map_osd, G_TYPE_OBJECT, static void osm_gps_map_osd_render (OsmGpsMapLayer *osd, OsmGpsMap *map); static void osm_gps_map_osd_draw (OsmGpsMapLayer *osd, OsmGpsMap *map, cairo_t *cr); static gboolean osm_gps_map_osd_busy (OsmGpsMapLayer *osd); -static gboolean osm_gps_map_osd_button_press (OsmGpsMapLayer *osd, OsmGpsMap *map, GdkEventButton *event); +static gboolean osm_gps_map_osd_button_press (OsmGpsMapLayer *osd, OsmGpsMap *map, GtkGestureSingle *event, gint n_press, gdouble x_axis, gdouble y_axis, gpointer user_data); static void scale_render (OsmGpsMapOsd *self, OsmGpsMap *map); static void scale_draw (OsmGpsMapOsd *self, GtkAllocation *allocation, cairo_t *cr); @@ -538,23 +538,25 @@ osm_gps_map_osd_busy (OsmGpsMapLayer *osd) static gboolean osm_gps_map_osd_button_press (OsmGpsMapLayer *osd, OsmGpsMap *map, - GdkEventButton *event) + GtkGestureSingle *event, gint n_press, gdouble x_axis, gdouble y_axis, gpointer user_data) { gboolean handled = FALSE; OsdControlPress_t but = OSD_NONE; OsmGpsMapOsd *self; OsmGpsMapOsdPrivate *priv; GtkAllocation allocation; + GdkModifierType state; g_return_val_if_fail(OSM_GPS_MAP_IS_OSD(osd), FALSE); self = OSM_GPS_MAP_OSD(osd); priv = self->priv; + state = gtk_gesture_single_get_current_button (event); gtk_widget_get_allocation(GTK_WIDGET(map), &allocation); - if ((event->button == 1) && (event->type == GDK_BUTTON_PRESS)) { - gint mx = event->x - priv->osd_x; - gint my = event->y - priv->osd_y; + if (state == 1) { + gint mx = x_axis - priv->osd_x; + gint my = y_axis - priv->osd_y; if(priv->osd_x < 0) mx -= (allocation.width - priv->osd_w); diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 286fe3c..5ca1402 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -330,6 +330,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); */ static gboolean on_window_key_press (GtkEventControllerKey *self, guint keyval, guint keycode, GdkModifierType state, gpointer user_data); static gboolean osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy, gpointer user_data); +static gboolean osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); +static gboolean osm_gps_map_button_release (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); /* @@ -1840,6 +1842,9 @@ osm_gps_map_init (OsmGpsMap *object) GtkEventController* controller_key = gtk_event_controller_key_new (GTK_WIDGET (object)); + GtkGesture* controller_button = gtk_gesture_multi_press_new (GTK_WIDGET (object)); + gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller_button), 0); + GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_WIDGET (object), GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); @@ -1852,6 +1857,8 @@ osm_gps_map_init (OsmGpsMap *object) g_signal_connect (controller_key, "key-pressed", G_CALLBACK (on_window_key_press), priv); g_signal_connect (controller_scroll, "scroll", G_CALLBACK (osm_gps_map_scroll_event), priv); g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); + g_signal_connect (controller_button, "pressed", G_CALLBACK (osm_gps_map_button_press), priv); + g_signal_connect (controller_button, "released", G_CALLBACK (osm_gps_map_button_release), priv); } static char* @@ -2295,9 +2302,9 @@ osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy } static gboolean -osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) +osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data) { - OsmGpsMap *map = OSM_GPS_MAP(widget); + OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self))); OsmGpsMapPrivate *priv = map->priv; if (priv->layers) @@ -2306,16 +2313,17 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) for(list = priv->layers; list != NULL; list = list->next) { OsmGpsMapLayer *layer = list->data; - if (osm_gps_map_layer_button_press(layer, map, event)) + //printf ("call osm_gps_map_layer_button_press\n"); + if (osm_gps_map_layer_button_press (layer, map, GTK_GESTURE_SINGLE (self), n_press, x, y, user_data)) return FALSE; } } - if(event->button == 1) + if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (self)) == 1) { GSList* tracks = priv->tracks; - priv->clicked_x = event->x; - priv->clicked_y = event->y; + priv->clicked_x = (int)x; + priv->clicked_y = (int)y; while(tracks) { OsmGpsMapTrack* track = tracks->data; @@ -2336,7 +2344,7 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) OsmGpsMapPoint* point = (OsmGpsMapPoint*)points->data; osm_gps_map_convert_geographic_to_screen(map, point, &cx, &cy); - float dist_sqrd = (event->x - cx) * (event->x-cx) + (event->y-cy) * (event->y-cy); + float dist_sqrd = (x - cx) * (x - cx) + (y - cy) * (y - cy); if(dist_sqrd <= ((DOT_RADIUS + 1) * (DOT_RADIUS + 1))) { priv->is_button_down = TRUE; @@ -2369,7 +2377,7 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) { int ptx = (last_x+cx)/2.0; int pty = (last_y+cy)/2.0; - dist_sqrd = (event->x - ptx) * (event->x-ptx) + (event->y-pty) * (event->y-pty); + dist_sqrd = (x - ptx) * (x - ptx) + (y - pty) * (y - pty); if(dist_sqrd <= ((DOT_RADIUS + 1) * (DOT_RADIUS + 1))) { OsmGpsMapPoint* newpoint = malloc(sizeof(OsmGpsMapPoint)); @@ -2421,7 +2429,7 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) OsmGpsMapPoint* point = (OsmGpsMapPoint*)points->data; osm_gps_map_convert_geographic_to_screen(map, point, &cx, &cy); - float dist_sqrd = (event->x - cx) * (event->x-cx) + (event->y-cy) * (event->y-cy); + float dist_sqrd = (x - cx) * (x - cx) + (y - cy) * (y - cy); if(dist_sqrd <= ((DOT_RADIUS + 1) * (DOT_RADIUS + 1))) { priv->is_button_down = TRUE; @@ -2454,7 +2462,7 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) { int ptx = (last_x+cx)/2.0; int pty = (last_y+cy)/2.0; - dist_sqrd = (event->x - ptx) * (event->x-ptx) + (event->y-pty) * (event->y-pty); + dist_sqrd = (x - ptx) * (x - ptx) + (y - pty) * (y - pty); if(dist_sqrd <= ((DOT_RADIUS + 1) * (DOT_RADIUS + 1))) { OsmGpsMapPoint* newpoint = malloc(sizeof(OsmGpsMapPoint)); @@ -2484,7 +2492,7 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) int ptx = (last_x+first_x)/2.0; int pty = (last_y+first_y)/2.0; - float dist_sqrd = (event->x - ptx) * (event->x-ptx) + (event->y-pty) * (event->y-pty); + float dist_sqrd = (x - ptx) * (x - ptx) + (y - pty) * (y - pty); if(dist_sqrd <= ((DOT_RADIUS + 1) * (DOT_RADIUS + 1))) { OsmGpsMapPoint* newpoint = malloc(sizeof(OsmGpsMapPoint)); @@ -2507,8 +2515,8 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) priv->is_button_down = TRUE; priv->drag_counter = 0; - priv->drag_start_mouse_x = (int) event->x; - priv->drag_start_mouse_y = (int) event->y; + priv->drag_start_mouse_x = (int) x; + priv->drag_start_mouse_y = (int) y; priv->drag_start_map_x = priv->map_x; priv->drag_start_map_y = priv->map_y; @@ -2516,9 +2524,9 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event) } static gboolean -osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event) +osm_gps_map_button_release (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data) { - OsmGpsMap *map = OSM_GPS_MAP(widget); + OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self))); OsmGpsMapPrivate *priv = map->priv; if(!priv->is_button_down) @@ -2531,8 +2539,8 @@ osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event) priv->map_x = priv->drag_start_map_x; priv->map_y = priv->drag_start_map_y; - priv->map_x += (priv->drag_start_mouse_x - (int) event->x); - priv->map_y += (priv->drag_start_mouse_y - (int) event->y); + priv->map_x += (priv->drag_start_mouse_x - (int) x); + priv->map_y += (priv->drag_start_mouse_y - (int) y); center_coord_update(map); @@ -2542,7 +2550,7 @@ osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event) 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); + osm_gps_map_convert_screen_to_geographic(map, x, y, priv->drag_point); g_signal_emit_by_name(priv->drag_track, "point-changed"); } @@ -2710,8 +2718,6 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) widget_class = GTK_WIDGET_CLASS (klass); widget_class->draw = osm_gps_map_draw; widget_class->configure_event = osm_gps_map_configure; - widget_class->button_press_event = osm_gps_map_button_press; - widget_class->button_release_event = osm_gps_map_button_release; //widget_class->get_preferred_width = osm_gps_map_get_preferred_width; //widget_class->get_preferred_height = osm_gps_map_get_preferred_height; From dc60f346cf1eb0941286cafa005b38464aced81e Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 19 Jun 2022 21:55:32 +0200 Subject: [PATCH 33/47] do not listen to configure-event, but use notify event --- src/osm-gps-map-widget.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 5ca1402..aec4da6 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -333,6 +333,7 @@ static gboolean osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdoubl static gboolean osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_button_release (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); +static void osm_gps_map_configure (GObject* self, GParamSpec* pspec, gpointer user_data); /* * Drawing function forward defintions @@ -1859,6 +1860,9 @@ osm_gps_map_init (OsmGpsMap *object) g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); g_signal_connect (controller_button, "pressed", G_CALLBACK (osm_gps_map_button_press), priv); g_signal_connect (controller_button, "released", G_CALLBACK (osm_gps_map_button_release), priv); + g_signal_connect (GTK_WIDGET (object), "notify::default-height", G_CALLBACK (osm_gps_map_configure), priv); + g_signal_connect (GTK_WIDGET (object), "notify::default-width", G_CALLBACK (osm_gps_map_configure), priv); + g_signal_connect (GTK_WIDGET (object), "notify::fullscreened", G_CALLBACK (osm_gps_map_configure), priv); } static char* @@ -2640,20 +2644,20 @@ osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, return FALSE; } -static gboolean -osm_gps_map_configure (GtkWidget *widget, GdkEventConfigure *event) +static void +osm_gps_map_configure (GObject* self, GParamSpec* pspec, gpointer user_data) { - int w,h; + int w, h; GdkWindow *window; - OsmGpsMap *map = OSM_GPS_MAP(widget); + OsmGpsMap *map = OSM_GPS_MAP(self); OsmGpsMapPrivate *priv = map->priv; if (priv->pixmap) cairo_surface_destroy (priv->pixmap); - w = gtk_widget_get_allocated_width (widget); - h = gtk_widget_get_allocated_height (widget); - window = gtk_widget_get_window(widget); + w = gtk_widget_get_allocated_width (GTK_WIDGET(self)); + h = gtk_widget_get_allocated_height (GTK_WIDGET(self)); + window = gtk_widget_get_window(GTK_WIDGET (map)); priv->pixmap = gdk_window_create_similar_surface ( window, @@ -2668,11 +2672,11 @@ osm_gps_map_configure (GtkWidget *widget, GdkEventConfigure *event) priv->map_x = pixel_x - w/2; priv->map_y = pixel_y - h/2; - osm_gps_map_map_redraw(OSM_GPS_MAP(widget)); + osm_gps_map_map_redraw(OSM_GPS_MAP(self)); - g_signal_emit_by_name(widget, "changed"); + g_signal_emit_by_name(GTK_WIDGET(self), "changed"); - return FALSE; + return; } static gboolean @@ -2717,7 +2721,6 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) widget_class = GTK_WIDGET_CLASS (klass); widget_class->draw = osm_gps_map_draw; - widget_class->configure_event = osm_gps_map_configure; //widget_class->get_preferred_width = osm_gps_map_get_preferred_width; //widget_class->get_preferred_height = osm_gps_map_get_preferred_height; From 8efa69912a5c94a626dd02d5c54d179f666f5927 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Mon, 20 Jun 2022 22:17:20 +0200 Subject: [PATCH 34/47] fix the proper incovation of the configure function --- src/osm-gps-map-widget.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index aec4da6..f885d96 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -333,7 +333,8 @@ static gboolean osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdoubl static gboolean osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_button_release (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); -static void osm_gps_map_configure (GObject* self, GParamSpec* pspec, gpointer user_data); +static void osm_gps_map_configure_realize (GtkWidget* self, gpointer user_data); +static void osm_gps_map_configure (GtkWidget* self, GtkAllocation* allocation, gpointer user_data); /* * Drawing function forward defintions @@ -1860,9 +1861,8 @@ osm_gps_map_init (OsmGpsMap *object) g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); g_signal_connect (controller_button, "pressed", G_CALLBACK (osm_gps_map_button_press), priv); g_signal_connect (controller_button, "released", G_CALLBACK (osm_gps_map_button_release), priv); - g_signal_connect (GTK_WIDGET (object), "notify::default-height", G_CALLBACK (osm_gps_map_configure), priv); - g_signal_connect (GTK_WIDGET (object), "notify::default-width", G_CALLBACK (osm_gps_map_configure), priv); - g_signal_connect (GTK_WIDGET (object), "notify::fullscreened", G_CALLBACK (osm_gps_map_configure), priv); + g_signal_connect (GTK_WIDGET (object), "realize", G_CALLBACK (osm_gps_map_configure_realize), priv); + g_signal_connect (GTK_WIDGET (object), "size-allocate", G_CALLBACK (osm_gps_map_configure), priv); } static char* @@ -2645,11 +2645,17 @@ osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, } static void -osm_gps_map_configure (GObject* self, GParamSpec* pspec, gpointer user_data) +osm_gps_map_configure_realize (GtkWidget* self, gpointer user_data) +{ + osm_gps_map_configure (self, NULL, user_data); +} + +static void +osm_gps_map_configure (GtkWidget* self, GtkAllocation* allocation, gpointer user_data) { int w, h; GdkWindow *window; - OsmGpsMap *map = OSM_GPS_MAP(self); + OsmGpsMap *map = OSM_GPS_MAP (self); OsmGpsMapPrivate *priv = map->priv; if (priv->pixmap) @@ -2657,13 +2663,16 @@ osm_gps_map_configure (GObject* self, GParamSpec* pspec, gpointer user_data) w = gtk_widget_get_allocated_width (GTK_WIDGET(self)); h = gtk_widget_get_allocated_height (GTK_WIDGET(self)); - window = gtk_widget_get_window(GTK_WIDGET (map)); + window = gtk_widget_get_window (self); - priv->pixmap = gdk_window_create_similar_surface ( + if (window != NULL) + { + priv->pixmap = gdk_window_create_similar_surface ( window, CAIRO_CONTENT_COLOR, w + EXTRA_BORDER * 2, h + EXTRA_BORDER * 2); + } // pixel_x,y, offsets gint pixel_x = lon2pixel(priv->map_zoom, priv->center_rlon); From d567ca493b13d88cb81e304448504eea21beb4c7 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Mon, 20 Jun 2022 23:56:03 +0200 Subject: [PATCH 35/47] little code cleaning/styling --- src/osm-gps-map-widget.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index f885d96..3d91ffe 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1526,7 +1526,7 @@ osm_gps_map_print_polygons (OsmGpsMap *map, cairo_t* cr) static gboolean -osm_gps_map_purge_cache_check(gpointer key, gpointer value, gpointer user) +osm_gps_map_purge_cache_check (gpointer key, gpointer value, gpointer user) { return (((OsmCachedTile*)value)->redraw_cycle != ((OsmGpsMapPrivate*)user)->redraw_cycle); } @@ -1632,7 +1632,8 @@ osm_gps_map_map_redraw_idle (OsmGpsMap *map) /* call this to update center_rlat and center_rlon after * changin map_x or map_y */ static void -center_coord_update(OsmGpsMap *map) { +center_coord_update(OsmGpsMap *map) +{ GtkWidget *widget = GTK_WIDGET(map); OsmGpsMapPrivate *priv = map->priv; From 10be15290e28bcb1ee0cf03892ba52a2fe8a1af2 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Mon, 20 Jun 2022 23:58:12 +0200 Subject: [PATCH 36/47] one more code cleaning/styling --- src/osm-gps-map-widget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 3d91ffe..7071abf 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1875,7 +1875,7 @@ osm_gps_map_get_cache_base_dir(OsmGpsMapPrivate *priv) } static void -osm_gps_map_setup(OsmGpsMap *map) +osm_gps_map_setup (OsmGpsMap *map) { const char *uri; OsmGpsMapPrivate *priv = map->priv; From 7953b7bb0cc768563c9a3eb71e054bf39a5cf9e2 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:02:48 +0200 Subject: [PATCH 37/47] replace GtkGestureMultiPress with GtkGestureClick --- src/osm-gps-map-widget.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 7071abf..24040ff 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -330,8 +330,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA); */ static gboolean on_window_key_press (GtkEventControllerKey *self, guint keyval, guint keycode, GdkModifierType state, gpointer user_data); static gboolean osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy, gpointer user_data); -static gboolean osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); -static gboolean osm_gps_map_button_release (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data); +static gboolean osm_gps_map_button_press (GtkGestureClick* self, gint n_press, gdouble x, gdouble y, gpointer user_data); +static gboolean osm_gps_map_button_release (GtkGestureClick* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); static void osm_gps_map_configure_realize (GtkWidget* self, gpointer user_data); static void osm_gps_map_configure (GtkWidget* self, GtkAllocation* allocation, gpointer user_data); @@ -1705,12 +1705,14 @@ on_window_key_press (GtkEventControllerKey *self, guint keyval, guint keycode, G switch(i) { case OSM_GPS_MAP_KEY_FULLSCREEN: { - GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (map)); - if(!priv->is_fullscreen) - gtk_window_fullscreen(GTK_WINDOW(toplevel)); - else - gtk_window_unfullscreen(GTK_WINDOW(toplevel)); - + GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (map)); + if (GTK_IS_WINDOW (root)) { + GtkWindow *toplevel = GTK_WINDOW (root); + if (!priv->is_fullscreen) + gtk_window_fullscreen (toplevel); + else + gtk_window_unfullscreen (toplevel); + } priv->is_fullscreen = !priv->is_fullscreen; handled = TRUE; } break; @@ -1845,8 +1847,9 @@ osm_gps_map_init (OsmGpsMap *object) GtkEventController* controller_key = gtk_event_controller_key_new (GTK_WIDGET (object)); - GtkGesture* controller_button = gtk_gesture_multi_press_new (GTK_WIDGET (object)); + GtkGesture* controller_button = gtk_gesture_click_new (); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller_button), 0); + gtk_widget_add_controller (GTK_WIDGET (object), GTK_EVENT_CONTROLLER(controller_button)); GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); @@ -2307,7 +2310,7 @@ osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy } static gboolean -osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data) +osm_gps_map_button_press (GtkGestureClick* self, gint n_press, gdouble x, gdouble y, gpointer user_data) { OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self))); OsmGpsMapPrivate *priv = map->priv; @@ -2318,7 +2321,6 @@ osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, g for(list = priv->layers; list != NULL; list = list->next) { OsmGpsMapLayer *layer = list->data; - //printf ("call osm_gps_map_layer_button_press\n"); if (osm_gps_map_layer_button_press (layer, map, GTK_GESTURE_SINGLE (self), n_press, x, y, user_data)) return FALSE; } @@ -2529,7 +2531,7 @@ osm_gps_map_button_press (GtkGestureMultiPress* self, gint n_press, gdouble x, g } static gboolean -osm_gps_map_button_release (GtkGestureMultiPress* self, gint n_press, gdouble x, gdouble y, gpointer user_data) +osm_gps_map_button_release (GtkGestureClick* self, gint n_press, gdouble x, gdouble y, gpointer user_data) { OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self))); OsmGpsMapPrivate *priv = map->priv; From 141290b9ae9854f1bdf76ae4c95b81f5dd4778d6 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:07:20 +0200 Subject: [PATCH 38/47] update the window event controllers to GTK4 code --- src/osm-gps-map-widget.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 24040ff..b300383 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1837,23 +1837,18 @@ osm_gps_map_init (OsmGpsMap *object) g_free, (GDestroyNotify)cached_tile_free); priv->max_tile_cache_size = 20; - gtk_widget_add_events (GTK_WIDGET (object), - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK | - GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); -#ifdef HAVE_GDK_EVENT_GET_SCROLL_DELTAS - gtk_widget_add_events (GTK_WIDGET (object), GDK_SMOOTH_SCROLL_MASK) -#endif - - GtkEventController* controller_key = gtk_event_controller_key_new (GTK_WIDGET (object)); + GtkEventController* controller_key = gtk_event_controller_key_new (); + gtk_widget_add_controller (GTK_WIDGET (object), controller_key); GtkGesture* controller_button = gtk_gesture_click_new (); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller_button), 0); gtk_widget_add_controller (GTK_WIDGET (object), GTK_EVENT_CONTROLLER(controller_button)); - GtkEventController* controller_motion = gtk_event_controller_motion_new (GTK_WIDGET (object)); + GtkEventController* controller_motion = gtk_event_controller_motion_new (); + gtk_widget_add_controller (GTK_WIDGET (object), controller_motion); - GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_WIDGET (object), GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); + GtkEventController* controller_scroll = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); + gtk_widget_add_controller (GTK_WIDGET (object), controller_scroll); gtk_widget_set_can_focus (GTK_WIDGET (object), TRUE); From 87f7c4cb71bdaadc16e332f3d6058b7262e86c4c Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:09:37 +0200 Subject: [PATCH 39/47] update the draw and configure functions --- src/osm-gps-map-widget.c | 53 ++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index b300383..f3e5948 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -334,7 +334,8 @@ static gboolean osm_gps_map_button_press (GtkGestureClick* self, gint n_press, g static gboolean osm_gps_map_button_release (GtkGestureClick* self, gint n_press, gdouble x, gdouble y, gpointer user_data); static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data); static void osm_gps_map_configure_realize (GtkWidget* self, gpointer user_data); -static void osm_gps_map_configure (GtkWidget* self, GtkAllocation* allocation, gpointer user_data); +static void osm_gps_map_configure (GtkDrawingArea* self, gint width, gint height, gpointer user_data); +static void osm_gps_map_draw (GtkDrawingArea* drawing_area, cairo_t* cr, int width, int height, gpointer user_data); /* * Drawing function forward defintions @@ -1855,13 +1856,15 @@ osm_gps_map_init (OsmGpsMap *object) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL); /* setup signal handlers */ + gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (object), osm_gps_map_draw, NULL, NULL); + g_signal_connect (controller_key, "key-pressed", G_CALLBACK (on_window_key_press), priv); g_signal_connect (controller_scroll, "scroll", G_CALLBACK (osm_gps_map_scroll_event), priv); g_signal_connect (controller_motion, "motion", G_CALLBACK (osm_gps_map_motion_notify), priv); g_signal_connect (controller_button, "pressed", G_CALLBACK (osm_gps_map_button_press), priv); g_signal_connect (controller_button, "released", G_CALLBACK (osm_gps_map_button_release), priv); g_signal_connect (GTK_WIDGET (object), "realize", G_CALLBACK (osm_gps_map_configure_realize), priv); - g_signal_connect (GTK_WIDGET (object), "size-allocate", G_CALLBACK (osm_gps_map_configure), priv); + g_signal_connect (GTK_DRAWING_AREA (object), "resize", G_CALLBACK (osm_gps_map_configure), priv); } static char* @@ -2645,32 +2648,22 @@ osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, static void osm_gps_map_configure_realize (GtkWidget* self, gpointer user_data) { - osm_gps_map_configure (self, NULL, user_data); + osm_gps_map_configure (GTK_DRAWING_AREA (self), 0, 0, user_data); } static void -osm_gps_map_configure (GtkWidget* self, GtkAllocation* allocation, gpointer user_data) +osm_gps_map_configure (GtkDrawingArea* self, gint width, gint height, gpointer user_data) { int w, h; - GdkWindow *window; OsmGpsMap *map = OSM_GPS_MAP (self); OsmGpsMapPrivate *priv = map->priv; - if (priv->pixmap) - cairo_surface_destroy (priv->pixmap); + // If the pixmap is still empty, return and wait till the draw function has been called first + // In the draw function a new surface is created which can be used for drawing the background. + if (priv->pixmap == NULL) + return; - w = gtk_widget_get_allocated_width (GTK_WIDGET(self)); - h = gtk_widget_get_allocated_height (GTK_WIDGET(self)); - window = gtk_widget_get_window (self); - - if (window != NULL) - { - priv->pixmap = gdk_window_create_similar_surface ( - window, - CAIRO_CONTENT_COLOR, - w + EXTRA_BORDER * 2, - h + EXTRA_BORDER * 2); - } + priv->pixmap = cairo_surface_create_similar (priv->pixmap, cairo_surface_get_content (priv->pixmap), width + EXTRA_BORDER * 2, height + EXTRA_BORDER * 2); // pixel_x,y, offsets gint pixel_x = lon2pixel(priv->map_zoom, priv->center_rlon); @@ -2686,12 +2679,20 @@ osm_gps_map_configure (GtkWidget* self, GtkAllocation* allocation, gpointer user return; } -static gboolean -osm_gps_map_draw (GtkWidget *widget, cairo_t *cr) +static void +osm_gps_map_draw (GtkDrawingArea* drawing_area, cairo_t* cr, int width, int height, gpointer user_data) { - OsmGpsMap *map = OSM_GPS_MAP(widget); + OsmGpsMap *map = OSM_GPS_MAP (drawing_area); OsmGpsMapPrivate *priv = map->priv; + // If there is no pixmap set, create a surface from the given context. + if (priv->pixmap == NULL) { + cairo_surface_t *surface = cairo_get_target (cr); + priv->pixmap = cairo_surface_create_similar (surface, cairo_surface_get_content (surface), width, height); + // Call the configure function (again) to set up all variables. + osm_gps_map_configure (drawing_area, width, height, user_data); + } + if (!priv->drag_mouse_dx && !priv->drag_mouse_dy) { cairo_set_source_surface (cr, priv->pixmap, 0, 0); } else { @@ -2710,14 +2711,13 @@ osm_gps_map_draw (GtkWidget *widget, cairo_t *cr) } } - return FALSE; + return; } static void osm_gps_map_class_init (OsmGpsMapClass *klass) { GObjectClass* object_class; - GtkWidgetClass *widget_class; object_class = G_OBJECT_CLASS (klass); object_class->dispose = osm_gps_map_dispose; @@ -2726,11 +2726,6 @@ osm_gps_map_class_init (OsmGpsMapClass *klass) object_class->set_property = osm_gps_map_set_property; object_class->get_property = osm_gps_map_get_property; - widget_class = GTK_WIDGET_CLASS (klass); - widget_class->draw = osm_gps_map_draw; - //widget_class->get_preferred_width = osm_gps_map_get_preferred_width; - //widget_class->get_preferred_height = osm_gps_map_get_preferred_height; - /* default implementation of draw_gps_point */ klass->draw_gps_point = osm_gps_map_draw_gps_point; From 5100b8293338bd140fd64ffff1a703ff77fa3bb2 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:12:48 +0200 Subject: [PATCH 40/47] use gtk_event_controller_get_current_event_state instead of gtk_gesture_single_get_current_button --- src/osm-gps-map-osd.c | 4 ++-- src/osm-gps-map-widget.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/osm-gps-map-osd.c b/src/osm-gps-map-osd.c index ca3008e..d3fe3d0 100644 --- a/src/osm-gps-map-osd.c +++ b/src/osm-gps-map-osd.c @@ -551,10 +551,10 @@ osm_gps_map_osd_button_press (OsmGpsMapLayer *osd, self = OSM_GPS_MAP_OSD(osd); priv = self->priv; - state = gtk_gesture_single_get_current_button (event); + state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (event)); gtk_widget_get_allocation(GTK_WIDGET(map), &allocation); - if (state == 1) { + if (state == GDK_BUTTON1_MASK) { gint mx = x_axis - priv->osd_x; gint my = y_axis - priv->osd_y; diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index f3e5948..81945ef 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -2583,6 +2583,7 @@ osm_gps_map_idle_expose (GtkWidget *widget) static gboolean osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, gpointer user_data) { + GdkModifierType state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER(self)); OsmGpsMap *map = OSM_GPS_MAP(gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); OsmGpsMapPrivate *priv = map->priv; priv->mouse_x = x; @@ -2614,7 +2615,7 @@ osm_gps_map_motion_notify (GtkEventControllerMotion* self, gdouble x, gdouble y, } // are we being dragged - if (!(0 & GDK_BUTTON1_MASK)) + if (!(state & GDK_BUTTON1_MASK)) return FALSE; if (priv->drag_counter < 0) From cd26ed9f6a94b0f6eb84609c3772b3c8425f1cc1 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:13:42 +0200 Subject: [PATCH 41/47] update osm_gps_map_get_event_location function as GdkEventButton is not availible anymore --- src/osm-gps-map-widget.c | 7 ++++--- src/osm-gps-map-widget.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index 81945ef..f29c0ea 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -3970,7 +3970,8 @@ osm_gps_map_convert_geographic_to_screen(OsmGpsMap *map, OsmGpsMapPoint *pt, gin /** * osm_gps_map_get_event_location: * @map: a #OsmGpsMap widget - * @event: A #GtkEventButton that occured on the map + * @x: X coordinate of the event + * @y: Y coordinate of the event * * A convenience function for getting the geographic location of events, * such as mouse clicks, on the map @@ -3981,9 +3982,9 @@ osm_gps_map_convert_geographic_to_screen(OsmGpsMap *map, OsmGpsMapPoint *pt, gin * Since: 0.7.0 **/ OsmGpsMapPoint * -osm_gps_map_get_event_location (OsmGpsMap *map, GdkEventButton *event) +osm_gps_map_get_event_location (OsmGpsMap *map, gdouble x, gdouble y) { OsmGpsMapPoint *p = osm_gps_map_point_new_degrees(0.0,0.0); - osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, p); + osm_gps_map_convert_screen_to_geographic(map, x, y, p); return p; } diff --git a/src/osm-gps-map-widget.h b/src/osm-gps-map-widget.h index d75c831..cee1b70 100644 --- a/src/osm-gps-map-widget.h +++ b/src/osm-gps-map-widget.h @@ -115,7 +115,7 @@ gboolean osm_gps_map_layer_remove (OsmGpsMap *map, OsmGpsM void osm_gps_map_layer_remove_all (OsmGpsMap *map); void osm_gps_map_convert_screen_to_geographic(OsmGpsMap *map, gint pixel_x, gint pixel_y, OsmGpsMapPoint *pt); void osm_gps_map_convert_geographic_to_screen(OsmGpsMap *map, OsmGpsMapPoint *pt, gint *pixel_x, gint *pixel_y); -OsmGpsMapPoint *osm_gps_map_get_event_location (OsmGpsMap *map, GdkEventButton *event); +OsmGpsMapPoint *osm_gps_map_get_event_location (OsmGpsMap *map, gdouble x, gdouble y); gboolean osm_gps_map_map_redraw (OsmGpsMap *map); void osm_gps_map_map_redraw_idle (OsmGpsMap *map); From 9d89dd787a66bc5ec6892f96e59ab66d345a5d45 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:14:20 +0200 Subject: [PATCH 42/47] fix a few whitespaces --- src/osm-gps-map-widget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osm-gps-map-widget.c b/src/osm-gps-map-widget.c index f29c0ea..f1fc65d 100644 --- a/src/osm-gps-map-widget.c +++ b/src/osm-gps-map-widget.c @@ -1687,7 +1687,7 @@ on_window_key_press (GtkEventControllerKey *self, guint keyval, guint keycode, G int step; gboolean handled; GtkAllocation allocation; - OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); + OsmGpsMap *map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self))); OsmGpsMapPrivate *priv = map->priv; /* if no keybindings are set, let the app handle them... */ @@ -2282,7 +2282,7 @@ osm_gps_map_scroll_event (GtkEventControllerScroll* self, gdouble dx, gdouble dy OsmGpsMapPoint *pt; float lat, lon, c_lat, c_lon; - map = OSM_GPS_MAP(gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); + map = OSM_GPS_MAP (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER(self))); pt = osm_gps_map_point_new_degrees(0.0,0.0); /* arguably we could use get_event_location here, but I'm not convinced it is forward compatible to cast between GdkEventScroll and GtkEventButton */ From 6e7458f9811f56dc6190862e95e560a5de790007 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Tue, 21 Jun 2022 00:15:43 +0200 Subject: [PATCH 43/47] update function description of osm_gps_map_layer_button_press --- src/osm-gps-map-layer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osm-gps-map-layer.h b/src/osm-gps-map-layer.h index 029305b..0eda4c7 100644 --- a/src/osm-gps-map-layer.h +++ b/src/osm-gps-map-layer.h @@ -99,7 +99,7 @@ gboolean osm_gps_map_layer_busy (OsmGpsMapLayer *self); * osm_gps_map_layer_button_press: * @self: (in): a #OsmGpsMapLayer object * @map: (in): a #OsmGpsMap widget - * @event: (in): a GtkGestureClick event + * @event: (in): a GtkGestureSingle event * @n_press: (in): How many touch/button presses happened with this one. * @x: (in): The X coordinate, in widget allocation coordinates. * @y: (in): The Y coordinate, in widget allocation coordinates. From 9ff9359018024e7707abfcc00124c5fcfb2b068e Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 9 Oct 2022 15:41:09 +0200 Subject: [PATCH 44/47] osm-gps-map-track: introduce osm_gps_map_track_new_with_data function --- src/osm-gps-map-track.c | 8 ++++++++ src/osm-gps-map-track.h | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c index 3a2530c..b7fb2fc 100644 --- a/src/osm-gps-map-track.c +++ b/src/osm-gps-map-track.c @@ -500,6 +500,14 @@ osm_gps_map_track_get_highlight_point(OsmGpsMapTrack* track) return track->priv->highlight_point; } +OsmGpsMapTrack * +osm_gps_map_track_new_with_data (GSList *list) { + OsmGpsMapTrack *track = osm_gps_map_track_new (); + OsmGpsMapTrackPrivate* priv = track->priv; + priv->track = list; + + return track; +} OsmGpsMapTrack * osm_gps_map_track_new (void) diff --git a/src/osm-gps-map-track.h b/src/osm-gps-map-track.h index fdbe58c..feb42f2 100644 --- a/src/osm-gps-map-track.h +++ b/src/osm-gps-map-track.h @@ -70,6 +70,18 @@ GType osm_gps_map_track_get_type (void) G_GNUC_CONST; * Since: 0.7.0 **/ OsmGpsMapTrack * osm_gps_map_track_new (void); + +/** + * osm_gps_map_track_new_with_data: + * @list: (in) (element-type OsmGpsMapPoint): list of #OsmGpsMapPoint + * + * Create new track with data as per given list + * + * Returns: (transfer full): New track + * Since: 1.2.1 + **/ +OsmGpsMapTrack * osm_gps_map_track_new_with_data (GSList *list); + /** * osm_gps_map_track_add_point: * @track: (inout): a #OsmGpsMapTrack From e8cdab8d1db359e9b5c9510d80c5ddba248389f1 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 9 Oct 2022 15:41:57 +0200 Subject: [PATCH 45/47] osm-gps-map-osd: update code in osm_gps_map_osd_button_press function --- src/osm-gps-map-osd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/osm-gps-map-osd.c b/src/osm-gps-map-osd.c index d3fe3d0..624b5af 100644 --- a/src/osm-gps-map-osd.c +++ b/src/osm-gps-map-osd.c @@ -545,18 +545,18 @@ osm_gps_map_osd_button_press (OsmGpsMapLayer *osd, OsmGpsMapOsd *self; OsmGpsMapOsdPrivate *priv; GtkAllocation allocation; - GdkModifierType state; + guint state; g_return_val_if_fail(OSM_GPS_MAP_IS_OSD(osd), FALSE); self = OSM_GPS_MAP_OSD(osd); priv = self->priv; - state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (event)); + state = gtk_gesture_single_get_current_button (event); gtk_widget_get_allocation(GTK_WIDGET(map), &allocation); - if (state == GDK_BUTTON1_MASK) { - gint mx = x_axis - priv->osd_x; - gint my = y_axis - priv->osd_y; + if (state == 1) { + gint mx = (int)(x_axis) - priv->osd_x; + gint my = (int)(y_axis) - priv->osd_y; if(priv->osd_x < 0) mx -= (allocation.width - priv->osd_w); From 9ebd7785a1a71ddadcf6df78a2f351b26f78e06e Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 9 Oct 2022 15:42:58 +0200 Subject: [PATCH 46/47] update pkgconfig file to gtk4 --- osmgpsmap-1.0.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osmgpsmap-1.0.pc.in b/osmgpsmap-1.0.pc.in index c1fa711..7815e49 100644 --- a/osmgpsmap-1.0.pc.in +++ b/osmgpsmap-1.0.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: @PACKAGE_NAME@ Description: Moving map widget using openstreet map data Version: @PACKAGE_VERSION@ -Requires: gtk+-3.0 libsoup-2.4 >= 2.42 +Requires: gtk+-4.0 libsoup-2.4 >= 2.42 Libs: -L${libdir} -losmgpsmap-1. Cflags: -I${includedir}/osmgpsmap-1.2 From b92f0591aef53bf82a8b27489860e43ed6791fc3 Mon Sep 17 00:00:00 2001 From: Martijn Goedhart Date: Sun, 9 Oct 2022 16:26:37 +0200 Subject: [PATCH 47/47] look for gtk-4.0 gir file --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 6fa138c..ab98d7f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -84,7 +84,7 @@ if HAVE_INTROSPECTION introspection_sources = $(sources_c) $(sources_public_h) OsmGpsMap-1.0.gir: libosmgpsmap-1.0.la -OsmGpsMap_1_0_gir_INCLUDES = GObject-2.0 Gtk-3.0 +OsmGpsMap_1_0_gir_INCLUDES = GObject-2.0 Gtk-4.0 OsmGpsMap_1_0_gir_CFLAGS = $(OSMGPSMAP_CFLAGS) -I$(srcdir) -I$(builddir) OsmGpsMap_1_0_gir_LIBS = libosmgpsmap-1.0.la OsmGpsMap_1_0_gir_FILES = $(introspection_sources)