static void make_ui (ClutterActor *stage) { ClutterActor *editable = NULL; ClutterActor *rectangle = NULL; ClutterActor *label = NULL; ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff }; ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff }; ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 }; ClutterColor color_label = { 0x00, 0xff, 0x55, 0xff }; ClutterColor color_rect = { 0x00, 0xff, 0xff, 0x55 }; ClutterGeometry editable_geom = {150, 50, 100, 75}; ClutterActor *full_entry = NULL; ClutterActor *cloned_entry = NULL; clutter_stage_set_color (CLUTTER_STAGE (stage), &color_stage); clutter_actor_set_size (stage, WIDTH, HEIGHT); label = clutter_text_new_full ("Sans Bold 32px", "Entry", &color_label); clutter_actor_set_position (label, 0, 50); /* editable */ editable = clutter_text_new_full ("Sans Bold 32px", "ddd", &color_text); clutter_actor_set_position (editable, 150, 50); clutter_text_set_editable (CLUTTER_TEXT (editable), TRUE); clutter_text_set_selectable (CLUTTER_TEXT (editable), TRUE); clutter_text_set_selection_color (CLUTTER_TEXT (editable), &color_sel); clutter_actor_grab_key_focus (editable); clutter_actor_set_reactive (editable, TRUE); /* rectangle: to create a entry "feeling" */ rectangle = clutter_rectangle_new_with_color (&color_rect); clutter_actor_set_geometry (rectangle, &editable_geom); full_entry = clutter_group_new (); clutter_actor_set_position (full_entry, 0, 50); clutter_actor_set_size (full_entry, 100, 75); clutter_group_add (CLUTTER_GROUP (full_entry), label); clutter_group_add (CLUTTER_GROUP (full_entry), editable); clutter_group_add (CLUTTER_GROUP (full_entry), rectangle); clutter_actor_show_all (full_entry); clutter_actor_set_scale (full_entry, 2, 1); clutter_group_add (CLUTTER_GROUP (stage), full_entry); /* Cloning! */ cloned_entry = clutter_clone_new (full_entry); clutter_actor_set_position (cloned_entry, 50, 200); clutter_actor_set_scale (cloned_entry, 1, 2); clutter_actor_show_all (cloned_entry); clutter_actor_set_reactive (cloned_entry, TRUE); clutter_group_add (CLUTTER_GROUP (stage), cloned_entry); }
/* * Minimize effect completion callback; this function restores actor state, and * calls the manager callback function. */ static void on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data) { /* * Must reverse the effect of the effect; must hide it first to ensure * that the restoration will not be visible. */ MetaPlugin *plugin = data->plugin; ActorPrivate *apriv; MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor); apriv = get_actor_private (META_WINDOW_ACTOR (data->actor)); apriv->tml_minimize = NULL; clutter_actor_hide (data->actor); /* FIXME - we shouldn't assume the original scale, it should be saved * at the start of the effect */ clutter_actor_set_scale (data->actor, 1.0, 1.0); clutter_actor_move_anchor_point_from_gravity (data->actor, CLUTTER_GRAVITY_NORTH_WEST); /* Now notify the manager that we are done with this effect */ meta_plugin_minimize_completed (plugin, window_actor); g_free (data); }
int main(int argc,char *argv[]) { ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; ClutterColor actor_color = { 0xff,0xff,0xff,0x98}; /** 初始化clutter */ clutter_init(&argc, &argv); /** 获取默认的场景stage */ ClutterActor *stage = clutter_stage_get_default(); /** 设置场景大小,注意场景也actor的一种,所以可以使用actor的api设置*/ clutter_actor_set_size(stage,400,400); /** 设置场景背景*/ clutter_stage_set_color(CLUTTER_STAGE(stage), &stage_color); /** 载入一个图像的actor */ //ClutterActor * image = clutter_texture_new_from_file("demo.png",NULL); image = clutter_texture_new_from_file("demo.png",NULL); if(!image){ printf("load image error\n"); exit(-1); } /** 设置actor在场景中的位置*/ clutter_actor_set_position(image, 100,100); /** 缩放图像,这里设置长宽各放大了两倍*/ clutter_actor_set_scale(image,2.0,2.0); /** 设置图像旋转,以y轴旋转,角度20'c */ clutter_actor_set_rotation(image, CLUTTER_Y_AXIS, 120,0,0,0); /** 把actor加入场景中*/ clutter_container_add_actor(CLUTTER_CONTAINER(stage),image); clutter_actor_show(image); /** 打开actor的事件响应*/ clutter_actor_set_reactive(image,TRUE); /** 连接actor的某事件*/ g_signal_connect(image, "button-press-event", G_CALLBACK(on_image_button_press),NULL); /** 加入时间线*/ //ClutterTimeline* timeline = clutter_timeline_new(5000); timeline = clutter_timeline_new(5000); g_signal_connect(timeline, "new-frame",G_CALLBACK(on_timeline_new_frame),NULL); clutter_timeline_set_loop(timeline,TRUE); //clutter_timeline_start(timeline); clutter_actor_show(stage); clutter_main(); g_object_unref(timeline); printf("\n"); return 0; }
static void overview_animated_destroy(MosesOverview* self, MosesOverviewQuitReason reason, gboolean animate) { MosesOverviewPrivate* priv = self->priv; gboolean just_destroy = !animate; if (reason == MOSES_OV_REASON_ACTIVATE_WINDOW && !priv->selected_actor) { just_destroy = TRUE; } else if (reason == MOSES_OV_REASON_ACTIVATE_WORKSPACE && !priv->selected_workspace) { just_destroy = TRUE; } else if (reason == MOSES_OV_REASON_NORMAL) { just_destroy = TRUE; } if (just_destroy) { clutter_actor_destroy(CLUTTER_ACTOR(self)); return; } gfloat x, y, w, h; ClutterActor* target = NULL; if (reason == MOSES_OV_REASON_ACTIVATE_WINDOW) { target = self->priv->selected_actor; ClutterActor* orig = clutter_clone_get_source(CLUTTER_CLONE(target)); clutter_actor_get_position(orig, &x, &y); clutter_actor_get_size(orig, &w, &h); g_signal_handlers_disconnect_by_func(target, on_effect_complete, self); } else if (reason == MOSES_OV_REASON_ACTIVATE_WORKSPACE) { g_assert(priv->selected_actor == NULL); MetaScreen* screen = meta_plugin_get_screen(priv->plugin); target = overview_head_get_actor_for_workspace(priv->ov_head, priv->selected_workspace); MetaRectangle geom; int focused_monitor = meta_screen_get_current_monitor(screen); meta_screen_get_monitor_geometry(screen, focused_monitor, &geom); x = geom.x, y = geom.y, w = geom.width, h = geom.height; } if (target) { clutter_actor_remove_all_transitions(target); clutter_actor_set_child_above_sibling(clutter_actor_get_parent(target), target, NULL); clutter_actor_save_easing_state(target); clutter_actor_set_easing_mode(target, CLUTTER_LINEAR); clutter_actor_set_easing_duration(target, 150); clutter_actor_set_position(target, x, y); clutter_actor_set_scale(target, w / clutter_actor_get_width(target), h / clutter_actor_get_height(target)); clutter_actor_restore_easing_state(target); g_object_connect(target, "signal::transitions-completed", G_CALLBACK(on_restore_position_effect_complete), self, NULL); } }
static gboolean clutter_zoom_action_real_zoom (ClutterZoomAction *action, ClutterActor *actor, ClutterPoint *focal_point, gdouble factor) { ClutterZoomActionPrivate *priv = action->priv; gfloat x, y, z; gdouble scale_x, scale_y; ClutterVertex out, in; in.x = priv->transformed_focal_point.x; in.y = priv->transformed_focal_point.y; in.z = 0; clutter_actor_apply_transform_to_point (actor, &in, &out); clutter_actor_get_scale (actor, &scale_x, &scale_y); switch (priv->zoom_axis) { case CLUTTER_ZOOM_BOTH: clutter_actor_set_scale (actor, factor, factor); break; case CLUTTER_ZOOM_X_AXIS: clutter_actor_set_scale (actor, factor, scale_y); break; case CLUTTER_ZOOM_Y_AXIS: clutter_actor_set_scale (actor, scale_x, factor); break; default: break; } x = priv->initial_x + priv->focal_point.x - priv->initial_focal_point.x; y = priv->initial_y + priv->focal_point.y - priv->initial_focal_point.y; clutter_actor_get_translation (actor, NULL, NULL, &z); clutter_actor_set_translation (actor, x, y, z); return TRUE; }
void on_button_effect_complete (ClutterAnimation *animation, gpointer user_data) { ClutterActor *actor = (ClutterActor*)user_data; /* reset after effect */ clutter_actor_set_opacity (actor, 0xff); clutter_actor_set_scale (actor, 1.0, 1.0); }
static void clutter_zoom_action_gesture_cancel (ClutterGestureAction *action, ClutterActor *actor) { ClutterZoomActionPrivate *priv = ((ClutterZoomAction *) action)->priv; clutter_actor_set_translation (actor, priv->initial_x, priv->initial_y, priv->initial_z); clutter_actor_set_scale (actor, priv->initial_scale_x, priv->initial_scale_y); }
void gnibbles_worm_show (GnibblesWorm *worm) { clutter_actor_set_opacity (worm->actors, 0); clutter_actor_set_scale (worm->actors, 3.0, 3.0); clutter_actor_animate (worm->actors, CLUTTER_EASE_OUT_CIRC, 910, "scale-x", 1.0, "scale-y", 1.0, "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER, "opacity", 0xff, NULL); worm->stop = FALSE; }
//FIXME: ClutterClone seems to have problem rendering children, so badges are stay in grandpar static void create_window_badge(MosesOverview* self, ClutterActor* parent, int order) { ClutterActor* badge = clutter_actor_new(); clutter_actor_insert_child_above(clutter_actor_get_parent(parent), badge, NULL); gfloat tw, th; clutter_actor_get_transformed_size(parent, &tw, &th); gfloat w = 60.0, h = 60.0, x = (tw - w) / 2.0 + clutter_actor_get_x(parent), y = (th - h) / 2.0 + clutter_actor_get_y(parent); clutter_actor_set_position(badge, x, y); clutter_actor_set_size(badge, w, h); g_object_set_qdata(G_OBJECT(badge), moses_overview_window_clone_order(), GINT_TO_POINTER(order)); g_object_set_qdata(G_OBJECT(parent), moses_overview_window_clone_order(), GINT_TO_POINTER(order)); ClutterContent* canvas = clutter_canvas_new(); clutter_canvas_set_size(CLUTTER_CANVAS(canvas), w, h); clutter_actor_set_content(badge, canvas); g_object_unref(canvas); g_signal_connect(canvas, "draw", G_CALLBACK(on_badge_draw), badge); clutter_content_invalidate(canvas); clutter_actor_set_scale(badge, 0.0, 0.0); //do animated show clutter_actor_save_easing_state(badge); clutter_actor_set_easing_mode(badge, CLUTTER_EASE_OUT_BACK); clutter_actor_set_easing_duration(badge, 350); clutter_actor_set_pivot_point(badge, 0.5, 0.5); clutter_actor_set_scale(badge, 1.0, 1.0); clutter_actor_restore_easing_state(badge); g_ptr_array_add(self->priv->badges, badge); }
static void place_window(MosesOverview* self, ClutterActor* actor, MetaRectangle rect) { g_debug("%s: %d,%d,%d,%d", __func__, rect.x, rect.y, rect.width, rect.height); float fscale = rect.width / clutter_actor_get_width(actor); clutter_actor_save_easing_state(actor); clutter_actor_set_easing_mode(actor, CLUTTER_EASE_OUT_CUBIC); clutter_actor_set_easing_duration(actor, PLACEMENT_ANIMATION_DURATION); clutter_actor_set_scale(actor, fscale, fscale); clutter_actor_set_position(actor, rect.x, rect.y); /*clutter_actor_set_size(actor, rect.width, rect.height);*/ clutter_actor_restore_easing_state(actor); }
void button_activate (App *app, Button *b) { // Wait for the previous animation to end if (clutter_actor_get_animation (b->actor)) return; clutter_text_insert_text (CLUTTER_TEXT(app->dpy_entry), b->face, -1); clutter_actor_set_opacity (b->actor, 0xff); clutter_actor_set_scale (b->actor, 1.0, 1.0); clutter_actor_animate (b->actor, CLUTTER_LINEAR, 50, "opacity", 0x00, "scale-x", 1.5, "scale-y", 1.5, "signal-after::completed", on_button_effect_complete, b->actor, NULL); }
/* * Minimize effect completion callback; this function restores actor state, and * calls the manager callback function. */ static void on_maximize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data) { /* * Must reverse the effect of the effect. */ MetaPlugin *plugin = data->plugin; MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor); ActorPrivate *apriv = get_actor_private (window_actor); apriv->tml_maximize = NULL; /* FIXME - don't assume the original scale was 1.0 */ clutter_actor_set_scale (data->actor, 1.0, 1.0); clutter_actor_move_anchor_point_from_gravity (data->actor, CLUTTER_GRAVITY_NORTH_WEST); /* Now notify the manager that we are done with this effect */ meta_plugin_maximize_completed (plugin, window_actor); g_free (data); }
/* * Simple map handler: it applies a scale effect which must be reversed on * completion). */ static void map (MetaPlugin *plugin, MetaWindowActor *window_actor) { MetaWindowType type; ClutterActor *actor = CLUTTER_ACTOR (window_actor); MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); type = meta_window_get_window_type (meta_window); if (type == META_WINDOW_NORMAL) { ClutterAnimation *animation; EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); clutter_actor_set_pivot_point (actor, 0.5, 0.5); clutter_actor_set_opacity (actor, 0); clutter_actor_set_scale (actor, 0.5, 0.5); clutter_actor_show (actor); animation = clutter_actor_animate (actor, CLUTTER_EASE_OUT_QUAD, MAP_TIMEOUT, "opacity", 255, "scale-x", 1.0, "scale-y", 1.0, NULL); apriv->tml_map = clutter_animation_get_timeline (animation); data->actor = actor; data->plugin = plugin; g_signal_connect (apriv->tml_map, "completed", G_CALLBACK (on_map_effect_complete), data); } else meta_plugin_map_completed (plugin, window_actor); }
/* clutter scene */ ClutterActor * setup_stage (ClutterStage * stage) { ClutterTimeline *timeline = NULL; ClutterActor *texture_actor = NULL; ClutterColor rect_color = { 125, 50, 200, 255 }; ClutterActor *rect_actor = NULL; /* texture actor */ texture_actor = clutter_texture_new (); clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture_actor); clutter_actor_set_position (texture_actor, 300, 170); clutter_actor_set_scale (texture_actor, 0.6, 0.6); clutter_actor_show (texture_actor); g_object_set_data (G_OBJECT (texture_actor), "stage", stage); /* rectangle actor */ rect_actor = clutter_rectangle_new_with_color (&rect_color); clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect_actor); clutter_actor_set_size (rect_actor, 50, 50); clutter_actor_set_position (rect_actor, 300, 300); clutter_actor_show (rect_actor); /* timeline */ timeline = clutter_timeline_new (360, 60); g_object_set_data (G_OBJECT (timeline), "texture_actor", texture_actor); clutter_timeline_set_loop (timeline, TRUE); clutter_timeline_start (timeline); g_signal_connect (timeline, "new-frame", G_CALLBACK (on_new_frame), rect_actor); return texture_actor; }
G_MODULE_EXPORT gint test_animator_main (gint argc, gchar **argv) { ClutterActor *stage; ClutterActor *rects[COUNT]; gint i; clutter_init (&argc, &argv); stage = clutter_stage_get_default (); for (i=0; i<COUNT; i++) { rects[i]=new_rect (255 *(i * 1.0/COUNT), 50, 160, 255); clutter_container_add_actor (CLUTTER_CONTAINER (stage), rects[i]); clutter_actor_set_anchor_point (rects[i], 64, 64); clutter_actor_set_position (rects[i], 320.0, 240.0); clutter_actor_set_opacity (rects[i], 0x70); } g_timeout_add (10000, nuke_one, rects[2]); animator = clutter_animator_new (); /* Note: when both animations are active for the same actor at the same * time there is a race, such races should be handled by avoiding * controlling the same properties from multiple animations. This is * an intentional design flaw of this test for testing the corner case. */ clutter_animator_set (animator, rects[0], "x", 1, 0.0, 180.0, rects[0], "x", CLUTTER_LINEAR, 0.25, 450.0, rects[0], "x", CLUTTER_LINEAR, 0.5, 450.0, rects[0], "x", CLUTTER_LINEAR, 0.75, 180.0, rects[0], "x", CLUTTER_LINEAR, 1.0, 180.0, rects[0], "y", -1, 0.0, 100.0, rects[0], "y", CLUTTER_LINEAR, 0.25, 100.0, rects[0], "y", CLUTTER_LINEAR, 0.5, 380.0, rects[0], "y", CLUTTER_LINEAR, 0.75, 380.0, rects[0], "y", CLUTTER_LINEAR, 1.0, 100.0, rects[3], "x", 0, 0.0, 180.0, rects[3], "x", CLUTTER_LINEAR, 0.25, 180.0, rects[3], "x", CLUTTER_LINEAR, 0.5, 450.0, rects[3], "x", CLUTTER_LINEAR, 0.75, 450.0, rects[3], "x", CLUTTER_LINEAR, 1.0, 180.0, rects[3], "y", 0, 0.0, 100.0, rects[3], "y", CLUTTER_LINEAR, 0.25, 380.0, rects[3], "y", CLUTTER_LINEAR, 0.5, 380.0, rects[3], "y", CLUTTER_LINEAR, 0.75, 100.0, rects[3], "y", CLUTTER_LINEAR, 1.0, 100.0, rects[2], "rotation-angle-y", 0, 0.0, 0.0, rects[2], "rotation-angle-y", CLUTTER_LINEAR, 1.0, 360.0, rects[1], "scale-x", 0, 0.0, 1.0, rects[1], "scale-x", CLUTTER_LINEAR, 1.0, 2.0, rects[1], "scale-y", 0, 0.0, 1.0, rects[1], "scale-y", CLUTTER_LINEAR, 1.0, 2.0, NULL); clutter_actor_set_scale (rects[0], 1.4, 1.4); clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "x", TRUE); clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "y", TRUE); clutter_animator_property_set_interpolation (animator, G_OBJECT (rects[0]), "x", CLUTTER_INTERPOLATION_CUBIC); clutter_animator_property_set_interpolation (animator, G_OBJECT (rects[0]), "y", CLUTTER_INTERPOLATION_CUBIC); clutter_stage_hide_cursor(CLUTTER_STAGE (stage)); clutter_actor_show (stage); clutter_animator_set_duration (animator, 5000); g_signal_connect (clutter_animator_start (animator), "completed", G_CALLBACK (reverse_timeline), NULL); clutter_main (); g_object_unref (animator); return EXIT_SUCCESS; }
/* The marker is drawn with cairo. It is composed of 1 static filled circle * and 1 stroked circle animated as an echo. */ static ClutterActor * create_marker () { ClutterActor *marker; ClutterActor *bg; ClutterTimeline *timeline; cairo_t *cr; /* Create the marker */ marker = champlain_custom_marker_new (); /* Static filled circle ----------------------------------------------- */ bg = clutter_cairo_texture_new (MARKER_SIZE, MARKER_SIZE); cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (bg)); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); /* Draw the circle */ cairo_set_source_rgb (cr, 0, 0, 0); cairo_arc (cr, MARKER_SIZE / 2.0, MARKER_SIZE / 2.0, MARKER_SIZE / 2.0, 0, 2 * M_PI); cairo_close_path (cr); /* Fill the circle */ cairo_set_source_rgba (cr, 0.1, 0.1, 0.9, 1.0); cairo_fill (cr); cairo_destroy (cr); /* Add the circle to the marker */ clutter_container_add_actor (CLUTTER_CONTAINER (marker), bg); clutter_actor_set_anchor_point_from_gravity (bg, CLUTTER_GRAVITY_CENTER); clutter_actor_set_position (bg, 0, 0); /* Echo circle -------------------------------------------------------- */ bg = clutter_cairo_texture_new (2 * MARKER_SIZE, 2 * MARKER_SIZE); cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (bg)); /* Draw the circle */ cairo_set_source_rgb (cr, 0, 0, 0); cairo_arc (cr, MARKER_SIZE, MARKER_SIZE, 0.9 * MARKER_SIZE, 0, 2 * M_PI); cairo_close_path (cr); /* Stroke the circle */ cairo_set_line_width (cr, 2.0); cairo_set_source_rgba (cr, 0.1, 0.1, 0.7, 1.0); cairo_stroke (cr); cairo_destroy (cr); /* Add the circle to the marker */ clutter_container_add_actor (CLUTTER_CONTAINER (marker), bg); clutter_actor_lower_bottom (bg); /* Ensure it is under the previous circle */ clutter_actor_set_position (bg, 0, 0); clutter_actor_set_anchor_point_from_gravity (bg, CLUTTER_GRAVITY_CENTER); /* Animate the echo circle */ timeline = clutter_timeline_new (1000); clutter_timeline_set_loop (timeline, TRUE); clutter_actor_set_opacity (CLUTTER_ACTOR (bg), 255); clutter_actor_set_scale (CLUTTER_ACTOR (bg), 0.5, 0.5); clutter_actor_animate_with_timeline (CLUTTER_ACTOR (bg), CLUTTER_EASE_OUT_SINE, timeline, "opacity", 0, "scale-x", 2.0, "scale-y", 2.0, NULL); clutter_timeline_start (timeline); return marker; }
static void switch_workspace (MetaPlugin *plugin, gint from, gint to, MetaMotionDirection direction) { MetaScreen *screen; MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv; GList *l; ClutterActor *workspace0 = clutter_group_new (); ClutterActor *workspace1 = clutter_group_new (); ClutterActor *stage; int screen_width, screen_height; ClutterAnimation *animation; screen = meta_plugin_get_screen (plugin); stage = meta_get_stage_for_screen (screen); meta_screen_get_size (screen, &screen_width, &screen_height); clutter_actor_set_anchor_point (workspace1, screen_width, screen_height); clutter_actor_set_position (workspace1, screen_width, screen_height); clutter_actor_set_scale (workspace1, 0.0, 0.0); clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1); clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0); if (from == to) { meta_plugin_switch_workspace_completed (plugin); return; } l = g_list_last (meta_get_window_actors (screen)); while (l) { MetaWindowActor *window_actor = l->data; MetaWindow *window = meta_window_actor_get_meta_window (window_actor); MetaWorkspace *workspace; ActorPrivate *apriv = get_actor_private (window_actor); ClutterActor *actor = CLUTTER_ACTOR (window_actor); gint win_workspace; workspace = meta_window_get_workspace (window); win_workspace = meta_workspace_index (workspace); if (win_workspace == to || win_workspace == from) { apriv->orig_parent = clutter_actor_get_parent (actor); clutter_actor_reparent (actor, win_workspace == to ? workspace1 : workspace0); clutter_actor_show_all (actor); clutter_actor_raise_top (actor); } else if (win_workspace < 0) { /* Sticky window */ apriv->orig_parent = NULL; } else { /* Window on some other desktop */ clutter_actor_hide (actor); apriv->orig_parent = NULL; } l = l->prev; } priv->desktop1 = workspace0; priv->desktop2 = workspace1; animation = clutter_actor_animate (workspace0, CLUTTER_EASE_IN_SINE, SWITCH_TIMEOUT, "scale-x", 1.0, "scale-y", 1.0, NULL); priv->tml_switch_workspace1 = clutter_animation_get_timeline (animation); g_signal_connect (priv->tml_switch_workspace1, "completed", G_CALLBACK (on_switch_workspace_effect_complete), plugin); animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE, SWITCH_TIMEOUT, "scale-x", 0.0, "scale-y", 0.0, NULL); priv->tml_switch_workspace2 = clutter_animation_get_timeline (animation); }
static void on_monitors_changed (MetaScreen *screen, MetaPlugin *plugin) { MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin); __attribute__ ((unused)) ClutterAnimation *animation; int i, n; gchar *wallpaper = NULL; GFile *wallpaper_file = NULL; gchar *filename = NULL; GDesktopBackgroundStyle style; GDesktopBackgroundShading shading_direction; ClutterColor primary_color; ClutterColor secondary_color; gboolean random_colour = FALSE; clutter_actor_destroy_all_children (self->priv->background_group); wallpaper = g_settings_get_string (self->priv->settings, PICTURE_URI_KEY); /* We don't currently support slideshows */ if (!wallpaper || g_str_has_suffix(wallpaper, ".xml")) random_colour = TRUE; else { gchar *color_str; /* Shading direction*/ shading_direction = g_settings_get_enum (self->priv->settings, COLOR_SHADING_TYPE_KEY); /* Primary color */ color_str = g_settings_get_string (self->priv->settings, PRIMARY_COLOR_KEY); if (color_str) { clutter_color_from_string (&primary_color, color_str); g_free (color_str); color_str = NULL; } /* Secondary color */ color_str = g_settings_get_string (self->priv->settings, SECONDARY_COLOR_KEY); if (color_str) { clutter_color_from_string (&secondary_color, color_str); g_free (color_str); color_str = NULL; } /* Picture options: "none", "wallpaper", "centered", "scaled", "stretched", "zoom", "spanned" */ style = g_settings_get_enum (self->priv->settings, BACKGROUND_STYLE_KEY); wallpaper_file = g_file_new_for_uri(wallpaper); filename = g_file_get_path(wallpaper_file); } n = meta_screen_get_n_monitors (screen); for (i = 0; i < n; i++) { MetaBackground *content; MetaRectangle rect; ClutterActor *background; background = meta_background_actor_new (); content = meta_background_new (screen, i, META_BACKGROUND_EFFECTS_NONE); // Don't use rand() here, mesa calls srand() internally when // parsing the driconf XML, but it's nice if the colors are // reproducible. if (random_colour) { clutter_color_init (&primary_color, g_random_int () % 255, g_random_int () % 255, g_random_int () % 255, 255); meta_background_load_color (content, &primary_color); } else { if (style == G_DESKTOP_BACKGROUND_STYLE_NONE || g_str_has_suffix (filename, GNOME_COLOR_HACK)) { if (shading_direction == G_DESKTOP_BACKGROUND_SHADING_SOLID) meta_background_load_color (content, &primary_color); else meta_background_load_gradient (content, shading_direction, &primary_color, &secondary_color); } else { /* Set the background */ meta_background_load_file_async (content, filename, style, NULL, /*TODO use cancellable*/ background_load_file_cb, self); } } clutter_actor_set_content (background, CLUTTER_CONTENT (content)); g_object_unref (content); meta_screen_get_monitor_geometry (screen, i, &rect); clutter_actor_set_position (background, rect.x, rect.y); clutter_actor_set_size (background, rect.width, rect.height); clutter_actor_add_child (self->priv->background_group, background); clutter_actor_set_scale (background, 0.0, 0.0); clutter_actor_show (background); clutter_actor_set_pivot_point (background, 0.5, 0.5); /* Ease in the background using a scale effect */ animation = clutter_actor_animate (background, CLUTTER_EASE_IN_SINE, BACKGROUND_TIMEOUT, "scale-x", 1.0, "scale-y", 1.0, NULL); } if (wallpaper_file) g_object_unref(wallpaper_file); g_free(wallpaper); g_free(filename); }
static void gnibbles_board_load_level (GnibblesBoard *board) { gint i,j; gint x_pos, y_pos; ClutterActor *tmp; gboolean is_wall = TRUE; if (board->level) { clutter_group_remove_all (CLUTTER_GROUP (board->level)); clutter_container_remove_actor (CLUTTER_CONTAINER (stage), board->level); } board->level = clutter_group_new (); /* Load wall_pixmaps onto the surface*/ for (i = 0; i < BOARDHEIGHT; i++) { y_pos = i * properties->tilesize; for (j = 0; j < BOARDWIDTH; j++) { is_wall = TRUE; switch (board->walls[j][i]) { case 'a': // empty space is_wall = FALSE; break; // break right away case 'b': // straight up tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[0]); break; case 'c': // straight side tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[1]); break; case 'd': // corner bottom left tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[2]); break; case 'e': // corner bottom right tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[3]); break; case 'f': // corner up left tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[4]); break; case 'g': // corner up right tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[5]); break; case 'h': // tee up tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[6]); break; case 'i': // tee right tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[7]); break; case 'j': // tee left tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[8]); break; case 'k': // tee down tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[9]); break; case 'l': // cross tmp = gtk_clutter_texture_new_from_pixbuf (wall_pixmaps[10]); break; default: is_wall = FALSE; break; } if (is_wall) { x_pos = j * properties->tilesize; clutter_actor_set_size (CLUTTER_ACTOR(tmp), properties->tilesize, properties->tilesize); clutter_actor_set_position (CLUTTER_ACTOR (tmp), x_pos, y_pos); clutter_actor_show (CLUTTER_ACTOR (tmp)); clutter_container_add_actor (CLUTTER_CONTAINER (board->level), CLUTTER_ACTOR (tmp)); } } } clutter_container_add_actor (CLUTTER_CONTAINER (stage), board->level); clutter_actor_raise (board->level, board->surface); clutter_actor_set_opacity (board->level, 0); clutter_actor_set_scale (CLUTTER_ACTOR (board->level), 0.2, 0.2); clutter_actor_animate (board->level, CLUTTER_EASE_OUT_BOUNCE, 1210, "opacity", 0xff, "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER, "scale-x", 1.0, "scale-y", 1.0, NULL); }
static void render_logo (void) { ClutterActor *image; ClutterActor *text, *text_shadow; ClutterActor *desc, *desc_shadow; ClutterColor actor_color = {0xff,0xff,0xff,0xff}; ClutterColor shadow_color = {0x00, 0x00, 0x00, 0x88}; ClutterActor *text_group; static gint width, height; gint size; gfloat stage_w, stage_h; PangoFontDescription *pfd; PangoLayout *layout; PangoContext *context; gchar *nibbles = _("Nibbles"); /* Translators: This string will be included in the intro screen, so don't make sure it fits! */ gchar *description = _("A worm game for MATE."); logo = clutter_group_new (); text_group = clutter_group_new (); if (!logo_pixmap) gnibbles_load_logo (properties->tilesize); image = gtk_clutter_texture_new_from_pixbuf (logo_pixmap); stage_w = board->width * properties->tilesize; stage_h = board->height * properties->tilesize; clutter_actor_set_size (CLUTTER_ACTOR (image), stage_w, stage_h); clutter_actor_set_position (CLUTTER_ACTOR (image), 0, 0); clutter_actor_show (image); text = clutter_text_new (); clutter_text_set_color (CLUTTER_TEXT (text), &actor_color); context = gdk_pango_context_get (); layout = clutter_text_get_layout (CLUTTER_TEXT (text)); pfd = pango_context_get_font_description (context); size = pango_font_description_get_size (pfd); pango_font_description_set_size (pfd, (size * stage_w) / 100); pango_font_description_set_family (pfd, "Sans"); pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD); pango_layout_set_font_description (layout, pfd); pango_layout_set_text (layout, nibbles, -1); pango_layout_get_pixel_size (layout, &width, &height); text_shadow = clutter_text_new (); clutter_text_set_color (CLUTTER_TEXT (text_shadow), &shadow_color); layout = clutter_text_get_layout (CLUTTER_TEXT (text_shadow)); pango_layout_set_font_description (layout, pfd); pango_layout_set_text (layout, nibbles, -1); clutter_actor_set_position (CLUTTER_ACTOR (text), (stage_w - width) * 0.5 , stage_h * .72); clutter_actor_set_position (CLUTTER_ACTOR (text_shadow), (stage_w - width) * 0.5 + 5, stage_h * .72 + 5); desc = clutter_text_new (); layout = clutter_text_get_layout (CLUTTER_TEXT (desc)); clutter_text_set_color (CLUTTER_TEXT (desc), &actor_color); pango_font_description_set_size (pfd, (size * stage_w) / 400); pango_layout_set_font_description (layout, pfd); pango_layout_set_text (layout, description, -1); pango_layout_get_pixel_size(layout, &width, &height); desc_shadow = clutter_text_new (); layout = clutter_text_get_layout (CLUTTER_TEXT (desc_shadow)); clutter_text_set_color (CLUTTER_TEXT (desc_shadow), &shadow_color); pango_font_description_set_size (pfd, (size * stage_w) / 400); pango_layout_set_font_description (layout, pfd); pango_layout_set_text (layout, description, -1); clutter_actor_set_position (CLUTTER_ACTOR (desc), (stage_w - width) * 0.5, stage_h* .93); clutter_actor_set_position (CLUTTER_ACTOR (desc_shadow), (stage_w - width) * 0.5 + 3, stage_h * .93 + 3); clutter_container_add (CLUTTER_CONTAINER (text_group), CLUTTER_ACTOR (text_shadow), CLUTTER_ACTOR (text), CLUTTER_ACTOR (desc_shadow), CLUTTER_ACTOR (desc), NULL); clutter_container_add (CLUTTER_CONTAINER (logo), CLUTTER_ACTOR (image), CLUTTER_ACTOR (text_group), NULL); clutter_actor_set_opacity (CLUTTER_ACTOR (text_group), 0); clutter_actor_set_scale (CLUTTER_ACTOR (text_group), 0.0, 0.0); clutter_actor_animate (text_group, CLUTTER_EASE_OUT_CIRC, 800, "opacity", 0xff, "scale-x", 1.0, "scale-y", 1.0, "fixed::scale-center-y", stage_w / 2, "fixed::scale-center-x", stage_h / 2, NULL); clutter_container_add_actor (CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (logo)); }
/* Private functions */ static void ensure_layout (AstroAppview *view) { AstroAppviewPrivate *priv; GList *l; gint groupx = 0; gint center = 0; gint i = 0; priv = view->priv; groupx = clutter_actor_get_x (CLUTTER_ACTOR (view)); center = CSW()/2; l = clutter_container_get_children (CLUTTER_CONTAINER (view)); for (l = l; l; l = l->next) { ClutterActor *icon = l->data; gint realx, diff, y_diff;; gfloat scale; realx = clutter_actor_get_x (icon) + groupx; if (realx > center && realx < CSW ()) { diff = center - (realx - center); } else if (realx > 0 && realx <= center) { diff = realx; } else { diff = 0; } scale = (gfloat)diff/center; scale = 0.2 + (0.8 * scale); clutter_actor_set_scale (icon, scale, scale); if (realx < center) { gfloat angle, sine; angle = scale * (3.14*2); sine = sin (0.5 *angle); y_diff = (CSH()/2) + (VARIANCE * sine); } else { gfloat angle, sine; angle = scale * (3.14*2); sine = sin (0.5*angle); y_diff = (CSH()/2) - (VARIANCE * sine); } clutter_actor_set_y (icon, y_diff); astro_appicon_set_blur (ASTRO_APPICON (icon), (1.0 - scale) * MAX_BLUR); i++; } }
int main (int argc, char *argv[]) { ClutterActor *stage; ClutterActor *label; int w, h; int row, col; float scale = 1.0f; g_setenv ("CLUTTER_VBLANK", "none", FALSE); g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE); if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; if (argc != 3) { g_printerr ("Usage test-text-perf FONT_SIZE N_CHARS\n"); exit (1); } font_size = atoi (argv[1]); n_chars = atoi (argv[2]); g_print ("Monospace %dpx, string length = %d\n", font_size, n_chars); stage = clutter_stage_new (); clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black); clutter_stage_set_title (CLUTTER_STAGE (stage), "Text Performance"); g_signal_connect (stage, "paint", G_CALLBACK (on_paint), NULL); label = create_label (); w = clutter_actor_get_width (label); h = clutter_actor_get_height (label); /* If the label is too big to fit on the stage then scale it so that it will fit */ if (w > STAGE_WIDTH || h > STAGE_HEIGHT) { float x_scale = STAGE_WIDTH / (float) w; float y_scale = STAGE_HEIGHT / (float) h; if (x_scale < y_scale) { scale = x_scale; cols = 1; rows = STAGE_HEIGHT / (h * scale); } else { scale = y_scale; cols = STAGE_WIDTH / (w * scale); rows = 1; } g_print ("Text scaled by %f to fit on the stage\n", scale); } else { cols = STAGE_WIDTH / w; rows = STAGE_HEIGHT / h; } clutter_actor_destroy (label); for (row=0; row<rows; row++) for (col=0; col<cols; col++) { label = create_label(); clutter_actor_set_scale (label, scale, scale); clutter_actor_set_position (label, w * col * scale, h * row * scale); clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); } clutter_actor_show_all (stage); clutter_threads_add_idle (queue_redraw, stage); clutter_main (); return 0; }
static void on_monitors_changed (MetaScreen *screen, MetaPlugin *plugin) { MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin); __attribute__ ((unused)) ClutterAnimation *animation; int i, n; gchar *wallpaper = NULL; GFile *wallpaper_file = NULL; gchar *filename = NULL; gboolean random_colour = FALSE; clutter_actor_destroy_all_children (self->priv->background_group); wallpaper = g_settings_get_string(self->priv->settings, PICTURE_KEY); if (!wallpaper) random_colour = TRUE; else { wallpaper_file = g_file_new_for_uri(wallpaper); filename = g_file_get_path(wallpaper_file); } n = meta_screen_get_n_monitors (screen); for (i = 0; i < n; i++) { MetaRectangle rect; ClutterActor *background; ClutterColor color; meta_screen_get_monitor_geometry (screen, i, &rect); /* Don't use rand() here, mesa calls srand() internally when parsing the driconf XML, but it's nice if the colors are reproducible. */ if (random_colour) { background = meta_background_actor_new (); clutter_color_init (&color, g_random_int () % 255, g_random_int () % 255, g_random_int () % 255, 255); clutter_actor_set_background_color (background, &color); } else { /* Set the background */ background = clutter_texture_new_from_file(filename, NULL); } clutter_actor_set_position (background, rect.x, rect.y); clutter_actor_set_size (background, rect.width, rect.height); clutter_actor_add_child (self->priv->background_group, background); clutter_actor_set_scale (background, 0.0, 0.0); clutter_actor_show (background); clutter_actor_move_anchor_point_from_gravity (background, CLUTTER_GRAVITY_CENTER); /* Ease in the background using a scale effect */ animation = clutter_actor_animate (background, CLUTTER_EASE_IN_SINE, BACKGROUND_TIMEOUT, "scale-x", 1.0, "scale-y", 1.0, NULL); } if (wallpaper_file) g_object_unref(wallpaper_file); g_free(wallpaper); g_free(filename); }
void call_activate (App *app) { gint i; gfloat x, y; ClutterAnimation *anim; ClutterAlpha *alpha; /* zoom in the dialing window */ clutter_actor_set_scale (app->screen_dial, 0.1, 0.1); clutter_actor_set_opacity (app->screen_dial, 0x66); clutter_actor_show_all (app->screen_dial); anim = clutter_actor_animate (app->screen_dial, CLUTTER_EASE_OUT_SINE, 150, "opacity", 0xff, "scale-x", 1.0, "scale-y", 1.0, NULL); alpha = clutter_animation_get_alpha (anim); /* Set up effects to shoot everything offscreen, synchronized with screen_dial animation */ for (i=0; i<12; i++) { clutter_actor_set_position (app->buttons[i]->actor, app->buttons[i]->sx, app->buttons[i]->sy); switch ((i+1) % 3) { case 0: x = CSW + clutter_actor_get_width (app->buttons[i]->actor) / 2; y = app->buttons[i]->sy; break; case 1: x = -clutter_actor_get_width (app->buttons[i]->actor) / 2; y = app->buttons[i]->sy; break; case 2: x = app->buttons[i]->sx; if (i < 3) y = -clutter_actor_get_height (app->buttons[i]->actor) / 2; else y = CSH + clutter_actor_get_height (app->buttons[i]->actor) / 2; break; } clutter_actor_animate_with_alpha (app->buttons[i]->actor, alpha, "opacity", 0x00, "x", x, "y", y, NULL); } clutter_actor_set_position (app->dpy, app->dpyx, app->dpyy); clutter_actor_animate_with_alpha(app->dpy, alpha, "x", (float)app->dpyx, "y", -clutter_actor_get_height (app->dpy), "signal-after::completed", on_call_activate_complete, app, NULL); }
/* * Simple map handler: it applies a scale effect which must be reversed on * completion). */ static void map (MetaPlugin *plugin, MetaWindowActor *window_actor) { MetaWindowType type; ClutterActor *actor = CLUTTER_ACTOR (window_actor); MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); type = meta_window_get_window_type (meta_window); if (type == META_WINDOW_NORMAL || type == META_WINDOW_DIALOG || type == META_WINDOW_MODAL_DIALOG) { ClutterAnimation *animation; EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); clutter_actor_move_anchor_point_from_gravity (actor, CLUTTER_GRAVITY_CENTER); clutter_actor_set_scale (actor, MAP_SCALE, MAP_SCALE); clutter_actor_set_opacity (actor, 0); clutter_actor_show (actor); animation = clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, MAP_TIMEOUT, "scale-x", 1.0, "scale-y", 1.0, "opacity", 255, NULL); apriv->tml_map = clutter_animation_get_timeline (animation); data->actor = actor; data->plugin = plugin; g_signal_connect (apriv->tml_map, "completed", G_CALLBACK (on_map_effect_complete), data); apriv->is_minimized = FALSE; } else if (type == META_WINDOW_DOCK) { /* For context menus (popup/dropdown) we fade the menu in */ ClutterAnimation *animation; EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); clutter_actor_set_opacity (actor, 0); clutter_actor_show (actor); animation = clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, MAP_TIMEOUT, "opacity", 255, NULL); apriv->tml_map = clutter_animation_get_timeline (animation); data->actor = actor; data->plugin = plugin; g_signal_connect (apriv->tml_map, "completed", G_CALLBACK (on_map_effect_complete), data); apriv->is_minimized = FALSE; } else meta_plugin_map_completed (plugin, window_actor); }
static void rc_sync_actor(RendererClutter *rc) { PixbufRenderer *pr = rc->pr; gint anchor_x = 0; gint anchor_y = 0; gint rot_z = 0; gint rot_y = 0; clutter_actor_set_anchor_point(CLUTTER_ACTOR(rc->texture), 0, 0); DEBUG_3("scale %d %d", rc->pr->width, rc->pr->height); DEBUG_3("pos %d %d", rc->pr->x_offset, rc->pr->y_offset); clutter_actor_set_scale(CLUTTER_ACTOR(rc->texture), (gfloat)pr->width / pr->image_width, (gfloat)pr->height / pr->image_height); switch (pr->orientation) { case EXIF_ORIENTATION_TOP_LEFT: /* 1 - Horizontal (normal) */ break; case EXIF_ORIENTATION_TOP_RIGHT: /* 2 - Mirror horizontal */ rot_y = 180; anchor_x = pr->width; break; case EXIF_ORIENTATION_BOTTOM_RIGHT: /* 3 - Rotate 180 */ rot_z = 180; anchor_x = pr->width; anchor_y = pr->height; break; case EXIF_ORIENTATION_BOTTOM_LEFT: /* 4 - Mirror vertical */ rot_z = 180; rot_y = 180; anchor_y = pr->height; break; case EXIF_ORIENTATION_LEFT_TOP: /* 5 - Mirror horizontal and rotate 270 CW */ rot_z = 270; rot_y = 180; break; case EXIF_ORIENTATION_RIGHT_TOP: /* 6 - Rotate 90 CW */ rot_z = 90; anchor_x = pr->width; break; case EXIF_ORIENTATION_RIGHT_BOTTOM: /* 7 - Mirror horizontal and rotate 90 CW */ rot_z = 90; rot_y = 180; anchor_x = pr->width; anchor_y = pr->height; break; case EXIF_ORIENTATION_LEFT_BOTTOM: /* 8 - Rotate 270 CW */ rot_z = 270; anchor_y = pr->height; break; default: /* The other values are out of range */ break; } clutter_actor_set_rotation( CLUTTER_ACTOR(rc->texture), CLUTTER_Z_AXIS, rot_z, 0, 0, 0); clutter_actor_set_rotation( CLUTTER_ACTOR(rc->texture), CLUTTER_Y_AXIS, rot_y, 0, 0, 0); clutter_actor_set_position(CLUTTER_ACTOR(rc->texture), pr->x_offset - pr->x_scroll + anchor_x, pr->y_offset - pr->y_scroll + anchor_y); }
static void mnb_zones_preview_completed_cb (ClutterAnimation *animation, MnbZonesPreview *preview) { MnbZonesPreviewPrivate *priv = preview->priv; switch (priv->anim_phase) { case MNB_ZP_STATIC: /* Start zooming out */ priv->anim_phase = MNB_ZP_ZOOM_OUT; mnb_zones_preview_enable_fanciness (preview, TRUE); clutter_actor_save_easing_state (CLUTTER_ACTOR(preview)); clutter_actor_set_easing_duration (CLUTTER_ACTOR(preview), 220); clutter_actor_set_easing_mode(CLUTTER_ACTOR(preview), CLUTTER_EASE_IN_SINE); clutter_actor_set_scale(CLUTTER_ACTOR(preview), 0.3f, 0.3f); clutter_actor_restore_easing_state (CLUTTER_ACTOR(preview)); break; case MNB_ZP_ZOOM_OUT: /* Start panning */ { guint duration = 175 * abs (priv->dest_workspace - priv->workspace); if (duration) { priv->anim_phase = MNB_ZP_PAN; clutter_actor_save_easing_state (CLUTTER_ACTOR(preview)); clutter_actor_set_easing_duration (CLUTTER_ACTOR(preview), duration); clutter_actor_set_easing_mode(CLUTTER_ACTOR(preview), CLUTTER_LINEAR); clutter_actor_set_scale(CLUTTER_ACTOR(preview), (gdouble)priv->dest_workspace, (gdouble)priv->dest_workspace); clutter_actor_restore_easing_state (CLUTTER_ACTOR(preview)); break; } /* If duration == 0, fall through here to the next phase*/ } case MNB_ZP_PAN: /* Start zooming in */ mnb_zones_preview_enable_fanciness (preview, FALSE); priv->anim_phase = MNB_ZP_ZOOM_IN; clutter_actor_save_easing_state (CLUTTER_ACTOR(preview)); clutter_actor_set_easing_duration (CLUTTER_ACTOR(preview), 250); clutter_actor_set_easing_mode(CLUTTER_ACTOR(preview), CLUTTER_EASE_OUT_CUBIC); clutter_actor_set_scale(CLUTTER_ACTOR(preview), 1.0f, 1.0f); clutter_actor_restore_easing_state (CLUTTER_ACTOR(preview)); break; case MNB_ZP_ZOOM_IN: /* Complete the animation */ priv->anim_phase = MNB_ZP_STATIC; g_signal_emit (preview, signals[SWITCH_COMPLETED], 0); return; default: g_warning (G_STRLOC ": This shouldn't happen"); return; } animation = clutter_actor_get_animation (CLUTTER_ACTOR (preview)); g_signal_connect_after (animation, "completed", G_CALLBACK (mnb_zones_preview_completed_cb), preview); }
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(); }