X-Git-Url: http://pileus.org/git/?p=grits;a=blobdiff_plain;f=src%2Fgrits-viewer.c;h=86d00c45256751f59d549c35bfa3a55641aff615;hp=b4b672a62e6f814473dc36a79a98ded4d2238a9d;hb=8941c8e6e06588d43732645e6af3feb959f1eb41;hpb=46c47c0bc0785333480ce29b78594e60939efd35 diff --git a/src/grits-viewer.c b/src/grits-viewer.c index b4b672a..86d00c4 100644 --- a/src/grits-viewer.c +++ b/src/grits-viewer.c @@ -61,6 +61,26 @@ static void _grits_viewer_fix_location(GritsViewer *viewer) viewer->location[2] = ABS(viewer->location[2]); } +static void _grits_viewer_fix_rotation(GritsViewer *viewer) +{ + while (viewer->rotation[0] < -180) viewer->rotation[0] += 360; + while (viewer->rotation[0] > 180) viewer->rotation[0] -= 360; + while (viewer->rotation[1] < -180) viewer->rotation[1] += 360; + while (viewer->rotation[1] > 180) viewer->rotation[1] -= 360; + while (viewer->rotation[2] < -180) viewer->rotation[2] += 360; + while (viewer->rotation[2] > 180) viewer->rotation[2] -= 360; +} + +static gboolean _grits_viewer_queue_draw_cb(gpointer _viewer) +{ + GritsViewer *viewer = _viewer; + g_mutex_lock(&viewer->draw_lock); + gtk_widget_queue_draw(GTK_WIDGET(viewer)); + viewer->draw_source = 0; + g_mutex_unlock(&viewer->draw_lock); + return FALSE; +} + /* Signal helpers */ static void _grits_viewer_emit_location_changed(GritsViewer *viewer) { @@ -163,11 +183,11 @@ static gboolean on_motion_notify(GritsViewer *viewer, GdkEventMotion *event, gpo gdouble lat, lon, elev, scale, rx, ry, rz; grits_viewer_get_location(GRITS_VIEWER(viewer), &lat, &lon, &elev); grits_viewer_get_rotation(GRITS_VIEWER(viewer), &rx, &ry, &rz); - scale = (elev/EARTH_R/40) * (sin(deg2rad(ABS(rx)))*4+1); + scale = (elev/EARTH_R/14.1) * (sin(deg2rad(ABS(rx)))*4+1); switch (viewer->drag_mode) { - case GRITS_DRAG_PAN: grits_viewer_pan(viewer, -y*scale, x*scale, 0); break; + case GRITS_DRAG_PAN: grits_viewer_pan(viewer, -y*scale*0.782, x*scale, 0); break; case GRITS_DRAG_ZOOM: grits_viewer_zoom(viewer, pow(2, -y/500)); break; - case GRITS_DRAG_TILT: grits_viewer_rotate(viewer, y/30, 0, x/20); break; + case GRITS_DRAG_TILT: grits_viewer_rotate(viewer, y/10, 0, x/10); break; } viewer->drag_x = event->x; viewer->drag_y = event->y; @@ -177,14 +197,7 @@ static gboolean on_motion_notify(GritsViewer *viewer, GdkEventMotion *event, gpo static void on_view_changed(GritsViewer *viewer, gdouble _1, gdouble _2, gdouble _3) { - gtk_widget_queue_draw(GTK_WIDGET(viewer)); -} - -static void on_realize(GritsViewer *viewer) -{ - GdkCursor *cursor = gdk_cursor_new(GDK_FLEUR); - GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(viewer)); - gdk_window_set_cursor(window, cursor); + grits_viewer_queue_draw(viewer); } /*********** @@ -334,6 +347,7 @@ void grits_viewer_set_rotation(GritsViewer *viewer, gdouble x, gdouble y, gdoubl viewer->rotation[0] = x; viewer->rotation[1] = y; viewer->rotation[2] = z; + _grits_viewer_fix_rotation(viewer); _grits_viewer_emit_rotation_changed(viewer); } @@ -371,6 +385,7 @@ void grits_viewer_rotate(GritsViewer *viewer, gdouble x, gdouble y, gdouble z) viewer->rotation[0] += x; viewer->rotation[1] += y; viewer->rotation[2] += z; + _grits_viewer_fix_rotation(viewer); _grits_viewer_emit_rotation_changed(viewer); } @@ -419,6 +434,22 @@ gboolean grits_viewer_get_offline(GritsViewer *viewer) return viewer->offline; } +/** + * grits_viewer_queue_draw: + * @viewer: the viewer + * + * Causes the viewer to redraw the screen. This has the safe effect as + * gtk_widget_queue_draw, but is thread safe, and probably faster. + */ +void grits_viewer_queue_draw(GritsViewer *viewer) +{ + g_mutex_lock(&viewer->draw_lock); + if (!viewer->draw_source) + viewer->draw_source = g_idle_add_full(G_PRIORITY_HIGH, + _grits_viewer_queue_draw_cb, viewer, NULL); + g_mutex_unlock(&viewer->draw_lock); +} + /*********************************** * To be implemented by subclasses * ***********************************/ @@ -543,37 +574,33 @@ void grits_viewer_set_height_func(GritsViewer *viewer, GritsBounds *bounds, * * The viewer steals the objects reference. Call g_object_ref if you plan on * holding a reference as well. - * - * Returns: a handle to be pass to grits_viewer_remove() */ -gpointer grits_viewer_add(GritsViewer *viewer, GritsObject *object, +void grits_viewer_add(GritsViewer *viewer, GritsObject *object, gint level, gboolean sort) { GritsViewerClass *klass = GRITS_VIEWER_GET_CLASS(viewer); if (!klass->add) g_warning("GritsViewer: add - Unimplemented"); - object->ref = klass->add(viewer, object, level, sort); object->viewer = viewer; - return object; + klass->add(viewer, object, level, sort); } /** * grits_viewer_remove: * @viewer: the viewer - * @ref: the handle obtained from grits_viewer_add() - * - * Remove an object from the viewer. The objects reference count is decremented - * prior to being removed. + * @object: the object to remove * - * Returns: the #GritsObject referenced by the handle + * Remove an object from the viewer. */ -GritsObject *grits_viewer_remove(GritsViewer *viewer, GritsObject *object) +void grits_viewer_remove(GritsViewer *viewer, GritsObject *object) { GritsViewerClass *klass = GRITS_VIEWER_GET_CLASS(viewer); + if (!object->viewer) + return; if (!klass->remove) g_warning("GritsViewer: remove - Unimplemented"); + object->viewer = NULL; klass->remove(viewer, object); - return object; } /**************** @@ -587,11 +614,13 @@ static void grits_viewer_init(GritsViewer *viewer) viewer->time = time(NULL); viewer->location[0] = 40; viewer->location[1] = -100; - viewer->location[2] = 4*EARTH_R; + viewer->location[2] = EARTH_R; viewer->rotation[0] = 0; viewer->rotation[1] = 0; viewer->rotation[2] = 0; + g_mutex_init(&viewer->draw_lock); + g_object_set(viewer, "can-focus", TRUE, NULL); gtk_widget_add_events(GTK_WIDGET(viewer), GDK_BUTTON_PRESS_MASK | @@ -608,12 +637,22 @@ static void grits_viewer_init(GritsViewer *viewer) g_signal_connect(viewer, "location-changed", G_CALLBACK(on_view_changed), NULL); g_signal_connect(viewer, "rotation-changed", G_CALLBACK(on_view_changed), NULL); - - g_signal_connect(viewer, "realize", G_CALLBACK(on_realize), NULL); +} +static void grits_viewer_dispose(GObject *gobject) +{ + g_debug("GritsViewer: dispose"); + GritsViewer *viewer = GRITS_VIEWER(gobject); + g_mutex_lock(&viewer->draw_lock); + if (viewer->draw_source) + g_source_remove(viewer->draw_source); + g_mutex_unlock(&viewer->draw_lock); + G_OBJECT_CLASS(grits_viewer_parent_class)->dispose(gobject); } static void grits_viewer_finalize(GObject *gobject) { g_debug("GritsViewer: finalize"); + GritsViewer *viewer = GRITS_VIEWER(gobject); + g_mutex_clear(&viewer->draw_lock); G_OBJECT_CLASS(grits_viewer_parent_class)->finalize(gobject); g_debug("GritsViewer: finalize - done"); } @@ -621,6 +660,7 @@ static void grits_viewer_class_init(GritsViewerClass *klass) { g_debug("GritsViewer: class_init"); GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + gobject_class->dispose = grits_viewer_dispose; gobject_class->finalize = grits_viewer_finalize; /**