cookbook: Example of using a bind constraint for an overlay

Example code which loads an image into a texture, and resizes
the image in response to +/- key presses. The overlay is
a transparent rectangle which is bound to the height and
width of the texture; on clicking the texture, the overlay
is made visible by increasing its opacity.

This demonstrates how to use constraints to simplify code
for resizing an actor which is "dependent" on another actor.
This commit is contained in:
Elliot Smith 2010-09-15 15:50:32 +01:00
parent 68da998c9b
commit a0f63a3153
2 changed files with 137 additions and 0 deletions

View File

@ -10,6 +10,7 @@ noinst_PROGRAMS = \
textures-reflection \
textures-split-go \
textures-sub-texture \
layouts-bind-constraint-overlay \
layouts-stacking \
layouts-stacking-diff-sized-actors \
events-mouse-scroll \
@ -52,6 +53,7 @@ text_shadow_SOURCES = text-shadow.c
textures_reflection_SOURCES = textures-reflection.c
textures_split_go_SOURCES = textures-split-go.c
textures_sub_texture_SOURCES = textures-sub-texture.c
layouts_bind_constraint_overlay_SOURCES = layouts-bind-constraint-overlay.c
layouts_stacking_SOURCES = layouts-stacking.c
layouts_stacking_diff_sized_actors_SOURCES = layouts-stacking-diff-sized-actors.c
events_mouse_scroll_SOURCES = events-mouse-scroll.c

View File

@ -0,0 +1,135 @@
#include <stdlib.h>
#include <clutter/clutter.h>
#define STAGE_SIDE 400
#define RECTANGLE_SIDE STAGE_SIDE * 0.5
#define TEXTURE_SIZE_MAX STAGE_SIDE * 0.9
#define TEXTURE_SIZE_MIN STAGE_SIDE * 0.1
#define TEXTURE_SIZE_STEP 0.2
#define OVERLAY_OPACITY_OFF 0
#define OVERLAY_OPACITY_ON 100
static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
static const ClutterColor overlay_color = { 0xaa, 0x99, 0x00, 0xff };
/* change the texture size with +/- */
static gboolean
key_press_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
ClutterActor *texture;
gfloat texture_width, texture_height;
guint key_pressed;
texture = CLUTTER_ACTOR (user_data);
clutter_actor_get_size (texture, &texture_width, &texture_height);
key_pressed = clutter_event_get_key_symbol (event);
if (key_pressed == CLUTTER_KEY_plus)
{
texture_width *= 1.0 + TEXTURE_SIZE_STEP;
texture_height *= 1.0 + TEXTURE_SIZE_STEP;
}
else if (key_pressed == CLUTTER_KEY_minus)
{
texture_width *= 1.0 - TEXTURE_SIZE_STEP;
texture_height *= 1.0 - TEXTURE_SIZE_STEP;
}
if (texture_width <= TEXTURE_SIZE_MAX && texture_width >= TEXTURE_SIZE_MIN)
clutter_actor_animate (texture, CLUTTER_EASE_OUT_CUBIC, 500,
"width", texture_width,
"height", texture_height,
NULL);
return TRUE;
}
/* turn overlay opacity on/off */
static void
click_cb (ClutterClickAction *action,
ClutterActor *actor,
gpointer user_data)
{
ClutterActor *overlay = CLUTTER_ACTOR (user_data);
guint8 opacity = clutter_actor_get_opacity (overlay);
if (opacity < OVERLAY_OPACITY_ON)
opacity = OVERLAY_OPACITY_ON;
else
opacity = OVERLAY_OPACITY_OFF;
clutter_actor_set_opacity (overlay, opacity);
}
int
main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
ClutterActor *overlay;
ClutterAction *click;
GError *error = NULL;
gchar *filename = TESTS_DATA_DIR "/redhand.png";
if (argc > 1)
filename = argv[1];
clutter_init (&argc, &argv);
stage = clutter_stage_new ();
clutter_actor_set_size (stage, STAGE_SIDE, STAGE_SIDE);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_set_reactive (texture, TRUE);
clutter_actor_set_size (texture, RECTANGLE_SIDE, RECTANGLE_SIDE);
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5));
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
&error);
if (error != NULL)
{
g_warning ("Error loading %s\n%s", filename, error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
/* overlay is 10px wider and taller than the texture, and centered on it;
* initially, it is transparent; but it is made semi-opaque when the
* texture is clicked
*/
overlay = clutter_rectangle_new_with_color (&overlay_color);
clutter_actor_set_opacity (overlay, OVERLAY_OPACITY_OFF);
clutter_actor_add_constraint (overlay, clutter_bind_constraint_new (texture, CLUTTER_BIND_WIDTH, 10));
clutter_actor_add_constraint (overlay, clutter_bind_constraint_new (texture, CLUTTER_BIND_HEIGHT, 10));
clutter_actor_add_constraint (overlay, clutter_align_constraint_new (texture, CLUTTER_ALIGN_X_AXIS, 0.5));
clutter_actor_add_constraint (overlay, clutter_align_constraint_new (texture, CLUTTER_ALIGN_Y_AXIS, 0.5));
click = clutter_click_action_new ();
clutter_actor_add_action (texture, click);
clutter_container_add (CLUTTER_CONTAINER (stage), texture, overlay, NULL);
clutter_actor_raise_top (overlay);
g_signal_connect (click, "clicked", G_CALLBACK (click_cb), overlay);
g_signal_connect (stage,
"key-press-event",
G_CALLBACK (key_press_cb),
texture);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}