]> Pileus Git - grits/commitdiff
Add mouse support
authorAndy Spencer <andy753421@gmail.com>
Mon, 8 Feb 2010 05:03:56 +0000 (05:03 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 8 Feb 2010 05:03:56 +0000 (05:03 +0000)
Left mouse button:   Panning
Middle mouse button: Zooming
Right mouse button:  Rotation

TODO
src/gis-opengl.c
src/gis-viewer.c
src/gis-viewer.h

diff --git a/TODO b/TODO
index 0225ffd9a8980ca2a1177d5dd3654d13de775b86..29c7a4190871706039769ad59678c587bff5b7f0 100644 (file)
--- 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:
index 65821d74038872e2f04d09d51d3dd77466b88e25..c1d6fd5e03729a8b7211645f8ef7de5d89485c99 100644 (file)
@@ -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);
index afe2655d6638ed6d34602a39633038b0eaee2d56..a4d7dc5a28adcff982a3ca8d59e046f8570c57db 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <config.h>
+#include <math.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -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)
 {
index 06378d76d032fdf2c488da741c5df5b9ac222c74..c20cac843672fe6163b21b51043c9c11828a4205 100644 (file)
@@ -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 {