diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index eef680ccd..e0ba87ad6 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -65,6 +65,7 @@ AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) $(GCOV_CFLAGS)
# please, keep this sorted alphabetically
source_h = \
+ $(srcdir)/clutter-action.h \
$(srcdir)/clutter-actor-meta.h \
$(srcdir)/clutter-actor.h \
$(srcdir)/clutter-alpha.h \
@@ -139,6 +140,7 @@ include $(top_srcdir)/build/autotools/Makefile.am.enums
# please, keep this sorted alphabetically
source_c = \
+ $(srcdir)/clutter-action.c \
$(srcdir)/clutter-actor-meta.c \
$(srcdir)/clutter-actor.c \
$(srcdir)/clutter-alpha.c \
diff --git a/clutter/clutter-action.c b/clutter/clutter-action.c
new file mode 100644
index 000000000..41b956f80
--- /dev/null
+++ b/clutter/clutter-action.c
@@ -0,0 +1,61 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Author:
+ * Emmanuele Bassi
+ */
+
+/**
+ * SECTION:ClutterAction
+ * @Title: ClutterAction
+ * @Short_Description: Abstract class for actor actions
+ * @See_Also: #ClutterEffect
+ *
+ * #ClutterAction is an abstract base class for action that modify the
+ * user interaction of a #ClutterActor, just like #ClutterEffect is an
+ * abstract class for modifiers of the appearance of a #ClutterActor.
+ *
+ * Implementations of #ClutterAction are associated to an actor and can
+ * provide behavioral changes when dealing with user input - for instance
+ * drag and drop capabilities, or scrolling, or panning.
+ *
+ * #ClutterAction is available since Clutter 1.4
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "clutter-action.h"
+
+#include "clutter-debug.h"
+#include "clutter-private.h"
+
+G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META);
+
+static void
+clutter_action_class_init (ClutterActionClass *klass)
+{
+}
+
+static void
+clutter_action_init (ClutterAction *self)
+{
+}
diff --git a/clutter/clutter-action.h b/clutter/clutter-action.h
new file mode 100644
index 000000000..7f3c8501c
--- /dev/null
+++ b/clutter/clutter-action.h
@@ -0,0 +1,94 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Author:
+ * Emmanuele Bassi
+ */
+
+#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __CLUTTER_ACTION_H__
+#define __CLUTTER_ACTION_H__
+
+#include
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
+#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
+#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
+#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
+#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
+#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
+
+typedef struct _ClutterActionClass ClutterActionClass;
+
+/**
+ * ClutterAction:
+ *
+ * The ClutterAction structure contains only
+ * private data and should be accessed using the provided API
+ *
+ * Since: 1.4
+ */
+struct _ClutterAction
+{
+ /*< private >*/
+ ClutterActorMeta parent_instance;
+};
+
+/**
+ * ClutterActionClass:
+ *
+ * The ClutterActionClass structure contains
+ * only private data
+ *
+ * Since: 1.4
+ */
+struct _ClutterActionClass
+{
+ /*< private >*/
+ ClutterActorMetaClass parent_class;
+
+ void (* _clutter_action1) (void);
+ void (* _clutter_action2) (void);
+ void (* _clutter_action3) (void);
+ void (* _clutter_action4) (void);
+ void (* _clutter_action5) (void);
+ void (* _clutter_action6) (void);
+ void (* _clutter_action7) (void);
+ void (* _clutter_action8) (void);
+};
+
+GType clutter_action_get_type (void) G_GNUC_CONST;
+
+/* ClutterActor API */
+void clutter_actor_add_action (ClutterActor *self,
+ ClutterAction *action);
+void clutter_actor_remove_action (ClutterActor *self,
+ ClutterAction *action);
+GList *clutter_actor_get_actions (ClutterActor *self);
+void clutter_actor_clear_actions (ClutterActor *self);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_ACTION_H__ */
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 4e2f46b76..a60aeeea1 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -226,17 +226,21 @@
#endif
#include "clutter-actor.h"
+
+#include "clutter-action.h"
+#include "clutter-actor-meta-private.h"
#include "clutter-container.h"
-#include "clutter-main.h"
+#include "clutter-debug.h"
#include "clutter-enum-types.h"
-#include "clutter-scriptable.h"
-#include "clutter-script.h"
+#include "clutter-main.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
-#include "clutter-debug.h"
-#include "clutter-units.h"
#include "clutter-profile.h"
+#include "clutter-scriptable.h"
+#include "clutter-script.h"
#include "clutter-stage.h"
+#include "clutter-units.h"
+
#include "cogl/cogl.h"
typedef struct _ShaderData ShaderData;
@@ -391,6 +395,8 @@ struct _ClutterActorPrivate
* See clutter_actor_queue_clipped_redraw() for details.
*/
const ClutterActorBox *oob_queue_redraw_clip;
+
+ ClutterMetaGroup *actions;
};
enum
@@ -471,7 +477,9 @@ enum
PROP_SHOW_ON_SET_PARENT,
PROP_TEXT_DIRECTION,
- PROP_HAS_POINTER
+ PROP_HAS_POINTER,
+
+ PROP_ACTIONS
};
enum
@@ -2892,6 +2900,10 @@ clutter_actor_set_property (GObject *object,
clutter_actor_set_text_direction (actor, g_value_get_enum (value));
break;
+ case PROP_ACTIONS:
+ clutter_actor_add_action (actor, g_value_get_object (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3199,12 +3211,18 @@ clutter_actor_dispose (GObject *object)
destroy_shader_data (self);
- if (priv->pango_context)
+ if (priv->pango_context != NULL)
{
g_object_unref (priv->pango_context);
priv->pango_context = NULL;
}
+ if (priv->actions != NULL)
+ {
+ g_object_unref (priv->actions);
+ priv->actions = NULL;
+ }
+
g_signal_emit (self, actor_signals[DESTROY], 0);
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
@@ -3999,6 +4017,20 @@ clutter_actor_class_init (ClutterActorClass *klass)
PROP_HAS_POINTER,
pspec);
+ /**
+ * ClutterActor:actions:
+ *
+ * Adds a #ClutterAction to the actor
+ *
+ * Since: 1.4
+ */
+ pspec = g_param_spec_object ("actions",
+ "Actions",
+ "Adds an action to the actor",
+ CLUTTER_TYPE_ACTION,
+ CLUTTER_PARAM_WRITABLE);
+ g_object_class_install_property (object_class, PROP_ACTIONS, pspec);
+
/**
* ClutterActor::destroy:
* @actor: the object which received the signal
@@ -10172,3 +10204,117 @@ clutter_actor_has_allocation (ClutterActor *self)
CLUTTER_ACTOR_IS_VISIBLE (self) &&
!priv->needs_allocation;
}
+
+/**
+ * clutter_actor_add_action:
+ * @self: a #ClutterActor
+ * @action: a #ClutterAction
+ *
+ * Adds @action to the list of actions applied to @self
+ *
+ * A #ClutterAction can only belong to one actor at a time
+ *
+ * The #ClutterActor will hold a reference on @action until either
+ * clutter_actor_remove_action() or clutter_actor_clear_actions()
+ * is called
+ *
+ * Since: 1.4
+ */
+void
+clutter_actor_add_action (ClutterActor *self,
+ ClutterAction *action)
+{
+ ClutterActorPrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_ACTOR (self));
+ g_return_if_fail (CLUTTER_IS_ACTION (action));
+
+ priv = self->priv;
+
+ if (priv->actions == NULL)
+ {
+ priv->actions = g_object_new (CLUTTER_TYPE_META_GROUP, NULL);
+ priv->actions->actor = self;
+ }
+
+ _clutter_meta_group_add_meta (priv->actions, CLUTTER_ACTOR_META (action));
+
+ g_object_notify (G_OBJECT (self), "actions");
+}
+
+/**
+ * clutter_actor_remove_action:
+ * @self: a #ClutterActor
+ * @action: a #ClutterAction
+ *
+ * Removes @action from the list of actions applied to @self
+ *
+ * The reference held by @self on the #ClutterAction will be released
+ *
+ * Since: 1.4
+ */
+void
+clutter_actor_remove_action (ClutterActor *self,
+ ClutterAction *action)
+{
+ ClutterActorPrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_ACTOR (self));
+ g_return_if_fail (CLUTTER_IS_ACTION (action));
+
+ priv = self->priv;
+
+ if (priv->actions == NULL)
+ return;
+
+ _clutter_meta_group_remove_meta (priv->actions, CLUTTER_ACTOR_META (action));
+
+ g_object_notify (G_OBJECT (self), "actions");
+}
+
+/**
+ * clutter_actor_get_actions:
+ * @self: a #ClutterActor
+ *
+ * Retrieves the list of actions applied to @self
+ *
+ * Return value: (transfer container) (element-type ClutterAction): a copy
+ * of the list of #ClutterActions. The contents of the list are
+ * owned by the #ClutterActor. Use g_list_free() to free the resources
+ * allocated by the returned #GList
+ *
+ * Since: 1.4
+ */
+GList *
+clutter_actor_get_actions (ClutterActor *self)
+{
+ const GList *actions;
+
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
+
+ if (self->priv->actions == NULL)
+ return NULL;
+
+ actions = _clutter_meta_group_peek_metas (self->priv->actions);
+
+ return g_list_copy ((GList *) actions);
+}
+
+/**
+ * clutter_actor_clear_actions:
+ * @self: a #ClutterActor
+ *
+ * Clears the list of actions applied to @self
+ *
+ * Since: 1.4
+ */
+void
+clutter_actor_clear_actions (ClutterActor *self)
+{
+ g_return_if_fail (CLUTTER_IS_ACTOR (self));
+
+ if (self->priv->actions == NULL)
+ return;
+
+ _clutter_meta_group_clear_metas (self->priv->actions);
+}
diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h
index ca7ba4be6..597ebf38f 100644
--- a/clutter/clutter-types.h
+++ b/clutter/clutter-types.h
@@ -47,6 +47,7 @@ typedef struct _ClutterChildMeta ClutterChildMeta;
typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
typedef struct _ClutterAnimator ClutterAnimator;
+typedef struct _ClutterAction ClutterAction;
typedef struct _ClutterActorMeta ClutterActorMeta;
diff --git a/clutter/clutter.h b/clutter/clutter.h
index c6dd78f68..d69f74fed 100644
--- a/clutter/clutter.h
+++ b/clutter/clutter.h
@@ -30,6 +30,7 @@
#include "clutter-deprecated.h"
+#include "clutter-action.h"
#include "clutter-actor.h"
#include "clutter-actor-meta.h"
#include "clutter-alpha.h"