2006-10-23 Matthew Allum <mallum@openedhand.com>
authorMatthew Allum <mallum@openedhand.com>
Sun, 22 Oct 2006 23:33:14 +0000 (23:33 +0000)
committerMatthew Allum <mallum@openedhand.com>
Sun, 22 Oct 2006 23:33:14 +0000 (23:33 +0000)
        * clutter/clutter-alpha.h:
        * clutter/clutter-behaviour.c:
        * clutter/clutter-behaviour.h:
        * clutter/clutter-behaviours.c:
        * clutter/clutter-behaviours.h:
        * examples/behave.c:
        Behaviours now only 'driven' by ClutterAlpha, not any object/prop.
        Add simple Clutter path behaviour.

ChangeLog
clutter/clutter-alpha.h
clutter/clutter-behaviour.c
clutter/clutter-behaviour.h
clutter/clutter-behaviours.c
clutter/clutter-behaviours.h
examples/behave.c

index 09a02a8..c59992e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-10-23  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-alpha.h:
+       * clutter/clutter-behaviour.c:
+       * clutter/clutter-behaviour.h:
+       * clutter/clutter-behaviours.c:
+       * clutter/clutter-behaviours.h:
+       * examples/behave.c:
+       Behaviours now only 'driven' by ClutterAlpha, not any object/prop.
+       Add simple Clutter path behaviour. 
+
 2006-10-03  Matthew Allum  <mallum@openedhand.com>
 
        * configure.ac:
index 8ebc849..142aed5 100644 (file)
@@ -80,8 +80,11 @@ struct _ClutterAlphaClass
   void (*_clutter_alpha_5) (void);
 }; 
 
+
 #define CLUTTER_ALPHA_MAX_ALPHA 0xffff
 
+GType clutter_alpha_get_type         (void) G_GNUC_CONST;
+
 ClutterAlpha *
 clutter_alpha_new (ClutterTimeline *timeline,
                    ClutterAlphaFunc func);
index 3e100d2..dc93621 100644 (file)
 
 #include "clutter-actor.h"
 #include "clutter-behaviour.h"
-#include "clutter-marshal.h"
 
 G_DEFINE_TYPE (ClutterBehaviour, clutter_behaviour, G_TYPE_OBJECT);
 
 struct ClutterBehaviourPrivate
 {
-  GObject    *object;
-  GParamSpec *param_spec;
-  guint       notify_id;
-  GSList     *actors;
+  ClutterAlpha *alpha;
+  guint         notify_id;
+  GSList       *actors;
 };
 
 enum
 {
   PROP_0,
-  PROP_OBJECT,
-  PROP_PROPERTY
+  PROP_ALPHA
 };
 
 enum {
-  SIGNAL_PROPERTY_CHANGE,
   SIGNAL_LAST
 };
 
-static guint signals[SIGNAL_LAST];
 
 #define CLUTTER_BEHAVIOUR_GET_PRIVATE(obj)         \
               (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
@@ -73,7 +68,7 @@ _clutter_behaviour_dispose (GObject *object)
     {
       /* FIXME: remove all actors */
 
-      clutter_behaviour_set_object (self, NULL);
+      clutter_behaviour_set_alpha (self, NULL);
     }
 
   G_OBJECT_CLASS (clutter_behaviour_parent_class)->dispose (object);
@@ -105,11 +100,8 @@ _clutter_behaviour_set_property (GObject      *object,
 
   switch (prop_id) 
     {
-    case PROP_OBJECT:
-      clutter_behaviour_set_object (behaviour, g_value_get_object (value));
-      break;
-    case PROP_PROPERTY:
-      clutter_behaviour_set_property (behaviour, g_value_get_string (value));
+    case PROP_ALPHA:
+      clutter_behaviour_set_alpha (behaviour, g_value_get_object (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -131,11 +123,8 @@ _clutter_behaviour_get_property (GObject    *object,
 
   switch (prop_id) 
     {
-    case PROP_OBJECT:
-      g_value_set_object (value, priv->object);
-      break;
-    case PROP_PROPERTY:
-      g_value_set_string (value, priv->param_spec->name);
+    case PROP_ALPHA:
+      g_value_set_object (value, priv->alpha);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -157,31 +146,13 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass)
   object_class->get_property = _clutter_behaviour_get_property;
 
   g_object_class_install_property
-    (object_class, PROP_OBJECT,
-     g_param_spec_object ("object",
-                         "Object",
-                         "Object whose property to monitor",
-                         G_TYPE_OBJECT,
-                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
-
-  g_object_class_install_property
-    (object_class, PROP_PROPERTY,
-     g_param_spec_string ("property",
-                         "Property",
-                         "Property to monitor",
-                          NULL,
+    (object_class, PROP_ALPHA,
+     g_param_spec_object ("alpha",
+                         "Alpha",
+                         "Alpha Object to drive the behaviour",
+                         CLUTTER_TYPE_ALPHA,
                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
 
-  signals[SIGNAL_PROPERTY_CHANGE] =
-     g_signal_new ("property-change",
-                 G_TYPE_FROM_CLASS (object_class),
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (ClutterBehaviourClass, property_change),
-                 NULL, NULL,
-                 clutter_marshal_VOID__OBJECT_POINTER,
-                 G_TYPE_NONE, 
-                 2, G_TYPE_OBJECT, G_TYPE_POINTER);
-
   g_type_class_add_private (object_class, sizeof (ClutterBehaviourPrivate));
 }
 
@@ -246,54 +217,10 @@ clutter_behaviour_actors_foreach (ClutterBehaviour *behave,
   g_slist_foreach (behave->priv->actors, func, userdata);
 }
 
-GObject*
-clutter_behaviour_get_object (ClutterBehaviour *behave)
-{
-  return behave->priv->object;
-}
-
-void
-clutter_behaviour_set_object (ClutterBehaviour *behave, 
-                              GObject          *object)
-{
-  ClutterBehaviourPrivate *priv;
-  const char *property;
-
-  priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behave);
-
-  if (priv->object)
-    {
-      property = clutter_behaviour_get_property (behave);
-      clutter_behaviour_set_property (behave, NULL);
-
-      g_object_unref(priv->object);
-      priv->object = NULL;
-    }
-  else
-    property = NULL;
-
-  if (object)
-    {
-      priv->object = g_object_ref(object);
-
-      if (property)
-        clutter_behaviour_set_property (behave, property);
-    }
-}
-
-const char *
-clutter_behaviour_get_property (ClutterBehaviour *behave)
-{
-  if (behave->priv->param_spec)
-    return behave->priv->param_spec->name;
-  else
-    return NULL;
-}
-
-GParamSpec *
-clutter_behaviour_get_param_spec (ClutterBehaviour *behave)
+ClutterAlpha*
+clutter_behaviour_get_alpha (ClutterBehaviour *behave)
 {
-  return behave->priv->param_spec;
+  return behave->priv->alpha;
 }
 
 static void
@@ -301,47 +228,39 @@ notify_cb (GObject          *object,
            GParamSpec       *param_spec,
            ClutterBehaviour *behave)
 {
-        g_signal_emit (behave,
-                       signals[SIGNAL_PROPERTY_CHANGE],
-                       0,
-                       object,
-                       param_spec);
+  ClutterBehaviourClass *class;
+
+  class = CLUTTER_BEHAVIOUR_GET_CLASS(behave);
+
+  if (class->alpha_notify)
+    class->alpha_notify (behave);
 }
 
 void
-clutter_behaviour_set_property (ClutterBehaviour *behave,
-                                const char       *property)
+clutter_behaviour_set_alpha (ClutterBehaviour *behave,
+                            ClutterAlpha     *alpha)
 {
-  g_return_if_fail (behave->priv->object);
-
   if (behave->priv->notify_id)
     {
-      g_signal_handler_disconnect (behave->priv->object,
+      g_signal_handler_disconnect (behave->priv->alpha,
                                    behave->priv->notify_id);
       behave->priv->notify_id = 0;
     }
 
-  behave->priv->param_spec = NULL;
+  if (behave->priv->alpha)
+    {
+      g_object_unref (behave->priv->alpha);
+      behave->priv->alpha = NULL;
+    }
 
-  if (property)
+  if (alpha)
     {
-      guint signal_id;
-      GClosure *closure;
-
-      behave->priv->param_spec =
-        g_object_class_find_property (G_OBJECT_GET_CLASS (behave->priv->object),
-                                      property);
-      g_return_if_fail (behave->priv->param_spec);
-
-      signal_id = g_signal_lookup ("notify",
-                                   G_OBJECT_TYPE (behave->priv->object));
-      closure = g_cclosure_new ((GCallback) notify_cb, behave, NULL);
-
-      behave->priv->notify_id =
-        g_signal_connect_closure_by_id (behave->priv->object,
-                                        signal_id,
-                                        g_quark_from_string (property),
-                                        closure,
-                                        FALSE);
+      behave->priv->alpha = alpha;
+      g_object_ref (behave->priv->alpha);
+
+      behave->priv->notify_id = g_signal_connect (behave->priv->alpha, 
+                                                 "notify::alpha",
+                                                 G_CALLBACK(notify_cb),
+                                                 behave);
     }
 }
index f426d53..d83cbc1 100644 (file)
@@ -2,6 +2,7 @@
 #define _HAVE_CLUTTER_BEHAVIOUR_H
 
 #include <glib-object.h>
+#include "clutter-alpha.h"
 
 G_BEGIN_DECLS
 
@@ -41,9 +42,7 @@ struct _ClutterBehaviourClass
 {
   GObjectClass parent_class;
 
-  void (* property_change) (ClutterBehaviour *behave,
-                            GObject          *object,
-                            GParamSpec       *param_spec);
+  void (*alpha_notify) (ClutterBehaviour *behave);
 };
 
 GType clutter_behaviour_get_type (void);
@@ -66,22 +65,12 @@ clutter_behaviour_actors_foreach (ClutterBehaviour *behave,
                                  GFunc             func,
                                  gpointer          userdata);
 
-void
-clutter_behaviour_set_object (ClutterBehaviour *behave, 
-                              GObject          *object);
-
-GObject*
-clutter_behaviour_get_object (ClutterBehaviour *behave);
+ClutterAlpha*
+clutter_behaviour_get_alpha (ClutterBehaviour *behave);
 
 void
-clutter_behaviour_set_property (ClutterBehaviour *behave,
-                                const char       *property);
-
-const char*
-clutter_behaviour_get_property (ClutterBehaviour *behave);
-
-GParamSpec*
-clutter_behaviour_get_param_spec (ClutterBehaviour *behave);
+clutter_behaviour_set_alpha (ClutterBehaviour *behave,
+                            ClutterAlpha     *alpha);
 
 G_END_DECLS
 
index 35e2256..47a4973 100644 (file)
 #include "clutter-enum-types.h"
 #include "clutter-main.h"
 
+#include <math.h>
+
+static ClutterKnot *
+clutter_knot_copy (const ClutterKnot *knot)
+{
+  ClutterKnot *copy;
+
+  copy = g_slice_new0 (ClutterKnot);
+  
+  *copy = *knot;
+
+  return copy;
+}
+
+static void
+clutter_knot_free (ClutterKnot *knot)
+{
+  if (G_LIKELY (knot))
+    {
+      g_slice_free (ClutterKnot, knot);
+    }
+}
+
+GType
+clutter_knot_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (G_UNLIKELY (!our_type))
+    our_type = g_boxed_type_register_static 
+                            ("ClutterKnot",
+                            (GBoxedCopyFunc) clutter_knot_copy,
+                            (GBoxedFreeFunc) clutter_knot_free);
+  return our_type;
+}
+
+
 G_DEFINE_TYPE (ClutterBehaviourPath,   \
                clutter_behaviour_path, \
               CLUTTER_TYPE_BEHAVIOUR);
 
 struct ClutterBehaviourPathPrivate
 {
-  gint x1, y1, x2, y2;
+  GSList *knots;
 };
 
 #define CLUTTER_BEHAVIOUR_PATH_GET_PRIVATE(obj)    \
@@ -51,6 +88,9 @@ struct ClutterBehaviourPathPrivate
                CLUTTER_TYPE_BEHAVIOUR_PATH,        \
                ClutterBehaviourPathPrivate))
 
+static void
+clutter_behaviour_path_alpha_notify (ClutterBehaviour *behave);
+
 static void 
 clutter_behaviour_path_dispose (GObject *object)
 {
@@ -58,7 +98,7 @@ clutter_behaviour_path_dispose (GObject *object)
 
   if (self->priv)
     {
-      /* FIXME: remove all actors */
+      /* FIXME: unref knots */
     }
 
   G_OBJECT_CLASS (clutter_behaviour_path_parent_class)->dispose (object);
@@ -82,13 +122,17 @@ clutter_behaviour_path_finalize (GObject *object)
 static void
 clutter_behaviour_path_class_init (ClutterBehaviourPathClass *klass)
 {
-  GObjectClass        *object_class;
+  GObjectClass          *object_class;
+  ClutterBehaviourClass *behave_class;
 
   object_class = (GObjectClass*) klass;
+  behave_class = (ClutterBehaviourClass*) klass;
 
   object_class->finalize     = clutter_behaviour_path_finalize;
   object_class->dispose      = clutter_behaviour_path_dispose;
 
+  behave_class->alpha_notify = clutter_behaviour_path_alpha_notify;
+
   g_type_class_add_private (object_class, sizeof (ClutterBehaviourPathPrivate));
 }
 
@@ -100,48 +144,218 @@ clutter_behaviour_path_init (ClutterBehaviourPath *self)
   self->priv = priv = CLUTTER_BEHAVIOUR_PATH_GET_PRIVATE (self);
 }
 
-/* 
-
-function line(x0, x1, y0, y1)
-     boolean steep := abs(y1 - y0) > abs(x1 - x0)
-     if steep then
-         swap(x0, y0)
-         swap(x1, y1)
-     if x0 > x1 then
-         swap(x0, x1)
-         swap(y0, y1)
-     int deltax := x1 - x0
-     int deltay := abs(y1 - y0)
-     int error := 0
-     int ystep
-     int y := y0
-     if y0 < y1 then ystep := 1 else ystep := -1
-     for x from x0 to x1
-         if steep then plot(y,x) else plot(x,y)
-         error := error + deltay
-         if 2
+static void
+interpolate (const ClutterKnot *begin, 
+            const ClutterKnot *end, 
+            ClutterKnot       *out,
+            double             t)
+{
+  /* FIXME: fixed point */
+  out->x = begin->x + t * (end->x - begin->x);
+  out->y = begin->y + t * (end->y - begin->y);
+}
+
+static gint
+node_distance (const ClutterKnot *begin, const ClutterKnot *end)
+{
+  g_return_val_if_fail (begin != NULL, 0);
+  g_return_val_if_fail (end != NULL, 0);
 
- */
+  /* FIXME: need fixed point here */
+  return sqrt ((end->x - begin->x) * (end->x - begin->x) +
+               (end->y - begin->y) * (end->y - begin->y));
+}
+
+static gint
+path_total_length (ClutterBehaviourPath *behave)
+{
+  GSList *l;
+  gint    len = 0;
+
+  for (l = behave->priv->knots; l != NULL; l = l->next)
+    if (l->next)
+      len += node_distance (l->data, l->next->data);
+
+  return len;
+}
+
+static void
+actor_apply_knot_foreach (ClutterActor            *actor,
+                         ClutterKnot             *knot)
+{
+  clutter_actor_set_position (actor, knot->x, knot->y);
+}
+
+static void
+path_alpha_to_position (ClutterBehaviourPath *behave)
+{
+  guint32  alpha;
+  GSList  *l;
+  gint     total_len, offset, dist_to_next, dist = 0;
+
+  /* FIXME: Optimise. Much of the data used here can be pre-generated  
+   *        ( total_len, dist between knots ) when knots are added/removed.
+  */
+
+  /* Calculation as follows:
+   *  o Get total length of path
+   *  o Find the offset on path where alpha val corresponds to
+   *  o Figure out between which knots this offset lies.
+   *  o Interpolate new co-ords via dist between these knots
+   *  o Apply to actors.
+  */
+
+  alpha = clutter_alpha_get_alpha 
+                   (clutter_behaviour_get_alpha (CLUTTER_BEHAVIOUR(behave)));
+
+  total_len = path_total_length (behave);
+
+  offset = (alpha * total_len) / CLUTTER_ALPHA_MAX_ALPHA;
+
+  if (offset == 0)
+    {
+      clutter_behaviour_actors_foreach (CLUTTER_BEHAVIOUR(behave), 
+                                       (GFunc)actor_apply_knot_foreach,
+                                       behave->priv->knots->data);
+      return;
+    }
+
+  for (l = behave->priv->knots; l != NULL; l = l->next)
+    if (l->next)
+      {
+       dist_to_next = node_distance (l->data, l->next->data);
+       
+       if (offset >= dist && offset < (dist + dist_to_next))
+         {
+           ClutterKnot new;
+           double t;
+           
+           /* FIXME: Use fixed */
+           t = (double)(offset - dist) / dist_to_next ;
+           
+           interpolate (l->data, l->next->data, &new, t);
+           
+           clutter_behaviour_actors_foreach (CLUTTER_BEHAVIOUR(behave), 
+                                             (GFunc)actor_apply_knot_foreach,
+                                             &new);
+           return;
+         }
+
+       dist += dist_to_next;
+      }
+}
+
+static void
+clutter_behaviour_path_alpha_notify (ClutterBehaviour *behave)
+{
+  path_alpha_to_position (CLUTTER_BEHAVIOUR_PATH(behave));
+}
 
 ClutterBehaviour*
-clutter_behaviour_path_new (GObject    *object,
-                            const char *property,
-                           gint        x1,
-                           gint        y1,
-                           gint        x2,
-                           gint        y2)
+clutter_behaviour_path_new (ClutterAlpha          *alpha,
+                           const ClutterKnot     *knots,
+                            guint                  n_knots)
 {
   ClutterBehaviourPath *behave;
-
+  gint i; 
+     
   behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_PATH, 
-                         "object", object,
-                         "property", property,
+                         "alpha", alpha,
                         NULL);
 
+  for (i = 0; i < n_knots; i++)
+    {
+      ClutterKnot knot = knots[i];
+      clutter_path_behaviour_append_knot (behave, &knot);
+    }
+
   return CLUTTER_BEHAVIOUR(behave);
 }
 
-/* opacity */
+GSList*
+clutter_path_behaviour_get_knots (ClutterBehaviourPath *behave)
+{
+  GSList *retval, *l;
+
+  g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_PATH (behave), NULL);
+
+  retval = NULL;
+  for (l = behave->priv->knots; l != NULL; l = l->next)
+    retval = g_slist_prepend (retval, l->data);
+  
+  return g_slist_reverse (retval);
+}
+
+void
+clutter_path_behaviour_append_knot (ClutterBehaviourPath  *pathb,
+                                   const ClutterKnot     *knot)
+{
+  ClutterBehaviourPathPrivate *priv;
+
+  g_return_if_fail (knot != NULL);
+
+  priv = pathb->priv;
+
+  priv->knots = g_slist_append (priv->knots,
+                                clutter_knot_copy (knot));
+}
+
+void
+clutter_path_behaviour_append_knots_valist (ClutterBehaviourPath  *pathb,
+                                           const ClutterKnot     *first_knot,
+                                           va_list                args)
+{
+  const ClutterKnot * knot;
+
+  knot = first_knot;
+  while (knot)
+    {
+      clutter_path_behaviour_append_knot (pathb, knot);
+      knot = va_arg (args, ClutterKnot*);
+    }
+}
+
+void
+clutter_path_behavior_append_knots (ClutterBehaviourPath  *pathb,
+                                   const ClutterKnot     *first_knot,
+                                   ...)
+{
+  va_list args;
+
+  g_return_if_fail (first_knot != NULL);
+
+  va_start (args, first_knot);
+  clutter_path_behaviour_append_knots_valist (pathb, first_knot, args);
+  va_end (args);
+}
+
+void
+clutter_path_behavior_remove_knot (ClutterBehaviourPath  *behave,
+                                  guint                  index)
+{
+  /* FIXME: implement */
+}
+
+ClutterKnot*
+clutter_path_behavior_get_knot (ClutterBehaviourPath  *behave,
+                               guint                  index)
+{
+  /* FIXME: implement */
+}
+
+void
+clutter_path_behavior_insert_knot (ClutterBehaviourPath  *behave,
+                                  ClutterKnot           *knot,
+                                  guint                  index)
+{
+  /* FIXME: implement */
+}
+
+
+/*
+ * ====================== Opacity ============================
+ */
+
 
 G_DEFINE_TYPE (ClutterBehaviourOpacity,   \
                clutter_behaviour_opacity, \
@@ -166,20 +380,14 @@ clutter_behaviour_opacity_frame_foreach (ClutterActor            *actor,
   guint8                          opacity;
   ClutterBehaviourOpacityPrivate *priv;
   ClutterBehaviour               *_behave;
-  GParamSpec                     *pspec;
 
   priv = CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE (behave);
   _behave = CLUTTER_BEHAVIOUR (behave);
 
-  pspec = clutter_behaviour_get_param_spec (_behave);
-
-  g_object_get (clutter_behaviour_get_object (_behave),
-                pspec->name,
-                &alpha,
-                NULL);
+  alpha = clutter_alpha_get_alpha (clutter_behaviour_get_alpha (_behave));
 
   opacity = (alpha * (priv->opacity_end - priv->opacity_start)) 
-                    / ((GParamSpecUInt *) pspec)->maximum;
+                            / CLUTTER_ALPHA_MAX_ALPHA;
 
   opacity += priv->opacity_start;
 
@@ -189,12 +397,8 @@ clutter_behaviour_opacity_frame_foreach (ClutterActor            *actor,
 }
 
 static void
-clutter_behaviour_property_change (ClutterBehaviour *behave,
-                                   GObject          *object,
-                                   GParamSpec       *param_spec)
+clutter_behaviour_alpha_notify (ClutterBehaviour *behave)
 {
-  g_return_if_fail (param_spec->value_type == G_TYPE_UINT);
-
   clutter_behaviour_actors_foreach 
                      (behave,
                      (GFunc)clutter_behaviour_opacity_frame_foreach,
@@ -235,7 +439,7 @@ clutter_behaviour_opacity_class_init (ClutterBehaviourOpacityClass *klass)
 
   behave_class = (ClutterBehaviourClass*) klass;
 
-  behave_class->property_change = clutter_behaviour_property_change;
+  behave_class->alpha_notify = clutter_behaviour_alpha_notify;
 
   g_type_class_add_private (object_class, sizeof (ClutterBehaviourOpacityPrivate));
 }
@@ -249,16 +453,14 @@ clutter_behaviour_opacity_init (ClutterBehaviourOpacity *self)
 }
 
 ClutterBehaviour*
-clutter_behaviour_opacity_new (GObject    *object,
-                               const char *property,
-                              guint8      opacity_start,
-                              guint8      opacity_end)
+clutter_behaviour_opacity_new (ClutterAlpha *alpha,
+                              guint8        opacity_start,
+                              guint8        opacity_end)
 {
   ClutterBehaviourOpacity *behave;
 
   behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_OPACITY, 
-                         "object", object,
-                         "property", property,
+                         "alpha", alpha,
                         NULL);
 
   behave->priv->opacity_start = opacity_start;
@@ -267,13 +469,3 @@ clutter_behaviour_opacity_new (GObject    *object,
   return CLUTTER_BEHAVIOUR(behave);
 }
 
-ClutterBehaviour*
-clutter_behaviour_opacity_new_from_alpha (ClutterAlpha *alpha,
-                                          guint8        opacity_start,
-                                          guint8        opacity_end)
-{
-  return clutter_behaviour_opacity_new (G_OBJECT (alpha),
-                                        "alpha",
-                                        opacity_start,
-                                        opacity_end);
-}
index 8e5743e..3eda56e 100644 (file)
@@ -7,6 +7,14 @@
 
 G_BEGIN_DECLS
 
+typedef struct _ClutterKnot  ClutterKnot;
+
+struct _ClutterKnot
+{
+  gint x,y;
+  /* FIXME: optionally include bezier control points also ? */
+};
+
 #define CLUTTER_TYPE_BEHAVIOUR_PATH clutter_behaviour_path_get_type()
 
 #define CLUTTER_BEHAVIOUR_PATH(obj) \
@@ -47,12 +55,26 @@ struct _ClutterBehaviourPathClass
 GType clutter_behaviour_path_get_type (void);
 
 ClutterBehaviour*
-clutter_behaviour_path_new (GObject    *object,
-                            const char *property,
-                           gint        x1,
-                           gint        y1,
-                           gint        x2,
-                           gint        y2);
+clutter_behaviour_path_new (ClutterAlpha          *alpha,
+                           const ClutterKnot     *knots,
+                            guint                  n_knots);
+
+GSList*
+clutter_path_behaviour_get_knots (ClutterBehaviourPath *behave);
+
+void
+clutter_path_behaviour_append_knot (ClutterBehaviourPath  *pathb,
+                                   const ClutterKnot     *knot);
+
+void
+clutter_path_behaviour_append_knots_valist (ClutterBehaviourPath  *pathb,
+                                           const ClutterKnot     *first_knot,
+                                           va_list                args);
+
+void
+clutter_path_behavior_append_knots (ClutterBehaviourPath  *pathb,
+                                   const ClutterKnot     *first_knot,
+                                   ...);
 
 /* opacity */
 
@@ -96,15 +118,9 @@ struct _ClutterBehaviourOpacityClass
 GType clutter_behaviour_opacity_get_type (void);
 
 ClutterBehaviour*
-clutter_behaviour_opacity_new (GObject    *object,
-                               const char *property,
-                              guint8      opacity_start,
-                              guint8      opacity_end);
-
-ClutterBehaviour*
-clutter_behaviour_opacity_new_from_alpha (ClutterAlpha *alpha,
-                                         guint8        opacity_start,
-                                         guint8        opacity_end);
+clutter_behaviour_opacity_new (ClutterAlpha *alpha,
+                              guint8        opacity_start,
+                              guint8        opacity_end);
 
 G_END_DECLS
 
index 666cd86..269137b 100644 (file)
@@ -10,6 +10,8 @@ main (int argc, char *argv[])
   ClutterColor      stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
   GdkPixbuf        *pixbuf;
 
+  ClutterKnot       knots[] = {{ 100, 100 }, { 100, 200 }, { 200, 200 },
+                               { 200, 100 }, {100, 100 }};
 
   clutter_init (&argc, &argv);
 
@@ -29,19 +31,23 @@ main (int argc, char *argv[])
   clutter_group_add (CLUTTER_GROUP (stage), hand);
 
   /* Make a timeline */
-  timeline = clutter_timeline_new (100, 30); /* num frames, fps */
+  timeline = clutter_timeline_new (100, 60); /* num frames, fps */
   g_object_set(timeline, "loop", TRUE, 0);  
 
   /* Set an alpha func to power behaviour - ramp is constant rise/fall */
   alpha = clutter_alpha_new (timeline, CLUTTER_ALPHA_RAMP);
 
-  /* Create a behaviour for that time line */
-  behave = clutter_behaviour_opacity_new_from_alpha (alpha, 0X33, 0xff); 
+  /* Create a behaviour for that alpha */
+  behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff); 
 
   /* Apply it to our actor */
   clutter_behaviour_apply (behave, hand);
 
-  /* start the timeline */
+  /* Make a path behaviour and apply that too */
+  behave = clutter_behaviour_path_new (alpha, knots, 5); 
+  clutter_behaviour_apply (behave, hand);
+
+  /* start the timeline and thus the animations */
   clutter_timeline_start (timeline);
 
   clutter_group_show_all (CLUTTER_GROUP (stage));