From 0e0db0d6242f84c8fb44ba57ec46d6dff5f265b3 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 11 May 2010 17:09:13 +0100 Subject: [PATCH] action: Add ClutterAction ClutterAction is an abstract class that should be used as the ancestor for objects that change how an actor behaves when dealing with events coming from user input. --- clutter/Makefile.am | 2 + clutter/clutter-action.c | 61 +++++++++++++++ clutter/clutter-action.h | 94 +++++++++++++++++++++++ clutter/clutter-actor.c | 160 +++++++++++++++++++++++++++++++++++++-- clutter/clutter-types.h | 1 + clutter/clutter.h | 1 + 6 files changed, 312 insertions(+), 7 deletions(-) create mode 100644 clutter/clutter-action.c create mode 100644 clutter/clutter-action.h 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"