1 #include <stdlib.h>
2 #include <gmodule.h>
3 #include <gdk-pixbuf/gdk-pixbuf.h>
4 #include <clutter/clutter.h>
5
6 typedef struct _SolidContent {
7 GObject parent_instance;
8
9 double red;
10 double green;
11 double blue;
12 double alpha;
13
14 float padding;
15 } SolidContent;
16
17 typedef struct _SolidContentClass {
18 GObjectClass parent_class;
19 } SolidContentClass;
20
21 static void clutter_content_iface_init (ClutterContentIface *iface);
22
G_DEFINE_TYPE_WITH_CODE(SolidContent,solid_content,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,clutter_content_iface_init))23 G_DEFINE_TYPE_WITH_CODE (SolidContent, solid_content, G_TYPE_OBJECT,
24 G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
25 clutter_content_iface_init))
26
27 static void
28 solid_content_paint_content (ClutterContent *content,
29 ClutterActor *actor,
30 ClutterPaintNode *root)
31 {
32 SolidContent *self = (SolidContent *) content;
33 ClutterActorBox box, content_box;
34 ClutterColor color;
35 PangoLayout *layout;
36 PangoRectangle logical;
37 ClutterPaintNode *node;
38
39 #if 0
40 g_debug ("Painting content [%p] "
41 "{ r:%.2f, g:%.2f, b:%.2f, a:%.2f } "
42 "for actor [%p] (context: [%p])",
43 content,
44 self->red,
45 self->green,
46 self->blue,
47 self->alpha,
48 actor, context);
49 #endif
50
51 clutter_actor_get_content_box (actor, &content_box);
52
53 box = content_box;
54 box.x1 += self->padding;
55 box.y1 += self->padding;
56 box.x2 -= self->padding;
57 box.y2 -= self->padding;
58
59 color.alpha = self->alpha * 255;
60
61 color.red = self->red * 255;
62 color.green = self->green * 255;
63 color.blue = self->blue * 255;
64
65 node = clutter_color_node_new (&color);
66 clutter_paint_node_add_rectangle (node, &box);
67 clutter_paint_node_add_child (root, node);
68 clutter_paint_node_unref (node);
69
70 color.red = (1.0 - self->red) * 255;
71 color.green = (1.0 - self->green) * 255;
72 color.blue = (1.0 - self->blue) * 255;
73
74 layout = clutter_actor_create_pango_layout (actor, "A");
75 pango_layout_get_pixel_extents (layout, NULL, &logical);
76
77 node = clutter_text_node_new (layout, &color);
78
79 /* top-left */
80 box.x1 = clutter_actor_box_get_x (&content_box);
81 box.y1 = clutter_actor_box_get_y (&content_box);
82 box.x2 = box.x1 + logical.width;
83 box.y2 = box.y1 + logical.height;
84 clutter_paint_node_add_rectangle (node, &box);
85
86 /* top-right */
87 box.x1 = clutter_actor_box_get_x (&content_box)
88 + clutter_actor_box_get_width (&content_box)
89 - logical.width;
90 box.y1 = clutter_actor_box_get_y (&content_box);
91 box.x2 = box.x1 + logical.width;
92 box.y2 = box.y1 + logical.height;
93 clutter_paint_node_add_rectangle (node, &box);
94
95 /* bottom-right */
96 box.x1 = clutter_actor_box_get_x (&content_box)
97 + clutter_actor_box_get_width (&content_box)
98 - logical.width;
99 box.y1 = clutter_actor_box_get_y (&content_box)
100 + clutter_actor_box_get_height (&content_box)
101 - logical.height;
102 box.x2 = box.x1 + logical.width;
103 box.y2 = box.y1 + logical.height;
104 clutter_paint_node_add_rectangle (node, &box);
105
106 /* bottom-left */
107 box.x1 = clutter_actor_box_get_x (&content_box);
108 box.y1 = clutter_actor_box_get_y (&content_box)
109 + clutter_actor_box_get_height (&content_box)
110 - logical.height;
111 box.x2 = box.x1 + logical.width;
112 box.y2 = box.y1 + logical.height;
113 clutter_paint_node_add_rectangle (node, &box);
114
115 /* center */
116 box.x1 = clutter_actor_box_get_x (&content_box)
117 + (clutter_actor_box_get_width (&content_box) - logical.width) / 2.0;
118 box.y1 = clutter_actor_box_get_y (&content_box)
119 + (clutter_actor_box_get_height (&content_box) - logical.height) / 2.0;
120 box.x2 = box.x1 + logical.width;
121 box.y2 = box.y1 + logical.height;
122 clutter_paint_node_add_rectangle (node, &box);
123
124 clutter_paint_node_add_child (root, node);
125 clutter_paint_node_unref (node);
126
127 g_object_unref (layout);
128 }
129
130 static void
clutter_content_iface_init(ClutterContentIface * iface)131 clutter_content_iface_init (ClutterContentIface *iface)
132 {
133 iface->paint_content = solid_content_paint_content;
134 }
135
136 static void
solid_content_class_init(SolidContentClass * klass)137 solid_content_class_init (SolidContentClass *klass)
138 {
139 }
140
141 static void
solid_content_init(SolidContent * self)142 solid_content_init (SolidContent *self)
143 {
144 }
145
146 static ClutterContent *
solid_content_new(double red,double green,double blue,double alpha,float padding)147 solid_content_new (double red,
148 double green,
149 double blue,
150 double alpha,
151 float padding)
152 {
153 SolidContent *self = g_object_new (solid_content_get_type (), NULL);
154
155 self->red = red;
156 self->green = green;
157 self->blue = blue;
158 self->alpha = alpha;
159 self->padding = padding;
160
161 return (ClutterContent *) self;
162 }
163
164 G_MODULE_EXPORT const char *
test_image_describe(void)165 test_image_describe (void)
166 {
167 return "A test with image content.";
168 }
169
170 G_MODULE_EXPORT int
test_image_main(int argc,char * argv[])171 test_image_main (int argc, char *argv[])
172 {
173 ClutterActor *stage, *grid;
174 ClutterContent *color, *image;
175 GdkPixbuf *pixbuf;
176 int i, n_rects;
177
178 if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
179 return EXIT_FAILURE;
180
181 stage = clutter_stage_new ();
182 clutter_actor_set_name (stage, "Stage");
183 clutter_stage_set_title (CLUTTER_STAGE (stage), "Content");
184 clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
185 g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
186 clutter_actor_show (stage);
187
188 grid = clutter_actor_new ();
189 clutter_actor_set_name (grid, "Grid");
190 clutter_actor_set_margin_top (grid, 12);
191 clutter_actor_set_margin_right (grid, 12);
192 clutter_actor_set_margin_bottom (grid, 12);
193 clutter_actor_set_margin_left (grid, 12);
194 clutter_actor_set_layout_manager (grid, clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL));
195 clutter_actor_add_constraint (grid, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.0));
196 clutter_actor_add_child (stage, grid);
197
198 color = solid_content_new (g_random_double_range (0.0, 1.0),
199 g_random_double_range (0.0, 1.0),
200 g_random_double_range (0.0, 1.0),
201 1.0,
202 2.0);
203
204 pixbuf = gdk_pixbuf_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", NULL);
205 image = clutter_image_new ();
206 clutter_image_set_data (CLUTTER_IMAGE (image),
207 gdk_pixbuf_get_pixels (pixbuf),
208 gdk_pixbuf_get_has_alpha (pixbuf)
209 ? COGL_PIXEL_FORMAT_RGBA_8888
210 : COGL_PIXEL_FORMAT_RGB_888,
211 gdk_pixbuf_get_width (pixbuf),
212 gdk_pixbuf_get_height (pixbuf),
213 gdk_pixbuf_get_rowstride (pixbuf),
214 NULL);
215 g_object_unref (pixbuf);
216
217 n_rects = g_random_int_range (12, 24);
218 for (i = 0; i < n_rects; i++)
219 {
220 ClutterActor *box = clutter_actor_new ();
221 ClutterColor bg_color = {
222 g_random_int_range (0, 255),
223 g_random_int_range (0, 255),
224 g_random_int_range (0, 255),
225 255
226 };
227 char *name, *str;
228
229 str = clutter_color_to_string (&bg_color);
230 name = g_strconcat ("Box <", color, ">", NULL);
231 clutter_actor_set_name (box, name);
232
233 free (name);
234 free (str);
235
236 if ((i % 2) == 0)
237 clutter_actor_set_content (box, color);
238 else
239 clutter_actor_set_content (box, image);
240
241 clutter_actor_set_size (box, 64, 64);
242
243 clutter_actor_add_child (grid, box);
244 }
245
246 clutter_main ();
247
248 g_object_unref (color);
249 g_object_unref (image);
250
251 return EXIT_SUCCESS;
252 }
253