[clutter/wip/actor-content: 12/24] Add ClutterContent
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/actor-content: 12/24] Add ClutterContent
- Date: Fri, 15 Apr 2011 16:44:45 +0000 (UTC)
commit 02d1e5c6ae6e485d5cabf83534b0e2c650757540
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Thu Nov 18 18:15:22 2010 +0000
Add ClutterContent
ClutterContent is an interface that provides a "paint object" API
that can be used to abstract (and share) the painting logic of an
actor.
clutter/Makefile.am | 3 +
clutter/clutter-content-private.h | 20 ++
clutter/clutter-content.c | 396 +++++++++++++++++++++++++++++++++++++
clutter/clutter-content.h | 73 +++++++
clutter/clutter-types.h | 2 +
clutter/clutter.h | 1 +
6 files changed, 495 insertions(+), 0 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 40328f3..f1d7fdb 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -101,6 +101,7 @@ source_h = \
$(srcdir)/clutter-colorize-effect.h \
$(srcdir)/clutter-constraint.h \
$(srcdir)/clutter-container.h \
+ $(srcdir)/clutter-content.h \
$(srcdir)/clutter-deform-effect.h \
$(srcdir)/clutter-deprecated.h \
$(srcdir)/clutter-desaturate-effect.h \
@@ -186,6 +187,7 @@ source_c = \
$(srcdir)/clutter-colorize-effect.c \
$(srcdir)/clutter-constraint.c \
$(srcdir)/clutter-container.c \
+ $(srcdir)/clutter-content.c \
$(srcdir)/clutter-deform-effect.c \
$(srcdir)/clutter-desaturate-effect.c \
$(srcdir)/clutter-device-manager.c \
@@ -244,6 +246,7 @@ source_h_priv = \
$(srcdir)/clutter-actor-private.h \
$(srcdir)/clutter-backend-private.h \
$(srcdir)/clutter-bezier.h \
+ $(srcdir)/clutter-content-private.h \
$(srcdir)/clutter-debug.h \
$(srcdir)/clutter-device-manager-private.h \
$(srcdir)/clutter-effect-private.h \
diff --git a/clutter/clutter-content-private.h b/clutter/clutter-content-private.h
new file mode 100644
index 0000000..5afb026
--- /dev/null
+++ b/clutter/clutter-content-private.h
@@ -0,0 +1,20 @@
+#ifndef __CLUTTER_CONTENT_PRIVATE_H__
+#define __CLUTTER_CONTENT_PRIVATE_H__
+
+#include <clutter/clutter-content.h>
+
+G_BEGIN_DECLS
+
+void _clutter_content_add_actor (ClutterContent *content,
+ ClutterActor *actor);
+void _clutter_content_remove_actor (ClutterContent *content,
+ ClutterActor *actor);
+GHashTable * _clutter_content_get_actors (ClutterContent *content);
+
+void _clutter_content_pick_content (ClutterContent *content,
+ ClutterActor *actor,
+ const ClutterColor *pick_color);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_CONTENT_PRIVATE_H__ */
diff --git a/clutter/clutter-content.c b/clutter/clutter-content.c
new file mode 100644
index 0000000..d09045c
--- /dev/null
+++ b/clutter/clutter-content.c
@@ -0,0 +1,396 @@
+/**
+ * SECTION:clutter-content
+ * @Title: ClutterContent
+ * @Short_Description: Retained paint objects
+ *
+ * #ClutterContent is an interface implemented by objects that provide a way
+ * to paint a #ClutterActor.
+ *
+ * A #ClutterContent implementation should provide the geometry of the paint
+ * mask, and the actual changes to the state of the pipeline, as represented
+ * by a Cogl material.
+ *
+ * Each #ClutterActor can use a #ClutterContent implementation to paint
+ * itself; multiple #ClutterActor<!-- -->s can share the same #ClutterContent
+ * instance.
+ *
+ * #ClutterContent is available since Clutter 1.8.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "clutter-content-private.h"
+#include "clutter-private.h"
+
+#include "clutter-actor.h"
+
+/**
+ * ClutterContent:
+ *
+ * <structname>ClutterContent</structname> is an opaque structure whose
+ * members cannot be directly accessed.
+ *
+ * Since: 1.8
+ */
+
+static GQuark quark_content_actor = 0;
+
+/* for G_DEFINE_INTERFACE */
+typedef ClutterContentIface ClutterContentInterface;
+
+G_DEFINE_INTERFACE (ClutterContent, clutter_content, G_TYPE_OBJECT);
+
+static void
+clutter_content_real_update_geometry (ClutterContent *content,
+ ClutterActor *actor)
+{
+ ClutterActorBox allocation;
+
+ clutter_actor_get_allocation_box (actor, &allocation);
+
+ cogl_rectangle (0, 0,
+ clutter_actor_box_get_width (&allocation),
+ clutter_actor_box_get_height (&allocation));
+}
+
+static gboolean
+clutter_content_real_setup_material (ClutterContent *content,
+ ClutterActor *actor)
+{
+ guint8 paint_opacity;
+
+ paint_opacity = clutter_actor_get_paint_opacity (actor);
+
+ cogl_set_source_color4f (0.0, 0.0, 0.0, paint_opacity / 255.0);
+
+ return TRUE;
+}
+
+static void
+clutter_content_real_paint_content (ClutterContent *content,
+ ClutterActor *actor)
+{
+ if (!clutter_content_setup_material (content, actor))
+ return;
+
+ clutter_content_update_geometry (content, actor);
+}
+
+static gboolean
+clutter_content_real_get_paint_volume (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintVolume *volume)
+{
+ /* we don't have to maintain backward compatibility, so we can
+ * default all Content implementations to the actor's allocation
+ * without breaking anything
+ */
+ clutter_paint_volume_set_from_allocation (volume, actor);
+
+ return TRUE;
+}
+
+static void
+clutter_content_real_invalidate (ClutterContent *content)
+{
+ GHashTable *actors = _clutter_content_get_actors (content);
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (actors == NULL)
+ return;
+
+ key = value = NULL;
+ g_hash_table_iter_init (&iter, actors);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ ClutterActor *actor = key;
+
+ g_assert (actor != NULL);
+
+ clutter_actor_queue_redraw (actor);
+ }
+}
+
+static void
+clutter_content_default_init (ClutterContentInterface *iface)
+{
+ quark_content_actor = g_quark_from_static_string ("clutter-content-actors");
+
+ iface->setup_material = clutter_content_real_setup_material;
+ iface->update_geometry = clutter_content_real_update_geometry;
+ iface->paint_content = clutter_content_real_paint_content;
+ iface->get_paint_volume = clutter_content_real_get_paint_volume;
+ iface->invalidate = clutter_content_real_invalidate;
+}
+
+/**
+ * clutter_content_setup_material:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ *
+ * Sets up the material for the given @actor.
+ *
+ * #ClutterContent implementations that provide a specific material
+ * as the source should override this virtual function in the
+ * #ClutterContent interface.
+ *
+ * An example implementation that paints a solid red color is:
+ *
+ * |[
+ * static gboolean
+ * setup_material (ClutterContent *content,
+ * ClutterActor *actor)
+ * {
+ * cogl_set_source_color_4f (1.0, 0.0, 0.0, 1.0);
+ *
+ * return TRUE;
+ * }
+ * ]|
+ *
+ * <note>If the implementation returns %FALSE, the #ClutterContent default
+ * implementation of the <function>paint_content</function> virtual function
+ * will not call clutter_content_update_geometry().</note>
+ *
+ * Return value: %TRUE if the material was set up correctly, and
+ * the @content should be painted, and %FALSE otherwise.
+ *
+ * Since: 1.8
+ */
+gboolean
+clutter_content_setup_material (ClutterContent *content,
+ ClutterActor *actor)
+{
+ g_return_val_if_fail (CLUTTER_IS_CONTENT (content), FALSE);
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
+
+ return CLUTTER_CONTENT_GET_IFACE (content)->setup_material (content, actor);
+}
+
+/**
+ * clutter_content_update_geometry:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ *
+ * Updates the geometry for the given @actor.
+ *
+ * #ClutterContent implementations that submit a geometry that is
+ * not a rectangle filling the @actor's allocation should override
+ * this virtual function in the #ClutterContent interface.
+ *
+ * An example implementation that submits a geometry in the shape
+ * of a triangle is:
+ *
+ * |[
+ * static void
+ * update_geometry (ClutterContent *content,
+ * ClutterActor *actor)
+ * {
+ * ClutterActorBox allocation;
+ * float width, height;
+ *
+ * clutter_actor_get_allocation_box (actor, &allocation);
+ * clutter_actor_box_get_size (actor, &width, &height);
+ *
+ * if (width > 0 && height > 0)
+ * {
+ * cogl_path_new ();
+ *
+ * cogl_path_move_to (0, height);
+ * cogl_path_line_to (width / 2, 0);
+ * cogl_path_line_to (width, height);
+ * cogl_path_close ();
+ *
+ * /* fill the path with the material set in the
+ * * setup_material() virtual function
+ * */
+ * cogl_path_fill ();
+ * }
+ * }
+ * ]|
+ *
+ * <note>This function will also be called by #ClutterActor when picking,
+ * to maintain the geometry used when painting.</note>
+ *
+ * Since: 1.8
+ */
+void
+clutter_content_update_geometry (ClutterContent *content,
+ ClutterActor *actor)
+{
+ g_return_if_fail (CLUTTER_IS_CONTENT (content));
+ g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+ CLUTTER_CONTENT_GET_IFACE (content)->update_geometry (content, actor);
+}
+
+/**
+ * clutter_content_paint_content:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ *
+ * Updates the graphics pipeline for the given @actor.
+ *
+ * #ClutterContent implementation should seldomly override this
+ * virtual function.
+ *
+ * The default implementation for #ClutterContent will call
+ * clutter_content_setup_material() and, depending on the returned
+ * value, clutter_content_update_geometry(). Any #ClutterContent
+ * implementation might decide to override either of these virtual
+ * functions, or override the <function>paint_content</function>
+ * virtual function entirely.
+ *
+ * #ClutterActor will call clutter_content_paint_content() when
+ * painting.
+ *
+ * Since: 1.8
+ */
+void
+clutter_content_paint_content (ClutterContent *content,
+ ClutterActor *actor)
+{
+ g_return_if_fail (CLUTTER_IS_CONTENT (content));
+ g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+ CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor);
+}
+
+/*< private >
+ * clutter_content_pick_content:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ * @pick_color: the color used to pick @actor
+ *
+ * Updates the graphics pipeline to paint the given @actor in pick
+ * mode, using the @content's geometry.
+ *
+ * This is an internal method called by the default pick implementation
+ * inside #ClutterActor.
+ *
+ * Since: 1.8
+ */
+void
+_clutter_content_pick_content (ClutterContent *content,
+ ClutterActor *actor,
+ const ClutterColor *pick_color)
+{
+ cogl_set_source_color4ub (pick_color->red,
+ pick_color->green,
+ pick_color->blue,
+ pick_color->alpha);
+
+ clutter_content_update_geometry (content, actor);
+}
+
+/**
+ * clutter_content_get_paint_volume:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ * @volume: a #ClutterPaintVolume
+ *
+ * Asks @content to modify a #ClutterActor's paint volume, in case
+ * the #ClutterContent instance should paint outside the allocation
+ * of @actor.
+ *
+ * Return value: %TRUE if the paint volume is valid, and %FALSE if
+ * it is invalid and should be discarded
+ *
+ * Since: 1.8
+ */
+gboolean
+clutter_content_get_paint_volume (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintVolume *volume)
+{
+ g_return_val_if_fail (CLUTTER_IS_CONTENT (content), FALSE);
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
+ g_return_val_if_fail (volume != NULL, FALSE);
+
+ return CLUTTER_CONTENT_GET_IFACE (content)->get_paint_volume (content,
+ actor,
+ volume);
+}
+
+/*< private >
+ * clutter_content_get_actors:
+ * @content: a #ClutterContent
+ *
+ * Retrieves a pointer to the list of #ClutterActor<!-- -->s using
+ * @content to paint themselves.
+ *
+ * Return value: a #GHashTable of #ClutterActor instances. The list is
+ * owned by the #ClutterContent and it should not be freed
+ */
+GHashTable *
+_clutter_content_get_actors (ClutterContent *content)
+{
+ return g_object_get_qdata (G_OBJECT (content), quark_content_actor);
+}
+
+/*< private >
+ * clutter_content_remove_actor:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ *
+ * Removes @actor from the list of #ClutterActor<!-- -->s using @content
+ * to paint themselves.
+ */
+void
+_clutter_content_remove_actor (ClutterContent *content,
+ ClutterActor *actor)
+{
+ GHashTable *actors = _clutter_content_get_actors (content);
+
+ if (G_UNLIKELY (actors == NULL))
+ return;
+
+ g_hash_table_remove (actors, actor);
+}
+
+/*< private >
+ * clutter_content_add_actor:
+ * @content: a #ClutterContent
+ * @actor: a #ClutterActor
+ *
+ * Adds @actor to the list of #ClutterActor<!-- -->s using @content
+ * when painting themselves.
+ */
+void
+_clutter_content_add_actor (ClutterContent *content,
+ ClutterActor *actor)
+{
+ GHashTable *actors = _clutter_content_get_actors (content);
+
+ if (G_UNLIKELY (actors == NULL))
+ {
+ actors = g_hash_table_new (NULL, NULL);
+ g_object_set_qdata_full (G_OBJECT (content), quark_content_actor,
+ actors,
+ (GDestroyNotify) g_hash_table_destroy);
+ }
+
+ g_hash_table_insert (actors, actor, GUINT_TO_POINTER (1));
+}
+
+/**
+ * clutter_content_invalidate:
+ * @content: a #ClutterContent
+ *
+ * Invalidates a #ClutterContent and causes a redraw to be queued on
+ * every actor using @content.
+ *
+ * This function should only be called by #ClutterContent implementations
+ * that have parameters affecting the way they are painted.
+ *
+ * Since: 1.8
+ */
+void
+clutter_content_invalidate (ClutterContent *content)
+{
+ g_return_if_fail (CLUTTER_IS_CONTENT (content));
+
+ CLUTTER_CONTENT_GET_IFACE (content)->invalidate (content);
+}
diff --git a/clutter/clutter-content.h b/clutter/clutter-content.h
new file mode 100644
index 0000000..6d59ab5
--- /dev/null
+++ b/clutter/clutter-content.h
@@ -0,0 +1,73 @@
+#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only <clutter/clutter.h> can be included directly."
+#endif
+
+#ifndef __CLUTTER_CONTENT_H__
+#define __CLUTTER_CONTENT_H__
+
+#include <clutter/clutter-types.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_CONTENT (clutter_content_get_type ())
+#define CLUTTER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONTENT, ClutterContent))
+#define CLUTTER_IS_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTENT))
+#define CLUTTER_CONTENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTENT, ClutterContentIface))
+
+typedef struct _ClutterContentIface ClutterContentIface;
+
+/**
+ * ClutterContentIface:
+ * @setup_material: virtual function, used to set up the material used
+ * by the content
+ * @update_geometry: virtual function, used to update the geometry of the
+ * content for the given actor
+ * @paint_content: virtual function, used to paint the content for
+ * the given actor
+ * @get_paint_volume: virtual function, used to update the paint volume
+ * for the given actor
+ * @invalidate: virtual function, used to notify actors of a content
+ * update
+ *
+ * Interface for #ClutterActor contents.
+ *
+ * Since: 1.8
+ */
+struct _ClutterContentIface
+{
+ /*< private >*/
+ GTypeInterface g_iface;
+
+ /*< public >*/
+ gboolean (* setup_material) (ClutterContent *content,
+ ClutterActor *actor);
+ void (* update_geometry) (ClutterContent *content,
+ ClutterActor *actor);
+ void (* paint_content) (ClutterContent *content,
+ ClutterActor *actor);
+
+ gboolean (* get_paint_volume) (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintVolume *volume);
+
+ void (* invalidate) (ClutterContent *content);
+};
+
+GType clutter_content_get_type (void) G_GNUC_CONST;
+
+gboolean clutter_content_setup_material (ClutterContent *content,
+ ClutterActor *actor);
+void clutter_content_update_geometry (ClutterContent *content,
+ ClutterActor *actor);
+void clutter_content_paint_content (ClutterContent *content,
+ ClutterActor *actor);
+
+gboolean clutter_content_get_paint_volume (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintVolume *volume);
+
+void clutter_content_invalidate (ClutterContent *content);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_CONTENT_H__ */
diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h
index 8ad7261..f4de269 100644
--- a/clutter/clutter-types.h
+++ b/clutter/clutter-types.h
@@ -53,6 +53,8 @@ typedef struct _ClutterAction ClutterAction;
typedef struct _ClutterConstraint ClutterConstraint;
typedef struct _ClutterEffect ClutterEffect;
+typedef struct _ClutterContent ClutterContent; /* dummy */
+
typedef struct _ClutterShader ClutterShader;
typedef struct _ClutterColor ClutterColor;
diff --git a/clutter/clutter.h b/clutter/clutter.h
index 1baf56e..e5cebc3 100644
--- a/clutter/clutter.h
+++ b/clutter/clutter.h
@@ -63,6 +63,7 @@
#include "clutter-colorize-effect.h"
#include "clutter-constraint.h"
#include "clutter-container.h"
+#include "clutter-content.h"
#include "clutter-deform-effect.h"
#include "clutter-desaturate-effect.h"
#include "clutter-device-manager.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]