[clutter/wip/transitions: 8/13] Add ClutterTransitionGroup



commit 249e9914b7c8492d2a79e29cfece6af69f774438
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Tue Mar 20 10:59:34 2012 +0000

    Add ClutterTransitionGroup
    
    The TransitionGroup class is a logical container for running multiple
    transitions.
    
    TransitionGroup is not a Score: it is a Transition that advances each
    Transition it contains using the delta between frames, and ensures that
    all transitions are in a consistent state; these transitions are not
    advanced by the master clock.

 clutter/Makefile.am                          |    2 +
 clutter/clutter-transition-group.c           |  257 ++++++++++++++++++++++++++
 clutter/clutter-transition-group.h           |   91 +++++++++
 clutter/clutter-types.h                      |   15 +-
 clutter/clutter.h                            |    1 +
 clutter/clutter.symbols                      |    5 +
 doc/reference/clutter/clutter-docs.xml.in    |    1 +
 doc/reference/clutter/clutter-sections.txt   |   20 ++
 doc/reference/clutter/clutter.types          |    1 +
 tests/interactive/test-keyframe-transition.c |   25 ++-
 10 files changed, 406 insertions(+), 12 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 80819ee..6b52fab 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -124,6 +124,7 @@ source_h =					\
 	$(srcdir)/clutter-text.h		\
 	$(srcdir)/clutter-text-buffer.h		\
 	$(srcdir)/clutter-timeline.h 		\
+	$(srcdir)/clutter-transition-group.h	\
 	$(srcdir)/clutter-transition.h		\
 	$(srcdir)/clutter-types.h		\
 	$(srcdir)/clutter-units.h 		\
@@ -204,6 +205,7 @@ source_c = \
 	$(srcdir)/clutter-texture.c 		\
 	$(srcdir)/clutter-text.c		\
 	$(srcdir)/clutter-text-buffer.c		\
+	$(srcdir)/clutter-transition-group.c	\
 	$(srcdir)/clutter-transition.c		\
 	$(srcdir)/clutter-timeline.c 		\
 	$(srcdir)/clutter-units.c		\
diff --git a/clutter/clutter-transition-group.c b/clutter/clutter-transition-group.c
new file mode 100644
index 0000000..1b8e664
--- /dev/null
+++ b/clutter/clutter-transition-group.c
@@ -0,0 +1,257 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Emmanuele Bassi <ebassi linux intel com>
+ */
+
+/**
+ * SECTION:clutter-transition-group
+ * @Title: ClutterTransitionGroup
+ * @Short_Description: Group transitions together
+ *
+ * The #ClutterTransitionGroup allows running multiple #ClutterTransition
+ * instances concurrently.
+ *
+ * The transitions inside a group will run within the boundaries of the
+ * group; for instance, if a transition has a duration of 10 seconds, and
+ * the group that contains it has a duration of 5 seconds, only the first
+ * 5 seconds of the transition will be played.
+ *
+ * #ClutterTransitionGroup is available since Clutter 1.12
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "clutter-transition-group.h"
+
+#include "clutter-debug.h"
+#include "clutter-private.h"
+
+struct _ClutterTransitionGroupPrivate
+{
+  GHashTable *transitions;
+};
+
+G_DEFINE_TYPE (ClutterTransitionGroup, clutter_transition_group, CLUTTER_TYPE_TRANSITION)
+
+static void
+clutter_transition_group_new_frame (ClutterTimeline *timeline,
+                                    gint             elapsed)
+{
+  ClutterTransitionGroupPrivate *priv;
+  GHashTableIter iter;
+  gpointer element;
+  gint64 msecs;
+
+  priv = CLUTTER_TRANSITION_GROUP (timeline)->priv;
+
+  /* get the time elapsed since the last ::new-frame... */
+  msecs = clutter_timeline_get_delta (timeline);
+
+  g_hash_table_iter_init (&iter, priv->transitions);
+  while (g_hash_table_iter_next (&iter, &element, NULL))
+    {
+      ClutterTimeline *t = element;
+
+      /* ... and advance every timeline */
+      clutter_timeline_set_direction (t, clutter_timeline_get_direction (timeline));
+      clutter_timeline_set_duration (t, clutter_timeline_get_duration (timeline));
+
+      _clutter_timeline_advance (t, msecs);
+    }
+}
+
+static void
+clutter_transition_group_attached (ClutterTransition *transition,
+                                   ClutterAnimatable *animatable)
+{
+  ClutterTransitionGroupPrivate *priv;
+  GHashTableIter iter;
+  gpointer element;
+
+  priv = CLUTTER_TRANSITION_GROUP (transition)->priv;
+
+  g_hash_table_iter_init (&iter, priv->transitions);
+  while (g_hash_table_iter_next (&iter, &element, NULL))
+    {
+      ClutterTransition *t = element;
+
+      clutter_transition_set_animatable (t, animatable);
+    }
+}
+
+static void
+clutter_transition_group_detached (ClutterTransition *transition,
+                                   ClutterAnimatable *animatable)
+{
+  ClutterTransitionGroupPrivate *priv;
+  GHashTableIter iter;
+  gpointer element;
+
+  priv = CLUTTER_TRANSITION_GROUP (transition)->priv;
+
+  g_hash_table_iter_init (&iter, priv->transitions);
+  while (g_hash_table_iter_next (&iter, &element, NULL))
+    {
+      ClutterTransition *t = element;
+
+      clutter_transition_set_animatable (t, NULL);
+    }
+}
+
+static void
+clutter_transition_group_started (ClutterTimeline *timeline)
+{
+  ClutterTransitionGroupPrivate *priv;
+  GHashTableIter iter;
+  gpointer element;
+
+  priv = CLUTTER_TRANSITION_GROUP (timeline)->priv;
+
+  g_hash_table_iter_init (&iter, priv->transitions);
+  while (g_hash_table_iter_next (&iter, &element, NULL))
+    {
+      ClutterTransition *t = element;
+
+      g_signal_emit_by_name (t, "started");
+    }
+}
+
+static void
+clutter_transition_group_finalize (GObject *gobject)
+{
+  ClutterTransitionGroupPrivate *priv;
+
+  priv = CLUTTER_TRANSITION_GROUP (gobject)->priv;
+
+  g_hash_table_unref (priv->transitions);
+
+  G_OBJECT_CLASS (clutter_transition_group_parent_class)->finalize (gobject);
+}
+
+static void
+clutter_transition_group_class_init (ClutterTransitionGroupClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  ClutterTimelineClass *timeline_class = CLUTTER_TIMELINE_CLASS (klass);
+  ClutterTransitionClass *transition_class = CLUTTER_TRANSITION_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (ClutterTransitionGroupPrivate));
+
+  gobject_class->finalize = clutter_transition_group_finalize;
+
+  timeline_class->started = clutter_transition_group_started;
+  timeline_class->new_frame = clutter_transition_group_new_frame;
+
+  transition_class->attached = clutter_transition_group_attached;
+  transition_class->detached = clutter_transition_group_detached;
+}
+
+static void
+clutter_transition_group_init (ClutterTransitionGroup *self)
+{
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+                                            CLUTTER_TYPE_TRANSITION_GROUP,
+                                            ClutterTransitionGroupPrivate);
+
+  self->priv->transitions =
+    g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL);
+}
+
+/**
+ * clutter_transition_group_new:
+ *
+ * Creates a new #ClutterTransitionGroup instance.
+ *
+ * Return value: the newly created #ClutterTransitionGroup. Use
+ *   g_object_unref() when done to deallocate the resources it
+ *   uses
+ *
+ * Since: 1.12
+ */
+ClutterTransition *
+clutter_transition_group_new (void)
+{
+  return g_object_new (CLUTTER_TYPE_TRANSITION_GROUP, NULL);
+}
+
+/**
+ * clutter_transition_group_add_transition:
+ * @group: a #ClutterTransitionGroup
+ * @transition: a #ClutterTransition
+ *
+ * Adds @transition to @group.
+ *
+ * This function acquires a reference on @transition that will be released
+ * when calling clutter_transition_group_remove_transition().
+ *
+ * Since: 1.12
+ */
+void
+clutter_transition_group_add_transition (ClutterTransitionGroup *group,
+                                         ClutterTransition      *transition)
+{
+  g_return_if_fail (CLUTTER_IS_TRANSITION_GROUP (group));
+  g_return_if_fail (CLUTTER_IS_TRANSITION (transition));
+
+  g_hash_table_add (group->priv->transitions, g_object_ref (transition));
+}
+
+/**
+ * clutter_transition_group_remove_transition:
+ * @group: a #ClutterTransitionGroup
+ * @transition: a #ClutterTransition
+ *
+ * Removes @transition from @group.
+ *
+ * This function releases the reference acquired on @transition when
+ * calling clutter_transition_group_add_transition().
+ *
+ * Since: 1.12
+ */
+void
+clutter_transition_group_remove_transition (ClutterTransitionGroup *group,
+                                            ClutterTransition      *transition)
+{
+  g_return_if_fail (CLUTTER_IS_TRANSITION_GROUP (group));
+
+  g_hash_table_remove (group->priv->transitions, transition);
+}
+
+/**
+ * clutter_transition_group_remove_all:
+ * @group: a #ClutterTransitionGroup
+ *
+ * Removes all transitions from @group.
+ *
+ * This function releases the reference acquired when calling
+ * clutter_transition_group_add_transition().
+ *
+ * Since: 1.12
+ */
+void
+clutter_transition_group_remove_all (ClutterTransitionGroup *group)
+{
+  g_return_if_fail (CLUTTER_IS_TRANSITION_GROUP (group));
+
+  g_hash_table_remove_all (group->priv->transitions);
+}
diff --git a/clutter/clutter-transition-group.h b/clutter/clutter-transition-group.h
new file mode 100644
index 0000000..efa9ddb
--- /dev/null
+++ b/clutter/clutter-transition-group.h
@@ -0,0 +1,91 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Emmanuele Bassi <ebassi linux intel com>
+ */
+
+#ifndef __CLUTTER_TRANSITION_GROUP_H__
+#define __CLUTTER_TRANSITION_GROUP_H__
+
+#include <clutter/clutter-types.h>
+#include <clutter/clutter-transition.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_TYPE_TRANSITION_GROUP                   (clutter_transition_group_get_type ())
+#define CLUTTER_TRANSITION_GROUP(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TRANSITION_GROUP, ClutterTransitionGroup))
+#define CLUTTER_IS_TRANSITION_GROUP(obj)                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TRANSITION_GROUP))
+#define CLUTTER_TRANSITION_GROUP_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_TRANSITION_GROUP, ClutterTransitionGroupClass))
+#define CLUTTER_IS_TRANSITION_GROUP_CLASS(klass)        (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_TRANSITION_GROUP))
+#define CLUTTER_TRANSITION_GROUP_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_TRANSITION_GROUP, ClutterTransitionGroup))
+
+typedef struct _ClutterTransitionGroupPrivate           ClutterTransitionGroupPrivate;
+typedef struct _ClutterTransitionGroupClass             ClutterTransitionGroupClass;
+
+/**
+ * ClutterTransitionGroup:
+ *
+ * The <structname>ClutterTransitionGroup</structname> structure contains
+ * private data and should only be accessed using the provided API.
+ *
+ * Since: 1.12
+ */
+struct _ClutterTransitionGroup
+{
+  /*< private >*/
+  ClutterTransition parent_instance;
+
+  ClutterTransitionGroupPrivate *priv;
+};
+
+/**
+ * ClutterTransitionGroupClass:
+ *
+ * The <structname>ClutterTransitionGroupClass</structname> structure
+ * contains only private data.
+ *
+ * Since: 1.12
+ */
+struct _ClutterTransitionGroupClass
+{
+  /*< private >*/
+  ClutterTransitionClass parent_class;
+
+  gpointer _padding[8];
+};
+
+CLUTTER_AVAILABLE_IN_1_12
+GType clutter_transition_group_get_type (void) G_GNUC_CONST;
+
+CLUTTER_AVAILABLE_IN_1_12
+ClutterTransition *     clutter_transition_group_new            (void);
+
+CLUTTER_AVAILABLE_IN_1_12
+void                    clutter_transition_group_add_transition         (ClutterTransitionGroup *group,
+                                                                         ClutterTransition      *transition);
+CLUTTER_AVAILABLE_IN_1_12
+void                    clutter_transition_group_remove_transition      (ClutterTransitionGroup *group,
+                                                                         ClutterTransition      *transition);
+CLUTTER_AVAILABLE_IN_1_12
+void                    clutter_transition_group_remove_all             (ClutterTransitionGroup *group);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_TRANSITION_GROUP_H__ */
diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h
index 124d675..0642335 100644
--- a/clutter/clutter-types.h
+++ b/clutter/clutter-types.h
@@ -56,15 +56,16 @@ typedef struct _ClutterActorIter        ClutterActorIter;
 typedef struct _ClutterPaintNode        ClutterPaintNode;
 typedef struct _ClutterContent          ClutterContent; /* dummy */
 
-typedef struct _ClutterAlpha            ClutterAlpha;
-typedef struct _ClutterAnimatable       ClutterAnimatable; /* dummy */
-typedef struct _ClutterAnimator         ClutterAnimator;
-typedef struct _ClutterInterval         ClutterInterval;
-typedef struct _ClutterState            ClutterState;
-typedef struct _ClutterTimeline         ClutterTimeline;
-typedef struct _ClutterTransition       ClutterTransition;
+typedef struct _ClutterAlpha            	ClutterAlpha;
+typedef struct _ClutterAnimator         	ClutterAnimator;
+typedef struct _ClutterState            	ClutterState;
+typedef struct _ClutterInterval         	ClutterInterval;
+typedef struct _ClutterAnimatable       	ClutterAnimatable; /* dummy */
+typedef struct _ClutterTimeline         	ClutterTimeline;
+typedef struct _ClutterTransition       	ClutterTransition;
 typedef struct _ClutterPropertyTransition       ClutterPropertyTransition;
 typedef struct _ClutterKeyframeTransition       ClutterKeyframeTransition;
+typedef struct _ClutterTransitionGroup		ClutterTransitionGroup;
 
 typedef struct _ClutterAction           ClutterAction;
 typedef struct _ClutterConstraint       ClutterConstraint;
diff --git a/clutter/clutter.h b/clutter/clutter.h
index 262bc71..29d6c0a 100644
--- a/clutter/clutter.h
+++ b/clutter/clutter.h
@@ -103,6 +103,7 @@
 #include "clutter-texture.h"
 #include "clutter-text.h"
 #include "clutter-timeline.h"
+#include "clutter-transition-group.h"
 #include "clutter-transition.h"
 #include "clutter-units.h"
 #include "clutter-version.h"
diff --git a/clutter/clutter.symbols b/clutter/clutter.symbols
index 0614393..72535c5 100644
--- a/clutter/clutter.symbols
+++ b/clutter/clutter.symbols
@@ -1376,6 +1376,11 @@ clutter_timeline_stop
 clutter_timeout_pool_add
 clutter_timeout_pool_new
 clutter_timeout_pool_remove
+clutter_transition_group_add_transition
+clutter_transition_group_get_type
+clutter_transition_group_new
+clutter_transition_group_remove_transition
+clutter_transition_group_remove_all
 clutter_transition_get_animatable
 clutter_transition_get_interval
 clutter_transition_get_type
diff --git a/doc/reference/clutter/clutter-docs.xml.in b/doc/reference/clutter/clutter-docs.xml.in
index 88f0aef..6a1c3cc 100644
--- a/doc/reference/clutter/clutter-docs.xml.in
+++ b/doc/reference/clutter/clutter-docs.xml.in
@@ -155,6 +155,7 @@
       <xi:include href="xml/clutter-transition.xml"/>
       <xi:include href="xml/clutter-property-transition.xml"/>
       <xi:include href="xml/clutter-keyframe-transition.xml"/>
+      <xi:include href="xml/clutter-transition-group.xml"/>
     </chapter>
 
     <chapter>
diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt
index c69b3e0..73e7d99 100644
--- a/doc/reference/clutter/clutter-sections.txt
+++ b/doc/reference/clutter/clutter-sections.txt
@@ -3183,3 +3183,23 @@ CLUTTER_KEYFRAME_TRANSITION_GET_CLASS
 ClutterKeyframeTransitionPrivate
 clutter_keyframe_transition_get_type
 </SECTION>
+
+<SECTION>
+<FILE>clutter-transition-group</FILE>
+ClutterTransitionGroup
+ClutterTransitionGroupClass
+clutter_transition_group_new
+clutter_transition_group_add_transition
+clutter_transition_group_remove_transition
+clutter_transition_group_remove_all
+<SUBSECTION Standard>
+CLUTTER_TYPE_TRANSITION_GROUP
+CLUTTER_TRANSITION_GROUP
+CLUTTER_TRANSITION_GROUP_CLASS
+CLUTTER_IS_TRANSITION_GROUP
+CLUTTER_IS_TRANSITION_GROUP_CLASS
+CLUTTER_TRANSITION_GROUP_GET_CLASS
+<SUBSECTION Private>
+ClutterTransitionGroupPrivate
+clutter_transition_group_get_type
+</SECTION>
diff --git a/doc/reference/clutter/clutter.types b/doc/reference/clutter/clutter.types
index f94fc39..cae6764 100644
--- a/doc/reference/clutter/clutter.types
+++ b/doc/reference/clutter/clutter.types
@@ -73,3 +73,4 @@ clutter_text_get_type
 clutter_texture_get_type
 clutter_timeline_get_type
 clutter_transition_get_type
+clutter_transition_group_get_type
diff --git a/tests/interactive/test-keyframe-transition.c b/tests/interactive/test-keyframe-transition.c
index aeef548..07b628d 100644
--- a/tests/interactive/test-keyframe-transition.c
+++ b/tests/interactive/test-keyframe-transition.c
@@ -32,15 +32,16 @@ test_keyframe_transition_main (int argc, char *argv[])
 
   for (i = 0; i < 3; i++)
     {
-      ClutterTransition *transition;
+      ClutterTransition *transition, *group;
       ClutterActor *rect;
       float cur_x, cur_y;
-      float new_x;
+      float new_x, new_y;
 
       cur_x = PADDING;
       cur_y = PADDING + ((SIZE + PADDING) * i);
 
       new_x = clutter_actor_get_width (stage) - PADDING - SIZE;
+      new_y = g_random_double_range (PADDING, clutter_actor_get_height (stage) - PADDING - SIZE);
 
       rect = clutter_actor_new ();
 
@@ -53,6 +54,10 @@ test_keyframe_transition_main (int argc, char *argv[])
       clutter_actor_set_easing_duration (rect, 2000);
       clutter_actor_set_easing_mode (rect, CLUTTER_LINEAR);
 
+      group = clutter_transition_group_new ();
+      clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (group), 1);
+      clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (group), TRUE);
+
       transition = clutter_keyframe_transition_new ("x");
       clutter_transition_set_from (transition, G_TYPE_FLOAT, cur_x);
       clutter_transition_set_to (transition, G_TYPE_FLOAT, new_x);
@@ -60,11 +65,21 @@ test_keyframe_transition_main (int argc, char *argv[])
       clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (transition),
                                        G_TYPE_FLOAT, 1,
                                        0.5, new_x / 2.0f, CLUTTER_EASE_OUT_EXPO);
+      clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), transition);
+      g_object_unref (transition);
+
+      transition = clutter_keyframe_transition_new ("y");
+      clutter_transition_set_from (transition, G_TYPE_FLOAT, cur_y);
+      clutter_transition_set_to (transition, G_TYPE_FLOAT, cur_y);
 
-      clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 1);
-      clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE);
+      clutter_keyframe_transition_set (CLUTTER_KEYFRAME_TRANSITION (transition),
+                                       G_TYPE_FLOAT, 1,
+                                       0.5, new_y, CLUTTER_EASE_OUT_EXPO);
+      clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), transition);
+      g_object_unref (transition);
 
-      clutter_actor_add_transition (rect, "horizAnimation", transition);
+      clutter_actor_add_transition (rect, "rectAnimation", group);
+      g_object_unref (group);
 
       clutter_actor_restore_easing_state (rect);
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]