[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.
This commit is contained in:
parent
7edaf8ece8
commit
6fff1bcdc6
3 changed files with 52 additions and 40 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue