#include #include #include typedef struct _ColorContent { GObject parent_instance; double red; double green; double blue; double alpha; float padding; } ColorContent; typedef struct _ColorContentClass { GObjectClass parent_class; } ColorContentClass; static void clutter_content_iface_init (ClutterContentIface *iface); G_DEFINE_TYPE_WITH_CODE (ColorContent, color_content, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, clutter_content_iface_init)) static void color_content_paint_content (ClutterContent *content, ClutterActor *actor, ClutterPaintNode *root) { ColorContent *self = (ColorContent *) content; ClutterActorBox box, content_box; ClutterColor color; PangoLayout *layout; PangoRectangle logical; ClutterPaintNode *node; #if 0 g_debug ("Painting content [%p] " "{ r:%.2f, g:%.2f, b:%.2f, a:%.2f } " "for actor [%p] (context: [%p])", content, self->red, self->green, self->blue, self->alpha, actor, context); #endif clutter_actor_get_content_box (actor, &content_box); box = content_box; box.x1 += self->padding; box.y1 += self->padding; box.x2 -= self->padding; box.y2 -= self->padding; color.alpha = self->alpha * 255; color.red = self->red * 255; color.green = self->green * 255; color.blue = self->blue * 255; node = clutter_color_node_new (&color); clutter_paint_node_add_rectangle (node, &box); clutter_paint_node_add_child (root, node); clutter_paint_node_unref (node); color.red = (1.0 - self->red) * 255; color.green = (1.0 - self->green) * 255; color.blue = (1.0 - self->blue) * 255; layout = clutter_actor_create_pango_layout (actor, "A"); pango_layout_get_pixel_extents (layout, NULL, &logical); node = clutter_text_node_new (layout, &color); /* top-left */ box.x1 = clutter_actor_box_get_x (&content_box); box.y1 = clutter_actor_box_get_y (&content_box); box.x2 = box.x1 + logical.width; box.y2 = box.y1 + logical.height; clutter_paint_node_add_rectangle (node, &box); /* top-right */ box.x1 = clutter_actor_box_get_x (&content_box) + clutter_actor_box_get_width (&content_box) - logical.width; box.y1 = clutter_actor_box_get_y (&content_box); box.x2 = box.x1 + logical.width; box.y2 = box.y1 + logical.height; clutter_paint_node_add_rectangle (node, &box); /* bottom-right */ box.x1 = clutter_actor_box_get_x (&content_box) + clutter_actor_box_get_width (&content_box) - logical.width; box.y1 = clutter_actor_box_get_y (&content_box) + clutter_actor_box_get_height (&content_box) - logical.height; box.x2 = box.x1 + logical.width; box.y2 = box.y1 + logical.height; clutter_paint_node_add_rectangle (node, &box); /* bottom-left */ box.x1 = clutter_actor_box_get_x (&content_box); box.y1 = clutter_actor_box_get_y (&content_box) + clutter_actor_box_get_height (&content_box) - logical.height; box.x2 = box.x1 + logical.width; box.y2 = box.y1 + logical.height; clutter_paint_node_add_rectangle (node, &box); /* center */ box.x1 = clutter_actor_box_get_x (&content_box) + (clutter_actor_box_get_width (&content_box) - logical.width) / 2.0; box.y1 = clutter_actor_box_get_y (&content_box) + (clutter_actor_box_get_height (&content_box) - logical.height) / 2.0; box.x2 = box.x1 + logical.width; box.y2 = box.y1 + logical.height; clutter_paint_node_add_rectangle (node, &box); clutter_paint_node_add_child (root, node); clutter_paint_node_unref (node); g_object_unref (layout); } static void clutter_content_iface_init (ClutterContentIface *iface) { iface->paint_content = color_content_paint_content; } static void color_content_class_init (ColorContentClass *klass) { } static void color_content_init (ColorContent *self) { } static ClutterContent * color_content_new (double red, double green, double blue, double alpha, float padding) { ColorContent *self = g_object_new (color_content_get_type (), NULL); self->red = red; self->green = green; self->blue = blue; self->alpha = alpha; self->padding = padding; return (ClutterContent *) self; } G_MODULE_EXPORT int test_content_main (int argc, char *argv[]) { ClutterActor *stage, *grid; ClutterContent *content; int i, n_rects; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; stage = clutter_stage_new (); clutter_actor_set_name (stage, "Stage"); clutter_stage_set_title (CLUTTER_STAGE (stage), "Content"); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_actor_show (stage); grid = clutter_actor_new (); clutter_actor_set_name (grid, "Grid"); clutter_actor_set_margin_top (grid, 12); clutter_actor_set_margin_right (grid, 12); clutter_actor_set_margin_bottom (grid, 12); clutter_actor_set_margin_left (grid, 12); clutter_actor_set_layout_manager (grid, clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL)); clutter_actor_add_constraint (grid, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.0)); clutter_actor_add_child (stage, grid); content = color_content_new (g_random_double_range (0.0, 1.0), g_random_double_range (0.0, 1.0), g_random_double_range (0.0, 1.0), 1.0, 2.0); n_rects = g_random_int_range (12, 24); for (i = 0; i < n_rects; i++) { ClutterActor *box = clutter_actor_new (); ClutterColor bg_color = { g_random_int_range (0, 255), g_random_int_range (0, 255), g_random_int_range (0, 255), 255 }; char *name, *color; color = clutter_color_to_string (&bg_color); name = g_strconcat ("Box <", color, ">", NULL); clutter_actor_set_name (box, name); g_free (name); g_free (color); clutter_actor_set_background_color (box, &bg_color); clutter_actor_set_content (box, content); clutter_actor_set_size (box, 64, 64); clutter_actor_add_child (grid, box); } clutter_main (); g_object_unref (content); return EXIT_SUCCESS; } G_MODULE_EXPORT const char * test_content_describe (void) { return "A simple test for ClutterContent"; }