mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
Add rounded corners rectangle example using Canvas
An old request: how to create a rectangle with rounded corners with Clutter; we use ClutterCanvas and Cairo because we want anti-aliased edges.
This commit is contained in:
parent
2bb84d9169
commit
b7c76a45bc
@ -9,6 +9,7 @@ all_examples = \
|
|||||||
drop-action \
|
drop-action \
|
||||||
easing-modes \
|
easing-modes \
|
||||||
flow-layout \
|
flow-layout \
|
||||||
|
rounded-rectangle \
|
||||||
threads
|
threads
|
||||||
|
|
||||||
if PIXBUF_TESTS
|
if PIXBUF_TESTS
|
||||||
|
107
examples/rounded-rectangle.c
Normal file
107
examples/rounded-rectangle.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
draw_content (ClutterCanvas *canvas,
|
||||||
|
cairo_t *cr,
|
||||||
|
int surface_width,
|
||||||
|
int surface_height)
|
||||||
|
{
|
||||||
|
/* rounded rectangle taken from:
|
||||||
|
*
|
||||||
|
* http://cairographics.org/samples/rounded_rectangle/
|
||||||
|
*
|
||||||
|
* we leave 1 pixel around the edges to avoid jagged edges
|
||||||
|
* when rotating the actor
|
||||||
|
*/
|
||||||
|
double x = 1.0, /* parameters like cairo_rectangle */
|
||||||
|
y = 1.0,
|
||||||
|
width = surface_width - 2.0,
|
||||||
|
height = surface_height - 2.0,
|
||||||
|
aspect = 1.0, /* aspect ratio */
|
||||||
|
corner_radius = height / 20.0; /* and corner curvature radius */
|
||||||
|
|
||||||
|
double radius = corner_radius / aspect;
|
||||||
|
double degrees = M_PI / 180.0;
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||||
|
cairo_paint (cr);
|
||||||
|
cairo_restore (cr);
|
||||||
|
|
||||||
|
cairo_new_sub_path (cr);
|
||||||
|
cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
|
||||||
|
cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
|
||||||
|
cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
|
||||||
|
cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
|
||||||
|
cairo_close_path (cr);
|
||||||
|
|
||||||
|
cairo_set_source_rgb (cr, 0.5, 0.5, 1);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
/* we're done drawing */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_rotation (actor, CLUTTER_Y_AXIS, 0.0, 250.f, 0.f, 0.f);
|
||||||
|
clutter_actor_add_constraint (actor, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.f));
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user