68
68
* a #ClutterAnimation instance and animate an actor between its current
69
69
* state and the specified final state.
71
* <refsect2 id="clutter-AnimationMode-Script">
72
* <title>Defining ClutterAnimationMode inside ClutterScript</title>
73
* <para>When defining a #ClutterAnimation inside a ClutterScript
74
* file or string the #ClutterAnimation:mode can be defined either
75
* using the #ClutterAnimationMode enumeration values through their
76
* "nick" (the short string used inside #GEnumValue), their numeric
77
* id, or using the following strings:</para>
80
* <term>easeInQuad, easeOutQuad, easeInOutQuad</term>
81
* <listitem><para>Corresponding to the quadratic easing
82
* modes</para></listitem>
85
* <term>easeInCubic, easeOutCubic, easeInOutCubic</term>
86
* <listitem><para>Corresponding to the cubic easing
87
* modes</para></listitem>
90
* <term>easeInQuart, easeOutQuart, easeInOutQuart</term>
91
* <listitem><para>Corresponding to the quartic easing
92
* modes</para></listitem>
95
* <term>easeInQuint, easeOutQuint, easeInOutQuint</term>
96
* <listitem><para>Corresponding to the quintic easing
97
* modes</para></listitem>
100
* <term>easeInSine, easeOutSine, easeInOutSine</term>
101
* <listitem><para>Corresponding to the sine easing
102
* modes</para></listitem>
105
* <term>easeInExpo, easeOutExpo, easeInOutExpo</term>
106
* <listitem><para>Corresponding to the exponential easing
107
* modes</para></listitem>
110
* <term>easeInCirc, easeOutCirc, easeInOutCirc</term>
111
* <listitem><para>Corresponding to the circular easing
112
* modes</para></listitem>
115
* <term>easeInElastic, easeOutElastic, easeInOutElastic</term>
116
* <listitem><para>Corresponding to the overshooting elastic
117
* easing modes</para></listitem>
120
* <term>easeInBack, easeOutBack, easeInOutBack</term>
121
* <listitem><para>Corresponding to the overshooting cubic
122
* easing modes</para></listitem>
125
* <term>easeInBounce, easeOutBounce, easeInOutBounce</term>
126
* <listitem><para>Corresponding to the bouncing easing
127
* modes</para></listitem>
71
132
* #ClutterAnimation is available since Clutter 1.0
126
189
static GQuark quark_object_animation = 0;
128
G_DEFINE_TYPE (ClutterAnimation, clutter_animation, G_TYPE_OBJECT);
191
static void clutter_scriptable_init (ClutterScriptableIface *iface);
193
G_DEFINE_TYPE_WITH_CODE (ClutterAnimation, clutter_animation, G_TYPE_OBJECT,
194
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
195
clutter_scriptable_init));
198
on_actor_dispose (gpointer user_data,
199
GObject *actor_pointer)
201
ClutterAnimation *self = user_data;
203
if (self->priv->object == actor_pointer)
205
CLUTTER_NOTE (ANIMATION, "Object [%p] was unref'd", actor_pointer);
206
g_object_unref (self);
131
212
clutter_animation_real_completed (ClutterAnimation *self)
141
222
direction = clutter_timeline_get_direction (timeline);
143
224
/* explicitly set the final state of the animation */
225
CLUTTER_NOTE (ANIMATION, "Set final state on object [%p]", priv->object);
144
226
g_hash_table_iter_init (&iter, priv->properties);
145
227
while (g_hash_table_iter_next (&iter, &key, &value))
167
249
animation = g_object_get_qdata (priv->object, quark_object_animation);
168
250
if (animation == self)
252
CLUTTER_NOTE (ANIMATION, "Unsetting animation for actor [%p]",
170
255
g_object_set_qdata (priv->object, quark_object_animation, NULL);
256
g_object_weak_unref (priv->object, on_actor_dispose, self);
258
CLUTTER_NOTE (ANIMATION, "Releasing the reference Animation [%p]",
171
260
g_object_unref (animation);
398
clutter_animation_parse_custom_node (ClutterScriptable *scriptable,
399
ClutterScript *script,
404
if (strncmp (name, "mode", 4) == 0)
408
mode = clutter_script_resolve_animation_mode (node);
410
g_value_init (value, G_TYPE_ULONG);
411
g_value_set_ulong (value, mode);
420
clutter_scriptable_init (ClutterScriptableIface *iface)
422
iface->parse_custom_node = clutter_animation_parse_custom_node;
307
426
clutter_animation_class_init (ClutterAnimationClass *klass)
548
if (!g_value_type_compatible (G_PARAM_SPEC_VALUE_TYPE (pspec),
668
pspec_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
670
if (!g_value_type_compatible (argtype, pspec_type) ||
671
!g_value_type_transformable (argtype, pspec_type))
551
673
g_warning ("Cannot bind property '%s': the interval value of "
552
674
"type '%s' is not compatible with the property value "
555
677
g_type_name (argtype),
556
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
678
g_type_name (pspec_type));
754
if (!g_value_type_compatible (G_PARAM_SPEC_VALUE_TYPE (pspec),
755
clutter_interval_get_value_type (interval)))
877
pspec_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
878
int_type = clutter_interval_get_value_type (interval);
880
if (!g_value_type_compatible (int_type, pspec_type) ||
881
!g_value_type_transformable (int_type, pspec_type))
757
883
g_warning ("Cannot update property '%s': the interval value of "
758
884
"type '%s' is not compatible with the property value "
761
g_type_name (clutter_interval_get_value_type (interval)),
762
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
887
g_type_name (int_type),
888
g_type_name (pspec_type));
896
* clutter_animation_update:
897
* @animation: a #ClutterAnimation
898
* @property_name: name of the property
899
* @final: The final value of the property
901
* Updates the @final value of the interval for @property_name
903
* Return value: (transfer none): The animation itself.
908
clutter_animation_update (ClutterAnimation *animation,
909
const gchar *property_name,
912
ClutterInterval *interval;
915
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL);
916
g_return_val_if_fail (property_name != NULL, NULL);
917
g_return_val_if_fail (final != NULL, NULL);
918
g_return_val_if_fail (G_VALUE_TYPE (final) != G_TYPE_INVALID, NULL);
920
interval = clutter_animation_get_interval (animation, property_name);
921
if (interval == NULL)
923
g_warning ("Cannot update property '%s': the animation has "
924
"no bound property with that name",
929
int_type = clutter_interval_get_value_type (interval);
931
if (!g_value_type_compatible (G_VALUE_TYPE (final), int_type) ||
932
!g_value_type_transformable (G_VALUE_TYPE (final), int_type))
934
g_warning ("Cannot update property '%s': the interval value of "
935
"type '%s' is not compatible with the property value "
938
g_type_name (int_type),
939
g_type_name (G_VALUE_TYPE (final)));
943
clutter_interval_set_final_value (interval, final);
770
949
* clutter_animation_get_interval:
771
950
* @animation: a #ClutterAnimation
772
951
* @property_name: name of the property
1461
1649
if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (&real_value)))
1463
if (!g_value_type_compatible (G_VALUE_TYPE (value),
1464
G_VALUE_TYPE (&real_value)) &&
1465
!g_value_type_compatible (G_VALUE_TYPE (&real_value),
1466
G_VALUE_TYPE (value)))
1468
g_warning ("%s: Unable to convert from %s to %s for "
1469
"the property '%s' of object %s",
1471
g_type_name (G_VALUE_TYPE (value)),
1472
g_type_name (G_VALUE_TYPE (&real_value)),
1474
G_OBJECT_TYPE_NAME (priv->object));
1475
g_value_unset (&real_value);
1479
if (!g_value_transform (value, &real_value))
1481
g_warning ("%s: Unable to transform from %s to %s",
1483
g_type_name (G_VALUE_TYPE (value)),
1484
g_type_name (G_VALUE_TYPE (&real_value)));
1485
g_value_unset (&real_value);
1651
/* are these two types compatible (can be directly copied)? */
1652
if (g_value_type_compatible (G_VALUE_TYPE (value),
1653
G_VALUE_TYPE (&real_value)))
1655
g_value_copy (value, &real_value);
1659
/* are these two type transformable? */
1660
if (g_value_type_transformable (G_VALUE_TYPE (value),
1661
G_VALUE_TYPE (&real_value)))
1663
if (g_value_transform (value, &real_value))
1667
/* if not compatible and not transformable then we can't do much */
1668
g_warning ("%s: Unable to convert from %s to %s for "
1669
"the property '%s' of object %s",
1671
g_type_name (G_VALUE_TYPE (value)),
1672
g_type_name (G_VALUE_TYPE (&real_value)),
1674
G_OBJECT_TYPE_NAME (priv->object));
1675
g_value_unset (&real_value);
1490
1679
g_value_copy (value, &real_value);
1492
1682
/* create an interval and bind it to the property, in case
1493
1683
* it's not a fixed property, otherwise just set it
1840
#if GLIB_CHECK_VERSION (2, 23, 2)
1841
G_VALUE_COLLECT_INIT (&final, G_PARAM_SPEC_VALUE_TYPE (pspec),
1845
/* this is the same as G_VALUE_COLLECT_INIT(), but slower */
1650
1846
g_value_init (&final, G_PARAM_SPEC_VALUE_TYPE (pspec));
1651
1847
G_VALUE_COLLECT (&final, var_args, 0, &error);
1848
#endif /* GLIB_CHECK_VERSION (2, 23, 2) */
1654
1852
g_warning ("%s: %s", G_STRLOC, error);
1678
1876
animation = clutter_animation_new ();
1679
1877
clutter_animation_set_object (animation, object);
1680
1878
g_object_set_qdata (object, quark_object_animation, animation);
1879
g_object_weak_ref (object, on_actor_dispose, animation);
1682
1881
CLUTTER_NOTE (ANIMATION,
1683
1882
"Created new Animation [%p] for actor [%p]",
1851
2050
* to control the animation or to know when the animation has been
1854
* If a name argument starts with "signal::", "signal-after::" or
1855
* "signal-swapped::" the two following arguments are used as callback
1856
* function and data for a signal handler installed on the
1857
* #ClutterAnimation object for the specified signal name, for
2053
* If a name argument starts with "signal::", "signal-after::",
2054
* "signal-swapped::" or "signal-swapped-after::" the two following arguments
2055
* are used as callback function and data for a signal handler installed on
2056
* the #ClutterAnimation object for the specified signal name, for instance:
2073
* or, to automatically destroy an actor at the end of the animation:
2076
* clutter_actor_animate (actor, CLUTTER_EASE_IN_CUBIC, 100,
2078
* "signal-swapped-after::completed",
2079
* clutter_actor_destroy,
1875
2084
* The "signal::" modifier is the equivalent of using g_signal_connect();
1876
2085
* the "signal-after::" modifier is the equivalent of using
1877
* g_signal_connect_after(); the "signal-swapped::" modifier is the equivalent
1878
* of using g_signal_connect_swapped(). The clutter_actor_animate() function
1879
* will not keep track of multiple connections to the same signal, so it is
1880
* your responsability to avoid them when calling clutter_actor_animate()
1881
* multiple times on the same actor.
2086
* g_signal_connect_after() or g_signal_connect_data() with the
2087
* %G_CONNECT_AFTER; the "signal-swapped::" modifier is the equivalent
2088
* of using g_signal_connect_swapped() or g_signal_connect_data() with the
2089
* %G_CONNECT_SWAPPED flah; finally, the "signal-swapped-after::" modifier
2090
* is the equivalent of using g_signal_connect_data() with both the
2091
* %G_CONNECT_AFTER and %G_CONNECT_SWAPPED flags. The clutter_actor_animate()
2092
* function will not keep track of multiple connections to the same signal,
2093
* so it is your responsability to avoid them when calling
2094
* clutter_actor_animate() multiple times on the same actor.
1883
2096
* Calling this function on an actor that is already being animated
1884
2097
* will cause the current animation to change with the new final values,