X-Git-Url: http://pileus.org/git/?p=grits;a=blobdiff_plain;f=src%2Fobjects%2Fgrits-object.c;h=6abc4eb26f3ba70b3ff25a945f2af5918cd38d44;hp=3cfd8026c6558d1ae172f1278ab4e7d25317a490;hb=1d0635977583ad84faaa1978f1fd78fa3ec83052;hpb=3d5aab9907082844afa9c1f5d28ef0b44d5fa74a diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c index 3cfd802..6abc4eb 100644 --- a/src/objects/grits-object.c +++ b/src/objects/grits-object.c @@ -34,18 +34,15 @@ #include "grits-object.h" - -/** - * grits_object_draw: - * @object: the object - * @opengl: the viewer the object is being displayed in - * - * Perform any OpenGL commands necessasairy to draw the object. - * - * The GL_PROJECTION and GL_MODELVIEW matricies and GL_ALL_ATTRIB_BITS will be - * restored to the default state after the call to draw. - */ -void grits_object_draw(GritsObject *object, GritsOpenGL *opengl) +/* Constants */ +enum { + SIG_ENTER, + SIG_LEAVE, + NUM_SIGNALS, +}; +static guint signals[NUM_SIGNALS]; + +void grits_object_pickdraw(GritsObject *object, GritsOpenGL *opengl, gboolean pick) { GritsObjectClass *klass = GRITS_OBJECT_GET_CLASS(object); if (!klass->draw) { @@ -111,7 +108,10 @@ void grits_object_draw(GritsObject *object, GritsOpenGL *opengl) object->center.lon, object->center.elev); - klass->draw(object, opengl); + if (pick && klass->pick) + klass->pick(object, opengl); + else + klass->draw(object, opengl); if (!(object->skip & GRITS_SKIP_STATE)) { glPopAttrib(); @@ -121,6 +121,21 @@ void grits_object_draw(GritsObject *object, GritsOpenGL *opengl) g_mutex_unlock(opengl->sphere_lock); } +/** + * grits_object_draw: + * @object: the object + * @opengl: the viewer the object is being displayed in + * + * Perform any OpenGL commands necessasairy to draw the object. + * + * The GL_PROJECTION and GL_MODELVIEW matricies and GL_ALL_ATTRIB_BITS will be + * restored to the default state after the call to draw. + */ +void grits_object_draw(GritsObject *object, GritsOpenGL *opengl) +{ + grits_object_pickdraw(object, opengl, FALSE); +} + void grits_object_hide(GritsObject *object, gboolean hidden) { GritsObjectClass *klass = GRITS_OBJECT_GET_CLASS(object); @@ -135,6 +150,41 @@ void grits_object_queue_draw(GritsObject *object) gtk_widget_queue_draw(GTK_WIDGET(object->viewer)); } +/* Event handling */ +void grits_object_pick_begin(GritsObject *object, GritsOpenGL *opengl) +{ + object->state.picked = FALSE; + + /* Check for connected signals */ + for (int i = 0; i < NUM_SIGNALS; i++) { + if (g_signal_has_handler_pending(object, signals[i], 0, FALSE)) { + /* Someone is watching, render the object _once_ */ + glPushName((guint)object); + grits_object_pickdraw(object, opengl, TRUE); + glPopName(); + return; + } + } +} + +void grits_object_pick_pointer(GritsObject *object, double x, double y) +{ + object->state.picked = TRUE; +} + +void grits_object_pick_end(GritsObject *object) +{ + if (object->state.picked) { + if (!object->state.selected) + g_signal_emit(object, signals[SIG_ENTER], 0); + object->state.selected = TRUE; + } else { + if (object->state.selected) + g_signal_emit(object, signals[SIG_LEAVE], 0); + object->state.selected = FALSE; + } +} + /* GObject stuff */ G_DEFINE_ABSTRACT_TYPE(GritsObject, grits_object, G_TYPE_OBJECT); static void grits_object_init(GritsObject *object) @@ -146,4 +196,40 @@ static void grits_object_init(GritsObject *object) static void grits_object_class_init(GritsObjectClass *klass) { + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + /** + * GritsObject::enter: + * @object: the object. + * + * The ::enter signal is emitted when the pointer moves over the object + */ + signals[SIG_ENTER] = g_signal_new( + "enter", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GritsViewer::leave: + * @object: the object. + * + * The ::leave signal is emitted when the pointer moves away from the + * object + */ + signals[SIG_LEAVE] = g_signal_new( + "leave", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); }