From e8af1dabca07d2b7a26369d845a81efeae3e08a0 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Sun, 29 Apr 2012 03:40:20 +0000 Subject: [PATCH] Add cursor support to GritsObject --- src/grits-opengl.c | 19 ++++++++++++++++--- src/grits-viewer.c | 9 --------- src/objects/grits-object.c | 6 ++++++ src/objects/grits-object.h | 10 ++++++++++ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/grits-opengl.c b/src/grits-opengl.c index 172b606..a02e868 100644 --- a/src/grits-opengl.c +++ b/src/grits-opengl.c @@ -200,7 +200,8 @@ static gboolean on_configure(GritsOpenGL *opengl, GdkEventConfigure *event, gpoi return FALSE; } -static gint run_picking(GritsOpenGL *opengl, GdkEvent *event, GPtrArray *objects) +static gint run_picking(GritsOpenGL *opengl, GdkEvent *event, + GPtrArray *objects, GritsObject **top) { /* Setup picking buffers */ guint buffer[100][4] = {}; @@ -230,6 +231,7 @@ static gint run_picking(GritsOpenGL *opengl, GdkEvent *event, GPtrArray *objects guint index = buffer[i][3]; GritsObject *object = objects->pdata[index]; object->state.picked = TRUE; + *top = object; } /* Notify objects of pointer movements */ @@ -263,6 +265,7 @@ static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpo g_mutex_lock(opengl->objects_lock); + GritsObject *top = NULL; GPtrArray *ortho = _objects_to_array(opengl, TRUE); GPtrArray *world = _objects_to_array(opengl, FALSE); @@ -270,14 +273,24 @@ 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, (GdkEvent*)event, world); + gint world_hits = run_picking(opengl, (GdkEvent*)event, world, &top); /* 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, (GdkEvent*)event, ortho); + gint ortho_hits = run_picking(opengl, (GdkEvent*)event, ortho, &top); + + /* Update cursor */ + static GdkCursor *cursor = NULL; + static GdkWindow *window = NULL; + if (!window || !cursor) { + cursor = gdk_cursor_new(GDK_FLEUR); + window = gtk_widget_get_window(GTK_WIDGET(opengl)); + } + GdkCursor *topcursor = top && top->cursor ? top->cursor : cursor; + gdk_window_set_cursor(window, topcursor); 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/grits-viewer.c b/src/grits-viewer.c index f7d70e9..92f6e86 100644 --- a/src/grits-viewer.c +++ b/src/grits-viewer.c @@ -180,13 +180,6 @@ static void on_view_changed(GritsViewer *viewer, 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); -} - /*********** * Methods * ***********/ @@ -608,8 +601,6 @@ 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_finalize(GObject *gobject) { diff --git a/src/objects/grits-object.c b/src/objects/grits-object.c index e9a7a0a..a1e80ec 100644 --- a/src/objects/grits-object.c +++ b/src/objects/grits-object.c @@ -166,6 +166,12 @@ void grits_object_queue_draw(GritsObject *object) gtk_widget_queue_draw(GTK_WIDGET(object->viewer)); } +void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor) +{ + // Used by grits OpenGL + object->cursor = gdk_cursor_new(cursor); +} + /* Event handling */ void grits_object_pick(GritsObject *object, GritsOpenGL *opengl) { diff --git a/src/objects/grits-object.h b/src/objects/grits-object.h index 0b8cacb..9969278 100644 --- a/src/objects/grits-object.h +++ b/src/objects/grits-object.h @@ -57,6 +57,7 @@ struct _GritsObject { guint32 skip; // Bit mask of safe operations GritsState state; // Internal, used for picking + GdkCursor *cursor; // Internal, cached cursor }; struct _GritsObjectClass { @@ -88,6 +89,15 @@ gboolean grits_object_event(GritsObject *object, GdkEvent *event); */ void grits_object_queue_draw(GritsObject *object); +/** + * grits_object_set_cursor: + * @object: The #GritsObject to set the cursor for + * @cursor: The cursor to use when the object is hovered over + * + * Causes the cursor to use a particular icon when located over a given object + */ +void grits_object_set_cursor(GritsObject *object, GdkCursorType cursor); + /** * grits_object_center: * @object: The #GritsObject to get the center of -- 2.43.2