1 #include <stdlib.h>
2 #include <math.h>
3 #include <cairo.h>
4 #include <clutter/clutter.h>
5
6 static gboolean
draw_content(ClutterCanvas * canvas,cairo_t * cr,int surface_width,int surface_height)7 draw_content (ClutterCanvas *canvas,
8 cairo_t *cr,
9 int surface_width,
10 int surface_height)
11 {
12 /* rounded rectangle taken from:
13 *
14 * http://cairographics.org/samples/rounded_rectangle/
15 *
16 * we leave 1 pixel around the edges to avoid jagged edges
17 * when rotating the actor
18 */
19 double x = 1.0, /* parameters like cairo_rectangle */
20 y = 1.0,
21 width = surface_width - 2.0,
22 height = surface_height - 2.0,
23 aspect = 1.0, /* aspect ratio */
24 corner_radius = height / 20.0; /* and corner curvature radius */
25
26 double radius = corner_radius / aspect;
27 double degrees = M_PI / 180.0;
28
29 cairo_save (cr);
30 cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
31 cairo_paint (cr);
32 cairo_restore (cr);
33
34 cairo_new_sub_path (cr);
35 cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
36 cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
37 cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
38 cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
39 cairo_close_path (cr);
40
41 cairo_set_source_rgba (cr, 0.5, 0.5, 1, 0.95);
42 cairo_fill (cr);
43
44 /* we're done drawing */
45 return TRUE;
46 }
47
48 int
main(int argc,char * argv[])49 main (int argc, char *argv[])
50 {
51 ClutterActor *stage, *actor;
52 ClutterContent *canvas;
53 ClutterTransition *transition;
54
55 /* initialize Clutter */
56 if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
57 return EXIT_FAILURE;
58
59 /* create a stage */
60 stage = clutter_stage_new ();
61 clutter_stage_set_title (CLUTTER_STAGE (stage), "Rectangle with rounded corners");
62 clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE);
63 clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black);
64 clutter_actor_set_size (stage, 500, 500);
65 clutter_actor_set_opacity (stage, 64);
66 clutter_actor_show (stage);
67
68 /* our 2D canvas, courtesy of Cairo */
69 canvas = clutter_canvas_new ();
70 clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 300, 300);
71
72 /* the actor that will display the contents of the canvas */
73 actor = clutter_actor_new ();
74 clutter_actor_set_content (actor, canvas);
75 clutter_actor_set_content_gravity (actor, CLUTTER_CONTENT_GRAVITY_CENTER);
76 clutter_actor_set_content_scaling_filters (actor,
77 CLUTTER_SCALING_FILTER_TRILINEAR,
78 CLUTTER_SCALING_FILTER_LINEAR);
79 clutter_actor_set_pivot_point (actor, 0.5f, 0.5f);
80 clutter_actor_add_constraint (actor, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5));
81 clutter_actor_set_request_mode (actor, CLUTTER_REQUEST_CONTENT_SIZE);
82 clutter_actor_add_child (stage, actor);
83
84 /* the actor now owns the canvas */
85 g_object_unref (canvas);
86
87 /* create the continuous animation of the actor spinning around its center */
88 transition = clutter_property_transition_new ("rotation-angle-y");
89 clutter_transition_set_from (transition, G_TYPE_DOUBLE, 0.0);
90 clutter_transition_set_to (transition, G_TYPE_DOUBLE, 360.0);
91 clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 2000);
92 clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), -1);
93 clutter_actor_add_transition (actor, "rotateActor", transition);
94
95 /* the actor now owns the transition */
96 g_object_unref (transition);
97
98 /* quit on destroy */
99 g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
100
101 /* connect our drawing code */
102 g_signal_connect (canvas, "draw", G_CALLBACK (draw_content), NULL);
103
104 /* invalidate the canvas, so that we can draw before the main loop starts */
105 clutter_content_invalidate (canvas);
106
107 clutter_main ();
108
109 return EXIT_SUCCESS;
110 }
111