state: Use the Animatable interface
The Animatable interface allows object classes to provide and animate properties outside of the usual GObject property introspection API. This change allows ClutterState to defer to the animatable objects the property introspection and animation, just like ClutterAnimation does.
This commit is contained in:
parent
8b03ec9d16
commit
f28c1d2d2a
@ -185,6 +185,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "clutter-alpha.h"
|
||||
#include "clutter-animatable.h"
|
||||
#include "clutter-animator.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-interval.h"
|
||||
@ -255,6 +256,7 @@ typedef struct _ClutterStateKey
|
||||
ClutterInterval *interval; /* The interval this key uses for
|
||||
interpolation */
|
||||
|
||||
guint is_animatable : 1;
|
||||
guint is_inert : 1; /* set if the key is being destroyed due to
|
||||
weak reference */
|
||||
gint ref_count; /* reference count for boxed life time */
|
||||
@ -345,6 +347,7 @@ clutter_state_key_new (State *state,
|
||||
state_key->object = object;
|
||||
state_key->property_name = g_intern_string (property_name);
|
||||
state_key->mode = mode;
|
||||
state_key->is_animatable = CLUTTER_IS_ANIMATABLE (object);
|
||||
|
||||
state_key->alpha = clutter_alpha_new ();
|
||||
g_object_ref_sink (state_key->alpha);
|
||||
@ -578,11 +581,10 @@ clutter_state_new_frame (ClutterTimeline *timeline,
|
||||
|
||||
if (found_specific || key->source_state == NULL)
|
||||
{
|
||||
const GValue *value;
|
||||
gdouble pre_delay = key->pre_delay + key->pre_pre_delay;
|
||||
|
||||
sub_progress = (progress - pre_delay) /
|
||||
(1.0 - (pre_delay + key->post_delay));
|
||||
sub_progress = (progress - pre_delay)
|
||||
/ (1.0 - (pre_delay + key->post_delay));
|
||||
|
||||
if (sub_progress >= 0.0)
|
||||
{
|
||||
@ -593,10 +595,39 @@ clutter_state_new_frame (ClutterTimeline *timeline,
|
||||
sub_progress * SLAVE_TIMELINE_LENGTH);
|
||||
sub_progress = clutter_alpha_get_alpha (key->alpha);
|
||||
|
||||
if (key->is_animatable)
|
||||
{
|
||||
ClutterAnimatable *animatable;
|
||||
GValue value = { 0, };
|
||||
gboolean res;
|
||||
|
||||
animatable = CLUTTER_ANIMATABLE (key->object);
|
||||
|
||||
g_value_init (&value, clutter_state_key_get_property_type (key));
|
||||
|
||||
res =
|
||||
clutter_animatable_interpolate_value (animatable,
|
||||
key->property_name,
|
||||
key->interval,
|
||||
sub_progress,
|
||||
&value);
|
||||
|
||||
if (res)
|
||||
clutter_animatable_set_final_state (animatable,
|
||||
key->property_name,
|
||||
&value);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GValue *value;
|
||||
|
||||
value = clutter_interval_compute (key->interval, sub_progress);
|
||||
if (value != NULL)
|
||||
g_object_set_property (key->object, key->property_name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: should the target value of the default destination be
|
||||
* used even when found a specific source_state key?
|
||||
@ -710,6 +741,17 @@ clutter_state_change (ClutterState *state,
|
||||
key->pre_pre_delay = 0;
|
||||
|
||||
g_value_init (&initial, clutter_interval_get_value_type (key->interval));
|
||||
|
||||
if (key->is_animatable)
|
||||
{
|
||||
ClutterAnimatable *animatable;
|
||||
|
||||
animatable = CLUTTER_ANIMATABLE (key->object);
|
||||
clutter_animatable_get_initial_state (animatable,
|
||||
key->property_name,
|
||||
&initial);
|
||||
}
|
||||
else
|
||||
g_object_get_property (key->object, key->property_name, &initial);
|
||||
|
||||
if (clutter_alpha_get_mode (key->alpha) != key->mode)
|
||||
@ -796,10 +838,21 @@ static GParamSpec *
|
||||
get_property_from_object (GObject *gobject,
|
||||
const gchar *property_name)
|
||||
{
|
||||
GObjectClass *klass = G_OBJECT_GET_CLASS (gobject);
|
||||
GParamSpec *pspec;
|
||||
|
||||
if (CLUTTER_IS_ANIMATABLE (gobject))
|
||||
{
|
||||
ClutterAnimatable *animatable = CLUTTER_ANIMATABLE (gobject);
|
||||
|
||||
pspec = clutter_animatable_find_property (animatable, property_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
GObjectClass *klass = G_OBJECT_GET_CLASS (gobject);
|
||||
|
||||
pspec = g_object_class_find_property (klass, property_name);
|
||||
}
|
||||
|
||||
if (pspec == NULL)
|
||||
{
|
||||
g_warning ("Cannot bind property '%s': objects of type '%s' "
|
||||
@ -1045,6 +1098,17 @@ clutter_state_set_key_internal (ClutterState *state,
|
||||
|
||||
g_value_init (&initial,
|
||||
clutter_interval_get_value_type (key->interval));
|
||||
|
||||
if (key->is_animatable)
|
||||
{
|
||||
ClutterAnimatable *animatable;
|
||||
|
||||
animatable = CLUTTER_ANIMATABLE (key->object);
|
||||
clutter_animatable_get_initial_state (animatable,
|
||||
key->property_name,
|
||||
&initial);
|
||||
}
|
||||
else
|
||||
g_object_get_property (key->object, key->property_name, &initial);
|
||||
|
||||
if (clutter_alpha_get_mode (key->alpha) != key->mode)
|
||||
@ -2061,8 +2125,7 @@ parse_state_transition (JsonArray *array,
|
||||
}
|
||||
|
||||
property = json_array_get_string_element (key, 1);
|
||||
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (gobject),
|
||||
property);
|
||||
pspec = get_property_from_object (gobject, property);
|
||||
if (pspec == NULL)
|
||||
{
|
||||
g_warning ("The object of type '%s' and name '%s' has no "
|
||||
|
@ -122,6 +122,8 @@ test_state_main (gint argc,
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_actor_add_effect_with_name (actor, "fade",
|
||||
clutter_desaturate_effect_new (0.0));
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
@ -162,10 +164,12 @@ test_state_main (gint argc,
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
actor, "@effects.fade.factor", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
actor, "@effects.fade.factor", CLUTTER_LINEAR, 1.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user