static void add_clutter_actor (ClutterActor *actor, ClutterActor *container, int i) { float x, y, w, h; /* Add to our group group */ clutter_actor_add_child (container, actor); /* Place around a circle */ w = clutter_actor_get_width (widgets[0]); h = clutter_actor_get_height (widgets[0]); x = WINWIDTH / 2 + RADIUS * cosf (i * 2 * M_PI / (MAX_NWIDGETS)) - w / 2; y = WINHEIGHT / 2 + RADIUS * sinf (i * 2 * M_PI / (MAX_NWIDGETS)) - h / 2; clutter_actor_set_position (actor, x, y); clutter_actor_set_pivot_point (actor, 0.5, 0.5); }
//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); }
/* * 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); }
static gboolean clutter_zoom_action_gesture_begin (ClutterGestureAction *action, ClutterActor *actor) { ClutterZoomActionPrivate *priv = ((ClutterZoomAction *) action)->priv; gfloat dx, dy; capture_point_initial_position (action, actor, 0, &priv->points[0]); capture_point_initial_position (action, actor, 1, &priv->points[1]); dx = priv->points[1].transformed_start_x - priv->points[0].transformed_start_x; dy = priv->points[1].transformed_start_y - priv->points[0].transformed_start_y; priv->zoom_initial_distance = sqrt (dx * dx + dy * dy); clutter_actor_get_translation (actor, &priv->initial_x, &priv->initial_y, &priv->initial_z); clutter_actor_get_scale (actor, &priv->initial_scale_x, &priv->initial_scale_y); priv->initial_focal_point.x = (priv->points[0].start_x + priv->points[1].start_x) / 2; priv->initial_focal_point.y = (priv->points[0].start_y + priv->points[1].start_y) / 2; clutter_actor_transform_stage_point (actor, priv->initial_focal_point.x, priv->initial_focal_point.y, &priv->transformed_focal_point.x, &priv->transformed_focal_point.y); clutter_actor_set_pivot_point (actor, priv->transformed_focal_point.x / clutter_actor_get_width (actor), priv->transformed_focal_point.y / clutter_actor_get_height (actor)); return TRUE; }
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); }
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; }
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; }
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; }