void meta_compositor_flash_window (MetaCompositor *compositor, MetaWindow *window) { ClutterActor *window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); ClutterActor *flash; ClutterTransition *transition; flash = clutter_actor_new (); clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black); clutter_actor_set_size (flash, window->rect.width, window->rect.height); clutter_actor_set_position (flash, window->custom_frame_extents.left, window->custom_frame_extents.top); clutter_actor_set_opacity (flash, 0); clutter_actor_add_child (window_actor, flash); clutter_actor_save_easing_state (flash); clutter_actor_set_easing_mode (flash, CLUTTER_EASE_IN_QUAD); clutter_actor_set_easing_duration (flash, FLASH_TIME_MS); clutter_actor_set_opacity (flash, 192); transition = clutter_actor_get_transition (flash, "opacity"); clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2); g_signal_connect (transition, "stopped", G_CALLBACK (window_flash_out_completed), flash); clutter_actor_restore_easing_state (flash); }
void meta_compositor_flash_screen (MetaCompositor *compositor, MetaScreen *screen) { ClutterActor *stage; ClutterActor *flash; ClutterTransition *transition; gfloat width, height; stage = meta_get_stage_for_screen (screen); clutter_actor_get_size (stage, &width, &height); flash = clutter_actor_new (); clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black); clutter_actor_set_size (flash, width, height); clutter_actor_set_opacity (flash, 0); clutter_actor_add_child (stage, flash); clutter_actor_save_easing_state (flash); clutter_actor_set_easing_mode (flash, CLUTTER_EASE_IN_QUAD); clutter_actor_set_easing_duration (flash, FLASH_TIME_MS); clutter_actor_set_opacity (flash, 192); transition = clutter_actor_get_transition (flash, "opacity"); clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2); g_signal_connect (transition, "stopped", G_CALLBACK (flash_out_completed), flash); clutter_actor_restore_easing_state (flash); }
G_MODULE_EXPORT int test_cairo_flowers_main (int argc, char **argv) { Flower *flowers[N_FLOWERS]; ClutterTimeline *timeline; int i; srand (time (NULL)); if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; /* Create a timeline to manage animation */ timeline = clutter_timeline_new (6000); clutter_timeline_set_repeat_count (timeline, -1); stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Cairo Flowers"); g_signal_connect (stage, "destroy", G_CALLBACK (stop_and_quit), timeline); clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black); for (i=0; i< N_FLOWERS; i++) { flowers[i] = g_new0(Flower, 1); flowers[i]->ctex = make_flower_actor(); flowers[i]->x = rand() % (int) clutter_actor_get_width (stage) - (PETAL_MIN + PETAL_VAR) * 2; flowers[i]->y = rand() % (int) clutter_actor_get_height (stage); flowers[i]->rv = rand() % 5 + 1; flowers[i]->v = rand() % 10 + 2; clutter_container_add_actor (CLUTTER_CONTAINER (stage), flowers[i]->ctex); clutter_actor_set_position (flowers[i]->ctex, flowers[i]->x, flowers[i]->y); } /* fire a callback for frame change */ g_signal_connect (timeline, "new-frame", G_CALLBACK (tick), flowers); clutter_actor_show (stage); clutter_timeline_start (timeline); g_signal_connect (stage, "key-press-event", G_CALLBACK (clutter_main_quit), NULL); clutter_main(); g_object_unref (timeline); return EXIT_SUCCESS; }
static ClutterTransition * create_fade_out_transition() { auto transition = clutter_property_transition_new("opacity"); clutter_transition_set_from(transition, G_TYPE_UINT, 255); clutter_transition_set_to(transition, G_TYPE_UINT, 0); clutter_timeline_set_duration(CLUTTER_TIMELINE(transition), FADE_DURATION); clutter_timeline_set_repeat_count(CLUTTER_TIMELINE(transition), 0); clutter_timeline_set_progress_mode(CLUTTER_TIMELINE(transition), CLUTTER_EASE_IN_OUT_CUBIC); return transition; }
G_MODULE_EXPORT int test_keyframe_transition_main (int argc, char *argv[]) { ClutterActor *stage; int i; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Keyframe Transitions"); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); for (i = 0; i < 3; i++) { ClutterTransition *transition, *group; ClutterActor *rect; float cur_x, cur_y; float new_x, new_y; gchar *name; cur_x = PADDING; cur_y = PADDING + ((SIZE + PADDING) * i); new_x = clutter_actor_get_width (stage) - PADDING - SIZE; new_y = g_random_double_range (PADDING, clutter_actor_get_height (stage) - PADDING - SIZE); name = g_strdup_printf ("rect%02d", i); rect = clutter_actor_new (); clutter_actor_set_name (rect, name); clutter_actor_set_background_color (rect, &colors[i]); clutter_actor_set_size (rect, SIZE, SIZE); clutter_actor_set_position (rect, PADDING, cur_y); clutter_actor_add_child (stage, rect); group = clutter_transition_group_new (); clutter_timeline_set_duration (CLUTTER_TIMELINE (group), 2000); clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (group), 1); clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (group), TRUE); transition = clutter_keyframe_transition_new ("x"); clutter_transition_set_from (transition, G_TYPE_FLOAT, cur_x); clutter_transition_set_to (transition, G_TYPE_FLOAT, new_x); clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (transition), G_TYPE_FLOAT, 1, 0.5, new_x / 2.0f, CLUTTER_EASE_OUT_EXPO); clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), transition); g_object_unref (transition); transition = clutter_keyframe_transition_new ("y"); clutter_transition_set_from (transition, G_TYPE_FLOAT, cur_y); clutter_transition_set_to (transition, G_TYPE_FLOAT, cur_y); clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (transition), G_TYPE_FLOAT, 1, 0.5, new_y, CLUTTER_EASE_OUT_EXPO); clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), transition); g_object_unref (transition); clutter_actor_add_transition (rect, "rectAnimation", group); g_signal_connect (rect, "transition-stopped", G_CALLBACK (on_transition_stopped), NULL); g_object_unref (group); g_free (name); } clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { ClutterTimeline *timeline; ClutterActor *stage; GtkWidget *window, *stack, *clutter; GtkWidget *label, *button, *vbox; GdkPixbuf *pixbuf; SuperOH *oh; gint i; GError *error; error = NULL; if (gtk_clutter_init_with_args (&argc, &argv, NULL, NULL, NULL, &error) != CLUTTER_INIT_SUCCESS) { if (error) { g_critical ("Unable to initialize Clutter-GTK: %s", error->message); g_error_free (error); return EXIT_FAILURE; } else g_error ("Unable to initialize Clutter-GTK"); } /* calling gtk_clutter_init* multiple times should be safe */ g_assert (gtk_clutter_init (NULL, NULL) == CLUTTER_INIT_SUCCESS); pixbuf = gdk_pixbuf_new_from_file (EXAMPLES_DATADIR G_DIR_SEPARATOR_S "redhand.png", NULL); if (!pixbuf) g_error("pixbuf load failed"); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), WINWIDTH, WINHEIGHT); gtk_window_set_title (GTK_WINDOW (window), "Clutter Embedding"); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); vbox = gtk_grid_new (); gtk_orientable_set_orientation (GTK_ORIENTABLE (vbox), GTK_ORIENTATION_VERTICAL); gtk_widget_set_hexpand (vbox, TRUE); gtk_widget_set_vexpand (vbox, TRUE); gtk_container_add (GTK_CONTAINER (window), vbox); stack = gtk_stack_new (); gtk_container_add (GTK_CONTAINER (vbox), stack); label = gtk_label_new ("This is a label in a stack"); gtk_stack_add_named (GTK_STACK (stack), label, "label"); clutter = gtk_clutter_embed_new (); gtk_stack_add_named (GTK_STACK (stack), clutter, "clutter"); gtk_widget_realize (clutter); stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (clutter)); clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); label = gtk_label_new ("This is a label"); gtk_container_add (GTK_CONTAINER (vbox), label); gtk_widget_set_hexpand (label, TRUE); button = gtk_button_new_with_label ("This is a button...clicky"); g_signal_connect (button, "clicked", G_CALLBACK (clickity), stack); gtk_container_add (GTK_CONTAINER (vbox), button); gtk_widget_set_hexpand (button, TRUE); button = gtk_button_new_with_mnemonic ("_Fullscreen"); g_signal_connect (button, "clicked", G_CALLBACK (on_fullscreen), window); gtk_container_add (GTK_CONTAINER (vbox), button); gtk_widget_set_hexpand (button, TRUE); button = gtk_button_new_with_mnemonic ("_Quit"); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window); gtk_container_add (GTK_CONTAINER (vbox), button); gtk_widget_set_hexpand (button, TRUE); oh = g_new (SuperOH, 1); oh->stage = stage; oh->group = clutter_actor_new (); clutter_actor_set_pivot_point (oh->group, 0.5, 0.5); for (i = 0; i < NHANDS; i++) { gint x, y, w, h; /* Create a texture from pixbuf, then clone in to same resources */ if (i == 0) { oh->hand[i] = gtk_clutter_texture_new (); gtk_clutter_texture_set_from_pixbuf (GTK_CLUTTER_TEXTURE (oh->hand[i]), pixbuf, NULL); } else oh->hand[i] = clutter_clone_new (oh->hand[0]); /* Place around a circle */ w = clutter_actor_get_width (oh->hand[0]); h = clutter_actor_get_height (oh->hand[0]); x = WINWIDTH / 2 + RADIUS * cos (i * M_PI / (NHANDS / 2)) - w / 2; y = WINHEIGHT / 2 + RADIUS * sin (i * M_PI / (NHANDS / 2)) - h / 2; clutter_actor_set_position (oh->hand[i], x, y); clutter_actor_set_pivot_point (oh->hand[i], 0.5, 0.5); /* Add to our group group */ clutter_actor_add_child (oh->group, oh->hand[i]); } /* Add the group to the stage */ clutter_actor_add_child (stage, oh->group); clutter_actor_add_constraint (oh->group, clutter_align_constraint_new (oh->stage, CLUTTER_ALIGN_BOTH, 0.5)); g_signal_connect (stage, "button-press-event", G_CALLBACK (input_cb), oh); g_signal_connect (stage, "key-release-event", G_CALLBACK (input_cb), oh); gtk_widget_show_all (window); /* Create a timeline to manage animation */ timeline = clutter_timeline_new (6000); clutter_timeline_set_repeat_count (timeline, -1); /* fire a callback for frame change */ g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh); /* and start it */ clutter_timeline_start (timeline); gtk_main (); return 0; }
G_MODULE_EXPORT int test_scale_main (int argc, char *argv[]) { ClutterActor *stage, *rect; ClutterColor rect_color = { 0xff, 0xff, 0xff, 0x99 }; ClutterTimeline *timeline; ClutterAlpha *alpha; ClutterBehaviour *behave; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Scaling"); clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black); clutter_actor_set_size (stage, 300, 300); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); rect = clutter_rectangle_new_with_color (&rect_color); clutter_actor_set_size (rect, 100, 100); clutter_actor_set_position (rect, 100, 100); clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect); label = clutter_text_new_with_text ("Sans 20px", ""); clutter_text_set_color (CLUTTER_TEXT (label), CLUTTER_COLOR_White); clutter_actor_set_position (label, clutter_actor_get_x (rect), clutter_actor_get_y (rect) + clutter_actor_get_height (rect)); clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); rect_color.alpha = 0xff; rect = clutter_rectangle_new_with_color (&rect_color); clutter_actor_set_position (rect, 100, 100); clutter_actor_set_size (rect, 100, 100); set_next_gravity (rect); clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect); timeline = clutter_timeline_new (750); alpha = clutter_alpha_new_with_func (timeline, my_ramp_func, NULL, NULL); behave = clutter_behaviour_scale_new (alpha, 0.0, 0.0, /* scale start */ 1.0, 1.0); /* scale end */ clutter_behaviour_apply (behave, rect); clutter_timeline_set_repeat_count (timeline, -1); g_signal_connect_swapped (timeline, "completed", G_CALLBACK (set_next_gravity), rect); clutter_timeline_start (timeline); clutter_actor_show_all (stage); clutter_main(); g_object_unref (timeline); g_object_unref (behave); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { ClutterActor *stage, *actor; ClutterContent *canvas; ClutterTransition *transition; /* initialize Clutter */ if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; /* create a stage */ stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Rectangle with rounded corners"); clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black); clutter_actor_set_size (stage, 500, 500); clutter_actor_show (stage); /* our 2D canvas, courtesy of Cairo */ canvas = clutter_canvas_new (); clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 300, 300); /* the actor that will display the contents of the canvas */ actor = clutter_actor_new (); clutter_actor_set_content (actor, canvas); clutter_actor_set_content_gravity (actor, CLUTTER_CONTENT_GRAVITY_CENTER); clutter_actor_set_content_scaling_filters (actor, CLUTTER_SCALING_FILTER_TRILINEAR, CLUTTER_SCALING_FILTER_LINEAR); clutter_actor_set_pivot_point (actor, 0.5f, 0.5f); clutter_actor_add_constraint (actor, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); clutter_actor_set_request_mode (actor, CLUTTER_REQUEST_CONTENT_SIZE); clutter_actor_add_child (stage, actor); /* the actor now owns the canvas */ g_object_unref (canvas); /* create the continuous animation of the actor spinning around its center */ transition = clutter_property_transition_new ("rotation-angle-y"); clutter_transition_set_from (transition, G_TYPE_DOUBLE, 0.0); clutter_transition_set_to (transition, G_TYPE_DOUBLE, 360.0); clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 2000); clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), -1); clutter_actor_add_transition (actor, "rotateActor", transition); /* the actor now owns the transition */ g_object_unref (transition); /* quit on destroy */ g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); /* connect our drawing code */ g_signal_connect (canvas, "draw", G_CALLBACK (draw_content), NULL); /* invalidate the canvas, so that we can draw before the main loop starts */ clutter_content_invalidate (canvas); clutter_main (); return EXIT_SUCCESS; }
static void set_up_stage (CalibArea *calib_area, ClutterActor *stage) { ClutterPoint anchor; ClutterColor color; ClutterContent *success_content; gfloat height; gchar *markup; calib_area->stage = stage; calib_area->action_layer = clutter_actor_new (); calib_area->clock = cc_clock_actor_new (); calib_area->target = cc_target_actor_new (); calib_area->text_title_holder = clutter_actor_new (); calib_area->helper_text_title = clutter_text_new (); calib_area->text_body_holder = clutter_actor_new (); calib_area->helper_text_body = clutter_text_new (); calib_area->error_text = clutter_text_new (); calib_area->success_image = clutter_actor_new (); clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE); clutter_actor_hide (calib_area->target); /* bind the action layer's geometry to the stage's */ clutter_actor_add_constraint (calib_area->action_layer, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0)); clutter_actor_add_child (stage, calib_area->action_layer); g_signal_connect (stage, "allocation-changed", G_CALLBACK (on_allocation_changed), calib_area); clutter_color_from_string (&color, "#000"); color.alpha = WINDOW_OPACITY * 255; clutter_actor_set_background_color (stage, &color); clutter_actor_add_child (calib_area->action_layer, calib_area->clock); clutter_actor_add_constraint (calib_area->clock, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); clutter_actor_add_child (calib_area->action_layer, calib_area->target); /* set the helper text */ anchor.x = 0; g_object_set (calib_area->text_title_holder, "pivot-point", &anchor, NULL); clutter_actor_add_child (calib_area->action_layer, calib_area->text_title_holder); clutter_actor_add_child (calib_area->text_title_holder, calib_area->helper_text_title); height = clutter_actor_get_height (calib_area->clock); clutter_actor_add_constraint (calib_area->text_title_holder, clutter_bind_constraint_new (calib_area->clock, CLUTTER_BIND_Y, height * 1.5)); clutter_actor_add_constraint (calib_area->text_title_holder, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, .5)); clutter_text_set_line_alignment (CLUTTER_TEXT (calib_area->helper_text_title), PANGO_ALIGN_CENTER); color.red = COLOR_GRAY; color.green = COLOR_GRAY; color.blue = COLOR_GRAY; color.alpha = 255; markup = g_strdup_printf ("<big><b>%s</b></big>", _(HELP_TEXT_TITLE)); clutter_text_set_markup (CLUTTER_TEXT (calib_area->helper_text_title), markup); clutter_text_set_color (CLUTTER_TEXT (calib_area->helper_text_title), &color); g_free (markup); g_object_set (calib_area->text_body_holder, "pivot-point", &anchor, NULL); clutter_actor_add_child (calib_area->action_layer, calib_area->text_body_holder); clutter_actor_add_child (calib_area->text_body_holder, calib_area->helper_text_body); height = clutter_actor_get_height (calib_area->helper_text_title); clutter_actor_add_constraint (calib_area->text_body_holder, clutter_bind_constraint_new (calib_area->text_title_holder, CLUTTER_BIND_Y, height * 1.2)); clutter_actor_add_constraint (calib_area->text_body_holder, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, .5)); clutter_text_set_line_alignment (CLUTTER_TEXT (calib_area->helper_text_body), PANGO_ALIGN_CENTER); markup = g_strdup_printf ("<span foreground=\"white\"><big>%s</big></span>", _(HELP_TEXT_MAIN)); clutter_text_set_markup (CLUTTER_TEXT (calib_area->helper_text_body), markup); g_free (markup); /* set the error text */ g_object_set (calib_area->error_text, "pivot-point", &anchor, NULL); clutter_actor_add_child (calib_area->action_layer, calib_area->error_text); height = clutter_actor_get_height (calib_area->helper_text_body); clutter_actor_add_constraint (calib_area->error_text, clutter_bind_constraint_new (calib_area->text_title_holder, CLUTTER_BIND_Y, height * 3)); clutter_actor_add_constraint (calib_area->error_text, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, .5)); clutter_text_set_line_alignment (CLUTTER_TEXT (calib_area->error_text), PANGO_ALIGN_CENTER); markup = g_strdup_printf ("<span foreground=\"white\"><big>" "<b>%s</b></big></span>", ERROR_MESSAGE); clutter_text_set_markup (CLUTTER_TEXT (calib_area->error_text), markup); g_free (markup); clutter_actor_hide (calib_area->error_text); /* configure success image */ success_content = clutter_image_new (); clutter_actor_set_content (calib_area->success_image, success_content); g_object_unref (success_content); clutter_actor_add_child (stage, calib_area->success_image); clutter_actor_add_constraint (calib_area->success_image, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, .5)); /* animate clock */ calib_area->clock_timeline = clutter_property_transition_new ("angle"); clutter_timeline_set_progress_mode (CLUTTER_TIMELINE (calib_area->clock_timeline), CLUTTER_LINEAR); clutter_timeline_set_duration (CLUTTER_TIMELINE (calib_area->clock_timeline), MAX_TIME); clutter_transition_set_animatable (calib_area->clock_timeline, CLUTTER_ANIMATABLE (calib_area->clock)); clutter_transition_set_from (calib_area->clock_timeline, G_TYPE_FLOAT, .0); clutter_transition_set_to (calib_area->clock_timeline, G_TYPE_FLOAT, 360.0); clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (calib_area->clock_timeline), -1); clutter_timeline_start (CLUTTER_TIMELINE (calib_area->clock_timeline)); g_signal_connect (CLUTTER_TIMELINE (calib_area->clock_timeline), "completed", G_CALLBACK (on_timeout), calib_area); g_signal_connect (stage, "button-press-event", G_CALLBACK (on_button_press_event), calib_area); g_signal_connect (stage, "key-release-event", G_CALLBACK (on_key_release_event), calib_area); }
G_MODULE_EXPORT int test_paint_wrapper_main (int argc, char *argv[]) { ClutterAlpha *alpha; ClutterActor *stage; ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; SuperOH *oh; gint i; GError *error; ClutterActor *real_hand; error = NULL; #ifdef CLUTTER_WINDOWING_X11 clutter_x11_set_use_argb_visual (TRUE); #endif if (clutter_init_with_args (&argc, &argv, NULL, super_oh_entries, NULL, &error) != CLUTTER_INIT_SUCCESS) { g_warning ("Unable to initialise Clutter:\n%s", error->message); g_error_free (error); return EXIT_FAILURE; } oh = g_new(SuperOH, 1); stage = clutter_stage_new (); clutter_actor_set_size (stage, 800, 600); if (use_alpha != 255) { clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_opacity (stage, use_alpha); } clutter_stage_set_title (CLUTTER_STAGE (stage), "Paint Test"); clutter_actor_set_background_color (stage, &stage_color); g_signal_connect (stage, "destroy", G_CALLBACK (stop_and_quit), oh); oh->stage = stage; /* Create a timeline to manage animation */ oh->timeline = clutter_timeline_new (6000); clutter_timeline_set_repeat_count (oh->timeline, -1); /* fire a callback for frame change */ oh->frame_id = g_signal_connect (oh->timeline, "new-frame", G_CALLBACK (frame_cb), oh); /* Set up some behaviours to handle scaling */ alpha = clutter_alpha_new_with_func (oh->timeline, my_sine_wave, NULL, NULL); oh->scaler_1 = clutter_behaviour_scale_new (alpha, 0.5, 0.5, 1.0, 1.0); oh->scaler_2 = clutter_behaviour_scale_new (alpha, 1.0, 1.0, 0.5, 0.5); real_hand = clutter_texture_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", &error); if (real_hand == NULL) { g_error ("image load failed: %s", error->message); return EXIT_FAILURE; } /* create a new group to hold multiple actors in a group */ oh->group = clutter_group_new(); oh->hand = g_new (ClutterActor*, n_hands); oh->stage_width = clutter_actor_get_width (stage); oh->stage_height = clutter_actor_get_height (stage); oh->radius = (oh->stage_width + oh->stage_height) / n_hands; for (i = 0; i < n_hands; i++) { gint x, y, w, h; if (i == 0) oh->hand[i] = real_hand; else oh->hand[i] = clutter_clone_new (real_hand); clutter_actor_set_reactive (oh->hand[i], TRUE); clutter_actor_set_size (oh->hand[i], 200, 213); /* Place around a circle */ w = clutter_actor_get_width (oh->hand[i]); h = clutter_actor_get_height (oh->hand[i]); x = oh->stage_width / 2 + oh->radius * cos (i * G_PI / (n_hands / 2)) - w / 2; y = oh->stage_height / 2 + oh->radius * sin (i * G_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); g_signal_connect (oh->hand[i], "button-press-event", G_CALLBACK (on_button_press_event), oh); /* paint something before each hand */ g_signal_connect (oh->hand[i], "paint", G_CALLBACK (hand_pre_paint), oh); /* paint something after each hand */ g_signal_connect_after (oh->hand[i], "paint", G_CALLBACK (hand_post_paint), oh); /* Add to our group group */ clutter_container_add_actor (CLUTTER_CONTAINER (oh->group), oh->hand[i]); if (i % 2) clutter_behaviour_apply (oh->scaler_1, oh->hand[i]); else clutter_behaviour_apply (oh->scaler_2, oh->hand[i]); } oh->paint_guards = g_malloc0 (sizeof (gboolean) * n_hands); /* 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, "key-release-event", G_CALLBACK (input_cb), oh); /* and start it */ clutter_timeline_start (oh->timeline); clutter_main (); g_object_unref (oh->scaler_1); g_object_unref (oh->scaler_2); g_object_unref (oh->timeline); g_free (oh->paint_guards); g_free (oh->hand); g_free (oh); return 0; }
int main (int argc, char *argv[]) { ClutterTimeline *timeline; ClutterActor *stage; ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; GtkWidget *window, *clutter; GtkWidget *button, *vbox; gint i; if (gtk_clutter_init_with_args (&argc, &argv, NULL, NULL, NULL, NULL) != CLUTTER_INIT_SUCCESS) g_error ("Unable to initialize GtkClutter"); if (argc != 1) do_rotate = FALSE; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add (GTK_CONTAINER (window), vbox); clutter = gtk_clutter_embed_new (); gtk_widget_set_size_request (clutter, WINWIDTH, WINHEIGHT); gtk_box_pack_start (GTK_BOX (vbox), clutter, TRUE, TRUE, 0); stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (clutter)); button = gtk_button_new_with_mnemonic ("_Quit"); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window); gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); clutter_actor_set_background_color (stage, &stage_color); nwidgets = 0; /* create a new group to hold multiple actors in a group */ group = clutter_actor_new (); clutter_actor_set_pivot_point (group, 0.5, 0.5); for (i = 0; i < MAX_NWIDGETS; i++) { widgets[i] = create_gtk_actor (i); nwidgets++; add_clutter_actor (widgets[i], group, i); } /* Add the group to the stage and center it*/ clutter_actor_add_child (stage, group); clutter_actor_add_constraint (group, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); gtk_widget_show_all (window); /* Create a timeline to manage animation */ timeline = clutter_timeline_new (6000); clutter_timeline_set_repeat_count (timeline, -1); /* fire a callback for frame change */ g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), stage); /* and start it */ clutter_timeline_start (timeline); g_timeout_add_seconds (3, add_or_remove_timeout, NULL); gtk_main(); return 0; }
Animation::Animation(ClutterActor *stage, TCLControl *tcl) { printf("Building animation tools...\n"); //==================== // On screen display: // Build the Actor that will display what's going to the lights: lightDisplay = clutter_actor_new(); // Build the color delegate for the lightDisplay's content/texture: colors = clutter_image_new(); // Error object for GDK/Clutter calls that need them error = NULL; // Load image data from some other data source...: // guchar *data = // GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data); // Load image data from a file: // const char *img_path = "./wut.png"; // GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (img_path, WIDTH, HEIGHT, &error); // Build the color buffer we'll store the actual colors in: pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, WIDTH, HEIGHT); pixels = gdk_pixbuf_get_pixels(pixbuf); // Grab it's pixels... rowstride = gdk_pixbuf_get_rowstride(pixbuf); // figure out the width of the buffer... // And put some RED into the buffer to start off with for (int x = 0; x < WIDTH; x++) { for (int y = 0; y < HEIGHT; y++) { // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built... // and bind it to a pointer to a char... unsigned char *pixel = &pixels[y * rowstride + x * 3]; // And directly update that memory location with a new color // This AUTOMATICALLY updates the color of the pixbuf! // It's just hitting the memory directly! pixel[0] = 255;//red pixel[1] = 0x0;//green pixel[2] = 0x0;//blue } } // Dump the colors from the color buffer into the ClutterContent delegate! if (pixbuf != NULL) { clutter_image_set_data(CLUTTER_IMAGE(colors), gdk_pixbuf_get_pixels (pixbuf), COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), &error); } // Tell the lightDisplay that it's content should be whatever we've dumped in the content delegate: clutter_actor_set_content(lightDisplay, colors); // Define the size of the On Screen Display: clutter_actor_set_x_expand(lightDisplay, TRUE); clutter_actor_set_y_expand(lightDisplay, TRUE); clutter_actor_set_position(lightDisplay, 0, WIDTH*(osd_scale+7)+WIDTH); clutter_actor_set_size(lightDisplay, WIDTH, HEIGHT); clutter_actor_set_scale(lightDisplay, osd_scale, osd_scale+7); clutter_actor_set_rotation_angle(lightDisplay, CLUTTER_Z_AXIS, -90); // Actually add that actor to the stage! clutter_actor_add_child(stage, lightDisplay); // Allow for UI events on this crazy thing! clutter_actor_set_reactive(lightDisplay, TRUE); // Wire up the event listener on this lightDisplay actor. TouchData *touch_data; touch_data = g_slice_new(TouchData); // reserve memory for it... touch_data->lightDisplay = lightDisplay; // Place the button actor itself inside the struct touch_data->tcl = tcl; // TCLControl *tcl is just a POINTER here (unlike in main.cpp) touch_data->animationNumber = ¤tAnimation; // Actually wire up the events and set up the data structs that the events need to operate: g_signal_connect(lightDisplay, "touch-event", G_CALLBACK(handleTouchEvents), touch_data); g_signal_connect(lightDisplay, "button-press-event", G_CALLBACK(handleTouchEvents), touch_data); g_signal_connect(lightDisplay, "motion-event", G_CALLBACK(handleTouchEvents), touch_data); g_signal_connect(lightDisplay, "button-release-event", G_CALLBACK(handleTouchEvents), touch_data); // Set sane default values for the initial touch location input_y = 0; input_x = 0; // End On screen display //============================= // Shader setup and wirings: // Build the Actor that the shader will dump to directly: shaderOutput = clutter_actor_new(); clutter_actor_set_position(shaderOutput, 0, 0); clutter_actor_set_size(shaderOutput, WIDTH-1, HEIGHT); clutter_actor_set_rotation_angle(shaderOutput, CLUTTER_Z_AXIS, -90); clutter_actor_set_rotation_angle(shaderOutput, CLUTTER_Y_AXIS, 180); clutter_actor_add_child(stage, shaderOutput); // Allocate the memory for the shader output buffer: // Figure out how big our buffer needs to be. *4 because four bytes per pixel (r, g, b, a) in shader land int shaderBufferSize = WIDTH * HEIGHT * 4; shaderBuffer = (guint8 *) malloc(shaderBufferSize); // malloc the buffer!! // Double check that we built the buffer correctly. if (shaderBuffer == NULL) { printf("OOPS! malloc error!\n"); } else { // printf("We malloc'd %i bytes for your shaderBuffer. It points at: %p\n", shaderBufferSize, shaderBuffer); // printf(" The Rowstride on the shaderBuffer is %i\n", rowstride); } // init shader TEXTURES! // Populate the noiseImage: // const char *textureFile = "images/text_noise.png"; // audiopixbuf = gdk_pixbuf_new_from_file (textureFile, NULL); // Init the audioImage that will store the FFT output for attaching to the actor error = NULL; audioImage = clutter_image_new (); audiopixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, WIDTH, HEIGHT ); audioPixels = gdk_pixbuf_get_pixels(audiopixbuf); // Grab it's pixels... audioRowstride = gdk_pixbuf_get_rowstride(audiopixbuf); // figure out the width of the buffer... // Populate the audioImage with no data so we have a fresh start: for (int x = 0; x < WIDTH; x++) { for (int y = 0; y < HEIGHT; y++) { // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built... // and bind it to a pointer to a char... unsigned char *pixel = &audioPixels[y * audioRowstride + x * 3]; // And directly update that memory location with a new color // This AUTOMATICALLY updates the color of the pixbuf! // It's just hitting the memory directly! pixel[0] = getrand(0,255);//((int)(samples[x]*max)) & 0xff; // low bits... pixel[1] = getrand(0,255);//((int)(samples[x]*max)) & 0xff00; // high bits. pixel[2] = getrand(0,255); // some random value could be used for noise... } } // Actually load our color onto the actor clutter_image_set_data (CLUTTER_IMAGE (audioImage), gdk_pixbuf_get_pixels (audiopixbuf), COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_width (audiopixbuf), gdk_pixbuf_get_height (audiopixbuf), gdk_pixbuf_get_rowstride (audiopixbuf), &error); // g_object_unref (audiopixbuf); // we want to reuse this... don't dereference that memory yet... clutter_actor_set_content (shaderOutput, audioImage); //clutter_actor_set_content_gravity (shaderOutput, CLUTTER_CONTENT_GRAVITY_TOP_RIGHT); // audioTexture[0] = 0.25; // srand(time(NULL)); // for (i=0; i<noiseTextureSize; i++) { // noiseTexture[i] = getrandf(); // } // Make sure we don't have a current shader so we don't break the update loop: shaderLoaded = false; currentSpeed = 100; // Once we have all that set up, we still need to START THE ACTUAL ANIMATION!! // To do that, we'll need to use the event chain/callback system we have been using so far. // Get ready to hand this display chunk in to the animation event: AnimationData *data; data = g_slice_new(AnimationData); // reserve memory for it... data->tcl = tcl; // tcl is an pointer to the main TCLControl object. data->animationNumber = ¤tAnimation; data->animationObject = this; // The clutter timeline object takes a "duration" in milliseconds... timeline = clutter_timeline_new(1); g_signal_connect(timeline, "new-frame", G_CALLBACK(handleNewFrame), data); // which will just continue repeating: clutter_timeline_set_repeat_count(timeline, -1); // This actually starts the timeline animation! clutter_timeline_start(timeline); // Generate the list of known shaders: buildShaderList(); // Load the first shader so we do not get a black screen: currentShader = 0; // Set the inital shader to load (usually, first in the directory) updateCurrentShader(); }