From 5732b1184f013ce9ca33580e214d60400f00d271 Mon Sep 17 00:00:00 2001
From: Elliot Smith <elliot.smith@intel.com>
Date: Tue, 8 Mar 2011 14:54:00 +0000
Subject: [PATCH] docs: Add example of setting background color with
 ClutterEffect

Add example of a simple background color effect applied via
pre_paint() implementation in a ClutterEffect subclass.

This is a simple effect with an incomplete GObject
implementation (no properties, setters or getters)
to make it as easy to follow as possible.
---
 doc/cookbook/examples/Makefile.am            |   6 +-
 doc/cookbook/examples/cb-background-effect.c | 110 +++++++++++++++++++
 doc/cookbook/examples/cb-background-effect.h |  42 +++++++
 doc/cookbook/examples/effects-basic.c        |  37 +++++--
 4 files changed, 182 insertions(+), 13 deletions(-)
 create mode 100644 doc/cookbook/examples/cb-background-effect.c
 create mode 100644 doc/cookbook/examples/cb-background-effect.h

diff --git a/doc/cookbook/examples/Makefile.am b/doc/cookbook/examples/Makefile.am
index 6f0c4b396..52fec52f7 100644
--- a/doc/cookbook/examples/Makefile.am
+++ b/doc/cookbook/examples/Makefile.am
@@ -84,7 +84,11 @@ animations_reuse_SOURCES                   = animations-reuse.c
 animations_rotating_SOURCES                = animations-rotating.c
 animations_scaling_SOURCES                 = animations-scaling.c
 animations_scaling_zoom_SOURCES            = animations-scaling-zoom.c
-effects_basic_SOURCES                      = cb-border-effect.c cb-border-effect.h effects-basic.c
+effects_basic_SOURCES                      = cb-border-effect.c \
+                                             cb-border-effect.h \
+                                             cb-background-effect.c \
+                                             cb-background-effect.h \
+                                             effects-basic.c
 effects_built_in_SOURCES                   = effects-built-in.c
 effects_custom_deform_SOURCES              = cb-page-fold-effect.c cb-page-fold-effect.h effects-custom-deform.c
 text_shadow_SOURCES                        = text-shadow.c
diff --git a/doc/cookbook/examples/cb-background-effect.c b/doc/cookbook/examples/cb-background-effect.c
new file mode 100644
index 000000000..71b2ceee2
--- /dev/null
+++ b/doc/cookbook/examples/cb-background-effect.c
@@ -0,0 +1,110 @@
+#include "cb-background-effect.h"
+
+G_DEFINE_TYPE (CbBackgroundEffect, cb_background_effect, CLUTTER_TYPE_EFFECT);
+
+#define CB_BACKGROUND_EFFECT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+                                                                            CB_TYPE_BACKGROUND_EFFECT, \
+                                                                            CbBackgroundEffectPrivate))
+
+struct _CbBackgroundEffectPrivate
+{
+  CoglMaterial *background;
+  CoglColor    *color;
+};
+
+/* ClutterEffect implementation */
+
+/* note that if pre_paint() returns FALSE
+ * any post_paint() defined for the effect will not be called
+ */
+static gboolean
+cb_background_effect_pre_paint (ClutterEffect *self)
+{
+  ClutterActor *actor;
+  gfloat width;
+  gfloat height;
+  CbBackgroundEffectPrivate *priv;
+
+  ClutterActorMeta *meta = CLUTTER_ACTOR_META (self);
+
+  /* check that the effect is enabled before applying it */
+  if (!clutter_actor_meta_get_enabled (meta))
+    return TRUE;
+
+  priv = CB_BACKGROUND_EFFECT (self)->priv;
+
+  /* get the associated actor's dimensions */
+  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
+  clutter_actor_get_size (actor, &width, &height);
+
+  /* draw a grey Cogl rectangle in the background */
+  cogl_set_source (priv->background);
+
+  cogl_rectangle (0, 0, width, height);
+
+  return TRUE;
+}
+
+/* GObject implementation */
+static void
+cb_background_effect_dispose (GObject *gobject)
+{
+  CbBackgroundEffectPrivate *priv = CB_BACKGROUND_EFFECT (gobject)->priv;
+
+  if (priv->background != COGL_INVALID_HANDLE)
+    {
+      cogl_handle_unref (priv->background);
+      priv->background = COGL_INVALID_HANDLE;
+    }
+
+  if (priv->color != NULL)
+    {
+      cogl_color_free (priv->color);
+      priv->color = NULL;
+    }
+
+  G_OBJECT_CLASS (cb_background_effect_parent_class)->dispose (gobject);
+}
+
+static void
+cb_background_effect_class_init (CbBackgroundEffectClass *klass)
+{
+  ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  effect_class->pre_paint = cb_background_effect_pre_paint;
+  gobject_class->dispose = cb_background_effect_dispose;
+
+  g_type_class_add_private (klass, sizeof (CbBackgroundEffectPrivate));
+}
+
+static void
+cb_background_effect_init (CbBackgroundEffect *self)
+{
+  CbBackgroundEffectPrivate *priv;
+
+  priv = self->priv = CB_BACKGROUND_EFFECT_GET_PRIVATE (self);
+
+  priv->background = cogl_material_new ();
+
+  /* grey color for filling the background material */
+  priv->color = cogl_color_new ();
+  cogl_color_init_from_4ub (priv->color, 122, 122, 122, 255);
+
+  cogl_material_set_color (priv->background, priv->color);
+}
+
+/* public API */
+
+/**
+ * cb_background_effect_new:
+ *
+ * Creates a new #ClutterEffect which adds a grey background
+ * when applied to a rectangular actor.
+ */
+ClutterEffect *
+cb_background_effect_new ()
+{
+  return g_object_new (CB_TYPE_BACKGROUND_EFFECT,
+                       NULL);
+}
diff --git a/doc/cookbook/examples/cb-background-effect.h b/doc/cookbook/examples/cb-background-effect.h
new file mode 100644
index 000000000..b2ce987e3
--- /dev/null
+++ b/doc/cookbook/examples/cb-background-effect.h
@@ -0,0 +1,42 @@
+#ifndef __CB_BACKGROUND_EFFECT_H__
+#define __CB_BACKGROUND_EFFECT_H__
+
+#include <clutter/clutter.h>
+
+GType cb_background_effect_get_type (void);
+
+#define CB_TYPE_BACKGROUND_EFFECT (cb_background_effect_get_type ())
+#define CB_BACKGROUND_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                                                               CB_TYPE_BACKGROUND_EFFECT, \
+                                                               CbBackgroundEffect))
+#define CB_IS_BACKGROUND_EFFECT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+                                                                          CB_TYPE_BACKGROUND_EFFECT))
+#define CB_BACKGROUND_EFFECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), \
+                                                                       CB_TYPE_BACKGROUND_EFFECT, \
+                                                                       CbBackgroundEffectClass))
+#define CB_IS_BACKGROUND_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+                                                                       CB_TYPE_BACKGROUND_EFFECT))
+#define CB_BACKGROUND_EFFECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                                                                         CB_TYPE_BACKGROUND_EFFECT, \
+                                                                         CbBackgroundEffectClass))
+
+typedef struct _CbBackgroundEffectPrivate CbBackgroundEffectPrivate;
+typedef struct _CbBackgroundEffect        CbBackgroundEffect;
+typedef struct _CbBackgroundEffectClass   CbBackgroundEffectClass;
+
+/* object */
+struct _CbBackgroundEffect
+{
+  ClutterEffect              parent_instance;
+  CbBackgroundEffectPrivate *priv;
+};
+
+/* class */
+struct _CbBackgroundEffectClass
+{
+  ClutterEffectClass parent_class;
+};
+
+ClutterEffect *cb_background_effect_new ();
+
+#endif /* __CB_BACKGROUND_EFFECT_H__ */
diff --git a/doc/cookbook/examples/effects-basic.c b/doc/cookbook/examples/effects-basic.c
index a59291f24..875e4c8e5 100644
--- a/doc/cookbook/examples/effects-basic.c
+++ b/doc/cookbook/examples/effects-basic.c
@@ -2,14 +2,15 @@
 #include <clutter/clutter.h>
 
 #include "cb-border-effect.h"
+#include "cb-background-effect.h"
 
 static const ClutterColor stage_color = { 0x33, 0x33, 0x55, 0xff };
 static ClutterColor red_color = { 0xff, 0x00, 0x00, 0xff };
 
 static gboolean
-add_highlight (ClutterActor *actor,
-               ClutterEvent *event,
-               gpointer      user_data)
+toggle_highlight (ClutterActor *actor,
+                  ClutterEvent *event,
+                  gpointer      user_data)
 {
   ClutterActorMeta *meta = CLUTTER_ACTOR_META (user_data);
 
@@ -30,7 +31,9 @@ main (int   argc,
   ClutterActor *box;
   ClutterLayoutManager *layout_manager;
   ClutterActor *texture;
-  ClutterEffect *effect;
+  ClutterEffect *background_effect;
+  ClutterEffect *border_effect;
+  ClutterConstraint *width_constraint;
   gchar *filename;
   guint i;
   GError *error = NULL;
@@ -57,7 +60,10 @@ main (int   argc,
                                        10);
 
   box = clutter_box_new (layout_manager);
-  clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_WIDTH, 0.0));
+  width_constraint = clutter_bind_constraint_new (stage,
+                                                  CLUTTER_BIND_WIDTH,
+                                                  0.0);
+  clutter_actor_add_constraint (box, width_constraint);
 
   /* loop through the files specified on the command line, adding
    * each one into the box
@@ -80,18 +86,25 @@ main (int   argc,
                    filename,
                    error->message);
 
-      /* create a 5 pixel red border effect */
-      effect = cb_border_effect_new (5.0, &red_color);
+      /* create a grey background effect */
+      background_effect = cb_background_effect_new ();
 
-      /* add the effect to the actor, but disabled */
-      clutter_actor_add_effect (texture, effect);
-      clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
+      /* apply the effect to the actor */
+      clutter_actor_add_effect (texture, background_effect);
+
+      /* create a 5 pixel red border effect */
+      border_effect = cb_border_effect_new (5.0, &red_color);
+
+      /* apply the effect to the actor, but disabled */
+      clutter_actor_add_effect (texture, border_effect);
+      clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (border_effect),
+                                      FALSE);
 
       /* on mouse click, toggle the "enabled" property of the border effect */
       g_signal_connect (texture,
                         "button-press-event",
-                        G_CALLBACK (add_highlight),
-                        effect);
+                        G_CALLBACK (toggle_highlight),
+                        border_effect);
 
       clutter_container_add_actor (CLUTTER_CONTAINER (box), texture);
     }