diff --git a/doc/cookbook/examples/Makefile.am b/doc/cookbook/examples/Makefile.am index e88a9dcbb..624ddad94 100644 --- a/doc/cookbook/examples/Makefile.am +++ b/doc/cookbook/examples/Makefile.am @@ -12,6 +12,7 @@ noinst_PROGRAMS = \ layouts-stacking-diff-sized-actors \ events-mouse-scroll \ events-pointer-motion-crossing \ + events-pointer-motion-scribbler \ $(NULL) INCLUDES = \ @@ -42,5 +43,6 @@ layouts_stacking_SOURCES = layouts-stacking.c layouts_stacking_diff_sized_actors_SOURCES = layouts-stacking-diff-sized-actors.c events_mouse_scroll_SOURCES = events-mouse-scroll.c events_pointer_motion_crossing_SOURCES = events-pointer-motion-crossing.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-scribbler.c b/doc/cookbook/examples/events-pointer-motion-scribbler.c new file mode 100644 index 000000000..4dfd3805b --- /dev/null +++ b/doc/cookbook/examples/events-pointer-motion-scribbler.c @@ -0,0 +1,160 @@ +/* + * Simple scribble application: move mouse over the dark yellow + * rectangle to draw brighter yellow lines + */ +#include + +static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff }; +static const ClutterColor actor_color = { 0xaa, 0x99, 0x00, 0xff }; + +typedef struct { + ClutterPath *path; + CoglPath *cogl_path; +} Context; + +static void +convert_clutter_path_node_to_cogl_path (const ClutterPathNode *node, + gpointer data) +{ + g_return_if_fail (node != NULL); + + ClutterKnot knot; + + switch (node->type) + { + case CLUTTER_PATH_MOVE_TO: + knot = node->points[0]; + cogl_path_move_to (knot.x, knot.y); + g_debug ("move to %d, %d", knot.x, knot.y); + break; + case CLUTTER_PATH_LINE_TO: + knot = node->points[0]; + cogl_path_line_to (knot.x, knot.y); + g_debug ("line to %d, %d", knot.x, knot.y); + break; + default: + break; + } +} + +static void +_paint_cb (ClutterActor *actor, + gpointer user_data) +{ + Context *context = (Context *)user_data; + + cogl_set_source_color4ub (255, 255, 0, 255); + + cogl_set_path (context->cogl_path); + + clutter_path_foreach (context->path, convert_clutter_path_node_to_cogl_path, NULL); + + cogl_path_stroke_preserve (); + + clutter_path_clear (context->path); + + context->cogl_path = cogl_get_path (); + + g_signal_stop_emission_by_name (actor, "paint"); +} + +static gboolean +_motion_cb (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data) +{ + ClutterMotionEvent *motion_event = (ClutterMotionEvent *)event; + Context *context = (Context *)user_data; + + gfloat x, y; + clutter_actor_transform_stage_point (actor, motion_event->x, motion_event->y, &x, &y); + + g_debug ("motion; x %f, y %f", x, y); + + clutter_path_add_line_to (context->path, x, y); + + clutter_actor_queue_redraw (actor); + + return TRUE; +} + +static gboolean +_enter_cb (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data) +{ + ClutterCrossingEvent *cross_event = (ClutterCrossingEvent *)event; + Context *context = (Context *)user_data; + + gfloat x, y; + clutter_actor_transform_stage_point (actor, cross_event->x, cross_event->y, &x, &y); + + g_debug ("enter; x %f, y %f", x, y); + + clutter_path_add_move_to (context->path, x, y); + + clutter_actor_queue_redraw (actor); + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + Context *context = g_new0 (Context, 1); + + ClutterActor *stage; + ClutterActor *rect; + ClutterActor *canvas; + + clutter_init (&argc, &argv); + + context->path = clutter_path_new (); + + cogl_path_new (); + context->cogl_path = cogl_get_path (); + + stage = clutter_stage_get_default (); + clutter_actor_set_size (stage, 400, 400); + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + + rect = clutter_rectangle_new_with_color (&actor_color); + clutter_actor_set_size (rect, 300, 300); + clutter_actor_add_constraint (rect, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); + clutter_actor_add_constraint (rect, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); + + clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect); + + canvas = clutter_texture_new (); + clutter_actor_set_size (canvas, 300, 300); + clutter_actor_add_constraint (canvas, clutter_align_constraint_new (rect, CLUTTER_ALIGN_X_AXIS, 0.0)); + clutter_actor_add_constraint (canvas, clutter_align_constraint_new (rect, CLUTTER_ALIGN_Y_AXIS, 0.0)); + clutter_actor_set_reactive (canvas, TRUE); + + clutter_container_add_actor (CLUTTER_CONTAINER (stage), canvas); + clutter_actor_raise_top (canvas); + + g_signal_connect (canvas, + "motion-event", + G_CALLBACK (_motion_cb), + context); + + g_signal_connect (canvas, + "enter-event", + G_CALLBACK (_enter_cb), + context); + + g_signal_connect (canvas, + "paint", + G_CALLBACK (_paint_cb), + context); + + clutter_actor_show (stage); + + clutter_main (); + + g_object_unref (context->path); + g_free (context); + + return 0; +}