X-Git-Url: http://pileus.org/git/?p=grits;a=blobdiff_plain;f=src%2Fobjects%2Fgrits-object.c;h=55f39754d498cf7d4f93c0ca8116d06d376effdb;hp=65d7b420aae2e44e55e6585b327a385d104a273f;hb=67a63167629adc48ff31530dd58ece577f3d7460;hpb=7940344c1faea5b80fb39b44419b508568d3a6fc diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c index 65d7b42..55f3975 100644 --- a/src/objects/grits-object.c +++ b/src/objects/grits-object.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2010 Andy Spencer + * Copyright (C) 2009-2011 Andy Spencer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,9 +30,10 @@ #include #include -#include +#include "gtkgl.h" #include "grits-object.h" +#include "grits-marshal.h" /* Constants */ enum { @@ -51,6 +52,7 @@ 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) { g_warning("GritsObject: draw - Unimplemented"); return; @@ -60,6 +62,14 @@ void grits_object_pickdraw(GritsObject *object, GritsOpenGL *opengl, gboolean pi if (object->hidden) return; + /* Skip object with no signals when picking */ + for (int i = 0; pick; i++) { + if (i == NUM_SIGNALS) + return; + if (g_signal_has_handler_pending(object, signals[i], 0, FALSE)) + break; + } + /* Support GritsTester */ if (!GRITS_IS_OPENGL(opengl)) { g_debug("GritsObject: draw - drawing raw object"); @@ -67,7 +77,7 @@ void grits_object_pickdraw(GritsObject *object, GritsOpenGL *opengl, gboolean pi return; } - /* Calculae distance for LOD and horizon tests */ + /* Calculate distance for LOD and horizon tests */ GritsPoint *center = &object->center; if ((!(object->skip & GRITS_SKIP_LOD) || !(object->skip & GRITS_SKIP_HORIZON)) && @@ -101,7 +111,7 @@ void grits_object_pickdraw(GritsObject *object, GritsOpenGL *opengl, gboolean pi } /* Save state, draw, restore state */ - g_mutex_lock(opengl->sphere_lock); + g_mutex_lock(&opengl->sphere_lock); if (!(object->skip & GRITS_SKIP_STATE)) { glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -124,7 +134,7 @@ void grits_object_pickdraw(GritsObject *object, GritsOpenGL *opengl, gboolean pi glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } - g_mutex_unlock(opengl->sphere_lock); + g_mutex_unlock(&opengl->sphere_lock); } /** @@ -153,45 +163,44 @@ void grits_object_hide(GritsObject *object, gboolean hidden) void grits_object_queue_draw(GritsObject *object) { if (object->viewer) - gtk_widget_queue_draw(GTK_WIDGET(object->viewer)); + grits_viewer_queue_draw(object->viewer); } -/* Event handling */ -void grits_object_pick_begin(GritsObject *object, GritsOpenGL *opengl) +void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor) { - 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; - } - } + // Used by grits OpenGL + object->cursor = gdk_cursor_new(cursor); } -void grits_object_pick_pointer(GritsObject *object, double x, double y) +void grits_object_destroy(GritsObject *object) { - object->state.picked = TRUE; + if (object->viewer) + grits_viewer_remove(object->viewer, object); + g_object_unref(object); } -void grits_object_pick_end(GritsObject *object) +/* Event handling */ +void grits_object_pick(GritsObject *object, GritsOpenGL *opengl) { - if (object->state.picked) { + grits_object_pickdraw(object, opengl, TRUE); +} + +gboolean grits_object_set_pointer(GritsObject *object, GdkEvent *event, gboolean selected) +{ + gboolean rval = FALSE; + if (selected) { if (!object->state.selected) - g_signal_emit(object, signals[SIG_ENTER], 0); + g_signal_emit(object, signals[SIG_ENTER], 0, event, &rval); object->state.selected = TRUE; } else { if (object->state.selected) - g_signal_emit(object, signals[SIG_LEAVE], 0); + g_signal_emit(object, signals[SIG_LEAVE], 0, event, &rval); object->state.selected = FALSE; } + return rval; } -void grits_object_event(GritsObject *object, GdkEvent *event) +gboolean grits_object_event(GritsObject *object, GdkEvent *event) { const int map[GDK_EVENT_LAST] = { [GDK_BUTTON_PRESS ] SIG_BUTTON_PRESS, @@ -203,21 +212,30 @@ void grits_object_event(GritsObject *object, GdkEvent *event) [GDK_MOTION_NOTIFY ] SIG_MOTION, }; if (!object->state.selected) - return; + return FALSE; guint sig = map[event->type]; + gboolean rval = FALSE; /* Handle button click */ if (sig == SIG_BUTTON_PRESS) - object->state.clicking = TRUE; + object->state.clicking = GRITS_CLICK_THRESHOLD; + if (sig == SIG_MOTION && object->state.clicking) + object->state.clicking -= 1; if (sig == SIG_BUTTON_RELEASE && object->state.clicking) - g_signal_emit(object, signals[SIG_CLICKED], 0, event); - if (sig == SIG_BUTTON_RELEASE || sig == SIG_MOTION) - object->state.clicking = FALSE; + g_signal_emit(object, signals[SIG_CLICKED], 0, event, &rval); + if (sig == SIG_BUTTON_RELEASE) + object->state.clicking = 0; /* Emit this signal */ - if (!g_signal_has_handler_pending(object, signals[sig], 0, FALSE)) - return; - g_signal_emit(object, signals[sig], 0, event); + if (rval == FALSE) { + if (!g_signal_has_handler_pending(object, signals[sig], 0, FALSE)) + return FALSE; + g_signal_emit(object, signals[sig], 0, event, &rval); + } + + if (rval == TRUE) + g_debug("GritsObject: breaking chained event"); + return rval; } /* GObject stuff */ @@ -246,9 +264,10 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, + 1, + G_TYPE_POINTER); /** * GritsViewer::leave: @@ -264,9 +283,10 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, + 1, + G_TYPE_POINTER); /** * GritsViewer::clicked: @@ -281,9 +301,10 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, + 1, + G_TYPE_POINTER); /** * GritsViewer::button-press: @@ -300,8 +321,8 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); @@ -320,8 +341,8 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); @@ -339,8 +360,8 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); @@ -358,8 +379,8 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); @@ -377,8 +398,8 @@ static void grits_object_class_init(GritsObjectClass *klass) 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, + grits_cclosure_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); }