[clutter] state: Use the Animatable interface
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] state: Use the Animatable interface
- Date: Fri, 29 Jul 2011 10:53:42 +0000 (UTC)
commit f28c1d2d2a6bd90c494e860134195fcefcb78a6d
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Fri Jul 15 15:06:31 2011 +0100
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.
clutter/clutter-state.c | 87 ++++++++++++++++++++++++++++++++++-----
tests/interactive/test-state.c | 4 ++
2 files changed, 79 insertions(+), 12 deletions(-)
---
diff --git a/clutter/clutter-state.c b/clutter/clutter-state.c
index 597e589..7471f77 100644
--- a/clutter/clutter-state.c
+++ b/clutter/clutter-state.c
@@ -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,9 +595,38 @@ clutter_state_new_frame (ClutterTimeline *timeline,
sub_progress * SLAVE_TIMELINE_LENGTH);
sub_progress = clutter_alpha_get_alpha (key->alpha);
- value = clutter_interval_compute (key->interval, sub_progress);
- if (value != NULL)
- g_object_set_property (key->object, key->property_name, value);
+ 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
@@ -710,7 +741,18 @@ clutter_state_change (ClutterState *state,
key->pre_pre_delay = 0;
g_value_init (&initial, clutter_interval_get_value_type (key->interval));
- g_object_get_property (key->object, key->property_name, &initial);
+
+ 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)
clutter_alpha_set_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;
- pspec = g_object_class_find_property (klass, property_name);
+ 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,7 +1098,18 @@ clutter_state_set_key_internal (ClutterState *state,
g_value_init (&initial,
clutter_interval_get_value_type (key->interval));
- g_object_get_property (key->object, key->property_name, &initial);
+
+ 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)
clutter_alpha_set_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 "
diff --git a/tests/interactive/test-state.c b/tests/interactive/test-state.c
index 650d3c4..f02ecc6 100644
--- a/tests/interactive/test-state.c
+++ b/tests/interactive/test-state.c
@@ -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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]