diff --git a/ChangeLog b/ChangeLog index bebd99657..a4a1b1e63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-06-05 Emmanuele Bassi + + * tests/Makefile.am: + * tests/test-paint-wrapper.c: Add a test case (merely, a copy + of test-actors.c) that verifies that handlers to the ::paint + signal are called in the right order. + 2008-06-05 Emmanuele Bassi Bug #840 - Implement prepare-paint and finish-paint signals. diff --git a/tests/Makefile.am b/tests/Makefile.am index f70be79a5..586579b42 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,7 +12,7 @@ noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \ test-cogl-tex-convert test-cogl-tex-foreign \ test-cogl-tex-getset test-cogl-offscreen \ test-cogl-tex-polygon test-stage-read-pixels \ - test-random-text test-clip + test-random-text test-clip test-paint-wrapper if X11_TESTS noinst_PROGRAMS += test-pixmap @@ -63,5 +63,6 @@ test_cogl_tex_getset_SOURCES = test-cogl-tex-getset.c test_cogl_offscreen_SOURCES = test-cogl-offscreen.c test_stage_read_pixels_SOURCES = test-stage-read-pixels.c test_random_text_SOURCES = test-random-text.c +test_paint_wrapper_SOURCES = test-paint-wrapper.c EXTRA_DIST = redhand.png test-script.json diff --git a/tests/test-paint-wrapper.c b/tests/test-paint-wrapper.c new file mode 100644 index 000000000..bf3692525 --- /dev/null +++ b/tests/test-paint-wrapper.c @@ -0,0 +1,297 @@ +#include + +#if defined (_MSC_VER) && !defined (_USE_MATH_DEFINES) +#define _USE_MATH_DEFINES +#endif + +#include +#include +#include +#include + +#define TRAILS 0 +#define NHANDS 6 +#define RADIUS ((CLUTTER_STAGE_WIDTH()+CLUTTER_STAGE_HEIGHT())/NHANDS) + +typedef struct SuperOH +{ + ClutterActor **hand, *bgtex; + ClutterActor *group; + +} SuperOH; + +static gint n_hands = NHANDS; + +static GOptionEntry super_oh_entries[] = { + { + "num-hands", 'n', + 0, + G_OPTION_ARG_INT, &n_hands, + "Number of hands", "HANDS" + }, + { NULL } +}; + +static gint +get_radius (void) +{ + return (CLUTTER_STAGE_HEIGHT() + CLUTTER_STAGE_HEIGHT()) / n_hands ; +} + +/* input handler */ +static gboolean +input_cb (ClutterStage *stage, + ClutterEvent *event, + gpointer data) +{ + if (event->type == CLUTTER_BUTTON_PRESS) + { + ClutterButtonEvent *button_event; + ClutterActor *e; + gint x, y; + + clutter_event_get_coords (event, &x, &y); + + button_event = (ClutterButtonEvent *) event; + g_print ("*** button press event (button:%d) ***\n", + button_event->button); + + e = clutter_stage_get_actor_at_pos (stage, x, y); + + if (e && (CLUTTER_IS_TEXTURE (e) || CLUTTER_IS_CLONE_TEXTURE (e))) + { + clutter_actor_hide (e); + return TRUE; + } + } + else if (event->type == CLUTTER_KEY_RELEASE) + { + ClutterKeyEvent *kev = (ClutterKeyEvent *) event; + + g_print ("*** key press event (key:%c) ***\n", + clutter_key_event_symbol (kev)); + + if (clutter_key_event_symbol (kev) == CLUTTER_q) + { + clutter_main_quit (); + return TRUE; + } + } + + return FALSE; +} + + +/* Timeline handler */ +static void +frame_cb (ClutterTimeline *timeline, + gint frame_num, + gpointer data) +{ + SuperOH *oh = (SuperOH *)data; + gint i; + + /* Rotate everything clockwise about stage center*/ + + clutter_actor_set_rotation (CLUTTER_ACTOR (oh->group), + CLUTTER_Z_AXIS, + frame_num, + CLUTTER_STAGE_WIDTH () / 2, + CLUTTER_STAGE_HEIGHT () / 2, + 0); + + for (i = 0; i < n_hands; i++) + { + gdouble scale_x, scale_y; + + clutter_actor_get_scale (oh->hand[i], &scale_x, &scale_y); + + /* Rotate each hand around there centers - to get this we need + * to take into account any scaling. + * + * FIXME: scaling causes drift so disabled for now. Need rotation + * unit based functions to fix. + */ + clutter_actor_set_rotation (oh->hand[i], CLUTTER_Z_AXIS, + - 6.0 * frame_num, 0, 0, 0); + } +} + +static gboolean hand_pre_paint_guard = FALSE; + +static void +hand_pre_paint (ClutterActor *actor, + gpointer user_data) +{ + ClutterColor red = { 255, 0, 0, 128 }; + gint w, h; + + g_assert (hand_pre_paint_guard == FALSE); + + clutter_actor_get_size (actor, &w, &h); + + cogl_color (&red); + cogl_rectangle (0, 0, w / 2, h / 2); + + hand_pre_paint_guard = TRUE; +} + +static void +hand_post_paint (ClutterActor *actor, + gpointer user_data) +{ + ClutterColor green = { 0, 255, 0, 128 }; + gint w, h; + + g_assert (hand_pre_paint_guard == TRUE); + + clutter_actor_get_size (actor, &w, &h); + + cogl_color (&green); + cogl_rectangle (w / 2, h / 2, w / 2, h / 2); + + hand_pre_paint_guard = FALSE; +} + +int +main (int argc, char *argv[]) +{ + ClutterTimeline *timeline; + ClutterAlpha *alpha; + ClutterBehaviour *scaler_1, *scaler_2; + ClutterActor *stage; + ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; + SuperOH *oh; + gint i; + GError *error; + + error = NULL; + + clutter_init_with_args (&argc, &argv, + NULL, + super_oh_entries, + NULL, + &error); + if (error) + { + g_warning ("Unable to initialise Clutter:\n%s", + error->message); + g_error_free (error); + + exit (1); + } + + stage = clutter_stage_get_default (); + clutter_actor_set_size (stage, 800, 600); + + clutter_stage_set_title (CLUTTER_STAGE (stage), "Actors Test"); + clutter_stage_set_color (CLUTTER_STAGE (stage), + &stage_color); + + oh = g_new(SuperOH, 1); + + /* Create a timeline to manage animation */ + timeline = clutter_timeline_new (360, 60); /* num frames, fps */ + g_object_set (timeline, "loop", TRUE, NULL); /* have it loop */ + + /* fire a callback for frame change */ + g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh); + + /* Set up some behaviours to handle scaling */ + alpha = clutter_alpha_new_full (timeline, CLUTTER_ALPHA_SINE, NULL, NULL); + + scaler_1 = clutter_behaviour_scale_new (alpha, + 0.5, 0.5, + 1.0, 1.0); + + scaler_2 = clutter_behaviour_scale_new (alpha, + 1.0, 1.0, + 0.5, 0.5); + + /* create a new group to hold multiple actors in a group */ + oh->group = clutter_group_new(); + + oh->hand = g_new (ClutterActor*, n_hands); + for (i = 0; i < n_hands; i++) + { + gint x, y, w, h; + gint radius = get_radius (); + + /* Create a texture from file, then clone in to same resources */ + if (i == 0) + { + if ((oh->hand[i] = clutter_texture_new_from_file ("redhand.png", + &error)) == NULL) + { + g_error ("image load failed: %s", error->message); + exit (1); + } + } + else + oh->hand[i] = clutter_clone_texture_new (CLUTTER_TEXTURE(oh->hand[0])); + + /* paint something before each hand */ + g_signal_connect (oh->hand[i], + "paint", G_CALLBACK (hand_pre_paint), + NULL); + + /* paint something after each hand */ + g_signal_connect_after (oh->hand[i], + "paint", G_CALLBACK (hand_post_paint), + NULL); + + /* Place around a circle */ + w = clutter_actor_get_width (oh->hand[0]); + h = clutter_actor_get_height (oh->hand[0]); + + x = CLUTTER_STAGE_WIDTH () / 2 + + radius + * cos (i * M_PI / (n_hands / 2)) + - w / 2; + + y = CLUTTER_STAGE_HEIGHT () / 2 + + radius + * sin (i * M_PI / (n_hands / 2)) + - h / 2; + + clutter_actor_set_position (oh->hand[i], x, y); + + clutter_actor_move_anchor_point_from_gravity (oh->hand[i], + CLUTTER_GRAVITY_CENTER); + + /* Add to our group group */ + clutter_container_add_actor (CLUTTER_CONTAINER (oh->group), oh->hand[i]); + +#if 1 /* FIXME: disabled as causes drift? - see comment above */ + if (i % 2) + clutter_behaviour_apply (scaler_1, oh->hand[i]); + else + clutter_behaviour_apply (scaler_2, oh->hand[i]); +#endif + } + + /* Add the group to the stage */ + clutter_container_add_actor (CLUTTER_CONTAINER (stage), + CLUTTER_ACTOR (oh->group)); + + /* Show everying ( and map window ) */ + clutter_actor_show (stage); + + + g_signal_connect (stage, "button-press-event", + G_CALLBACK (input_cb), + oh); + g_signal_connect (stage, "key-release-event", + G_CALLBACK (input_cb), + oh); + + /* and start it */ + clutter_timeline_start (timeline); + + clutter_main (); + + g_free (oh->hand); + g_free (oh); + + return 0; +}