4 * An OpenGL based 'interactive canvas' library.
6 * Copyright (C) 2012 Intel Corporation
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
23 * SECTION:clutter-property-transition
24 * @Title: ClutterPropertyTransition
25 * @Short_Description: Property transitions
27 * #ClutterPropertyTransition is a specialized #ClutterTransition that
28 * can be used to tween a property of a #ClutterAnimatable instance.
30 * #ClutterPropertyTransition is available since Clutter 1.10
37 #include "clutter-property-transition.h"
39 #include "clutter-animatable.h"
40 #include "clutter-debug.h"
41 #include "clutter-interval.h"
42 #include "clutter-private.h"
43 #include "clutter-transition.h"
45 struct _ClutterPropertyTransitionPrivate
61 static GParamSpec *obj_props[PROP_LAST] = { NULL, };
63 G_DEFINE_TYPE (ClutterPropertyTransition, clutter_property_transition, CLUTTER_TYPE_TRANSITION)
66 clutter_property_transition_ensure_interval (ClutterPropertyTransition *transition,
67 ClutterAnimatable *animatable,
68 ClutterInterval *interval)
70 ClutterPropertyTransitionPrivate *priv = transition->priv;
73 if (clutter_interval_is_valid (interval))
76 /* if no initial value has been set, use the current value */
77 value_p = clutter_interval_peek_initial_value (interval);
78 if (!G_IS_VALUE (value_p))
80 g_value_init (value_p, clutter_interval_get_value_type (interval));
81 clutter_animatable_get_initial_state (animatable,
86 /* if no final value has been set, use the current value */
87 value_p = clutter_interval_peek_final_value (interval);
88 if (!G_IS_VALUE (value_p))
90 g_value_init (value_p, clutter_interval_get_value_type (interval));
91 clutter_animatable_get_initial_state (animatable,
98 clutter_property_transition_attached (ClutterTransition *transition,
99 ClutterAnimatable *animatable)
101 ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition);
102 ClutterPropertyTransitionPrivate *priv = self->priv;
103 ClutterInterval *interval;
105 if (priv->property_name == NULL)
109 clutter_animatable_find_property (animatable, priv->property_name);
111 if (priv->pspec == NULL)
114 interval = clutter_transition_get_interval (transition);
115 if (interval == NULL)
118 clutter_property_transition_ensure_interval (self, animatable, interval);
122 clutter_property_transition_detached (ClutterTransition *transition,
123 ClutterAnimatable *animatable)
125 ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition);
126 ClutterPropertyTransitionPrivate *priv = self->priv;
132 clutter_property_transition_compute_value (ClutterTransition *transition,
133 ClutterAnimatable *animatable,
134 ClutterInterval *interval,
137 ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition);
138 ClutterPropertyTransitionPrivate *priv = self->priv;
139 GValue value = G_VALUE_INIT;
142 /* if we have a GParamSpec we also have an animatable instance */
143 if (priv->pspec == NULL)
146 clutter_property_transition_ensure_interval (self, animatable, interval);
148 g_value_init (&value, clutter_interval_get_value_type (interval));
150 res = clutter_animatable_interpolate_value (animatable,
157 clutter_animatable_set_final_state (animatable,
161 g_value_unset (&value);
165 clutter_property_transition_set_property (GObject *gobject,
170 ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (gobject);
174 case PROP_PROPERTY_NAME:
175 clutter_property_transition_set_property_name (self,
176 g_value_get_string (value));
180 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
185 clutter_property_transition_get_property (GObject *gobject,
190 ClutterPropertyTransitionPrivate *priv = CLUTTER_PROPERTY_TRANSITION (gobject)->priv;
194 case PROP_PROPERTY_NAME:
195 g_value_set_string (value, priv->property_name);
199 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
204 clutter_property_transition_finalize (GObject *gobject)
206 ClutterPropertyTransitionPrivate *priv;
208 priv = CLUTTER_PROPERTY_TRANSITION (gobject)->priv;
210 g_free (priv->property_name);
212 G_OBJECT_CLASS (clutter_property_transition_parent_class)->finalize (gobject);
216 clutter_property_transition_class_init (ClutterPropertyTransitionClass *klass)
218 ClutterTransitionClass *transition_class = CLUTTER_TRANSITION_CLASS (klass);
219 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
221 g_type_class_add_private (klass, sizeof (ClutterPropertyTransitionPrivate));
223 transition_class->attached = clutter_property_transition_attached;
224 transition_class->detached = clutter_property_transition_detached;
225 transition_class->compute_value = clutter_property_transition_compute_value;
227 gobject_class->set_property = clutter_property_transition_set_property;
228 gobject_class->get_property = clutter_property_transition_get_property;
229 gobject_class->finalize = clutter_property_transition_finalize;
232 * ClutterPropertyTransition:property-name:
234 * The name of the property of a #ClutterAnimatable to animate.
238 obj_props[PROP_PROPERTY_NAME] =
239 g_param_spec_string ("property-name",
241 P_("The name of the property to animate"),
243 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
245 g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
249 clutter_property_transition_init (ClutterPropertyTransition *self)
252 G_TYPE_INSTANCE_GET_PRIVATE (self, CLUTTER_TYPE_PROPERTY_TRANSITION,
253 ClutterPropertyTransitionPrivate);
257 * clutter_property_transition_new:
258 * @property_name: (allow-none): a property of @animatable, or %NULL
260 * Creates a new #ClutterPropertyTransition.
262 * Return value: (transfer full): the newly created #ClutterPropertyTransition.
263 * Use g_object_unref() when done
268 clutter_property_transition_new (const char *property_name)
270 return g_object_new (CLUTTER_TYPE_PROPERTY_TRANSITION,
271 "property-name", property_name,
276 * clutter_property_transition_set_property_name:
277 * @transition: a #ClutterPropertyTransition
278 * @property_name: (allow-none): a property name
280 * Sets the #ClutterPropertyTransition:property-name property of @transition.
285 clutter_property_transition_set_property_name (ClutterPropertyTransition *transition,
286 const char *property_name)
288 ClutterPropertyTransitionPrivate *priv;
289 ClutterAnimatable *animatable;
291 g_return_if_fail (CLUTTER_IS_PROPERTY_TRANSITION (transition));
293 priv = transition->priv;
295 if (g_strcmp0 (priv->property_name, property_name) == 0)
298 g_free (priv->property_name);
299 priv->property_name = g_strdup (property_name);
303 clutter_transition_get_animatable (CLUTTER_TRANSITION (transition));
304 if (animatable != NULL)
306 priv->pspec = clutter_animatable_find_property (animatable,
307 priv->property_name);
310 g_object_notify_by_pspec (G_OBJECT (transition),
311 obj_props[PROP_PROPERTY_NAME]);
315 * clutter_property_transition_get_property_name:
316 * @transition: a #ClutterPropertyTransition
318 * Retrieves the value of the #ClutterPropertyTransition:property-name
321 * Return value: the name of the property being animated, or %NULL if
322 * none is set. The returned string is owned by the @transition and
323 * it should not be freed.
328 clutter_property_transition_get_property_name (ClutterPropertyTransition *transition)
330 g_return_val_if_fail (CLUTTER_IS_PROPERTY_TRANSITION (transition), NULL);
332 return transition->priv->property_name;