From 64b6476b923d6f779bfad1d9a608f925943b39b9 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Mon, 8 Feb 2010 05:03:56 +0000 Subject: [PATCH] Add mouse support Left mouse button: Panning Middle mouse button: Zooming Right mouse button: Rotation --- TODO | 1 - src/gis-opengl.c | 10 +------ src/gis-viewer.c | 78 +++++++++++++++++++++++++++++++++++++++++------- src/gis-viewer.h | 4 +++ 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/TODO b/TODO index 0225ffd..29c7a41 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ Miscellaneous ------------- - Use VertexArrays/VertexBufferObjects/DisplayLists/etc -- Mouse control - Plugins can time/location references too a tree-view GisObject: diff --git a/src/gis-opengl.c b/src/gis-opengl.c index 65821d7..c1d6fd5 100644 --- a/src/gis-opengl.c +++ b/src/gis-opengl.c @@ -441,14 +441,12 @@ static void on_view_changed(GisOpenGL *self, gdouble _1, gdouble _2, gdouble _3) { g_debug("GisOpenGL: on_view_changed"); - gdk_threads_enter(); _set_visuals(self); #ifndef ROAM_DEBUG self->ue_source = g_idle_add_full(G_PRIORITY_HIGH_IDLE+30, _update_errors_cb, self->sphere, NULL); //roam_sphere_update_errors(self->sphere); #endif - gdk_threads_leave(); } static gboolean on_idle(GisOpenGL *self) @@ -615,13 +613,6 @@ static void gis_opengl_init(GisOpenGL *self) g_error("GL lacks required capabilities"); g_object_unref(glconfig); - gtk_widget_set_size_request(GTK_WIDGET(self), 600, 550); - gtk_widget_set_events(GTK_WIDGET(self), - GDK_BUTTON_PRESS_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_KEY_PRESS_MASK); - g_object_set(self, "can-focus", TRUE, NULL); - self->objects = g_tree_new_full(_objects_cmp, NULL, NULL, _objects_free); self->sphere = roam_sphere_new(self); self->sphere_lock = g_mutex_new(); @@ -631,6 +622,7 @@ static void gis_opengl_init(GisOpenGL *self) self->sm_source[1] = g_timeout_add_full(G_PRIORITY_HIGH_IDLE+10, 500, (GSourceFunc)on_idle, self, NULL); #endif + gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_PRESS_MASK); g_signal_connect(self, "realize", G_CALLBACK(on_realize), NULL); g_signal_connect(self, "configure-event", G_CALLBACK(on_configure), NULL); g_signal_connect(self, "expose-event", G_CALLBACK(on_expose), NULL); diff --git a/src/gis-viewer.c b/src/gis-viewer.c index afe2655..a4d7dc5 100644 --- a/src/gis-viewer.c +++ b/src/gis-viewer.c @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -83,12 +84,6 @@ static void _gis_viewer_emit_offline(GisViewer *self) /************* * Callbacks * *************/ -static gboolean on_button_press(GisViewer *self, GdkEventButton *event, gpointer _) -{ - g_debug("GisViewer: on_button_press - Grabbing focus"); - gtk_widget_grab_focus(GTK_WIDGET(self)); - return TRUE; -} static gboolean on_key_press(GisViewer *self, GdkEventKey *event, gpointer _) { g_debug("GisViewer: on_key_press - key=%x, state=%x, plus=%x", @@ -111,6 +106,59 @@ static gboolean on_key_press(GisViewer *self, GdkEventKey *event, gpointer _) else if (kv == GDK_L) gis_viewer_rotate(self, 0, 0, 2); return FALSE; } + +enum { + GIS_DRAG_NONE, + GIS_DRAG_PAN, + GIS_DRAG_ZOOM, + GIS_DRAG_TILT, +}; + +static gboolean on_button_press(GisViewer *self, GdkEventButton *event, gpointer _) +{ + g_debug("GisViewer: on_button_press - %d", event->button); + gtk_widget_grab_focus(GTK_WIDGET(self)); + switch (event->button) { + case 1: self->drag_mode = GIS_DRAG_PAN; break; + case 2: self->drag_mode = GIS_DRAG_ZOOM; break; + case 3: self->drag_mode = GIS_DRAG_TILT; break; + defualt: self->drag_mode = GIS_DRAG_NONE; break; + } + self->drag_x = event->x; + self->drag_y = event->y; + return FALSE; +} + +static gboolean on_button_release(GisViewer *self, GdkEventButton *event, gpointer _) +{ + g_debug("GisViewer: on_button_release"); + self->drag_mode = GIS_DRAG_NONE; + return FALSE; +} + +static gboolean on_motion_notify(GisViewer *self, GdkEventMotion *event, gpointer _) +{ + gdouble x_dist = self->drag_x - event->x; + gdouble y_dist = self->drag_y - event->y; + gdouble lat, lon, elev, scale; + gis_viewer_get_location(GIS_VIEWER(self), &lat, &lon, &elev); + scale = elev/EARTH_R/15; + switch (self->drag_mode) { + case GIS_DRAG_PAN: + gis_viewer_pan(self, -y_dist*scale, x_dist*scale, 0); + break; + case GIS_DRAG_ZOOM: + gis_viewer_zoom(self, pow(2, -y_dist/500)); + break; + case GIS_DRAG_TILT: + gis_viewer_rotate(self, y_dist/10, 0, x_dist/10); + break; + } + self->drag_x = event->x; + self->drag_y = event->y; + return FALSE; +} + static void on_view_changed(GisViewer *self, gdouble _1, gdouble _2, gdouble _3) { @@ -304,11 +352,21 @@ static void gis_viewer_init(GisViewer *self) self->rotation[1] = 0; self->rotation[2] = 0; - g_signal_connect(self, "key-press-event", G_CALLBACK(on_key_press), NULL); - g_signal_connect(self, "button-press-event", G_CALLBACK(on_button_press), NULL); + g_object_set(self, "can-focus", TRUE, NULL); + gtk_widget_add_events(GTK_WIDGET(self), + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_KEY_PRESS_MASK); + + g_signal_connect(self, "key-press-event", G_CALLBACK(on_key_press), NULL); + + g_signal_connect(self, "button-press-event", G_CALLBACK(on_button_press), NULL); + g_signal_connect(self, "button-release-event", G_CALLBACK(on_button_release), NULL); + g_signal_connect(self, "motion-notify-event", G_CALLBACK(on_motion_notify), NULL); - g_signal_connect(self, "location-changed", G_CALLBACK(on_view_changed), NULL); - g_signal_connect(self, "rotation-changed", G_CALLBACK(on_view_changed), NULL); + g_signal_connect(self, "location-changed", G_CALLBACK(on_view_changed), NULL); + g_signal_connect(self, "rotation-changed", G_CALLBACK(on_view_changed), NULL); } static void gis_viewer_finalize(GObject *gobject) { diff --git a/src/gis-viewer.h b/src/gis-viewer.h index 06378d7..c20cac8 100644 --- a/src/gis-viewer.h +++ b/src/gis-viewer.h @@ -55,6 +55,10 @@ struct _GisViewer { gdouble location[3]; gdouble rotation[3]; gboolean offline; + + /* For dragging */ + gint drag_mode; + gdouble drag_x, drag_y; }; struct _GisViewerClass { -- 2.41.0