From 322b51cded630fb36f1759ebb608fe4985bd228b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 9 Apr 2020 17:54:45 +0200 Subject: [PATCH] clutter: Remove ClutterAnimation This removes ClutterAnimation and related tests. ClutterAnimation has been deprecated for a long time, and replacements exist and are used by e.g. GNOME Shell since a while back. This also disables a few relatively unrelated interactive tests, as they rely on ClutterAnimation to implement some animations they use to illustrate what they actually test. As interactive tests currently are more or less untestable due to any interaction with them crashing, as well as they in practice means rewriting the tests using non-deprecated animation APIs, they are not ported right now. To actually port the interactive tests, it needs to be possible to fist interact with them. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1192 --- clutter/clutter/clutter-animatable.c | 14 +- clutter/clutter/clutter-animatable.h | 3 - clutter/clutter/clutter-deprecated.h | 1 - clutter/clutter/clutter-enums.h | 2 +- clutter/clutter/clutter-interval.c | 3 - clutter/clutter/clutter-script-parser.c | 81 - clutter/clutter/clutter-script-private.h | 2 - clutter/clutter/clutter-timeline.c | 3 +- clutter/clutter/clutter-types.h | 2 - .../clutter/deprecated/clutter-animation.c | 1598 ----------------- .../clutter/deprecated/clutter-animation.h | 152 -- clutter/clutter/meson.build | 2 - src/tests/clutter/conform/script-parser.c | 23 - .../scripts/test-script-animation.json | 14 - src/tests/clutter/interactive/meson.build | 5 - src/tests/clutter/interactive/test-easing.c | 38 +- 16 files changed, 19 insertions(+), 1924 deletions(-) delete mode 100644 clutter/clutter/deprecated/clutter-animation.c delete mode 100644 clutter/clutter/deprecated/clutter-animation.h delete mode 100644 src/tests/clutter/conform/scripts/test-script-animation.json diff --git a/clutter/clutter/clutter-animatable.c b/clutter/clutter/clutter-animatable.c index e8c951110..e14012c5d 100644 --- a/clutter/clutter/clutter-animatable.c +++ b/clutter/clutter/clutter-animatable.c @@ -27,35 +27,23 @@ * @short_description: Interface for animatable classes * * #ClutterAnimatable is an interface that allows a #GObject class - * to control how a #ClutterAnimation will animate a property. + * to control how an actor will animate a property. * * Each #ClutterAnimatable should implement the * #ClutterAnimatableInterface.interpolate_property() virtual function of the * interface to compute the animation state between two values of an interval * depending on a progress factor, expressed as a floating point value. * - * If a #ClutterAnimatable is animated by a #ClutterAnimation - * instance, the #ClutterAnimation will call - * clutter_animatable_interpolate_property() passing the name of the - * currently animated property; the values interval; and the progress factor. - * The #ClutterAnimatable implementation should return the computed value for - * the animated - * property. - * * #ClutterAnimatable is available since Clutter 1.0 */ #include "clutter-build-config.h" -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - #include "clutter-animatable.h" #include "clutter-interval.h" #include "clutter-debug.h" #include "clutter-private.h" -#include "deprecated/clutter-animation.h" - G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); static void diff --git a/clutter/clutter/clutter-animatable.h b/clutter/clutter/clutter-animatable.h index 92006d0ca..d03e0589d 100644 --- a/clutter/clutter/clutter-animatable.h +++ b/clutter/clutter/clutter-animatable.h @@ -51,9 +51,6 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable, * @interpolate_value: virtual function for interpolating the progress * of a property * - * Base interface for #GObjects that can be animated by a - * a #ClutterAnimation. - * * Since: 1.0 */ struct _ClutterAnimatableInterface diff --git a/clutter/clutter/clutter-deprecated.h b/clutter/clutter/clutter-deprecated.h index 4b6147324..c2bb1cff2 100644 --- a/clutter/clutter/clutter-deprecated.h +++ b/clutter/clutter/clutter-deprecated.h @@ -4,7 +4,6 @@ #define __CLUTTER_DEPRECATED_H_INSIDE__ #include "deprecated/clutter-actor.h" -#include "deprecated/clutter-animation.h" #include "deprecated/clutter-box.h" #include "deprecated/clutter-container.h" #include "deprecated/clutter-group.h" diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index f7e8bc4c2..2d4f41c42 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -190,7 +190,7 @@ typedef enum /*< prefix=CLUTTER_REQUEST >*/ * @CLUTTER_ANIMATION_LAST: last animation mode, used as a guard for * registered global alpha functions * - * The animation modes used by #ClutterAnimation. This + * The animation modes used by #ClutterAnimatable. This * enumeration can be expanded in later versions of Clutter. * *
diff --git a/clutter/clutter/clutter-interval.c b/clutter/clutter/clutter-interval.c index 6f14287b4..97d2026aa 100644 --- a/clutter/clutter/clutter-interval.c +++ b/clutter/clutter/clutter-interval.c @@ -37,9 +37,6 @@ * any object taking a reference on a #ClutterInterval instance should * also take ownership of the interval by using g_object_ref_sink(). * - * #ClutterInterval is used by #ClutterAnimation to define the - * interval of values that an implicit animation should tween over. - * * #ClutterInterval can be subclassed to override the validation * and value computation. * diff --git a/clutter/clutter/clutter-script-parser.c b/clutter/clutter/clutter-script-parser.c index c64289309..bf3d51878 100644 --- a/clutter/clutter/clutter-script-parser.c +++ b/clutter/clutter/clutter-script-parser.c @@ -798,87 +798,6 @@ parse_signals (ClutterScript *script, return retval; } -/* define the names of the animation modes to match the ones - * that developers might be more accustomed to - */ -static const struct -{ - const gchar *name; - ClutterAnimationMode mode; -} animation_modes[] = { - { "linear", CLUTTER_LINEAR }, - { "easeInQuad", CLUTTER_EASE_IN_QUAD }, - { "easeOutQuad", CLUTTER_EASE_OUT_QUAD }, - { "easeInOutQuad", CLUTTER_EASE_IN_OUT_QUAD }, - { "easeInCubic", CLUTTER_EASE_IN_CUBIC }, - { "easeOutCubic", CLUTTER_EASE_OUT_CUBIC }, - { "easeInOutCubic", CLUTTER_EASE_IN_OUT_CUBIC }, - { "easeInQuart", CLUTTER_EASE_IN_QUART }, - { "easeOutQuart", CLUTTER_EASE_OUT_QUART }, - { "easeInOutQuart", CLUTTER_EASE_IN_OUT_QUART }, - { "easeInQuint", CLUTTER_EASE_IN_QUINT }, - { "easeOutQuint", CLUTTER_EASE_OUT_QUINT }, - { "easeInOutQuint", CLUTTER_EASE_IN_OUT_QUINT }, - { "easeInSine", CLUTTER_EASE_IN_SINE }, - { "easeOutSine", CLUTTER_EASE_OUT_SINE }, - { "easeInOutSine", CLUTTER_EASE_IN_OUT_SINE }, - { "easeInExpo", CLUTTER_EASE_IN_EXPO }, - { "easeOutExpo", CLUTTER_EASE_OUT_EXPO }, - { "easeInOutExpo", CLUTTER_EASE_IN_OUT_EXPO }, - { "easeInCirc", CLUTTER_EASE_IN_CIRC }, - { "easeOutCirc", CLUTTER_EASE_OUT_CIRC }, - { "easeInOutCirc", CLUTTER_EASE_IN_OUT_CIRC }, - { "easeInElastic", CLUTTER_EASE_IN_ELASTIC }, - { "easeOutElastic", CLUTTER_EASE_OUT_ELASTIC }, - { "easeInOutElastic", CLUTTER_EASE_IN_OUT_ELASTIC }, - { "easeInBack", CLUTTER_EASE_IN_BACK }, - { "easeOutBack", CLUTTER_EASE_OUT_BACK }, - { "easeInOutBack", CLUTTER_EASE_IN_OUT_BACK }, - { "easeInBounce", CLUTTER_EASE_IN_BOUNCE }, - { "easeOutBounce", CLUTTER_EASE_OUT_BOUNCE }, - { "easeInOutBounce", CLUTTER_EASE_IN_OUT_BOUNCE }, -}; - -static const gint n_animation_modes = G_N_ELEMENTS (animation_modes); - -gulong -_clutter_script_resolve_animation_mode (JsonNode *node) -{ - gint i, res = CLUTTER_CUSTOM_MODE; - - if (JSON_NODE_TYPE (node) != JSON_NODE_VALUE) - return CLUTTER_CUSTOM_MODE; - - if (json_node_get_value_type (node) == G_TYPE_INT64) - return json_node_get_int (node); - - if (json_node_get_value_type (node) == G_TYPE_STRING) - { - const gchar *name = json_node_get_string (node); - - /* XXX - we might be able to optimize by changing the ordering - * of the animation_modes array, e.g. - * - special casing linear - * - tokenizing ('ease', 'In', 'Sine') and matching on token - * - binary searching? - */ - for (i = 0; i < n_animation_modes; i++) - { - if (strcmp (animation_modes[i].name, name) == 0) - return animation_modes[i].mode; - } - - if (_clutter_script_enum_from_string (CLUTTER_TYPE_ANIMATION_MODE, - name, - &res)) - return res; - - g_warning ("Unable to find the animation mode '%s'", name); - } - - return CLUTTER_CUSTOM_MODE; -} - static void clutter_script_parser_object_end (JsonParser *json_parser, JsonObject *object) diff --git a/clutter/clutter/clutter-script-private.h b/clutter/clutter/clutter-script-private.h index b17c04581..52c240e2a 100644 --- a/clutter/clutter/clutter-script-private.h +++ b/clutter/clutter/clutter-script-private.h @@ -110,8 +110,6 @@ gboolean _clutter_script_parse_node (ClutterScript *script, GType _clutter_script_get_type_from_symbol (const gchar *symbol); GType _clutter_script_get_type_from_class (const gchar *name); -gulong _clutter_script_resolve_animation_mode (JsonNode *node); - gboolean _clutter_script_enum_from_string (GType gtype, const gchar *string, gint *enum_value); diff --git a/clutter/clutter/clutter-timeline.c b/clutter/clutter/clutter-timeline.c index b6f7ac666..cd0e795eb 100644 --- a/clutter/clutter/clutter-timeline.c +++ b/clutter/clutter/clutter-timeline.c @@ -24,7 +24,6 @@ /** * SECTION:clutter-timeline * @short_description: A class for time-based events - * @see_also: #ClutterAnimation, #ClutterAnimator, #ClutterState * * #ClutterTimeline is a base class for managing time-based event that cause * Clutter to redraw a stage, such as animations. @@ -71,7 +70,7 @@ * when reaching completion by using the #ClutterTimeline:auto-reverse property. * * Timelines are used in the Clutter animation framework by classes like - * #ClutterAnimation, #ClutterAnimator, and #ClutterState. + * #ClutterTransition. * * ## Defining Timelines in ClutterScript * diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h index 35cf5580b..1b65573a3 100644 --- a/clutter/clutter/clutter-types.h +++ b/clutter/clutter/clutter-types.h @@ -79,8 +79,6 @@ typedef struct _ClutterKnot ClutterKnot; typedef struct _ClutterMargin ClutterMargin; typedef struct _ClutterPerspective ClutterPerspective; -typedef struct _ClutterAnimation ClutterAnimation; - typedef struct _ClutterInputDeviceTool ClutterInputDeviceTool; typedef struct _ClutterInputDevice ClutterInputDevice; typedef struct _ClutterVirtualInputDevice ClutterVirtualInputDevice; diff --git a/clutter/clutter/deprecated/clutter-animation.c b/clutter/clutter/deprecated/clutter-animation.c deleted file mode 100644 index 8bf9e73b3..000000000 --- a/clutter/clutter/deprecated/clutter-animation.c +++ /dev/null @@ -1,1598 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * SECTION:clutter-animation - * @short_description: Simple implicit animations - * @See_Also: #ClutterAnimatable, #ClutterInterval, #ClutterTimeline - * - * #ClutterAnimation is an object providing simple, implicit animations - * for #GObjects. - * - * #ClutterAnimation instances will bind one or more #GObject properties - * belonging to a #GObject to a #ClutterInterval, and will then interpolate the - * property between the initial and final values of the interval. - * - * The duration of the animation is set using clutter_animation_set_duration(). - * The easing mode of the animation is set using clutter_animation_set_mode(). - * - * If you want to control the animation you should retrieve the - * #ClutterTimeline using clutter_animation_get_timeline() and then - * use #ClutterTimeline functions like clutter_timeline_start(), - * clutter_timeline_pause() or clutter_timeline_stop(). - * - * A #ClutterAnimation will emit the #ClutterAnimation::completed signal - * when the #ClutterTimeline used by the animation is completed; unlike - * #ClutterTimeline, though, the #ClutterAnimation::completed will not be - * emitted if #ClutterAnimation:loop is set to %TRUE - that is, a looping - * animation never completes. - * - * If the #GObject instance bound to a #ClutterAnimation implements the - * #ClutterAnimatable interface it is possible for that instance to - * control the way the initial and final states are interpolated. - * - * For convenience, it is possible to use the clutter_actor_animate() - * function call which will take care of setting up and tearing down - * a #ClutterAnimation instance and animate an actor between its current - * state and the specified final state. - * - * #ClutterAnimation is available since Clutter 1.0. - * - * #ClutterAnimation has been deprecated in Clutter 1.12. You should use - * the [implicit animation API][clutter-actor-animation] available inside - * #ClutterActor instead. If you require to define explicit transitions for - * one or more properties in order to reuse them, see #ClutterTransition - * instead. - * - * ## Defining ClutterAnimationMode inside ClutterScript - * - * When defining a #ClutterAnimation inside a ClutterScript - * file or string the #ClutterAnimation:mode can be defined either - * using the #ClutterAnimationMode enumeration values through their - * "nick" (the short string used inside #GEnumValue), their numeric - * id, or using the following strings: - * - * - easeInQuad, easeOutQuad, easeInOutQuad - * - easeInCubic, easeOutCubic, easeInOutCubic - * - easeInQuart, easeOutQuart, easeInOutQuart - * - easeInQuint, easeOutQuint, easeInOutQuint - * - easeInSine, easeOutSine, easeInOutSine - * - easeInExpo, easeOutExpo, easeInOutExpo - * - easeInCirc, easeOutCirc, easeInOutCirc - * - easeInElastic, easeOutElastic, easeInOutElastic - * - easeInBack, easeOutBack, easeInOutBack - * - easeInBounce, easeOutBounce, easeInOutBounce - */ - -#include "clutter-build-config.h" - -#include -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-animatable.h" -#include "clutter-animation.h" -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-interval.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-scriptable.h" -#include "clutter-script-private.h" - -#include "deprecated/clutter-animation.h" - -enum -{ - PROP_0, - - PROP_OBJECT, - PROP_MODE, - PROP_DURATION, - PROP_LOOP, - PROP_TIMELINE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - STARTED, - COMPLETED, - - LAST_SIGNAL -}; - -struct _ClutterAnimationPrivate -{ - GObject *object; - - GHashTable *properties; - - ClutterTimeline *timeline; - - guint timeline_started_id; - guint timeline_completed_id; - guint timeline_frame_id; -}; - -static guint animation_signals[LAST_SIGNAL] = { 0, }; - -static GQuark quark_object_animation = 0; - -static void clutter_scriptable_init (ClutterScriptableIface *iface); - -static ClutterTimeline * clutter_animation_get_timeline_internal (ClutterAnimation *animation); - -G_DEFINE_TYPE_WITH_CODE (ClutterAnimation, clutter_animation, G_TYPE_OBJECT, - G_ADD_PRIVATE (ClutterAnimation) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, - clutter_scriptable_init)); - -static void -on_actor_destroy (ClutterActor *actor, - ClutterAnimation *animation) -{ - ClutterAnimationPrivate *priv = animation->priv; - GObject *obj = G_OBJECT (actor); - - if (obj == priv->object) - { - g_object_set_qdata (priv->object, quark_object_animation, NULL); - g_signal_handlers_disconnect_by_func (priv->object, - G_CALLBACK (on_actor_destroy), - animation); - g_object_unref (animation); - } -} - -static void -clutter_animation_real_completed (ClutterAnimation *self) -{ - ClutterAnimationPrivate *priv = self->priv; - ClutterAnimatable *animatable = NULL; - ClutterAnimation *animation; - ClutterTimeline *timeline; - ClutterTimelineDirection direction; - gpointer key, value; - GHashTableIter iter; - - timeline = clutter_animation_get_timeline (self); - direction = clutter_timeline_get_direction (timeline); - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - animatable = CLUTTER_ANIMATABLE (priv->object); - - /* explicitly set the final state of the animation */ - CLUTTER_NOTE (ANIMATION, "Set final state on object [%p]", priv->object); - g_hash_table_iter_init (&iter, priv->properties); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - const gchar *p_name = key; - ClutterInterval *interval = value; - GValue *p_value; - - if (direction == CLUTTER_TIMELINE_FORWARD) - p_value = clutter_interval_peek_final_value (interval); - else - p_value = clutter_interval_peek_initial_value (interval); - - if (animatable != NULL) - clutter_animatable_set_final_state (animatable, p_name, p_value); - else - g_object_set_property (priv->object, p_name, p_value); - } - - /* at this point, if this animation was created by clutter_actor_animate() - * and friends, the animation will be attached to the object's data; since - * we want to allow developers to use g_signal_connect_after("completed") - * to concatenate a new animation, we need to remove the animation back - * pointer here, and unref() the animation. FIXME - we might want to - * provide a clutter_animation_attach()/clutter_animation_detach() pair - * to let the user reattach an animation - */ - animation = g_object_get_qdata (priv->object, quark_object_animation); - if (animation == self) - { - CLUTTER_NOTE (ANIMATION, "Unsetting animation for actor [%p]", - priv->object); - - g_object_set_qdata (priv->object, quark_object_animation, NULL); - g_signal_handlers_disconnect_by_func (priv->object, - G_CALLBACK (on_actor_destroy), - animation); - - CLUTTER_NOTE (ANIMATION, "Releasing the reference Animation [%p]", - animation); - g_object_unref (animation); - } -} - -static void -clutter_animation_finalize (GObject *gobject) -{ - ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv; - - CLUTTER_NOTE (ANIMATION, - "Destroying properties table for Animation [%p]", - gobject); - g_hash_table_destroy (priv->properties); - - G_OBJECT_CLASS (clutter_animation_parent_class)->finalize (gobject); -} - -static void -clutter_animation_dispose (GObject *gobject) -{ - ClutterAnimationPrivate *priv = CLUTTER_ANIMATION (gobject)->priv; - ClutterTimeline *timeline; - - timeline = priv->timeline; - - if (timeline != NULL && priv->timeline_started_id != 0) - g_signal_handler_disconnect (timeline, priv->timeline_started_id); - - if (timeline != NULL && priv->timeline_completed_id != 0) - g_signal_handler_disconnect (timeline, priv->timeline_completed_id); - - if (timeline != NULL && priv->timeline_frame_id != 0) - g_signal_handler_disconnect (timeline, priv->timeline_frame_id); - - priv->timeline_started_id = 0; - priv->timeline_completed_id = 0; - priv->timeline_frame_id = 0; - - if (priv->timeline != NULL) - { - g_object_unref (priv->timeline); - priv->timeline = NULL; - } - - if (priv->object != NULL) - { - g_object_unref (priv->object); - priv->object = NULL; - } - - G_OBJECT_CLASS (clutter_animation_parent_class)->dispose (gobject); -} - -static void -clutter_animation_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterAnimation *animation = CLUTTER_ANIMATION (gobject); - - switch (prop_id) - { - case PROP_OBJECT: - clutter_animation_set_object (animation, g_value_get_object (value)); - break; - - case PROP_MODE: - clutter_animation_set_mode (animation, g_value_get_ulong (value)); - break; - - case PROP_DURATION: - clutter_animation_set_duration (animation, g_value_get_uint (value)); - break; - - case PROP_LOOP: - clutter_animation_set_loop (animation, g_value_get_boolean (value)); - break; - - case PROP_TIMELINE: - clutter_animation_set_timeline (animation, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_animation_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterAnimation *animation = CLUTTER_ANIMATION (gobject); - ClutterAnimationPrivate *priv = animation->priv; - - switch (prop_id) - { - case PROP_OBJECT: - g_value_set_object (value, priv->object); - break; - - case PROP_MODE: - g_value_set_ulong (value, clutter_animation_get_mode (animation)); - break; - - case PROP_DURATION: - g_value_set_uint (value, clutter_animation_get_duration (animation)); - break; - - case PROP_LOOP: - g_value_set_boolean (value, clutter_animation_get_loop (animation)); - break; - - case PROP_TIMELINE: - g_value_set_object (value, clutter_animation_get_timeline (animation)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static gboolean -clutter_animation_parse_custom_node (ClutterScriptable *scriptable, - ClutterScript *script, - GValue *value, - const gchar *name, - JsonNode *node) -{ - if (strncmp (name, "mode", 4) == 0) - { - gulong mode; - - mode = _clutter_script_resolve_animation_mode (node); - - g_value_init (value, G_TYPE_ULONG); - g_value_set_ulong (value, mode); - - return TRUE; - } - - return FALSE; -} - -static void -clutter_scriptable_init (ClutterScriptableIface *iface) -{ - iface->parse_custom_node = clutter_animation_parse_custom_node; -} - -static void -clutter_animation_class_init (ClutterAnimationClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - quark_object_animation = - g_quark_from_static_string ("clutter-actor-animation"); - - klass->completed = clutter_animation_real_completed; - - gobject_class->set_property = clutter_animation_set_property; - gobject_class->get_property = clutter_animation_get_property; - gobject_class->dispose = clutter_animation_dispose; - gobject_class->finalize = clutter_animation_finalize; - - /** - * ClutterAnimation:object: - * - * The #GObject to which the animation applies. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - obj_props[PROP_OBJECT] = - g_param_spec_object ("object", - P_("Object"), - P_("Object to which the animation applies"), - G_TYPE_OBJECT, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterAnimation:mode: - * - * A #ClutterAnimationMode. default value is %CLUTTER_LINEAR. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - obj_props[PROP_MODE] = - g_param_spec_ulong ("mode", - P_("Mode"), - P_("The mode of the animation"), - 0, G_MAXULONG, - CLUTTER_LINEAR, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterAnimation:duration: - * - * The duration of the animation, expressed in milliseconds. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - obj_props[PROP_DURATION] = - g_param_spec_uint ("duration", - P_("Duration"), - P_("Duration of the animation, in milliseconds"), - 0, G_MAXUINT, - 0, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterAnimation:loop: - * - * Whether the animation should loop. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - obj_props[PROP_LOOP] = - g_param_spec_boolean ("loop", - P_("Loop"), - P_("Whether the animation should loop"), - FALSE, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterAnimation:timeline: - * - * The #ClutterTimeline used by the animation. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - obj_props[PROP_TIMELINE] = - g_param_spec_object ("timeline", - P_("Timeline"), - P_("The timeline used by the animation"), - CLUTTER_TYPE_TIMELINE, - CLUTTER_PARAM_READWRITE); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); - - /** - * ClutterAnimation::started: - * @animation: the animation that emitted the signal - * - * The ::started signal is emitted once the animation has been - * started - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - animation_signals[STARTED] = - g_signal_new (I_("started"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterAnimationClass, started), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - /** - * ClutterAnimation::completed: - * @animation: the animation that emitted the signal - * - * The ::completed signal is emitted once the animation has - * been completed. - * - * The @animation instance is guaranteed to be valid for the entire - * duration of the signal emission chain. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ - animation_signals[COMPLETED] = - g_signal_new (I_("completed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterAnimationClass, completed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); -} - -static void -clutter_animation_init (ClutterAnimation *self) -{ - self->priv = clutter_animation_get_instance_private (self); - - self->priv->properties = - g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); -} - -static inline void -clutter_animation_bind_property_internal (ClutterAnimation *animation, - const gchar *property_name, - GParamSpec *pspec, - ClutterInterval *interval) -{ - ClutterAnimationPrivate *priv = animation->priv; - - if (!clutter_interval_validate (interval, pspec)) - { - g_warning ("Cannot bind property '%s': the interval is out " - "of bounds", - property_name); - return; - } - - g_hash_table_insert (priv->properties, - g_strdup (property_name), - g_object_ref_sink (interval)); -} - -static inline void -clutter_animation_update_property_internal (ClutterAnimation *animation, - const gchar *property_name, - GParamSpec *pspec, - ClutterInterval *interval) -{ - ClutterAnimationPrivate *priv = animation->priv; - - if (!clutter_interval_validate (interval, pspec)) - { - g_warning ("Cannot bind property '%s': the interval is out " - "of bounds", - property_name); - return; - } - - g_hash_table_replace (priv->properties, - g_strdup (property_name), - g_object_ref_sink (interval)); -} - -/** - * clutter_animation_has_property: - * @animation: a #ClutterAnimation - * @property_name: name of the property - * - * Checks whether @animation is controlling @property_name. - * - * Return value: %TRUE if the property is animated by the - * #ClutterAnimation, %FALSE otherwise - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -gboolean -clutter_animation_has_property (ClutterAnimation *animation, - const gchar *property_name) -{ - ClutterAnimationPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE); - g_return_val_if_fail (property_name != NULL, FALSE); - - priv = animation->priv; - - return g_hash_table_lookup (priv->properties, property_name) != NULL; -} - -/** - * clutter_animation_get_interval: - * @animation: a #ClutterAnimation - * @property_name: name of the property - * - * Retrieves the #ClutterInterval associated to @property_name - * inside @animation. - * - * Return value: (transfer none): a #ClutterInterval or %NULL if no - * property with the same name was found. The returned interval is - * owned by the #ClutterAnimation and should not be unreferenced - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -ClutterInterval * -clutter_animation_get_interval (ClutterAnimation *animation, - const gchar *property_name) -{ - ClutterAnimationPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - g_return_val_if_fail (property_name != NULL, NULL); - - priv = animation->priv; - - return g_hash_table_lookup (priv->properties, property_name); -} - -static void -on_timeline_started (ClutterTimeline *timeline, - ClutterAnimation *animation) -{ - g_signal_emit (animation, animation_signals[STARTED], 0); -} - -static void -on_timeline_completed (ClutterTimeline *timeline, - ClutterAnimation *animation) -{ - CLUTTER_NOTE (ANIMATION, "Timeline [%p] complete", timeline); - - if (!clutter_animation_get_loop (animation)) - g_signal_emit (animation, animation_signals[COMPLETED], 0); -} - -static void -on_timeline_frame (ClutterTimeline *timeline, - gint elapsed, - ClutterAnimation *animation) -{ - ClutterAnimationPrivate *priv; - GList *properties, *p; - gdouble alpha_value; - gboolean is_animatable = FALSE; - ClutterAnimatable *animatable = NULL; - - /* make sure the animation survives the notification */ - g_object_ref (animation); - - priv = animation->priv; - - alpha_value = clutter_timeline_get_progress (priv->timeline); - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - { - animatable = CLUTTER_ANIMATABLE (priv->object); - is_animatable = TRUE; - } - - g_object_freeze_notify (priv->object); - - properties = g_hash_table_get_keys (priv->properties); - for (p = properties; p != NULL; p = p->next) - { - const gchar *p_name = p->data; - ClutterInterval *interval; - GValue value = G_VALUE_INIT; - gboolean apply; - - interval = g_hash_table_lookup (priv->properties, p_name); - g_assert (CLUTTER_IS_INTERVAL (interval)); - - g_value_init (&value, clutter_interval_get_value_type (interval)); - - if (is_animatable) - { - apply = clutter_animatable_interpolate_value (animatable, p_name, - interval, - alpha_value, - &value); - } - else - { - apply = clutter_interval_compute_value (interval, - alpha_value, - &value); - } - - if (apply) - { - if (is_animatable) - clutter_animatable_set_final_state (animatable, p_name, &value); - else - g_object_set_property (priv->object, p_name, &value); - } - - g_value_unset (&value); - } - - g_list_free (properties); - - g_object_thaw_notify (priv->object); - - g_object_unref (animation); -} - -static ClutterTimeline * -clutter_animation_get_timeline_internal (ClutterAnimation *animation) -{ - ClutterAnimationPrivate *priv = animation->priv; - ClutterTimeline *timeline; - - if (priv->timeline != NULL) - return priv->timeline; - - timeline = g_object_new (CLUTTER_TYPE_TIMELINE, NULL); - - priv->timeline_started_id = - g_signal_connect (timeline, "started", - G_CALLBACK (on_timeline_started), - animation); - - priv->timeline_completed_id = - g_signal_connect (timeline, "completed", - G_CALLBACK (on_timeline_completed), - animation); - - priv->timeline_frame_id = - g_signal_connect (timeline, "new-frame", - G_CALLBACK (on_timeline_frame), - animation); - - priv->timeline = timeline; - - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_TIMELINE]); - - return priv->timeline; -} - -/** - * clutter_animation_new: - * - * Creates a new #ClutterAnimation instance. You should set the - * #GObject to be animated using clutter_animation_set_object(), - * set the duration with clutter_animation_set_duration() and the - * easing mode using clutter_animation_set_mode(). - * - * The clutter_actor_animate() and relative family of functions provide - * an easy way to animate a #ClutterActor and automatically manage the - * lifetime of a #ClutterAnimation instance, so you should consider using - * those functions instead of manually creating an animation. - * - * Return value: the newly created #ClutterAnimation. Use g_object_unref() - * to release the associated resources - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -ClutterAnimation * -clutter_animation_new (void) -{ - return g_object_new (CLUTTER_TYPE_ANIMATION, NULL); -} - -/** - * clutter_animation_set_object: - * @animation: a #ClutterAnimation - * @object: a #GObject - * - * Attaches @animation to @object. The #ClutterAnimation will take a - * reference on @object. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_set_object (ClutterAnimation *animation, - GObject *object) -{ - ClutterAnimationPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (object == NULL || G_IS_OBJECT (object)); - - priv = animation->priv; - - if (priv->object != NULL) - { - g_object_set_qdata (priv->object, quark_object_animation, NULL); - - g_object_unref (priv->object); - priv->object = NULL; - } - - if (object != NULL) - priv->object = g_object_ref (object); - - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_OBJECT]); -} - -/** - * clutter_animation_set_mode: - * @animation: a #ClutterAnimation - * @mode: an animation mode logical id - * - * Sets the animation @mode of @animation. The animation @mode is - * a logical id, coming from the #ClutterAnimationMode enumeration. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_set_mode (ClutterAnimation *animation, - gulong mode) -{ - ClutterTimeline *timeline; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - - g_object_freeze_notify (G_OBJECT (animation)); - - timeline = clutter_animation_get_timeline_internal (animation); - - clutter_timeline_set_progress_mode (timeline, mode); - - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_MODE]); - - g_object_thaw_notify (G_OBJECT (animation)); -} - -/** - * clutter_animation_get_mode: - * @animation: a #ClutterAnimation - * - * Retrieves the animation mode of @animation, as set by - * clutter_animation_set_mode(). - * - * Return value: the mode for the animation - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -gulong -clutter_animation_get_mode (ClutterAnimation *animation) -{ - ClutterTimeline *timeline; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), CLUTTER_LINEAR); - - timeline = clutter_animation_get_timeline_internal (animation); - - return clutter_timeline_get_progress_mode (timeline); -} - -/** - * clutter_animation_set_duration: - * @animation: a #ClutterAnimation - * @msecs: the duration in milliseconds - * - * Sets the duration of @animation in milliseconds. - * - * This function will set #ClutterAnimation:timeline if needed. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_set_duration (ClutterAnimation *animation, - guint msecs) -{ - ClutterTimeline *timeline; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - - g_object_freeze_notify (G_OBJECT (animation)); - - timeline = clutter_animation_get_timeline_internal (animation); - clutter_timeline_set_duration (timeline, msecs); - clutter_timeline_rewind (timeline); - - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_DURATION]); - - g_object_thaw_notify (G_OBJECT (animation)); -} - -/** - * clutter_animation_set_loop: - * @animation: a #ClutterAnimation - * @loop: %TRUE if the animation should loop - * - * Sets whether @animation should loop over itself once finished. - * - * A looping #ClutterAnimation will not emit the #ClutterAnimation::completed - * signal when finished. - * - * This function will set #ClutterAnimation:timeline if needed. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_set_loop (ClutterAnimation *animation, - gboolean loop) -{ - ClutterTimeline *timeline; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - - g_object_freeze_notify (G_OBJECT (animation)); - - timeline = clutter_animation_get_timeline_internal (animation); - clutter_timeline_set_repeat_count (timeline, loop ? -1 : 0); - - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_LOOP]); - - g_object_thaw_notify (G_OBJECT (animation)); -} - -/** - * clutter_animation_get_loop: - * @animation: a #ClutterAnimation - * - * Retrieves whether @animation is looping. - * - * Return value: %TRUE if the animation is looping - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -gboolean -clutter_animation_get_loop (ClutterAnimation *animation) -{ - ClutterTimeline *timeline; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE); - - timeline = clutter_animation_get_timeline_internal (animation); - - return clutter_timeline_get_repeat_count (timeline) != 0; -} - -/** - * clutter_animation_get_duration: - * @animation: a #ClutterAnimation - * - * Retrieves the duration of @animation, in milliseconds. - * - * Return value: the duration of the animation - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -guint -clutter_animation_get_duration (ClutterAnimation *animation) -{ - ClutterTimeline *timeline; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), 0); - - timeline = clutter_animation_get_timeline_internal (animation); - - return clutter_timeline_get_duration (timeline); -} - -/** - * clutter_animation_set_timeline: - * @animation: a #ClutterAnimation - * @timeline: (allow-none): a #ClutterTimeline, or %NULL to unset the - * current #ClutterTimeline - * - * Sets the #ClutterTimeline used by @animation. - * - * This function will take a reference on the passed @timeline. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_set_timeline (ClutterAnimation *animation, - ClutterTimeline *timeline) -{ - ClutterAnimationPrivate *priv; - ClutterTimeline *cur_timeline; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (timeline == NULL || CLUTTER_IS_TIMELINE (timeline)); - - priv = animation->priv; - - cur_timeline = priv->timeline; - - if (cur_timeline == timeline) - return; - - g_object_freeze_notify (G_OBJECT (animation)); - - if (cur_timeline != NULL && priv->timeline_started_id != 0) - g_signal_handler_disconnect (cur_timeline, priv->timeline_started_id); - - if (cur_timeline != NULL && priv->timeline_completed_id != 0) - g_signal_handler_disconnect (cur_timeline, priv->timeline_completed_id); - - if (cur_timeline != NULL && priv->timeline_frame_id != 0) - g_signal_handler_disconnect (cur_timeline, priv->timeline_frame_id); - - priv->timeline_started_id = 0; - priv->timeline_completed_id = 0; - priv->timeline_frame_id = 0; - - /* Release previously set timeline if any */ - g_clear_object (&priv->timeline); - - priv->timeline = timeline; - - if (priv->timeline) - g_object_ref (priv->timeline); - - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_TIMELINE]); - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_DURATION]); - g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_LOOP]); - - if (timeline != NULL) - { - priv->timeline_started_id = - g_signal_connect (timeline, "started", - G_CALLBACK (on_timeline_started), - animation); - priv->timeline_completed_id = - g_signal_connect (timeline, "completed", - G_CALLBACK (on_timeline_completed), - animation); - priv->timeline_frame_id = - g_signal_connect (timeline, "new-frame", - G_CALLBACK (on_timeline_frame), - animation); - } - - g_object_thaw_notify (G_OBJECT (animation)); -} - -/** - * clutter_animation_get_timeline: - * @animation: a #ClutterAnimation - * - * Retrieves the #ClutterTimeline used by @animation - * - * Return value: (transfer none): the timeline used by the animation - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -ClutterTimeline * -clutter_animation_get_timeline (ClutterAnimation *animation) -{ - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - - return clutter_animation_get_timeline_internal (animation); -} - -/* - * starts the timeline - */ -static void -clutter_animation_start (ClutterAnimation *animation) -{ - ClutterTimeline *timeline; - - timeline = clutter_animation_get_timeline_internal (animation); - - if (G_LIKELY (timeline != NULL)) - clutter_timeline_start (timeline); - else - { - /* sanity check */ - g_warning (G_STRLOC ": no timeline found, unable to start the animation"); - } -} - -static void -clutter_animation_setup_property (ClutterAnimation *animation, - const gchar *property_name, - const GValue *value, - GParamSpec *pspec, - gboolean is_fixed) -{ - ClutterAnimationPrivate *priv = animation->priv; - GValue real_value = G_VALUE_INIT; - - if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) - { - g_warning ("Cannot bind property '%s': the property is " - "construct-only", - property_name); - return; - } - - if (!(pspec->flags & G_PARAM_WRITABLE)) - { - g_warning ("Cannot bind property '%s': the property is " - "not writable", - property_name); - return; - } - - /* initialize the real value that will be used to store the - * final state of the animation - */ - g_value_init (&real_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - - /* if it's not the same type of the GParamSpec value, try to - * convert it using the GValue transformation API, otherwise - * just copy it - */ - if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (&real_value))) - { - /* are these two types compatible (can be directly copied)? */ - if (g_value_type_compatible (G_VALUE_TYPE (value), - G_VALUE_TYPE (&real_value))) - { - g_value_copy (value, &real_value); - goto done; - } - - /* are these two type transformable? */ - if (g_value_type_transformable (G_VALUE_TYPE (value), - G_VALUE_TYPE (&real_value))) - { - if (g_value_transform (value, &real_value)) - goto done; - } - - /* if not compatible and not transformable then we can't do much */ - g_warning ("%s: Unable to convert from %s to %s for " - "the property '%s' of object %s", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (&real_value)), - property_name, - G_OBJECT_TYPE_NAME (priv->object)); - g_value_unset (&real_value); - return; - } - else - g_value_copy (value, &real_value); - -done: - /* create an interval and bind it to the property, in case - * it's not a fixed property, otherwise just set it - */ - if (G_LIKELY (!is_fixed)) - { - ClutterInterval *interval; - GValue cur_value = G_VALUE_INIT; - - g_value_init (&cur_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - clutter_animatable_get_initial_state (CLUTTER_ANIMATABLE (priv->object), - property_name, - &cur_value); - else - g_object_get_property (priv->object, property_name, &cur_value); - - interval = - clutter_interval_new_with_values (G_PARAM_SPEC_VALUE_TYPE (pspec), - &cur_value, - &real_value); - - if (!clutter_animation_has_property (animation, property_name)) - clutter_animation_bind_property_internal (animation, property_name, - pspec, - interval); - else - clutter_animation_update_property_internal (animation, property_name, - pspec, - interval); - - g_value_unset (&cur_value); - } - else - { - if (CLUTTER_IS_ANIMATABLE (priv->object)) - clutter_animatable_set_final_state (CLUTTER_ANIMATABLE (priv->object), - property_name, - &real_value); - else - g_object_set_property (priv->object, property_name, &real_value); - } - - g_value_unset (&real_value); -} - -static const struct -{ - const gchar *name; - GConnectFlags flags; -} signal_prefixes[] = - { - { "::", 0 }, - { "-swapped::", G_CONNECT_SWAPPED }, - { "-after::", G_CONNECT_AFTER }, - { "-swapped-after::", G_CONNECT_SWAPPED | G_CONNECT_AFTER } - }; - -static gboolean -clutter_animation_has_signal_prefix (const gchar *property_name, - GConnectFlags *flags, - int *offset) -{ - int i; - - if (!g_str_has_prefix (property_name, "signal")) - return FALSE; - - for (i = 0; i < G_N_ELEMENTS (signal_prefixes); i++) - if (g_str_has_prefix (property_name + 6, signal_prefixes[i].name)) - { - *offset = strlen (signal_prefixes[i].name) + 6; - *flags = signal_prefixes[i].flags; - return TRUE; - } - - return FALSE; -} - -static void -clutter_animation_setup_valist (ClutterAnimation *animation, - const gchar *first_property_name, - va_list var_args) -{ - ClutterAnimationPrivate *priv = animation->priv; - ClutterAnimatable *animatable = NULL; - GObjectClass *klass = NULL; - const gchar *property_name; - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - animatable = CLUTTER_ANIMATABLE (priv->object); - else - klass = G_OBJECT_GET_CLASS (priv->object); - - property_name = first_property_name; - while (property_name != NULL) - { - GParamSpec *pspec; - GValue final = G_VALUE_INIT; - gchar *error = NULL; - gboolean is_fixed = FALSE; - GConnectFlags flags; - int offset; - - if (clutter_animation_has_signal_prefix (property_name, - &flags, - &offset)) - { - const gchar *signal_name = property_name + offset; - GCallback callback = va_arg (var_args, GCallback); - gpointer userdata = va_arg (var_args, gpointer); - - g_signal_connect_data (animation, signal_name, - callback, userdata, - NULL, flags); - } - else - { - if (g_str_has_prefix (property_name, "fixed::")) - { - property_name += 7; /* strlen("fixed::") */ - is_fixed = TRUE; - } - - if (animatable != NULL) - pspec = clutter_animatable_find_property (animatable, - property_name); - else - pspec = g_object_class_find_property (klass, property_name); - - if (pspec == NULL) - { - g_warning ("Cannot bind property '%s': objects of type '%s' do " - "not have this property", - property_name, - g_type_name (G_OBJECT_TYPE (priv->object))); - break; - } - - G_VALUE_COLLECT_INIT (&final, G_PARAM_SPEC_VALUE_TYPE (pspec), - var_args, 0, - &error); - - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - g_free (error); - break; - } - - clutter_animation_setup_property (animation, property_name, - &final, - pspec, - is_fixed); - - - g_value_unset (&final); - } - - property_name = va_arg (var_args, gchar*); - } -} - -static ClutterAnimation * -animation_create_for_actor (ClutterActor *actor) -{ - ClutterAnimation *animation; - GObject *object = G_OBJECT (actor); - - animation = g_object_get_qdata (object, quark_object_animation); - if (animation == NULL) - { - animation = clutter_animation_new (); - clutter_animation_set_object (animation, object); - g_object_set_qdata (object, quark_object_animation, animation); - - /* use the ::destroy signal to get a notification - * that the actor went away mid-animation - */ - g_signal_connect (object, "destroy", - G_CALLBACK (on_actor_destroy), - animation); - - CLUTTER_NOTE (ANIMATION, - "Created new Animation [%p] for actor [%p]", - animation, - actor); - } - else - { - CLUTTER_NOTE (ANIMATION, - "Reusing Animation [%p] for actor [%p]", - animation, - actor); - } - - return animation; -} - -/** - * clutter_actor_animate_with_timeline: - * @actor: a #ClutterActor - * @mode: an animation mode logical id - * @timeline: a #ClutterTimeline - * @first_property_name: the name of a property - * @...: a %NULL terminated list of property names and - * property values - * - * Animates the given list of properties of @actor between the current - * value for each property and a new final value. The animation has a - * definite duration given by @timeline and a speed given by the @mode. - * - * See clutter_actor_animate() for further details. - * - * This function is useful if you want to use an existing timeline - * to animate @actor. - * - * Return value: (transfer none): a #ClutterAnimation object. The object is - * owned by the #ClutterActor and should not be unreferenced with - * g_object_unref() - * - * Since: 1.0 - * Deprecated: 1.12: Use the implicit transition for animatable properties - * in #ClutterActor instead. See clutter_actor_save_easing_state(), - * clutter_actor_set_easing_mode(), clutter_actor_set_easing_duration(), - * clutter_actor_set_easing_delay(), and clutter_actor_restore_easing_state(). - */ -ClutterAnimation * -clutter_actor_animate_with_timeline (ClutterActor *actor, - gulong mode, - ClutterTimeline *timeline, - const gchar *first_property_name, - ...) -{ - ClutterAnimation *animation; - va_list args; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (first_property_name != NULL, NULL); - - animation = animation_create_for_actor (actor); - clutter_animation_set_mode (animation, mode); - clutter_animation_set_timeline (animation, timeline); - - va_start (args, first_property_name); - clutter_animation_setup_valist (animation, first_property_name, args); - va_end (args); - - clutter_animation_start (animation); - - return animation; -} - -/** - * clutter_actor_animate: - * @actor: a #ClutterActor - * @mode: an animation mode logical id - * @duration: duration of the animation, in milliseconds - * @first_property_name: the name of a property - * @...: a %NULL terminated list of property names and - * property values - * - * Animates the given list of properties of @actor between the current - * value for each property and a new final value. The animation has a - * definite duration and a speed given by the @mode. - * - * For example, this: - * - * |[ - * clutter_actor_animate (rectangle, CLUTTER_LINEAR, 250, - * "width", 100.0, - * "height", 100.0, - * NULL); - * ]| - * - * will make width and height properties of the #ClutterActor "rectangle" - * grow linearly between the current value and 100 pixels, in 250 milliseconds. - * - * The animation @mode is a logical id, from the #ClutterAnimationMode. - * - * All the properties specified will be animated between the current value - * and the final value. If a property should be set at the beginning of - * the animation but not updated during the animation, it should be prefixed - * by the "fixed::" string, for instance: - * - * |[ - * clutter_actor_animate (actor, CLUTTER_EASE_IN_SINE, 100, - * "rotation-angle-z", 360.0, - * "fixed::rotation-center-z", ¢er, - * NULL); - * ]| - * - * Will animate the "rotation-angle-z" property between the current value - * and 360 degrees, and set the "rotation-center-z" property to the fixed - * value of the #graphene_point3d_t "center". - * - * This function will implicitly create a #ClutterAnimation object which - * will be assigned to the @actor and will be returned to the developer - * to control the animation or to know when the animation has been - * completed. - * - * If a name argument starts with "signal::", "signal-after::", - * "signal-swapped::" or "signal-swapped-after::" the two following arguments - * are used as callback function and data for a signal handler installed on - * the #ClutterAnimation object for the specified signal name, for instance: - * - * |[ - * static void - * on_animation_completed (ClutterAnimation *animation, - * ClutterActor *actor) - * { - * clutter_actor_hide (actor); - * } - * - * clutter_actor_animate (actor, CLUTTER_EASE_IN_CUBIC, 100, - * "opacity", 0, - * "signal::completed", on_animation_completed, actor, - * NULL); - * ]| - * - * or, to automatically destroy an actor at the end of the animation: - * - * |[ - * clutter_actor_animate (actor, CLUTTER_EASE_IN_CUBIC, 100, - * "opacity", 0, - * "signal-swapped-after::completed", - * clutter_actor_destroy, - * actor, - * NULL); - * ]| - * - * The "signal::" modifier is the equivalent of using g_signal_connect(); - * the "signal-after::" modifier is the equivalent of using - * g_signal_connect_after() or g_signal_connect_data() with the - * %G_CONNECT_AFTER; the "signal-swapped::" modifier is the equivalent - * of using g_signal_connect_swapped() or g_signal_connect_data() with the - * %G_CONNECT_SWAPPED flah; finally, the "signal-swapped-after::" modifier - * is the equivalent of using g_signal_connect_data() with both the - * %G_CONNECT_AFTER and %G_CONNECT_SWAPPED flags. The clutter_actor_animate() - * function will not keep track of multiple connections to the same signal, - * so it is your responsability to avoid them when calling - * clutter_actor_animate() multiple times on the same actor. - * - * Calling this function on an actor that is already being animated - * will cause the current animation to change with the new final values, - * the new easing mode and the new duration - that is, this code: - * - * |[ - * clutter_actor_animate (actor, CLUTTER_LINEAR, 250, - * "width", 100.0, - * "height", 100.0, - * NULL); - * clutter_actor_animate (actor, CLUTTER_EASE_IN_CUBIC, 500, - * "x", 100.0, - * "y", 100.0, - * "width", 200.0, - * NULL); - * ]| - * - * is the equivalent of: - * - * |[ - * clutter_actor_animate (actor, CLUTTER_EASE_IN_CUBIC, 500, - * "x", 100.0, - * "y", 100.0, - * "width", 200.0, - * "height", 100.0, - * NULL); - * ]| - * - * Unless the animation is looping, the #ClutterAnimation created by - * clutter_actor_animate() will become invalid as soon as it is - * complete. - * - * Since the created #ClutterAnimation instance attached to @actor - * is guaranteed to be valid throughout the #ClutterAnimation::completed - * signal emission chain, you will not be able to create a new animation - * using clutter_actor_animate() on the same @actor from within the - * #ClutterAnimation::completed signal handler unless you use - * g_signal_connect_after() to connect the callback function, for instance: - * - * |[ - * static void - * on_animation_completed (ClutterAnimation *animation, - * ClutterActor *actor) - * { - * clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 250, - * "x", 500.0, - * "y", 500.0, - * NULL); - * } - * - * ... - * animation = clutter_actor_animate (actor, CLUTTER_EASE_IN_CUBIC, 250, - * "x", 100.0, - * "y", 100.0, - * NULL); - * g_signal_connect (animation, "completed", - * G_CALLBACK (on_animation_completed), - * actor); - * ... - * ]| - * - * Return value: (transfer none): a #ClutterAnimation object. The object is - * owned by the #ClutterActor and should not be unreferenced with - * g_object_unref() - * - * Since: 1.0 - * Deprecated: 1.12: Use the implicit transition for animatable properties - * in #ClutterActor instead. See clutter_actor_save_easing_state(), - * clutter_actor_set_easing_mode(), clutter_actor_set_easing_duration(), - * clutter_actor_set_easing_delay(), and clutter_actor_restore_easing_state(). - */ -ClutterAnimation * -clutter_actor_animate (ClutterActor *actor, - gulong mode, - guint duration, - const gchar *first_property_name, - ...) -{ - ClutterAnimation *animation; - va_list args; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (mode != CLUTTER_CUSTOM_MODE, NULL); - g_return_val_if_fail (duration > 0, NULL); - g_return_val_if_fail (first_property_name != NULL, NULL); - - animation = animation_create_for_actor (actor); - clutter_animation_set_mode (animation, mode); - clutter_animation_set_duration (animation, duration); - - va_start (args, first_property_name); - clutter_animation_setup_valist (animation, first_property_name, args); - va_end (args); - - clutter_animation_start (animation); - - return animation; -} diff --git a/clutter/clutter/deprecated/clutter-animation.h b/clutter/clutter/deprecated/clutter-animation.h deleted file mode 100644 index 012cf44e7..000000000 --- a/clutter/clutter/deprecated/clutter-animation.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_ANIMATION_H__ -#define __CLUTTER_ANIMATION_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ANIMATION (clutter_animation_get_type ()) -#define CLUTTER_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATION, ClutterAnimation)) -#define CLUTTER_IS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATION)) -#define CLUTTER_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ANIMATION, ClutterAnimationClass)) -#define CLUTTER_IS_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ANIMATION)) -#define CLUTTER_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ANIMATION, ClutterAnimationClass)) - -typedef struct _ClutterAnimationPrivate ClutterAnimationPrivate; -typedef struct _ClutterAnimationClass ClutterAnimationClass; - -/** - * ClutterAnimation: - * - * The #ClutterAnimation structure contains only private data and should - * be accessed using the provided functions. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use the implicit animation on #ClutterActor - */ -struct _ClutterAnimation -{ - /*< private >*/ - GObject parent_instance; - - ClutterAnimationPrivate *priv; -}; - -/** - * ClutterAnimationClass: - * @started: class handler for the #ClutterAnimation::started signal - * @completed: class handler for the #ClutterAnimation::completed signal - * - * The #ClutterAnimationClass structure contains only private data and - * should be accessed using the provided functions. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use the implicit animation on #ClutterActor - */ -struct _ClutterAnimationClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - void (* started) (ClutterAnimation *animation); - void (* completed) (ClutterAnimation *animation); - - /*< private >*/ - /* padding for future expansion */ - void (*_clutter_reserved1) (void); - void (*_clutter_reserved2) (void); - void (*_clutter_reserved3) (void); - void (*_clutter_reserved4) (void); - void (*_clutter_reserved5) (void); - void (*_clutter_reserved6) (void); - void (*_clutter_reserved7) (void); - void (*_clutter_reserved8) (void); -}; - -CLUTTER_DEPRECATED -GType clutter_animation_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_FOR(clutter_property_transition_new) -ClutterAnimation * clutter_animation_new (void); - -CLUTTER_DEPRECATED_FOR(clutter_transition_set_animatable) -void clutter_animation_set_object (ClutterAnimation *animation, - GObject *object); -CLUTTER_DEPRECATED_FOR(clutter_timeline_set_progress_mode) -void clutter_animation_set_mode (ClutterAnimation *animation, - gulong mode); -CLUTTER_DEPRECATED_FOR(clutter_timeline_get_progress_mode) -gulong clutter_animation_get_mode (ClutterAnimation *animation); -CLUTTER_DEPRECATED_FOR(clutter_timeline_set_duration) -void clutter_animation_set_duration (ClutterAnimation *animation, - guint msecs); -CLUTTER_DEPRECATED_FOR(clutter_timeline_get_duration) -guint clutter_animation_get_duration (ClutterAnimation *animation); -CLUTTER_DEPRECATED_FOR(clutter_timeline_set_repeat_count) -void clutter_animation_set_loop (ClutterAnimation *animation, - gboolean loop); -CLUTTER_DEPRECATED_FOR(clutter_timeline_get_repeat_count) -gboolean clutter_animation_get_loop (ClutterAnimation *animation); -CLUTTER_DEPRECATED -void clutter_animation_set_timeline (ClutterAnimation *animation, - ClutterTimeline *timeline); -CLUTTER_DEPRECATED -ClutterTimeline * clutter_animation_get_timeline (ClutterAnimation *animation); -CLUTTER_DEPRECATED -gboolean clutter_animation_has_property (ClutterAnimation *animation, - const gchar *property_name); -CLUTTER_DEPRECATED -ClutterInterval * clutter_animation_get_interval (ClutterAnimation *animation, - const gchar *property_name); - -/* - * ClutterActor API - */ - -CLUTTER_DEPRECATED -ClutterAnimation * clutter_actor_animate (ClutterActor *actor, - gulong mode, - guint duration, - const gchar *first_property_name, - ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED -ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor, - gulong mode, - ClutterTimeline *timeline, - const gchar *first_property_name, - ...) G_GNUC_NULL_TERMINATED; - -G_END_DECLS - -#endif /* __CLUTTER_ANIMATION_DEPRECATED_H__ */ diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index 22c5e4ee4..f21d0e77c 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -219,7 +219,6 @@ clutter_nonintrospected_sources = [ clutter_deprecated_headers = [ 'deprecated/clutter-actor.h', - 'deprecated/clutter-animation.h', 'deprecated/clutter-box.h', 'deprecated/clutter-container.h', 'deprecated/clutter-group.h', @@ -229,7 +228,6 @@ clutter_deprecated_headers = [ ] clutter_deprecated_sources = [ - 'deprecated/clutter-animation.c', 'deprecated/clutter-box.c', 'deprecated/clutter-group.c', 'deprecated/clutter-rectangle.c', diff --git a/src/tests/clutter/conform/script-parser.c b/src/tests/clutter/conform/script-parser.c index b51db38d6..7a7e6a8b6 100644 --- a/src/tests/clutter/conform/script-parser.c +++ b/src/tests/clutter/conform/script-parser.c @@ -251,28 +251,6 @@ script_named_object (void) g_free (test_file); } -static void -script_animation (void) -{ - ClutterScript *script = clutter_script_new (); - GObject *animation = NULL; - GError *error = NULL; - gchar *test_file; - - test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-animation.json", NULL); - clutter_script_load_from_file (script, test_file, &error); - if (g_test_verbose () && error) - g_print ("Error: %s", error->message); - - g_assert_no_error (error); - - animation = clutter_script_get_object (script, "test"); - g_assert (CLUTTER_IS_ANIMATION (animation)); - - g_object_unref (script); - g_free (test_file); -} - static void script_layout_property (void) { @@ -383,7 +361,6 @@ CLUTTER_TEST_SUITE ( CLUTTER_TEST_UNIT ("/script/single-object", script_single) CLUTTER_TEST_UNIT ("/script/container-child", script_child) CLUTTER_TEST_UNIT ("/script/named-object", script_named_object) - CLUTTER_TEST_UNIT ("/script/animation", script_animation) CLUTTER_TEST_UNIT ("/script/object-property", script_object_property) CLUTTER_TEST_UNIT ("/script/layout-property", script_layout_property) CLUTTER_TEST_UNIT ("/script/actor-margin", script_margin) diff --git a/src/tests/clutter/conform/scripts/test-script-animation.json b/src/tests/clutter/conform/scripts/test-script-animation.json deleted file mode 100644 index d6ef90343..000000000 --- a/src/tests/clutter/conform/scripts/test-script-animation.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type" : "ClutterAnimation", - "id" : "test", - "mode" : "easeInCubic", - "duration" : 500, - "object" : { - "type" : "ClutterRectangle", - "id" : "rect", - "opacity" : 128, - "width" : 100, - "height" : 16, - "color" : "white" - } -} diff --git a/src/tests/clutter/interactive/meson.build b/src/tests/clutter/interactive/meson.build index 59aead635..0e7180f13 100644 --- a/src/tests/clutter/interactive/meson.build +++ b/src/tests/clutter/interactive/meson.build @@ -17,7 +17,6 @@ clutter_tests_interactive_link_args = [ clutter_tests_interactive_test_sources = [ 'test-events.c', 'test-actors.c', - 'test-shader-effects.c', 'test-script.c', 'test-grab.c', 'test-cogl-shader-glsl.c', @@ -25,9 +24,7 @@ clutter_tests_interactive_test_sources = [ 'test-cogl-tex-convert.c', 'test-cogl-offscreen.c', 'test-cogl-tex-polygon.c', - 'test-cogl-multitexture.c', 'test-paint-wrapper.c', - 'test-layout.c', 'test-animation.c', 'test-easing.c', 'test-binding-pool.c', @@ -38,11 +35,9 @@ clutter_tests_interactive_test_sources = [ 'test-stage-sizing.c', 'test-swipe-action.c', 'test-cogl-point-sprites.c', - 'test-path-constraint.c', 'test-devices.c', 'test-content.c', 'test-keyframe-transition.c', - 'test-bind-constraint.c', 'test-touch-events.c', 'test-rotate-zoom.c', 'test-image.c', diff --git a/src/tests/clutter/interactive/test-easing.c b/src/tests/clutter/interactive/test-easing.c index c0d175a21..1ec88e814 100644 --- a/src/tests/clutter/interactive/test-easing.c +++ b/src/tests/clutter/interactive/test-easing.c @@ -53,8 +53,6 @@ static gboolean recenter = FALSE; static ClutterActor *main_stage = NULL; static ClutterActor *easing_mode_label = NULL; -static ClutterAnimation *last_animation = NULL; - int test_easing_main (int argc, char *argv[]); @@ -66,21 +64,23 @@ test_easing_describe (void); * repositions (through an animation) the bouncer at the center of the stage */ static void -recenter_bouncer (ClutterAnimation *animation, - ClutterActor *rectangle) +recenter_bouncer (ClutterActor *rectangle) { gfloat base_x, base_y; gint cur_mode; + + cur_mode = easing_modes[current_mode].mode; base_x = clutter_actor_get_width (main_stage) / 2; base_y = clutter_actor_get_height (main_stage) / 2; - cur_mode = easing_modes[current_mode].mode; + clutter_actor_set_easing_duration (rectangle, 250); + clutter_actor_set_easing_mode (rectangle, cur_mode); + clutter_actor_set_position (rectangle, base_x, base_y); - clutter_actor_animate (rectangle, cur_mode, 250, - "x", base_x, - "y", base_y, - NULL); + g_signal_connect_after (rectangle, "transition-completed", + G_CALLBACK (clutter_actor_restore_easing_state), + NULL); } static gboolean @@ -108,28 +108,22 @@ on_button_press (ClutterActor *actor, } else if (event->button == CLUTTER_BUTTON_PRIMARY) { - ClutterAnimation *animation; ClutterAnimationMode cur_mode; cur_mode = easing_modes[current_mode].mode; - /* tween the actor using the current easing mode */ - animation = - clutter_actor_animate (rectangle, cur_mode, duration * 1000, - "x", event->x, - "y", event->y, - NULL); + clutter_actor_save_easing_state (rectangle); + clutter_actor_set_easing_duration (rectangle, duration * 1000); + clutter_actor_set_easing_mode (rectangle, cur_mode); + clutter_actor_set_position (rectangle, event->x, event->y); /* if we were asked to, recenter the bouncer at the end of the * animation. we keep track of the animation to avoid connecting * the signal handler to the same Animation twice. */ - if (recenter && last_animation != animation) - g_signal_connect_after (animation, "completed", - G_CALLBACK (recenter_bouncer), - rectangle); - - last_animation = animation; + g_signal_connect_after (rectangle, "transition-completed", + G_CALLBACK (recenter_bouncer), + rectangle); } return TRUE;