This forces us to use the proper gtk accessor functions. It may not be worth it if people actually do the Qt conversion, but if we want to try gtk3 at some point, this might help. This all came about because I was trying to explain on G+ what an immense pain this all was to even figure out, if you don't actually know gtk at all. Google and the gtk migration guide are almost useless, and the gtk2 documentation itself actually uses the fields directly without any accessor functions in several places. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
191 lines
5.8 KiB
C
191 lines
5.8 KiB
C
/* gps.c */
|
|
/* Creates the UI displaying the dives locations on a map.
|
|
*/
|
|
#include <glib/gi18n.h>
|
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
|
|
|
#include "osm-gps-map.h"
|
|
|
|
#include "dive.h"
|
|
#include "display.h"
|
|
#include "display-gtk.h"
|
|
#include "divelist.h"
|
|
|
|
/* Several map providers are available, such as OSM_GPS_MAP_SOURCE_OPENSTREETMAP
|
|
and OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE. We should make more of
|
|
them available from e.g. a pull-down menu */
|
|
static OsmGpsMapSource_t opt_map_provider = OSM_GPS_MAP_SOURCE_GOOGLE_STREET;
|
|
|
|
|
|
static void on_close(GtkWidget *widget, gpointer user_data)
|
|
{
|
|
GtkWidget **window = user_data;
|
|
gtk_widget_destroy(widget);
|
|
*window = NULL;
|
|
}
|
|
|
|
/* the osm gps map default is to scroll-and-recenter around the mouse position
|
|
* that is BAT SHIT CRAZY.
|
|
* So let's do our own scroll handling instead */
|
|
static gboolean scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data)
|
|
{
|
|
OsmGpsMap *map = (OsmGpsMap *)widget;
|
|
OsmGpsMapPoint *pt, *lt, *rb, *target;
|
|
float target_lat, target_lon;
|
|
gint ltx, lty, rbx, rby, target_x, target_y;
|
|
gint zoom, max_zoom, min_zoom;
|
|
|
|
g_object_get(widget, "max-zoom", &max_zoom, "zoom", &zoom, "min-zoom", &min_zoom, NULL);
|
|
|
|
pt = osm_gps_map_point_new_degrees(0.0, 0.0);
|
|
lt = osm_gps_map_point_new_degrees(0.0, 0.0);
|
|
rb = osm_gps_map_point_new_degrees(0.0, 0.0);
|
|
target = osm_gps_map_point_new_degrees(0.0, 0.0);
|
|
|
|
osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, pt);
|
|
|
|
osm_gps_map_get_bbox(map, lt, rb);
|
|
osm_gps_map_convert_geographic_to_screen(map, lt, <x, <y);
|
|
osm_gps_map_convert_geographic_to_screen(map, rb, &rbx, &rby);
|
|
|
|
if (event->direction == GDK_SCROLL_UP) {
|
|
if (zoom == max_zoom)
|
|
return TRUE;
|
|
|
|
target_x = event->x + ((ltx + rbx) / 2.0 - (gint)(event->x)) / 2;
|
|
target_y = event->y + ((lty + rby) / 2.0 - (gint)(event->y)) / 2;
|
|
|
|
osm_gps_map_convert_screen_to_geographic(map, target_x, target_y, target);
|
|
osm_gps_map_point_get_degrees(target, &target_lat, &target_lon);
|
|
|
|
osm_gps_map_zoom_in(map);
|
|
osm_gps_map_set_center(map, target_lat, target_lon);
|
|
} else if (event->direction == GDK_SCROLL_DOWN) {
|
|
if(zoom == min_zoom)
|
|
return TRUE;
|
|
|
|
target_x = event->x + ((ltx + rbx) / 2.0 - (gint)(event->x)) * 2;
|
|
target_y = event->y + ((lty + rby) / 2.0 - (gint)(event->y)) * 2;
|
|
|
|
osm_gps_map_convert_screen_to_geographic(map, target_x, target_y, target);
|
|
osm_gps_map_point_get_degrees(target, &target_lat, &target_lon);
|
|
|
|
osm_gps_map_zoom_out(map);
|
|
osm_gps_map_set_center(map, target_lat, target_lon);
|
|
}
|
|
/* don't allow the insane default handler to get its hands on this event */
|
|
return TRUE;
|
|
}
|
|
|
|
static void add_gps_point(OsmGpsMap *map, float latitude, float longitude)
|
|
{
|
|
OsmGpsMapTrack * track = osm_gps_map_track_new();
|
|
OsmGpsMapPoint * point = osm_gps_map_point_new_degrees(latitude, longitude);
|
|
osm_gps_map_track_add_point(track, point);
|
|
osm_gps_map_track_add(map, track);
|
|
}
|
|
|
|
|
|
OsmGpsMap *init_map(void)
|
|
{
|
|
OsmGpsMap *map;
|
|
OsmGpsMapLayer *osd;
|
|
char *cachedir, *cachebasedir;
|
|
|
|
cachebasedir = osm_gps_map_get_default_cache_directory();
|
|
cachedir = g_strdup(OSM_GPS_MAP_CACHE_AUTO);
|
|
|
|
map = g_object_new(OSM_TYPE_GPS_MAP,
|
|
"map-source", opt_map_provider,
|
|
"tile-cache", cachedir,
|
|
"tile-cache-base", cachebasedir,
|
|
"proxy-uri", g_getenv("http_proxy"),
|
|
NULL);
|
|
osd = g_object_new(OSM_TYPE_GPS_MAP_OSD,
|
|
"show-scale", TRUE,
|
|
"show-coordinates", TRUE,
|
|
"show-crosshair", TRUE,
|
|
"show-dpad", TRUE,
|
|
"show-zoom", TRUE,
|
|
"show-gps-in-dpad", TRUE,
|
|
"show-gps-in-zoom", FALSE,
|
|
"dpad-radius", 30,
|
|
NULL);
|
|
|
|
osm_gps_map_layer_add(OSM_GPS_MAP(map), osd);
|
|
g_object_unref(G_OBJECT(osd));
|
|
return map;
|
|
}
|
|
|
|
void show_map(OsmGpsMap *map, GtkWidget **window)
|
|
{
|
|
if (!*window) {
|
|
/* Enable keyboard navigation */
|
|
osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_FULLSCREEN, GDK_F11);
|
|
osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_UP, GDK_Up);
|
|
osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_DOWN, GDK_Down);
|
|
osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_LEFT, GDK_Left);
|
|
osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_RIGHT, GDK_Right);
|
|
|
|
*window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
gtk_window_set_position(GTK_WINDOW(*window), GTK_WIN_POS_MOUSE);
|
|
gtk_window_set_default_size(GTK_WINDOW(*window), 640, 480);
|
|
gtk_window_set_title(GTK_WINDOW(*window), _("Dives locations"));
|
|
gtk_container_set_border_width(GTK_CONTAINER(*window), 5);
|
|
gtk_window_set_resizable(GTK_WINDOW(*window), TRUE);
|
|
gtk_container_add(GTK_CONTAINER(*window), GTK_WIDGET(map));
|
|
g_signal_connect(*window, "destroy", G_CALLBACK(on_close), (gpointer)window);
|
|
g_signal_connect(G_OBJECT(map), "scroll-event", G_CALLBACK(scroll_cb), NULL);
|
|
}
|
|
gtk_widget_show_all(*window);
|
|
gtk_window_present(GTK_WINDOW(*window));
|
|
}
|
|
|
|
void show_gps_location(struct dive *dp)
|
|
{
|
|
static GtkWidget *window = NULL;
|
|
static OsmGpsMap *map = NULL;
|
|
GdkPixbuf *picture;
|
|
GError *gerror = NULL;
|
|
|
|
double lat = dp->latitude.udeg / 1000000.0;
|
|
double lng = dp->longitude.udeg / 1000000.0;
|
|
|
|
if (!map || !window)
|
|
map = init_map();
|
|
if (lat != 0 || lng != 0) {
|
|
add_gps_point(map, lat, lng);
|
|
osm_gps_map_set_center_and_zoom(map, lat, lng, 8);
|
|
picture = gdk_pixbuf_new_from_file("./flag.png", &gerror);
|
|
if (picture) {
|
|
osm_gps_map_image_add_with_alignment(map, lat, lng, picture, 0, 1);
|
|
} else {
|
|
printf("error message: %s\n", gerror->message);
|
|
}
|
|
} else {
|
|
osm_gps_map_set_center_and_zoom(map, 0, 0, 2);
|
|
}
|
|
show_map(map, &window);
|
|
}
|
|
|
|
void show_gps_locations()
|
|
{
|
|
static OsmGpsMap *map = NULL;
|
|
static GtkWidget *window = NULL;
|
|
struct dive *dp;
|
|
int idx;
|
|
|
|
if (!window || !map)
|
|
map = init_map();
|
|
|
|
for_each_dive(idx, dp) {
|
|
if (dive_has_location(dp)) {
|
|
add_gps_point(map, dp->latitude.udeg / 1000000.0,
|
|
dp->longitude.udeg / 1000000.0);
|
|
}
|
|
}
|
|
osm_gps_map_set_center_and_zoom(map, 0, 0, 2);
|
|
|
|
show_map(map, &window);
|
|
}
|