[grits] Add mouse, keyboard, and motion events to GritsObject



commit c9c02a03eef667b277d4408f08445fb6dd070263
Author: Andy Spencer <andy753421 gmail com>
Date:   Sat Oct 15 06:20:43 2011 +0000

    Add mouse, keyboard, and motion events to GritsObject
    
    These work by chaining the event from GritsOpenGL up to each individual
    object, which then emits the callback if it is currently selected
    (moused over).

 src/grits-opengl.c         |   12 ++++
 src/objects/grits-object.c |  121 ++++++++++++++++++++++++++++++++++++++++++++
 src/objects/grits-object.h |    1 +
 3 files changed, 134 insertions(+), 0 deletions(-)
---
diff --git a/src/grits-opengl.c b/src/grits-opengl.c
index 423c849..5e2590b 100644
--- a/src/grits-opengl.c
+++ b/src/grits-opengl.c
@@ -299,6 +299,12 @@ static gboolean on_key_press(GritsOpenGL *opengl, GdkEventKey *event, gpointer _
 	return FALSE;
 }
 
+static gboolean on_chained_event(GritsOpenGL *opengl, GdkEvent *event, gpointer _)
+{
+	_foreach_object(opengl, (GFunc)grits_object_event, event);
+	return FALSE;
+}
+
 static gboolean _update_errors_cb(gpointer _opengl)
 {
 	GritsOpenGL *opengl = _opengl;
@@ -349,6 +355,12 @@ static void on_realize(GritsOpenGL *opengl, gpointer _)
 	g_signal_connect(opengl, "rotation-changed", G_CALLBACK(on_view_changed), NULL);
 
 	g_signal_connect(opengl, "motion-notify-event", G_CALLBACK(on_motion_notify), NULL);
+	g_signal_connect_after(opengl, "key-press-event",      G_CALLBACK(on_chained_event), NULL);
+	g_signal_connect_after(opengl, "key-release-event",    G_CALLBACK(on_chained_event), NULL);
+	g_signal_connect_after(opengl, "button-press-event",   G_CALLBACK(on_chained_event), NULL);
+	g_signal_connect_after(opengl, "button-release-event", G_CALLBACK(on_chained_event), NULL);
+	g_signal_connect_after(opengl, "motion-notify-event",  G_CALLBACK(on_chained_event), NULL);
+
 #ifndef ROAM_DEBUG
 	opengl->sm_source[0] = g_timeout_add_full(G_PRIORITY_HIGH_IDLE+30, 33,  (GSourceFunc)on_idle, opengl, NULL);
 	opengl->sm_source[1] = g_timeout_add_full(G_PRIORITY_HIGH_IDLE+10, 500, (GSourceFunc)on_idle, opengl, NULL);
diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c
index 6abc4eb..5eb15d9 100644
--- a/src/objects/grits-object.c
+++ b/src/objects/grits-object.c
@@ -38,6 +38,11 @@
 enum {
 	SIG_ENTER,
 	SIG_LEAVE,
+	SIG_BUTTON_PRESS,
+	SIG_BUTTON_RELEASE,
+	SIG_KEY_PRESS,
+	SIG_KEY_RELEASE,
+	SIG_MOTION,
 	NUM_SIGNALS,
 };
 static guint signals[NUM_SIGNALS];
@@ -185,6 +190,25 @@ void grits_object_pick_end(GritsObject *object)
 	}
 }
 
+void grits_object_event(GritsObject *object, GdkEvent *event)
+{
+	const int map[GDK_EVENT_LAST] = {
+		[GDK_BUTTON_PRESS  ] SIG_BUTTON_PRESS,
+		[GDK_2BUTTON_PRESS ] SIG_BUTTON_PRESS,
+		[GDK_3BUTTON_PRESS ] SIG_BUTTON_PRESS,
+		[GDK_BUTTON_RELEASE] SIG_BUTTON_RELEASE,
+		[GDK_KEY_PRESS     ] SIG_KEY_PRESS,
+		[GDK_KEY_RELEASE   ] SIG_KEY_RELEASE,
+		[GDK_MOTION_NOTIFY ] SIG_MOTION,
+	};
+	if (!object->state.selected)
+		return;
+	guint sig = signals[map[event->type]];
+	if (!g_signal_has_handler_pending(object, sig, 0, FALSE))
+		return;
+	g_signal_emit(object, sig, 0, event);
+}
+
 /* GObject stuff */
 G_DEFINE_ABSTRACT_TYPE(GritsObject, grits_object, G_TYPE_OBJECT);
 static void grits_object_init(GritsObject *object)
@@ -232,4 +256,101 @@ static void grits_object_class_init(GritsObjectClass *klass)
 			g_cclosure_marshal_VOID__VOID,
 			G_TYPE_NONE,
 			0);
+
+	/**
+	 * GritsViewer::button-press:
+	 * @object: the object.
+	 * @event:  the GdkEventButton which triggered this signal
+	 *
+	 * The ::button-press signal is emitted when a button (typically from a
+	 * mouse) is pressed.
+	 */
+	signals[SIG_BUTTON_PRESS] = g_signal_new(
+			"button-press",
+			G_TYPE_FROM_CLASS(gobject_class),
+			G_SIGNAL_RUN_LAST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__POINTER,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_POINTER);
+
+	/**
+	 * GritsViewer::button-release:
+	 * @object: the object.
+	 * @event:  the GdkEventButton which triggered this signal
+	 *
+	 * The ::button-release signal is emitted when a button (typically from
+	 * a mouse) is released.
+	 */
+	signals[SIG_BUTTON_RELEASE] = g_signal_new(
+			"button-release",
+			G_TYPE_FROM_CLASS(gobject_class),
+			G_SIGNAL_RUN_LAST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__POINTER,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_POINTER);
+
+	/**
+	 * GritsViewer::key-press:
+	 * @object: the object.
+	 * @event:  the GdkEventKey which triggered this signal
+	 *
+	 * The ::key-press signal is emitted when a key is pressed.
+	 */
+	signals[SIG_KEY_PRESS] = g_signal_new(
+			"key-press",
+			G_TYPE_FROM_CLASS(gobject_class),
+			G_SIGNAL_RUN_LAST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__POINTER,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_POINTER);
+
+	/**
+	 * GritsViewer::key-release:
+	 * @object: the object.
+	 * @event:  the GdkEventKey which triggered this signal
+	 *
+	 * The ::key-release signal is emitted when a key is released.
+	 */
+	signals[SIG_KEY_RELEASE] = g_signal_new(
+			"key-release",
+			G_TYPE_FROM_CLASS(gobject_class),
+			G_SIGNAL_RUN_LAST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__POINTER,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_POINTER);
+
+	/**
+	 * GritsViewer::motion:
+	 * @object: the object.
+	 * @event:  the GdkEventMotion which triggered this signal
+	 *
+	 * The ::motion signal is emitted the pointer moves over the object
+	 */
+	signals[SIG_MOTION] = g_signal_new(
+			"motion",
+			G_TYPE_FROM_CLASS(gobject_class),
+			G_SIGNAL_RUN_LAST,
+			0,
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__POINTER,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_POINTER);
 }
diff --git a/src/objects/grits-object.h b/src/objects/grits-object.h
index d7cd2b0..4390a41 100644
--- a/src/objects/grits-object.h
+++ b/src/objects/grits-object.h
@@ -78,6 +78,7 @@ void grits_object_hide(GritsObject *object, gboolean hidden);
 void grits_object_pick_begin(GritsObject *object, GritsOpenGL *opengl);
 void grits_object_pick_pointer(GritsObject *object, double x, double y);
 void grits_object_pick_end(GritsObject *object);
+void grits_object_event(GritsObject *object, GdkEvent *event);
 
 /**
  * grits_object_queue_draw:



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