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] = {};
guint index = buffer[i][3];
GritsObject *object = objects->pdata[index];
object->state.picked = TRUE;
+ *top = object;
}
/* Notify objects of pointer movements */
g_mutex_lock(opengl->objects_lock);
+ GritsObject *top = NULL;
GPtrArray *ortho = _objects_to_array(opengl, TRUE);
GPtrArray *world = _objects_to_array(opengl, FALSE);
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);
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 *
***********/
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)
{
guint32 skip; // Bit mask of safe operations
GritsState state; // Internal, used for picking
+ GdkCursor *cursor; // Internal, cached cursor
};
struct _GritsObjectClass {
*/
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