Hi,
On Tue, 2007-10-23 at 16:57 +0300, Kate Alhola wrote:
> What is best way to highlight button (actor), so just
> simple thing, having active and passive texture for actor
> and then cross-fading them when button is acticated ?
>
Attached is a basic example which I pulled out from another project. It
sets up the stage and adds a ClutterGroup which is essentially the
'button'.
The button group contains everything that makes up the button, which is
the inactive and active representation of the button, plus a text label.
Another thing that the button has is a transparent rectangle which is
set to 'reactive'. This means that you can connect to input events on
that actor, and it basically acts like a GtkEventBox.
When there is a focus event, the 'active' representation of the button
is faded in/out depending on if it is a focus in or focus out event.
I hope that helps.
Neil Patel
/* compile with:
* gcc test.c -o test `pkg-config clutter-glx-0.5 --cflags --libs`
*/
#include <clutter/clutter.h>
#include <stdio.h>
#include <glib.h>
static ClutterActor *active; /* The active button */
static ClutterTimeline *main_timeline;
static ClutterTimeline *active_timeline = NULL;
static ClutterEffectTemplate *effect_temp;
static gboolean focused = FALSE;
static void on_fade_in_complete (ClutterActor *actor, gpointer null);
static void on_fade_out_complete (ClutterActor *actor, gpointer null);
static void
fade_in (void)
{
if (active_timeline)
g_object_unref (active_timeline);
active_timeline = clutter_effect_fade (effect_temp,
active,
clutter_actor_get_opacity (active),
255,
on_fade_in_complete,
NULL);
clutter_timeline_start (active_timeline);
}
static void
fade_out (void)
{
if (active_timeline)
g_object_unref (active_timeline);
active_timeline = clutter_effect_fade (effect_temp,
active,
clutter_actor_get_opacity (active),
0,
on_fade_out_complete,
NULL);
clutter_timeline_start (active_timeline);
}
static void
on_fade_in_complete (ClutterActor *actor, gpointer null)
{
if (!focused)
fade_out ();
}
static void
on_fade_out_complete (ClutterActor *actor, gpointer null)
{
if (focused)
fade_in ();
}
static gboolean
on_focus_in_event (ClutterActor *actor, ClutterCrossingEvent *e, gpointer null)
{
focused = TRUE;
if (clutter_timeline_is_playing (active_timeline))
return TRUE;
fade_in ();
return TRUE;
}
static gboolean
on_focus_out_event (ClutterActor *actor, ClutterCrossingEvent *e, gpointer null)
{
focused = FALSE;
if (clutter_timeline_is_playing (active_timeline))
return TRUE;
fade_out ();
return TRUE;
}
gint
main (gint argc, gchar *argv[])
{
ClutterColor blue = { 0x00, 0xff, 0x00, 0xff };
ClutterColor red = { 0xff, 0x00, 0x00, 0xff };
ClutterColor black = { 0x00, 0x00, 0x00, 0xff };
ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
ClutterActor *label, *stage, *button, *trans, *inactive;
GError *err = NULL;
clutter_init_with_args (&argc, &argv, NULL, NULL, NULL, &err);
if (err)
{
g_warning ("Unanble to init Clutter: %s\n", err->message);
g_error_free (err);
return 1;
}
stage = clutter_stage_get_default ();
clutter_actor_set_size (stage, 400, 200);
clutter_stage_set_color (CLUTTER_STAGE (stage), &blue);
/* Make sure actors receive motion events */
clutter_enable_motion_events (TRUE);
/* The button group */
button = clutter_group_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), button);
clutter_actor_set_size (button, 100, 40);
clutter_actor_set_position (button, 150, 60);
clutter_actor_set_reactive (button);
/* The transparent rectangle that captures the motion event (like a
* GtkEventBox) */
trans = clutter_rectangle_new_with_color (&black);
clutter_container_add_actor (CLUTTER_CONTAINER (button), trans);
clutter_actor_set_size (trans, 125, 80);
clutter_actor_set_position (trans, 0, 0);
clutter_actor_set_reactive (trans);
clutter_actor_set_opacity (trans, 255);
/* The inactive button */
inactive = clutter_rectangle_new_with_color (&red);
clutter_container_add_actor (CLUTTER_CONTAINER (button), inactive);
clutter_actor_set_size (inactive, 125, 80);
clutter_actor_set_position (inactive, 0, 0);
clutter_actor_unset_reactive (inactive);
/* The active button */
active = clutter_rectangle_new_with_color (&black);
clutter_container_add_actor (CLUTTER_CONTAINER (button), active);
clutter_actor_set_size (active, 125, 80);
clutter_actor_set_position (active, 0, 0);
clutter_actor_set_opacity (active, 0);
/* The label */
label = clutter_label_new_full ("Sans 14", "Hover over me", &white);
clutter_label_set_line_wrap (CLUTTER_LABEL (label), FALSE);
clutter_container_add_actor (CLUTTER_CONTAINER (button), label);
clutter_actor_set_size (label, 125, 80);
clutter_actor_set_position (label, 0, 25);
/* Set up the effect stuff */
main_timeline = active_timeline = clutter_timeline_new (40, 60);
effect_temp = clutter_effect_template_new (main_timeline,
clutter_sine_inc_func);
/* Hook up to the relevant events */
g_signal_connect (trans, "enter-event",
G_CALLBACK (on_focus_in_event), NULL);
g_signal_connect (trans, "leave-event",
G_CALLBACK (on_focus_out_event), NULL);
clutter_actor_show_all (button);
clutter_actor_show_all (stage);
clutter_main ();
return 0;
}