From c480e5ec00d52b176bdda1b26d1dfee8aea3384f Mon Sep 17 00:00:00 2001 From: Elliot Smith Date: Fri, 20 Aug 2010 12:38:35 +0100 Subject: [PATCH] cookbook: Added example to show how stacking affects pointer events Added another example (used for a screenshot) to demonstrate how pointer events pass through non-reactive actors and how depth ordering affects whether an actor will emit a pointer motion signal. --- doc/cookbook/examples/Makefile.am | 2 + .../examples/events-pointer-motion-stacked.c | 90 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 doc/cookbook/examples/events-pointer-motion-stacked.c diff --git a/doc/cookbook/examples/Makefile.am b/doc/cookbook/examples/Makefile.am index 370b61b5f..4f28f1027 100644 --- a/doc/cookbook/examples/Makefile.am +++ b/doc/cookbook/examples/Makefile.am @@ -13,6 +13,7 @@ noinst_PROGRAMS = \ events-mouse-scroll \ events-pointer-motion \ events-pointer-motion-crossing \ + events-pointer-motion-stacked \ events-pointer-motion-scribbler \ $(NULL) @@ -45,6 +46,7 @@ layouts_stacking_diff_sized_actors_SOURCES = layouts-stacking-diff-sized-actors. events_mouse_scroll_SOURCES = events-mouse-scroll.c events_pointer_motion_SOURCES = events-pointer-motion.c events_pointer_motion_crossing_SOURCES = events-pointer-motion-crossing.c +events_pointer_motion_stacked_SOURCES = events-pointer-motion-stacked.c events_pointer_motion_scribbler_SOURCES = events-pointer-motion-scribbler.c -include $(top_srcdir)/build/autotools/Makefile.am.gitignore diff --git a/doc/cookbook/examples/events-pointer-motion-stacked.c b/doc/cookbook/examples/events-pointer-motion-stacked.c new file mode 100644 index 000000000..a71293102 --- /dev/null +++ b/doc/cookbook/examples/events-pointer-motion-stacked.c @@ -0,0 +1,90 @@ +/* + * Testing what happens with a stack of actors and pointer events + * red and green are reactive; blue is not + * + * when the pointer is over green (even if green is obscured by blue) + * signals are emitted by green (not by blue); + * + * but when the pointer is over the overlap between red and green, + * signals are emitted by green + * + * gcc -g -O0 -o stacked-actors-and-events stacked-actors-and-events.c `pkg-config --libs --cflags clutter-1.0 glib-2.0` -lm + */ +#include + +static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff }; +static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff }; +static const ClutterColor green = { 0x00, 0xff, 0x00, 0xff }; +static const ClutterColor blue = { 0x00, 0x00, 0xff, 0xff }; + +static gboolean +_pointer_motion_cb (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data) +{ + /* get the coordinates where the pointer crossed into the actor */ + gfloat stage_x, stage_y; + clutter_event_get_coords (event, &stage_x, &stage_y); + + /* + * as the coordinates are relative to the stage, rather than + * the actor which emitted the signal, it can be useful to + * transform them to actor-relative coordinates + */ + gfloat actor_x, actor_y; + clutter_actor_transform_stage_point (actor, + stage_x, stage_y, + &actor_x, &actor_y); + + g_debug ("pointer on actor %s @ x %.0f, y %.0f", + clutter_actor_get_name (actor), + actor_x, actor_y); + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage; + ClutterActor *r1, *r2, *r3; + + clutter_init (&argc, &argv); + + stage = clutter_stage_get_default (); + clutter_actor_set_size (stage, 300, 300); + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + + r1 = clutter_rectangle_new_with_color (&red); + clutter_actor_set_size (r1, 150, 150); + clutter_actor_add_constraint (r1, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.25)); + clutter_actor_add_constraint (r1, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.25)); + clutter_actor_set_reactive (r1, TRUE); + clutter_actor_set_name (r1, "red"); + + r2 = clutter_rectangle_new_with_color (&green); + clutter_actor_set_size (r2, 150, 150); + clutter_actor_add_constraint (r2, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); + clutter_actor_add_constraint (r2, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); + clutter_actor_set_reactive (r2, TRUE); + clutter_actor_set_depth (r2, -100); + clutter_actor_set_name (r2, "green"); + + r3 = clutter_rectangle_new_with_color (&blue); + clutter_actor_set_size (r3, 150, 150); + clutter_actor_add_constraint (r3, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.75)); + clutter_actor_add_constraint (r3, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.75)); + clutter_actor_set_opacity (r3, 125.5); + clutter_actor_set_name (r3, "blue"); + + clutter_container_add (CLUTTER_CONTAINER (stage), r1, r2, r3, NULL); + + g_signal_connect (r1, "motion-event", G_CALLBACK (_pointer_motion_cb), NULL); + g_signal_connect (r2, "motion-event", G_CALLBACK (_pointer_motion_cb), NULL); + + clutter_actor_show (stage); + + clutter_main (); + + return 0; +}