[grits] Add parameters and return values to GritsObject events



commit 420f1ea8e4aea5dd7bddc77325ab643900c34cd5
Author: Andy Spencer <andy753421 gmail com>
Date:   Sat Apr 28 20:15:32 2012 +0000

    Add parameters and return values to GritsObject events
    
    This should eventually let us break the chain so that a mouse-click
    doesn't cause multiple things to happen.

 src/grits-marshal.list     |    1 +
 src/grits-opengl.c         |   22 ++++++++------
 src/objects/grits-object.c |   69 ++++++++++++++++++++++++++------------------
 src/objects/grits-object.h |    4 +-
 src/plugins/test.c         |   23 +++++++++-----
 5 files changed, 72 insertions(+), 47 deletions(-)
---
diff --git a/src/grits-marshal.list b/src/grits-marshal.list
index f588897..dd34931 100644
--- a/src/grits-marshal.list
+++ b/src/grits-marshal.list
@@ -1,2 +1,3 @@
 VOID:DOUBLE,DOUBLE,DOUBLE
 VOID:STRING,UINT,POINTER
+BOOLEAN:POINTER
diff --git a/src/grits-opengl.c b/src/grits-opengl.c
index 4da0729..172b606 100644
--- a/src/grits-opengl.c
+++ b/src/grits-opengl.c
@@ -139,7 +139,7 @@ static void _set_visuals(GritsOpenGL *opengl)
 	g_mutex_unlock(opengl->sphere_lock);
 }
 
-typedef void (*GritsLevelFunc)(GritsObject *obj, gpointer user_data, gint level, gboolean sorted);
+typedef gboolean (*GritsLevelFunc)(GritsObject *obj, gpointer user_data, gint level, gboolean sorted);
 
 static gboolean _foreach_object_cb(gpointer key, gpointer value, gpointer pointers)
 {
@@ -147,9 +147,11 @@ static gboolean _foreach_object_cb(gpointer key, gpointer value, gpointer pointe
 	GritsLevelFunc user_func = ((gpointer*)pointers)[0];
 	gpointer       user_data = ((gpointer*)pointers)[1];
 	for (GList *cur = level->unsorted.next; cur; cur = cur->next)
-		user_func(cur->data, user_data, (gint)key, FALSE);
+		if (user_func(cur->data, user_data, (gint)key, FALSE))
+			return TRUE;
 	for (GList *cur = level->sorted.next;   cur; cur = cur->next)
-		user_func(cur->data, user_data, (gint)key, TRUE);
+		if (user_func(cur->data, user_data, (gint)key, TRUE))
+			return TRUE;
 	return FALSE;
 }
 
@@ -159,16 +161,18 @@ static void _foreach_object(GritsOpenGL *opengl, GritsLevelFunc func, gpointer u
 	g_tree_foreach(opengl->objects, _foreach_object_cb, pointers);
 }
 
-static void _add_object_world(GritsObject *object, GPtrArray *array, gint level, gboolean sorted)
+static gboolean _add_object_world(GritsObject *object, GPtrArray *array, gint level, gboolean sorted)
 {
 	if (level < GRITS_LEVEL_HUD)
 		g_ptr_array_add(array, object);
+	return FALSE;
 }
 
-static void _add_object_ortho(GritsObject *object, GPtrArray *array, gint level, gboolean sorted)
+static gboolean _add_object_ortho(GritsObject *object, GPtrArray *array, gint level, gboolean sorted)
 {
 	if (level >= GRITS_LEVEL_HUD)
 		g_ptr_array_add(array, object);
+	return FALSE;
 }
 
 static GPtrArray *_objects_to_array(GritsOpenGL *opengl, gboolean ortho)
@@ -196,7 +200,7 @@ static gboolean on_configure(GritsOpenGL *opengl, GdkEventConfigure *event, gpoi
 	return FALSE;
 }
 
-static gint run_picking(GritsOpenGL *opengl, GPtrArray *objects)
+static gint run_picking(GritsOpenGL *opengl, GdkEvent *event, GPtrArray *objects)
 {
 	/* Setup picking buffers */
 	guint buffer[100][4] = {};
@@ -231,7 +235,7 @@ static gint run_picking(GritsOpenGL *opengl, GPtrArray *objects)
 	/* Notify objects of pointer movements */
 	for (guint i = 0; i < objects->len; i++) {
 		GritsObject *object = objects->pdata[i];
-		grits_object_set_pointer(object, object->state.picked);
+		grits_object_set_pointer(object, event, object->state.picked);
 	}
 
 	return hits;
@@ -266,14 +270,14 @@ static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpo
 	glMatrixMode(GL_PROJECTION); glLoadIdentity();
 	gluPickMatrix(gl_x, gl_y, delta, delta, viewport);
 	glMultMatrixd(projection);
-	gint world_hits = run_picking(opengl, world);
+	gint world_hits = run_picking(opengl, (GdkEvent*)event, world);
 
 	/* Run ortho picking */
 	glMatrixMode(GL_PROJECTION); glLoadIdentity();
 	gluPickMatrix(gl_x, gl_y, delta, delta, viewport);
 	glMatrixMode(GL_MODELVIEW);  glLoadIdentity();
 	glOrtho(0, viewport[2], viewport[3], 0, 1000, -1000);
-	gint ortho_hits = run_picking(opengl, ortho);
+	gint ortho_hits = run_picking(opengl, (GdkEvent*)event, ortho);
 
 	g_debug("GritsOpenGL: on_motion_notify - hits=%d/%d,%d/%d ev=%.0lf,%.0lf",
 			world_hits, world->len, ortho_hits, ortho->len, gl_x, gl_y);
diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c
index fc8cddf..e9a7a0a 100644
--- a/src/objects/grits-object.c
+++ b/src/objects/grits-object.c
@@ -33,6 +33,7 @@
 
 #include "gtkgl.h"
 #include "grits-object.h"
+#include "grits-marshal.h"
 
 /* Constants */
 enum {
@@ -171,20 +172,22 @@ void grits_object_pick(GritsObject *object, GritsOpenGL *opengl)
 	grits_object_pickdraw(object, opengl, TRUE);
 }
 
-void grits_object_set_pointer(GritsObject *object, gboolean selected)
+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,
@@ -196,21 +199,28 @@ 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;
 	if (sig == SIG_BUTTON_RELEASE && object->state.clicking)
-		g_signal_emit(object, signals[SIG_CLICKED], 0, event);
+		g_signal_emit(object, signals[SIG_CLICKED], 0, event, &rval);
 	if (sig == SIG_BUTTON_RELEASE || sig == SIG_MOTION)
 		object->state.clicking = FALSE;
 
 	/* 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 */
@@ -239,9 +249,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:
@@ -257,9 +268,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:
@@ -274,9 +286,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:
@@ -293,8 +306,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);
 
@@ -313,8 +326,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);
 
@@ -332,8 +345,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);
 
@@ -351,8 +364,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);
 
@@ -370,8 +383,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);
 }
diff --git a/src/objects/grits-object.h b/src/objects/grits-object.h
index d7b8b03..0b8cacb 100644
--- a/src/objects/grits-object.h
+++ b/src/objects/grits-object.h
@@ -77,8 +77,8 @@ void grits_object_hide(GritsObject *object, gboolean hidden);
 
 /* Interal, used by grits_opengl */
 void grits_object_pick(GritsObject *object, GritsOpenGL *opengl);
-void grits_object_set_pointer(GritsObject *object, gboolean selected);
-void grits_object_event(GritsObject *object, GdkEvent *event);
+gboolean grits_object_set_pointer(GritsObject *object, GdkEvent *event, gboolean selected);
+gboolean grits_object_event(GritsObject *object, GdkEvent *event);
 
 /**
  * grits_object_queue_draw:
diff --git a/src/plugins/test.c b/src/plugins/test.c
index b5ab621..e1dab0e 100644
--- a/src/plugins/test.c
+++ b/src/plugins/test.c
@@ -30,21 +30,23 @@
 
 #include "test.h"
 
-static void on_poly_enter(GritsPoly *poly)
+static gboolean on_poly_enter(GritsPoly *poly)
 {
 	g_debug("GritsPluginTest: on_poly_enter");
 	poly->color[3] = 0.50;
 	grits_object_queue_draw(GRITS_OBJECT(poly));
+	return FALSE;
 }
 
-static void on_poly_leave(GritsPoly *poly)
+static gboolean on_poly_leave(GritsPoly *poly)
 {
 	g_debug("GritsPluginTest: on_poly_leave");
 	poly->color[3] = 0.2;
 	grits_object_queue_draw(GRITS_OBJECT(poly));
+	return FALSE;
 }
 
-static void on_poly_button(GritsPoly *poly, GdkEventButton *event)
+static gboolean on_poly_button(GritsPoly *poly, GdkEventButton *event)
 {
 	g_debug("GritsPluginTest: on_poly_button");
 	static int i = 0;
@@ -56,9 +58,10 @@ static void on_poly_button(GritsPoly *poly, GdkEventButton *event)
 	int idx = i++ % G_N_ELEMENTS(colors);
 	memcpy(poly->color, colors[idx], sizeof(gdouble)*3);
 	grits_object_queue_draw(GRITS_OBJECT(poly));
+	return TRUE;
 }
 
-static void on_poly_key(GritsPoly *poly, GdkEventKey *event)
+static gboolean on_poly_key(GritsPoly *poly, GdkEventKey *event)
 {
 	g_debug("GritsPluginTest: on_poly_key - %d", event->keyval);
 	gdouble colors[0xff][3] = {
@@ -67,33 +70,37 @@ static void on_poly_key(GritsPoly *poly, GdkEventKey *event)
 		[GDK_b] {0, 0, 1},
 	};
 	if (event->keyval >= G_N_ELEMENTS(colors))
-		return;
+		return FALSE;
 	int key = event->keyval;
 	memcpy(poly->color, colors[key], sizeof(gdouble)*3);
 	grits_object_queue_draw(GRITS_OBJECT(poly));
+	return TRUE;
 }
 
-static void on_marker_enter(GritsMarker *marker, GritsViewer *viewer)
+static gboolean on_marker_enter(GritsMarker *marker, GdkEvent *event, GritsViewer *viewer)
 {
 	g_debug("GritsPluginTest: on_marker_enter");
 	GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(viewer));
 	GdkCursor *cursor = gdk_cursor_new(GDK_HAND2);
 	gdk_window_set_cursor(window, cursor);
+	return FALSE;
 }
 
-static void on_marker_leave(GritsMarker *marker, GritsViewer *viewer)
+static gboolean on_marker_leave(GritsMarker *marker, GdkEvent *event, GritsViewer *viewer)
 {
 	g_debug("GritsPluginTest: on_marker_leave");
 	GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(viewer));
 	gdk_window_set_cursor(window, NULL);
+	return FALSE;
 }
 
-static void on_marker_button(GritsMarker *marker, GdkEventButton *event)
+static gboolean on_marker_button(GritsMarker *marker, GdkEventButton *event)
 {
 	g_debug("GritsPluginTest: on_marker_button");
 	GtkWidget *dialog = gtk_dialog_new_with_buttons(
 			"St. Charles!", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
 	gtk_dialog_run(GTK_DIALOG(dialog));
+	return TRUE;
 }
 
 /***********



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]