From 6fff1bcdc6cd90bfc75eff765c7512545fedded9 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 27 May 2009 13:01:31 +0100 Subject: [PATCH] [animatable] Allow validation in ::animate_property The Animatable interface implementation will always have the computed value applied, whilst the non-Animatable objects go through the interval validation first to avoid incurring in assertions and warnings. The Animatable::animate_property() should also be able to validate the property it's supposed to interpolate, and eventually discard it. This requires adding a return value to the virtual function (and its wrapper function). The Animation code will then apply the computed value only if the animate_property() returns TRUE -- unifying the code path with the non-Animatable objects. --- clutter/clutter-animatable.c | 43 ++++++++++++++++++++++-------------- clutter/clutter-animatable.h | 28 +++++++++++------------ clutter/clutter-animation.c | 21 ++++++++++-------- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/clutter/clutter-animatable.c b/clutter/clutter-animatable.c index fb2b88b19..e448a694f 100644 --- a/clutter/clutter-animatable.c +++ b/clutter/clutter-animatable.c @@ -86,9 +86,12 @@ clutter_animatable_get_type (void) * All implementation of the #ClutterAnimatable interface must * implement this function. * + * Return value: %TRUE if the value has been validated and can + * be applied to the #ClutterAnimatable, and %FALSE otherwise + * * Since: 1.0 */ -void +gboolean clutter_animatable_animate_property (ClutterAnimatable *animatable, ClutterAnimation *animation, const gchar *property_name, @@ -97,21 +100,27 @@ clutter_animatable_animate_property (ClutterAnimatable *animatable, gdouble progress, GValue *value) { - g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (property_name != NULL); - g_return_if_fail (initial_value != NULL && final_value != NULL); - g_return_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID); - g_return_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID); - g_return_if_fail (value != NULL); - g_return_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) && - G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value)); + gboolean res; - CLUTTER_ANIMATABLE_GET_IFACE (animatable)->animate_property (animatable, - animation, - property_name, - initial_value, - final_value, - progress, - value); + g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE); + g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE); + g_return_val_if_fail (property_name != NULL, FALSE); + g_return_val_if_fail (initial_value != NULL && final_value != NULL, FALSE); + g_return_val_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID, FALSE); + g_return_val_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) && + G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value), + FALSE); + + res = + CLUTTER_ANIMATABLE_GET_IFACE (animatable)->animate_property (animatable, + animation, + property_name, + initial_value, + final_value, + progress, + value); + + return res; } diff --git a/clutter/clutter-animatable.h b/clutter/clutter-animatable.h index aee717ac4..71a88d65e 100644 --- a/clutter/clutter-animatable.h +++ b/clutter/clutter-animatable.h @@ -56,24 +56,24 @@ struct _ClutterAnimatableIface GTypeInterface parent_iface; /*< public >*/ - void (* animate_property) (ClutterAnimatable *animatable, - ClutterAnimation *animation, - const gchar *property_name, - const GValue *initial_value, - const GValue *final_value, - gdouble progress, - GValue *value); + gboolean (* animate_property) (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value); }; GType clutter_animatable_get_type (void) G_GNUC_CONST; -void clutter_animatable_animate_property (ClutterAnimatable *animatable, - ClutterAnimation *animation, - const gchar *property_name, - const GValue *initial_value, - const GValue *final_value, - gdouble progress, - GValue *value); +gboolean clutter_animatable_animate_property (ClutterAnimatable *animatable, + ClutterAnimation *animation, + const gchar *property_name, + const GValue *initial_value, + const GValue *final_value, + gdouble progress, + GValue *value); G_END_DECLS diff --git a/clutter/clutter-animation.c b/clutter/clutter-animation.c index e7c596618..3584ebb17 100644 --- a/clutter/clutter-animation.c +++ b/clutter/clutter-animation.c @@ -778,6 +778,7 @@ on_alpha_notify (GObject *gobject, const gchar *p_name = p->data; ClutterInterval *interval; GValue value = { 0, }; + gboolean apply; interval = g_hash_table_lookup (priv->properties, p_name); g_assert (CLUTTER_IS_INTERVAL (interval)); @@ -791,20 +792,22 @@ on_alpha_notify (GObject *gobject, initial = clutter_interval_peek_initial_value (interval); final = clutter_interval_peek_final_value (interval); - clutter_animatable_animate_property (animatable, animation, - p_name, - initial, final, - alpha_value, - &value); - - g_object_set_property (priv->object, p_name, &value); + apply = clutter_animatable_animate_property (animatable, animation, + p_name, + initial, final, + alpha_value, + &value); } else { - if (clutter_interval_compute_value (interval, alpha_value, &value)) - g_object_set_property (priv->object, p_name, &value); + apply = clutter_interval_compute_value (interval, + alpha_value, + &value); } + if (apply) + g_object_set_property (priv->object, p_name, &value); + g_value_unset (&value); }