From 0cb0a841cc56c7912b59973dddc9e157fba7e0f5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 5 Mar 2009 23:10:00 -0500 Subject: [PATCH] [animation] Enhance the bind API Bug 1419 - Add clutter_animation_bind, rename clutter_animation_bind_interval This is a different approach from the clutter_actor_animatev vector variant. The single call should be even easier on automatic bindings, since calls can be chained like: new Clutter.Animation({object: myactor}).bind("x", 42).bind("y", 43); Note clutter_animation_bind_property which took a ClutterInterval is renamed to clutter_animation_bind_interval for clarity, and to discourage use since there are friendlier APIs about. Signed-off-by: Emmanuele Bassi --- clutter/clutter-animation.c | 129 +++++++++++++++++++++++++++++++++----------- clutter/clutter-animation.h | 7 ++- 2 files changed, 104 insertions(+), 32 deletions(-) diff --git a/clutter/clutter-animation.c b/clutter/clutter-animation.c index 865e7ad..5d509e6 100644 --- a/clutter/clutter-animation.c +++ b/clutter/clutter-animation.c @@ -426,34 +426,15 @@ clutter_animation_update_property_internal (ClutterAnimation *animation, g_object_ref_sink (interval)); } -/** - * clutter_animation_bind_property: - * @animation: a #ClutterAnimation - * @property_name: the property to control - * @interval: a #ClutterInterval - * - * Binds @interval to the @property_name of the #GObject - * attached to @animation. The #ClutterAnimation will take - * ownership of the passed #ClutterInterval. - * - * If you need to update the interval instance use - * clutter_animation_update_property() instead. - * - * Since: 1.0 - */ -void -clutter_animation_bind_property (ClutterAnimation *animation, - const gchar *property_name, - ClutterInterval *interval) +static GParamSpec * +clutter_animation_validate_bind (ClutterAnimation *animation, + const char *property_name, + GType argtype) { ClutterAnimationPrivate *priv; GObjectClass *klass; GParamSpec *pspec; - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (property_name != NULL); - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - priv = animation->priv; if (G_UNLIKELY (!priv->object)) @@ -462,7 +443,7 @@ clutter_animation_bind_property (ClutterAnimation *animation, "object set. You need to call clutter_animation_set_object() " "first to be able to bind a property", property_name); - return; + return NULL; } if (G_UNLIKELY (clutter_animation_has_property (animation, property_name))) @@ -470,7 +451,7 @@ clutter_animation_bind_property (ClutterAnimation *animation, g_warning ("Cannot bind property `%s': the animation already has " "a bound property with the same name", property_name); - return; + return NULL; } klass = G_OBJECT_GET_CLASS (priv->object); @@ -481,31 +462,119 @@ clutter_animation_bind_property (ClutterAnimation *animation, "no such property", property_name, g_type_name (G_OBJECT_TYPE (priv->object))); - return; + return NULL; } if (!(pspec->flags & G_PARAM_WRITABLE)) { g_warning ("Cannot bind property `%s': the property is not writable", property_name); - return; + return NULL; } if (!g_value_type_compatible (G_PARAM_SPEC_VALUE_TYPE (pspec), - clutter_interval_get_value_type (interval))) + argtype)) { g_warning ("Cannot bind property `%s': the interval value of " "type `%s' is not compatible with the property value " "of type `%s'", property_name, - g_type_name (clutter_interval_get_value_type (interval)), + g_type_name (argtype), g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); - return; + return NULL; } + return pspec; +} + +/** + * clutter_animation_bind_interval: + * @animation: a #ClutterAnimation + * @property_name: the property to control + * @interval: (transfer full): a #ClutterInterval + * + * Binds @interval to the @property_name of the #GObject + * attached to @animation. The #ClutterAnimation will take + * ownership of the passed #ClutterInterval. For more information + * about animations, see clutter_actor_animate(). + * + * If you need to update the interval instance use + * clutter_animation_update_property() instead. + * + * Return value: (transfer none): The animation itself. + * Since: 1.0 + */ +ClutterAnimation * +clutter_animation_bind_interval (ClutterAnimation *animation, + const gchar *property_name, + ClutterInterval *interval) +{ + GParamSpec *pspec; + + g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL); + + pspec = clutter_animation_validate_bind (animation, property_name, + clutter_interval_get_value_type (interval)); + if (pspec == NULL) + return NULL; + + clutter_animation_bind_property_internal (animation, pspec, interval); + + return animation; +} + + +/** + * clutter_animation_bind: + * @animation: a #ClutterAnimation + * @property_name: the property to control + * @final: The final value of the property + * + * Adds a single property with name @property_name to the + * animation @animation. For more information about animations, + * see clutter_actor_animate(). + * + * This method returns the animation primarily to make chained + * calls convenient in language bindings. + * + * Return value: (transfer none): The animation itself. + * Since: 1.0 + */ +ClutterAnimation * +clutter_animation_bind (ClutterAnimation *animation, + const gchar *property_name, + const GValue *final) +{ + ClutterAnimationPrivate *priv; + GParamSpec *pspec; + ClutterInterval *interval; + GType type; + GValue initial = { 0, }; + + g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + + priv = animation->priv; + + type = G_VALUE_TYPE (final); + pspec = clutter_animation_validate_bind (animation, property_name, + type); + if (pspec == NULL) + return NULL; + + g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_object_get_property (priv->object, property_name, &initial); + + interval = clutter_interval_new_with_values (type, &initial, final); + g_value_unset (&initial); clutter_animation_bind_property_internal (animation, pspec, interval); + + return animation; } + /** * clutter_animation_unbind_property: * @animation: a #ClutterAnimation diff --git a/clutter/clutter-animation.h b/clutter/clutter-animation.h index 1660bfc..7792015 100644 --- a/clutter/clutter-animation.h +++ b/clutter/clutter-animation.h @@ -116,7 +116,10 @@ void clutter_animation_set_alpha (ClutterAnimation *an ClutterAlpha *alpha); ClutterAlpha * clutter_animation_get_alpha (ClutterAnimation *animation); -void clutter_animation_bind_property (ClutterAnimation *animation, +ClutterAnimation * clutter_animation_bind (ClutterAnimation *animation, + const gchar *property_name, + const GValue *final); +ClutterAnimation * clutter_animation_bind_interval (ClutterAnimation *animation, const gchar *property_name, ClutterInterval *interval); gboolean clutter_animation_has_property (ClutterAnimation *animation, @@ -124,7 +127,7 @@ gboolean clutter_animation_has_property (ClutterAnimation *an void clutter_animation_update_property (ClutterAnimation *animation, const gchar *property_name, ClutterInterval *interval); -void clutter_animation_unbind_property (ClutterAnimation *animation, +void clutter_animation_unbind (ClutterAnimation *animation, const gchar *property_name); ClutterInterval *clutter_animation_get_interval (ClutterAnimation *animation, const gchar *property_name); -- 2.7.4