1 #include <clutter/clutter.h>
2
3 #include "tests/clutter-test-utils.h"
4
5 static void
actor_add_child(void)6 actor_add_child (void)
7 {
8 ClutterActor *actor = clutter_actor_new ();
9 ClutterActor *iter;
10
11 g_object_ref_sink (actor);
12 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
13
14 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
15 "name", "foo",
16 NULL));
17 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
18 "name", "bar",
19 NULL));
20 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
21 "name", "baz",
22 NULL));
23
24 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
25
26 iter = clutter_actor_get_first_child (actor);
27 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
28
29 iter = clutter_actor_get_next_sibling (iter);
30 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
31
32 iter = clutter_actor_get_next_sibling (iter);
33 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
34 g_assert (iter == clutter_actor_get_last_child (actor));
35 g_assert (clutter_actor_get_next_sibling (iter) == NULL);
36
37 iter = clutter_actor_get_last_child (actor);
38 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
39
40 iter = clutter_actor_get_previous_sibling (iter);
41 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
42
43 iter = clutter_actor_get_previous_sibling (iter);
44 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
45 g_assert (iter == clutter_actor_get_first_child (actor));
46 g_assert (clutter_actor_get_previous_sibling (iter) == NULL);
47
48 clutter_actor_destroy (actor);
49 g_assert (actor == NULL);
50 }
51
52 static void
actor_insert_child(void)53 actor_insert_child (void)
54 {
55 ClutterActor *actor = clutter_actor_new ();
56 ClutterActor *iter;
57
58 g_object_ref_sink (actor);
59 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
60
61 clutter_actor_insert_child_at_index (actor,
62 g_object_new (CLUTTER_TYPE_ACTOR,
63 "name", "foo",
64 NULL),
65 0);
66
67 iter = clutter_actor_get_first_child (actor);
68 g_assert (iter != NULL);
69 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
70 g_assert (iter == clutter_actor_get_child_at_index (actor, 0));
71
72 clutter_actor_insert_child_below (actor,
73 g_object_new (CLUTTER_TYPE_ACTOR,
74 "name", "bar",
75 NULL),
76 iter);
77
78 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 2);
79
80 iter = clutter_actor_get_first_child (actor);
81 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
82 iter = clutter_actor_get_next_sibling (iter);
83 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
84 g_assert (iter == clutter_actor_get_child_at_index (actor, 1));
85
86 iter = clutter_actor_get_first_child (actor);
87 clutter_actor_insert_child_above (actor,
88 g_object_new (CLUTTER_TYPE_ACTOR,
89 "name", "baz",
90 NULL),
91 iter);
92
93 iter = clutter_actor_get_last_child (actor);
94 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
95
96 iter = clutter_actor_get_previous_sibling (iter);
97 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
98
99 iter = clutter_actor_get_previous_sibling (iter);
100 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
101
102 clutter_actor_remove_all_children (actor);
103
104 clutter_actor_insert_child_at_index (actor,
105 g_object_new (CLUTTER_TYPE_ACTOR,
106 "name", "1",
107 NULL),
108 0);
109 iter = clutter_actor_get_child_at_index (actor, 0);
110 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "1");
111 g_assert (clutter_actor_get_first_child (actor) == iter);
112 g_assert (clutter_actor_get_last_child (actor) == iter);
113
114 clutter_actor_insert_child_at_index (actor,
115 g_object_new (CLUTTER_TYPE_ACTOR,
116 "name", "2",
117 NULL),
118 0);
119 iter = clutter_actor_get_child_at_index (actor, 0);
120 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "2");
121 g_assert (clutter_actor_get_first_child (actor) == iter);
122 iter = clutter_actor_get_child_at_index (actor, 1);
123 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "1");
124 g_assert (clutter_actor_get_last_child (actor) == iter);
125
126 clutter_actor_insert_child_at_index (actor,
127 g_object_new (CLUTTER_TYPE_ACTOR,
128 "name", "3",
129 NULL),
130 -1);
131 iter = clutter_actor_get_child_at_index (actor, 2);
132 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "3");
133 g_assert (clutter_actor_get_last_child (actor) == iter);
134
135 clutter_actor_destroy (actor);
136 g_assert (actor == NULL);
137 }
138
139 static void
actor_remove_child(void)140 actor_remove_child (void)
141 {
142 ClutterActor *actor = clutter_actor_new ();
143 ClutterActor *iter;
144
145 g_object_ref_sink (actor);
146 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
147
148 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
149 "name", "foo",
150 NULL));
151 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
152 "name", "bar",
153 NULL));
154
155 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 2);
156
157 g_assert (clutter_actor_get_first_child (actor) != clutter_actor_get_last_child (actor));
158
159 iter = clutter_actor_get_first_child (actor);
160 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
161
162 iter = clutter_actor_get_last_child (actor);
163 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
164
165 clutter_actor_remove_child (actor, clutter_actor_get_first_child (actor));
166
167 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 1);
168
169 iter = clutter_actor_get_first_child (actor);
170 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
171 g_assert (clutter_actor_get_first_child (actor) == clutter_actor_get_last_child (actor));
172
173 clutter_actor_remove_child (actor, clutter_actor_get_first_child (actor));
174
175 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 0);
176 g_assert (clutter_actor_get_first_child (actor) == NULL);
177 g_assert (clutter_actor_get_last_child (actor) == NULL);
178
179 clutter_actor_destroy (actor);
180 g_assert (actor == NULL);
181 }
182
183 static void
actor_raise_child(void)184 actor_raise_child (void)
185 {
186 ClutterActor *actor = clutter_actor_new ();
187 ClutterActor *iter;
188 gboolean show_on_set_parent;
189
190 g_object_ref_sink (actor);
191 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
192
193 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
194 "name", "foo",
195 "visible", FALSE,
196 NULL));
197 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
198 "name", "bar",
199 "visible", FALSE,
200 NULL));
201 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
202 "name", "baz",
203 "visible", FALSE,
204 NULL));
205
206 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
207
208 iter = clutter_actor_get_child_at_index (actor, 1);
209 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
210
211 clutter_actor_set_child_above_sibling (actor, iter,
212 clutter_actor_get_child_at_index (actor, 2));
213
214 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
215 ==,
216 "foo");
217 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
218 ==,
219 "baz");
220 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
221 ==,
222 "bar");
223 g_assert (!clutter_actor_is_visible (iter));
224 g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
225 g_assert (!show_on_set_parent);
226
227 iter = clutter_actor_get_child_at_index (actor, 0);
228 clutter_actor_set_child_above_sibling (actor, iter, NULL);
229 g_object_add_weak_pointer (G_OBJECT (iter), (gpointer *) &iter);
230
231 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
232 ==,
233 "baz");
234 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
235 ==,
236 "bar");
237 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
238 ==,
239 "foo");
240 g_assert (!clutter_actor_is_visible (iter));
241 g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
242 g_assert (!show_on_set_parent);
243
244 clutter_actor_destroy (actor);
245 g_assert (actor == NULL);
246 g_assert (iter == NULL);
247 }
248
249 static void
actor_lower_child(void)250 actor_lower_child (void)
251 {
252 ClutterActor *actor = clutter_actor_new ();
253 ClutterActor *iter;
254 gboolean show_on_set_parent;
255
256 g_object_ref_sink (actor);
257 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
258
259 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
260 "name", "foo",
261 "visible", FALSE,
262 NULL));
263 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
264 "name", "bar",
265 "visible", FALSE,
266 NULL));
267 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
268 "name", "baz",
269 "visible", FALSE,
270 NULL));
271
272 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
273
274 iter = clutter_actor_get_child_at_index (actor, 1);
275 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
276
277 clutter_actor_set_child_below_sibling (actor, iter,
278 clutter_actor_get_child_at_index (actor, 0));
279
280 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
281 ==,
282 "bar");
283 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
284 ==,
285 "foo");
286 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
287 ==,
288 "baz");
289 g_assert (!clutter_actor_is_visible (iter));
290 g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
291 g_assert (!show_on_set_parent);
292
293 iter = clutter_actor_get_child_at_index (actor, 2);
294 clutter_actor_set_child_below_sibling (actor, iter, NULL);
295
296 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 0)),
297 ==,
298 "baz");
299 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 1)),
300 ==,
301 "bar");
302 g_assert_cmpstr (clutter_actor_get_name (clutter_actor_get_child_at_index (actor, 2)),
303 ==,
304 "foo");
305 g_assert (!clutter_actor_is_visible (iter));
306 g_object_get (iter, "show-on-set-parent", &show_on_set_parent, NULL);
307 g_assert (!show_on_set_parent);
308
309 clutter_actor_destroy (actor);
310 g_assert (actor == NULL);
311 }
312
313 static void
actor_replace_child(void)314 actor_replace_child (void)
315 {
316 ClutterActor *actor = clutter_actor_new ();
317 ClutterActor *iter;
318
319 g_object_ref_sink (actor);
320 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
321
322 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
323 "name", "foo",
324 NULL));
325 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
326 "name", "bar",
327 NULL));
328
329 iter = clutter_actor_get_child_at_index (actor, 0);
330 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
331
332 clutter_actor_replace_child (actor, iter,
333 g_object_new (CLUTTER_TYPE_ACTOR,
334 "name", "baz",
335 NULL));
336
337 iter = clutter_actor_get_child_at_index (actor, 0);
338 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
339
340 iter = clutter_actor_get_child_at_index (actor, 1);
341 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
342
343 clutter_actor_replace_child (actor, iter,
344 g_object_new (CLUTTER_TYPE_ACTOR,
345 "name", "qux",
346 NULL));
347
348 iter = clutter_actor_get_child_at_index (actor, 0);
349 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
350
351 iter = clutter_actor_get_child_at_index (actor, 1);
352 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "qux");
353
354 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
355 "name", "foo",
356 NULL));
357
358 clutter_actor_replace_child (actor, iter,
359 g_object_new (CLUTTER_TYPE_ACTOR,
360 "name", "bar",
361 NULL));
362
363 iter = clutter_actor_get_last_child (actor);
364 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "foo");
365 iter = clutter_actor_get_previous_sibling (iter);
366 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "bar");
367 iter = clutter_actor_get_previous_sibling (iter);
368 g_assert_cmpstr (clutter_actor_get_name (iter), ==, "baz");
369
370 clutter_actor_destroy (actor);
371 g_assert (actor == NULL);
372 }
373
374 static void
actor_remove_all(void)375 actor_remove_all (void)
376 {
377 ClutterActor *actor = clutter_actor_new ();
378
379 g_object_ref_sink (actor);
380 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
381
382 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
383 "name", "foo",
384 NULL));
385 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
386 "name", "bar",
387 NULL));
388 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
389 "name", "baz",
390 NULL));
391
392 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 3);
393
394 clutter_actor_remove_all_children (actor);
395
396 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 0);
397
398 clutter_actor_destroy (actor);
399 g_assert (actor == NULL);
400 }
401
402 static void
actor_added(ClutterContainer * container,ClutterActor * child,gpointer data)403 actor_added (ClutterContainer *container,
404 ClutterActor *child,
405 gpointer data)
406 {
407 ClutterActor *actor = CLUTTER_ACTOR (container);
408 int *counter = data;
409 ClutterActor *old_child;
410
411 if (!g_test_quiet ())
412 g_print ("Adding actor '%s'\n", clutter_actor_get_name (child));
413
414 old_child = clutter_actor_get_child_at_index (actor, 0);
415 if (old_child != child)
416 clutter_actor_remove_child (actor, old_child);
417
418 *counter += 1;
419 }
420
421 static void
actor_removed(ClutterContainer * container,ClutterActor * child,gpointer data)422 actor_removed (ClutterContainer *container,
423 ClutterActor *child,
424 gpointer data)
425 {
426 int *counter = data;
427
428 if (!g_test_quiet ())
429 g_print ("Removing actor '%s'\n", clutter_actor_get_name (child));
430
431 *counter += 1;
432 }
433
434 static void
actor_container_signals(void)435 actor_container_signals (void)
436 {
437 ClutterActor *actor = clutter_actor_new ();
438 int add_count, remove_count;
439
440 g_object_ref_sink (actor);
441 g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
442
443 add_count = remove_count = 0;
444 g_signal_connect (actor,
445 "actor-added", G_CALLBACK (actor_added),
446 &add_count);
447 g_signal_connect (actor,
448 "actor-removed", G_CALLBACK (actor_removed),
449 &remove_count);
450
451 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
452 "name", "foo",
453 NULL));
454
455 g_assert_cmpint (add_count, ==, 1);
456 g_assert_cmpint (remove_count, ==, 0);
457 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 1);
458
459 clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
460 "name", "bar",
461 NULL));
462
463 g_assert_cmpint (add_count, ==, 2);
464 g_assert_cmpint (remove_count, ==, 1);
465 g_assert_cmpint (clutter_actor_get_n_children (actor), ==, 1);
466
467 g_signal_handlers_disconnect_by_func (actor, G_CALLBACK (actor_added),
468 &add_count);
469 g_signal_handlers_disconnect_by_func (actor, G_CALLBACK (actor_removed),
470 &remove_count);
471
472 clutter_actor_destroy (actor);
473 g_assert (actor == NULL);
474 }
475
476 static void
actor_contains(void)477 actor_contains (void)
478 {
479 /* This build up the following tree:
480 *
481 * a
482 * ╱ │ ╲
483 * ╱ │ ╲
484 * b c d
485 * ╱ ╲ ╱ ╲ ╱ ╲
486 * e f g h i j
487 */
488 struct {
489 ClutterActor *actor_a, *actor_b, *actor_c, *actor_d, *actor_e;
490 ClutterActor *actor_f, *actor_g, *actor_h, *actor_i, *actor_j;
491 } d;
492 int x, y;
493 ClutterActor **actor_array = &d.actor_a;
494
495 /* Matrix of expected results */
496 static const gboolean expected_results[] =
497 { /* a, b, c, d, e, f, g, h, i, j */
498 /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
499 /* b */ 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
500 /* c */ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0,
501 /* d */ 0, 0, 0, 1, 0, 0, 0, 0, 1, 1,
502 /* e */ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
503 /* f */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
504 /* g */ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
505 /* h */ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
506 /* i */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
507 /* j */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
508 };
509
510 d.actor_a = clutter_actor_new ();
511 d.actor_b = clutter_actor_new ();
512 d.actor_c = clutter_actor_new ();
513 d.actor_d = clutter_actor_new ();
514 d.actor_e = clutter_actor_new ();
515 d.actor_f = clutter_actor_new ();
516 d.actor_g = clutter_actor_new ();
517 d.actor_h = clutter_actor_new ();
518 d.actor_i = clutter_actor_new ();
519 d.actor_j = clutter_actor_new ();
520
521 clutter_actor_add_child (d.actor_a, d.actor_b);
522 clutter_actor_add_child (d.actor_a, d.actor_c);
523 clutter_actor_add_child (d.actor_a, d.actor_d);
524
525 clutter_actor_add_child (d.actor_b, d.actor_e);
526 clutter_actor_add_child (d.actor_b, d.actor_f);
527
528 clutter_actor_add_child (d.actor_c, d.actor_g);
529 clutter_actor_add_child (d.actor_c, d.actor_h);
530
531 clutter_actor_add_child (d.actor_d, d.actor_i);
532 clutter_actor_add_child (d.actor_d, d.actor_j);
533
534 for (y = 0; y < 10; y++)
535 for (x = 0; x < 10; x++)
536 g_assert_cmpint (clutter_actor_contains (actor_array[x],
537 actor_array[y]),
538 ==,
539 expected_results[x * 10 + y]);
540 }
541
542 CLUTTER_TEST_SUITE (
543 CLUTTER_TEST_UNIT ("/actor/graph/add-child", actor_add_child)
544 CLUTTER_TEST_UNIT ("/actor/graph/insert-child", actor_insert_child)
545 CLUTTER_TEST_UNIT ("/actor/graph/remove-child", actor_remove_child)
546 CLUTTER_TEST_UNIT ("/actor/graph/raise-child", actor_raise_child)
547 CLUTTER_TEST_UNIT ("/actor/graph/lower-child", actor_lower_child)
548 CLUTTER_TEST_UNIT ("/actor/graph/replace-child", actor_replace_child)
549 CLUTTER_TEST_UNIT ("/actor/graph/remove-all", actor_remove_all)
550 CLUTTER_TEST_UNIT ("/actor/graph/container-signals", actor_container_signals)
551 CLUTTER_TEST_UNIT ("/actor/graph/contains", actor_contains)
552 )
553