actor: Add ActorMeta, a base class for actor modifiers

ClutterActorMeta is a base, abstract class that can be used to derive
classes that are attached to a ClutterActor instance in order to modify
the way an actor is painted, sized/positioned or responds to events.

A typed container for ActorMeta instances is also provided to the
sub-classes can be attached to an Actor.
This commit is contained in:
Emmanuele Bassi 2010-05-14 16:42:50 +01:00
parent 7caa10160d
commit c075d26fb2
6 changed files with 547 additions and 0 deletions

View File

@ -65,6 +65,7 @@ AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) $(GCOV_CFLAGS)
# please, keep this sorted alphabetically # please, keep this sorted alphabetically
source_h = \ source_h = \
$(srcdir)/clutter-actor-meta.h \
$(srcdir)/clutter-actor.h \ $(srcdir)/clutter-actor.h \
$(srcdir)/clutter-alpha.h \ $(srcdir)/clutter-alpha.h \
$(srcdir)/clutter-animatable.h \ $(srcdir)/clutter-animatable.h \
@ -138,6 +139,7 @@ include $(top_srcdir)/build/autotools/Makefile.am.enums
# please, keep this sorted alphabetically # please, keep this sorted alphabetically
source_c = \ source_c = \
$(srcdir)/clutter-actor-meta.c \
$(srcdir)/clutter-actor.c \ $(srcdir)/clutter-actor.c \
$(srcdir)/clutter-alpha.c \ $(srcdir)/clutter-alpha.c \
$(srcdir)/clutter-animatable.c \ $(srcdir)/clutter-animatable.c \
@ -206,6 +208,7 @@ source_c_priv = \
$(NULL) $(NULL)
source_h_priv = \ source_h_priv = \
$(srcdir)/clutter-actor-meta-private.h \
$(srcdir)/clutter-bezier.h \ $(srcdir)/clutter-bezier.h \
$(srcdir)/clutter-debug.h \ $(srcdir)/clutter-debug.h \
$(srcdir)/clutter-keysyms-table.h \ $(srcdir)/clutter-keysyms-table.h \

View File

@ -0,0 +1,42 @@
#ifndef __CLUTTER_ACTOR_META_PRIVATE_H__
#define __CLUTTER_ACTOR_META_PRIVATE_H__
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_META_GROUP (_clutter_meta_group_get_type ())
#define CLUTTER_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_META_GROUP, ClutterMetaGroup))
#define CLUTTER_IS_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_META_GROUP))
typedef struct _ClutterMetaGroup ClutterMetaGroup;
typedef struct _ClutterMetaGroupClass ClutterMetaGroupClass;
struct _ClutterMetaGroup
{
GObject parent_instance;
ClutterActor *actor;
GList *meta;
};
struct _ClutterMetaGroupClass
{
GObjectClass parent_class;
};
GType _clutter_meta_group_get_type (void) G_GNUC_CONST;
void _clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta);
void _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta);
G_CONST_RETURN GList *_clutter_meta_group_peek_metas (ClutterMetaGroup *group);
void _clutter_meta_group_clear_metas (ClutterMetaGroup *group);
ClutterActorMeta * _clutter_meta_group_get_meta (ClutterMetaGroup *group,
const gchar *name);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_META_PRIVATE_H__ */

View File

@ -0,0 +1,413 @@
/**
* SECTION:ClutterActorMeta
* @Title: ClutterActorMeta
* @Short_Description: Base class of actor modifiers
*
* #ClutterActorMeta is an abstract class providing a common API for
* modifiers of #ClutterActor
*
* A #ClutterActorMeta can only be owned by a single #ClutterActor at
* any time
*
* #ClutterActorMeta is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-actor-meta-private.h"
#include "clutter-debug.h"
#include "clutter-private.h"
struct _ClutterActorMetaPrivate
{
ClutterActor *actor;
gchar *name;
guint is_enabled : 1;
};
enum
{
PROP_0,
PROP_ACTOR,
PROP_NAME,
PROP_ENABLED
};
G_DEFINE_ABSTRACT_TYPE (ClutterActorMeta,
clutter_actor_meta,
G_TYPE_INITIALLY_UNOWNED);
static void
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
meta->priv->actor = actor;
}
static void
clutter_actor_meta_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
switch (prop_id)
{
case PROP_NAME:
clutter_actor_meta_set_name (meta, g_value_get_string (value));
break;
case PROP_ENABLED:
clutter_actor_meta_set_enabled (meta, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_actor_meta_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
switch (prop_id)
{
case PROP_ACTOR:
g_value_set_object (value, meta->priv->actor);
break;
case PROP_NAME:
g_value_set_string (value, meta->priv->name);
break;
case PROP_ENABLED:
g_value_set_boolean (value, meta->priv->is_enabled);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_actor_meta_finalize (GObject *gobject)
{
ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
g_free (priv->name);
G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject);
}
void
clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (ClutterActorMetaPrivate));
klass->set_actor = clutter_actor_meta_real_set_actor;
gobject_class->set_property = clutter_actor_meta_set_property;
gobject_class->get_property = clutter_actor_meta_get_property;
gobject_class->finalize = clutter_actor_meta_finalize;
/**
* ClutterActorMeta:actor:
*
* The #ClutterActor attached to the #ClutterActorMeta instance
*
* Since: 1.4
*/
pspec = g_param_spec_object ("actor",
"Actor",
"The actor attached to the meta",
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READABLE);
g_object_class_install_property (gobject_class, PROP_ACTOR, pspec);
/**
* ClutterActorMeta:name:
*
* The unique name to access the #ClutterActorMeta
*
* Since: 1.4
*/
pspec = g_param_spec_string ("name",
"Name",
"The name of the meta",
NULL,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (gobject_class, PROP_NAME, pspec);
/**
* ClutterActorMeta:enabled:
*
* Whether or not the #ClutterActorMeta is enabled
*
* Since: 1.4
*/
pspec = g_param_spec_boolean ("enabled",
"Enabled",
"Whether the meta is enabled",
TRUE,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ENABLED, pspec);
}
void
clutter_actor_meta_init (ClutterActorMeta *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
CLUTTER_TYPE_ACTOR_META,
ClutterActorMetaPrivate);
self->priv->is_enabled = TRUE;
}
/**
* clutter_actor_meta_set_name:
* @meta: a #ClutterActorMeta
* @name: the name of @meta
*
* Sets the name of @meta
*
* The name can be used to identify the #ClutterActorMeta instance
*
* Since: 1.4
*/
void
clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
if (g_strcmp0 (meta->priv->name, name) == 0)
return;
g_free (meta->priv->name);
meta->priv->name = g_strdup (name);
g_object_notify (G_OBJECT (meta), "name");
}
/**
* clutter_actor_meta_get_name:
* @meta: a #ClutterActorMeta
*
* Retrieves the name set using clutter_actor_meta_set_name()
*
* Return value: (transfer none): the name of the #ClutterActorMeta
* instance, or %NULL if none was set. The returned string is owned
* by the #ClutterActorMeta instance and it should not be modified
* or freed
*
* Since: 1.4
*/
G_CONST_RETURN gchar *
clutter_actor_meta_get_name (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
return meta->priv->name;
}
/**
* clutter_actor_meta_set_enabled:
* @meta: a #ClutterActorMeta
* @is_enabled: whether @meta is enabled
*
* Sets whether @meta should be enabled or not
*
* Since: 1.4
*/
void
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
is_enabled = !!is_enabled;
if (meta->priv->is_enabled == is_enabled)
return;
meta->priv->is_enabled = is_enabled;
g_object_notify (G_OBJECT (meta), "enabled");
}
/**
* clutter_actor_meta_get_enabled:
* @meta: a #ClutterActorMeta
*
* Retrieves whether @meta is enabled
*
* Return value: %TRUE if the #ClutterActorMeta instance is enabled
*
* Since: 1.4
*/
gboolean
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
return meta->priv->is_enabled;
}
/*
* _clutter_actor_meta_set_actor
* @meta: a #ClutterActorMeta
* @actor: a #ClutterActor or %NULL
*
* Sets or unsets a back pointer to the #ClutterActor that owns
* the @meta
*
* Since: 1.4
*/
void
_clutter_actor_meta_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_actor (meta, actor);
}
/**
* clutter_actor_meta_get_actor:
* @meta: a #ClutterActorMeta
*
* Retrieves a pointer to the #ClutterActor that owns @meta
*
* Return value: (transfer none): a pointer to a #ClutterActor or %NULL
*
* Since: 1.4
*/
ClutterActor *
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
return meta->priv->actor;
}
G_DEFINE_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT);
static void
_clutter_meta_group_dispose (GObject *gobject)
{
_clutter_meta_group_clear_metas (CLUTTER_META_GROUP (gobject));
G_OBJECT_CLASS (_clutter_meta_group_parent_class)->dispose (gobject);
}
static void
_clutter_meta_group_class_init (ClutterMetaGroupClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = _clutter_meta_group_dispose;
}
static void
_clutter_meta_group_init (ClutterMetaGroup *self)
{
}
void
_clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta)
{
if (meta->priv->actor != NULL)
{
g_warning ("The meta of type '%s' with name '%s' is "
"already attached to actor '%s'",
G_OBJECT_TYPE_NAME (meta),
meta->priv->name != NULL
? meta->priv->name
: "<unknown>",
clutter_actor_get_name (meta->priv->actor) != NULL
? clutter_actor_get_name (meta->priv->actor)
: G_OBJECT_TYPE_NAME (meta->priv->actor));
return;
}
group->meta = g_list_append (group->meta, meta);
g_object_ref_sink (meta);
_clutter_actor_meta_set_actor (meta, group->actor);
}
void
_clutter_meta_group_remove_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta)
{
if (meta->priv->actor != group->actor)
{
g_warning ("The meta of type '%s' with name '%s' is not "
"attached to the actor '%s'",
G_OBJECT_TYPE_NAME (meta),
meta->priv->name != NULL
? meta->priv->name
: "<unknown>",
clutter_actor_get_name (group->actor) != NULL
? clutter_actor_get_name (group->actor)
: G_OBJECT_TYPE_NAME (group->actor));
return;
}
_clutter_actor_meta_set_actor (meta, NULL);
group->meta = g_list_remove (group->meta, meta);
g_object_unref (meta);
}
G_CONST_RETURN GList *
_clutter_meta_group_peek_metas (ClutterMetaGroup *group)
{
return group->meta;
}
void
_clutter_meta_group_clear_metas (ClutterMetaGroup *group)
{
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
g_list_free (group->meta);
group->meta = NULL;
}
ClutterActorMeta *
_clutter_meta_group_get_meta (ClutterMetaGroup *group,
const gchar *name)
{
GList *l;
for (l = group->meta; l != NULL; l = l->next)
{
ClutterActorMeta *meta = l->data;
if (g_strcmp0 (meta->priv->name, name) == 0)
return meta;
}
return NULL;
}

View File

@ -0,0 +1,84 @@
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_ACTOR_META_H__
#define __CLUTTER_ACTOR_META_H__
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
#define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
#define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
/**
* ClutterActorMeta:
*
* The <structname>ClutterActorMeta</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterActorMeta
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterActorMetaPrivate *priv;
};
/**
* ClutterActorMetaClass:
* @set_actor: virtual function, invoked when attaching and detaching
* a #ClutterActorMeta instance to a #ClutterActor
*
* The <structname>ClutterActorMetaClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _ClutterActorMetaClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< public >*/
void (* set_actor) (ClutterActorMeta *meta,
ClutterActor *actor);
/*< private >*/
void (* _clutter_meta1) (void);
void (* _clutter_meta2) (void);
void (* _clutter_meta3) (void);
void (* _clutter_meta4) (void);
void (* _clutter_meta5) (void);
void (* _clutter_meta6) (void);
void (* _clutter_meta7) (void);
};
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
void clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name);
G_CONST_RETURN gchar *clutter_actor_meta_get_name (ClutterActorMeta *meta);
void clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled);
gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta);
ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta);
/* private */
void _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
ClutterActor *actor);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_META_H__ */

View File

@ -40,12 +40,16 @@ G_BEGIN_DECLS
/* Forward delarations to avoid header catch 22's */ /* Forward delarations to avoid header catch 22's */
typedef struct _ClutterActor ClutterActor; typedef struct _ClutterActor ClutterActor;
typedef struct _ClutterStage ClutterStage; typedef struct _ClutterStage ClutterStage;
typedef struct _ClutterContainer ClutterContainer; /* dummy */ typedef struct _ClutterContainer ClutterContainer; /* dummy */
typedef struct _ClutterChildMeta ClutterChildMeta; typedef struct _ClutterChildMeta ClutterChildMeta;
typedef struct _ClutterLayoutMeta ClutterLayoutMeta; typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
typedef struct _ClutterAnimator ClutterAnimator; typedef struct _ClutterAnimator ClutterAnimator;
typedef struct _ClutterActorMeta ClutterActorMeta;
typedef union _ClutterEvent ClutterEvent; typedef union _ClutterEvent ClutterEvent;
/** /**

View File

@ -31,6 +31,7 @@
#include "clutter-deprecated.h" #include "clutter-deprecated.h"
#include "clutter-actor.h" #include "clutter-actor.h"
#include "clutter-actor-meta.h"
#include "clutter-alpha.h" #include "clutter-alpha.h"
#include "clutter-animatable.h" #include "clutter-animatable.h"
#include "clutter-animation.h" #include "clutter-animation.h"