## Migrating from ClutterBehaviour

### Emmanuele Bassi

`<ebassi`linux.intel.com`>`

The ClutterBehaviour class and its sub-classes have been deprecated since Clutter 1.6. The animation framework provided by ClutterAnimation, ClutterAnimator and ClutterState fully replaces all functionality from the ClutterBehaviour classes.

Generally, animations using ClutterBehaviour sub-classes can be effectively re-implemented just by using ClutterActor properties.

Here is an example of an animation using a ClutterBehaviourOpacity instance:

    1
    2
    3
    4
    5
    6
    7
    ClutterTimeline *timeline = clutter_timeline_new (250);
    ClutterAlpha *alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
    ClutterBehaviour *behaviour = clutter_behaviour_opacity_new (alpha, 255, 0);

    clutter_behaviour_apply (behaviour, some_actor);

    clutter_timeline_start (timeline);

The same effect can be achieved by using `clutter_actor_animate()` and the "opacity" property:

    1
    2
    3
    4
    clutter_actor_set_opacity (some_actor, 255);
    clutter_actor_animate (some_actor, CLUTTER_LINEAR, 250,
                           "opacity", 0,
                           NULL);

ClutterBehaviours used for continuous animations with looping timelines can still be effectively replaced by looping animations; for instance, the following example of a "pulsating" actor using ClutterBehaviourScale:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    static void
    reverse_timeline (ClutterTimeline *timeline)
    {
      ClutterTimelineDirection dir = clutter_timeline_get_direction (timeline);

      if (dir == CLUTTER_TIMELINE_FORWARD)
        dir = CLUTTER_TIMELINE_BACKWARD;
      else
        dir = CLUTTER_TIMELINE_FORWARD;

      clutter_timeline_set_direction (timeline, dir);
    }

      ClutterTimeline *timeline = clutter_timeline_new (500);
      ClutterAlpha *alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
      ClutterBehaviour *behaviour;

      g_object_set (some_actor, "scale-gravity", CLUTTER_GRAVITY_CENTER, NULL);
      behaviour = clutter_behaviour_scale_new (alpha,
                                               1.0, 2.0,
                                               1.0, 2.0);
      clutter_behaviour_apply (behaviour, some_actor);

      g_signal_connect (timeline,
                        "completed", G_CALLBACK (reverse_timeline),
                        NULL);

      clutter_timeline_set_loop (timeline);
      clutter_timeline_start (timeline);

The same effect can be achieved using a ClutterAnimation:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ClutterAnimation *animation =
      clutter_actor_animate (some_actor, CLUTTER_LINEAR, 500,
                             "scale-x", 2.0,
                             "scale-y", 2.0,
                             "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER,
                             NULL);

    ClutterTimeline *timeline = clutter_animation_get_timeline (animation);
    clutter_timeline_set_loop (timeline, TRUE);
    clutter_timeline_set_auto_reverse (timeline, TRUE);

ClutterBehaviour sub-classes can be applied to multiple actors, in order to share the duration and the easing mode. It is possible to use the same underlying ClutterTimeline and ClutterAlpha instances with ClutterAnimation to achieve the same effect. Complex animations, spanning multiple actors, should use the ClutterAnimator and ClutterState classes instead.