ClutterEffect

ClutterEffect — Base class for actor effects

Synopsis

struct              ClutterEffect;
struct              ClutterEffectClass;

Object Hierarchy

  GObject
   +----GInitiallyUnowned
         +----ClutterActorMeta
               +----ClutterEffect
                     +----ClutterOffscreenEffect

Description

The ClutterEffect class provides a default type and API for creating effects for generic actors.

Effects are a ClutterActorMeta sub-class that modify the way an actor is painted in a way that is not part of the actor's implementation.

Effects should be the preferred way to affect the paint sequence of an actor without sub-classing the actor itself and overriding the "paint" virtual function.

Implementing a ClutterEffect

Creating a sub-class of ClutterEffect requires the implementation of two virtual functions:

  • pre_paint(), which is called before painting the ClutterActor.
  • post_paint(), which is called after painting the ClutterActor.

The pre_paint() function should be used to set up the ClutterEffect right before the ClutterActor's paint sequence. This function can fail, and return FALSE; in that case, no post_paint() invocation will follow.

The post_paint() function is called after the ClutterActor's paint sequence.

The pre_paint() phase could be seen as a custom handler to the "paint" signal, while the post_paint() phase could be seen as a custom handler to the "paint" signal connected using g_signal_connect_after().

Example 3. A simple ClutterEffect implementation

The example below creates two rectangles: one will be painted "behind" the actor, while another will be painted "on top" of the actor. The set_actor() implementation will create the two materials used for the two different rectangles; the pre_paint() function will paint the first material using cogl_rectangle(), while the post_paint() phase will paint the second material.

 typedef struct {
   ClutterEffect parent_instance;

   CoglHandle rect_1;
   CoglHandle rect_2;
 } MyEffect;

 typedef struct _ClutterEffectClass MyEffectClass;

 G_DEFINE_TYPE (MyEffect, my_effect, CLUTTER_TYPE_EFFECT);

 static void
 my_effect_set_actor (ClutterActorMeta *meta,
                      ClutterActor     *actor)
 {
   MyEffect *self = MY_EFFECT (meta);

   /* Clear the previous state */
   if (self->rect_1)
     {
       cogl_handle_unref (self->rect_1);
       self->rect_1 = NULL;
     }

   if (self->rect_2)
     {
       cogl_handle_unref (self->rect_2);
       self->rect_2 = NULL;
     }

   /* Maintain a pointer to the actor *
   self->actor = actor;

   /* If we've been detached by the actor then we should
    * just bail out here
    */
   if (self->actor == NULL)
     return;

   /* Create a red material */
   self->rect_1 = cogl_material_new ();
   cogl_material_set_color4f (self->rect_1, 1.0, 0.0, 0.0, 1.0);

   /* Create a green material */
   self->rect_2 = cogl_material_new ();
   cogl_material_set_color4f (self->rect_2, 0.0, 1.0, 0.0, 1.0);
 }

 static gboolean
 my_effect_pre_paint (ClutterEffect *effect)
 {
   MyEffect *self = MY_EFFECT (effect);
   gfloat width, height;

   /* If we were disabled we don't need to paint anything */
   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
     return FALSE;

   clutter_actor_get_size (self->actor, &width, &height);

   /* Paint the first rectangle in the upper left quadrant */
   cogl_set_source (self->rect_1);
   cogl_rectangle (0, 0, width / 2, height / 2);

   return TRUE;
 }

 static void
 my_effect_post_paint (ClutterEffect *effect)
 {
   MyEffect *self = MY_EFFECT (effect);
   gfloat width, height;

   clutter_actor_get_size (self->actor, &width, &height);

   /* Paint the second rectangle in the lower right quadrant */
   cogl_set_source (self->rect_2);
   cogl_rectangle (width / 2, height / 2, width, height);
 }

 static void
 my_effect_class_init (MyEffectClass *klass)
 {
   ClutterActorMetaClas *meta_class = CLUTTER_ACTOR_META_CLASS (klass);

   meta_class->set_actor = my_effect_set_actor;

   klass->pre_paint = my_effect_pre_paint;
   klass->post_paint = my_effect_post_paint;
 }
    

ClutterEffect is available since Clutter 1.4

Details

struct ClutterEffect

struct ClutterEffect;

The ClutterEffect structure contains only private data and should be accessed using the provided API

Since 1.4


struct ClutterEffectClass

struct ClutterEffectClass {
  gboolean (* pre_paint)  (ClutterEffect *effect);
  void     (* post_paint) (ClutterEffect *effect);
};

The ClutterEffectClass structure contains only private data

pre_paint ()

virtual function

post_paint ()

virtual function

Since 1.4