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;
}

Reply via email to