summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@linux.intel.com>2012-03-28 11:52:01 +0100
committerEmmanuele Bassi <ebassi@linux.intel.com>2012-04-10 09:41:50 +0100
commit835849c7bbe6dca4831f733bb59962ab53520960 (patch)
tree07e682fa60fdf9cd5c80fbc7835dd19c24af185c
parentacd630f49c7bcb639f2fcc24a26ee0085e1ca9aa (diff)
downloadclutter-835849c7bbe6dca4831f733bb59962ab53520960.tar.gz
actor: Simplify setters of animatable properties
Instead of checking the duration of the current easing state we should check if there's a transition in progress, and update it unconditionally. If there is no easing state, or the easing state has a duration of zero milliseconds, then create_transition() should bail out early and set the requested final state. This allows us to write: clutter_actor_save_easing_state (actor); clutter_actor_set_x (actor, 200); clutter_actor_restore_easing_state (actor); [...] clutter_actor_set_x (actor, 100); and have the second set_x() update the easing in progress, instead of being ignored. https://bugzilla.gnome.org/show_bug.cgi?id=672945
-rw-r--r--clutter/clutter-actor.c344
1 files changed, 129 insertions, 215 deletions
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 011da44d8..78edfbaba 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -4014,52 +4014,39 @@ clutter_actor_set_rotation_angle (ClutterActor *self,
ClutterRotateAxis axis,
gdouble angle)
{
- ClutterTransformInfo *info;
+ const ClutterTransformInfo *info;
+ const double *cur_angle_p = NULL;
+ GParamSpec *pspec = NULL;
- info = _clutter_actor_get_transform_info (self);
+ info = _clutter_actor_get_transform_info_or_defaults (self);
- if (clutter_actor_get_easing_duration (self) != 0)
+ switch (axis)
{
- ClutterTransition *transition;
- GParamSpec *pspec = NULL;
- double *cur_angle_p = NULL;
-
- switch (axis)
- {
- case CLUTTER_X_AXIS:
- cur_angle_p = &info->rx_angle;
- pspec = obj_props[PROP_ROTATION_ANGLE_X];
- break;
-
- case CLUTTER_Y_AXIS:
- cur_angle_p = &info->ry_angle;
- pspec = obj_props[PROP_ROTATION_ANGLE_Y];
- break;
+ case CLUTTER_X_AXIS:
+ cur_angle_p = &info->rx_angle;
+ pspec = obj_props[PROP_ROTATION_ANGLE_X];
+ break;
- case CLUTTER_Z_AXIS:
- cur_angle_p = &info->rz_angle;
- pspec = obj_props[PROP_ROTATION_ANGLE_Z];
- break;
- }
+ case CLUTTER_Y_AXIS:
+ cur_angle_p = &info->ry_angle;
+ pspec = obj_props[PROP_ROTATION_ANGLE_Y];
+ break;
- g_assert (pspec != NULL);
- g_assert (cur_angle_p != NULL);
+ case CLUTTER_Z_AXIS:
+ cur_angle_p = &info->rz_angle;
+ pspec = obj_props[PROP_ROTATION_ANGLE_Z];
+ break;
+ }
- transition = _clutter_actor_get_transition (self, pspec);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self, pspec,
- *cur_angle_p,
- angle);
- }
- else
- _clutter_actor_update_transition (self, pspec, angle);
+ g_assert (pspec != NULL);
+ g_assert (cur_angle_p != NULL);
- self->priv->transform_valid = FALSE;
- clutter_actor_queue_redraw (self);
- }
+ if (_clutter_actor_get_transition (self, pspec) == NULL)
+ _clutter_actor_create_transition (self, pspec, *cur_angle_p, angle);
else
- clutter_actor_set_rotation_angle_internal (self, axis, angle);
+ _clutter_actor_update_transition (self, pspec, angle);
+
+ clutter_actor_queue_redraw (self);
}
/*< private >
@@ -4120,29 +4107,6 @@ clutter_actor_set_rotation_center_internal (ClutterActor *self,
}
static void
-clutter_actor_animate_scale_factor (ClutterActor *self,
- double old_factor,
- double new_factor,
- GParamSpec *pspec)
-{
- ClutterTransition *transition;
-
- transition = _clutter_actor_get_transition (self, pspec);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self, pspec,
- old_factor,
- new_factor);
- }
- else
- _clutter_actor_update_transition (self, pspec, new_factor);
-
-
- self->priv->transform_valid = FALSE;
- clutter_actor_queue_redraw (self);
-}
-
-static void
clutter_actor_set_scale_factor_internal (ClutterActor *self,
double factor,
GParamSpec *pspec)
@@ -4167,39 +4131,37 @@ clutter_actor_set_scale_factor (ClutterActor *self,
ClutterRotateAxis axis,
gdouble factor)
{
- GObject *obj = G_OBJECT (self);
- ClutterTransformInfo *info;
- GParamSpec *pspec;
-
- info = _clutter_actor_get_transform_info (self);
+ const ClutterTransformInfo *info;
+ const double *scale_p = NULL;
+ GParamSpec *pspec = NULL;
- g_object_freeze_notify (obj);
+ info = _clutter_actor_get_transform_info_or_defaults (self);
switch (axis)
{
case CLUTTER_X_AXIS:
pspec = obj_props[PROP_SCALE_X];
-
- if (clutter_actor_get_easing_duration (self) != 0)
- clutter_actor_animate_scale_factor (self, info->scale_x, factor, pspec);
- else
- clutter_actor_set_scale_factor_internal (self, factor, pspec);
+ scale_p = &info->scale_x;
break;
case CLUTTER_Y_AXIS:
pspec = obj_props[PROP_SCALE_Y];
-
- if (clutter_actor_get_easing_duration (self) != 0)
- clutter_actor_animate_scale_factor (self, info->scale_y, factor, pspec);
- else
- clutter_actor_set_scale_factor_internal (self, factor, pspec);
+ scale_p = &info->scale_y;
break;
- default:
- g_assert_not_reached ();
+ case CLUTTER_Z_AXIS:
+ break;
}
- g_object_thaw_notify (obj);
+ g_assert (pspec != NULL);
+ g_assert (scale_p != NULL);
+
+ if (_clutter_actor_get_transition (self, pspec) == NULL)
+ _clutter_actor_create_transition (self, pspec, *scale_p, factor);
+ else
+ _clutter_actor_update_transition (self, pspec, factor);
+
+ clutter_actor_queue_redraw (self);
}
static inline void
@@ -9488,33 +9450,19 @@ clutter_actor_set_width (ClutterActor *self,
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, obj_props[PROP_WIDTH]) == NULL)
{
- ClutterTransition *transition;
-
- transition = _clutter_actor_get_transition (self, obj_props[PROP_WIDTH]);
- if (transition == NULL)
- {
- float old_width = clutter_actor_get_width (self);
+ float cur_size = clutter_actor_get_width (self);
- transition = _clutter_actor_create_transition (self,
- obj_props[PROP_WIDTH],
- old_width,
- width);
- }
- else
- _clutter_actor_update_transition (self, obj_props[PROP_WIDTH], width);
-
- clutter_actor_queue_relayout (self);
+ _clutter_actor_create_transition (self,
+ obj_props[PROP_WIDTH],
+ cur_size,
+ width);
}
else
- {
- g_object_freeze_notify (G_OBJECT (self));
-
- clutter_actor_set_width_internal (self, width);
+ _clutter_actor_update_transition (self, obj_props[PROP_WIDTH], width);
- g_object_thaw_notify (G_OBJECT (self));
- }
+ clutter_actor_queue_relayout (self);
}
/**
@@ -9538,33 +9486,19 @@ clutter_actor_set_height (ClutterActor *self,
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, obj_props[PROP_HEIGHT]) == NULL)
{
- ClutterTransition *transition;
+ float cur_size = clutter_actor_get_height (self);
- transition = _clutter_actor_get_transition (self, obj_props[PROP_HEIGHT]);
- if (transition == NULL)
- {
- float old_height = clutter_actor_get_height (self);
-
- transition = _clutter_actor_create_transition (self,
- obj_props[PROP_HEIGHT],
- old_height,
- height);
- }
- else
- _clutter_actor_update_transition (self, obj_props[PROP_HEIGHT], height);
-
- clutter_actor_queue_relayout (self);
+ _clutter_actor_create_transition (self,
+ obj_props[PROP_HEIGHT],
+ cur_size,
+ height);
}
else
- {
- g_object_freeze_notify (G_OBJECT (self));
+ _clutter_actor_update_transition (self, obj_props[PROP_HEIGHT], height);
- clutter_actor_set_height_internal (self, height);
-
- g_object_thaw_notify (G_OBJECT (self));
- }
+ clutter_actor_queue_relayout (self);
}
static inline void
@@ -9631,31 +9565,20 @@ void
clutter_actor_set_x (ClutterActor *self,
gfloat x)
{
- const ClutterLayoutInfo *linfo;
-
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- linfo = _clutter_actor_get_layout_info_or_defaults (self);
-
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, obj_props[PROP_X]) == NULL)
{
- ClutterTransition *transition;
-
- transition = _clutter_actor_get_transition (self, obj_props[PROP_X]);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self,
- obj_props[PROP_X],
- linfo->fixed_x,
- x);
- }
- else
- _clutter_actor_update_transition (self, obj_props[PROP_X], x);
+ float cur_position = clutter_actor_get_x (self);
- clutter_actor_queue_relayout (self);
+ _clutter_actor_create_transition (self, obj_props[PROP_X],
+ cur_position,
+ x);
}
else
- clutter_actor_set_x_internal (self, x);
+ _clutter_actor_update_transition (self, obj_props[PROP_X], x);
+
+ clutter_actor_queue_relayout (self);
}
/**
@@ -9676,31 +9599,18 @@ void
clutter_actor_set_y (ClutterActor *self,
gfloat y)
{
- const ClutterLayoutInfo *linfo;
-
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- linfo = _clutter_actor_get_layout_info_or_defaults (self);
-
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, obj_props[PROP_Y]) == NULL)
{
- ClutterTransition *transition;
-
- transition = _clutter_actor_get_transition (self, obj_props[PROP_Y]);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self,
- obj_props[PROP_Y],
- linfo->fixed_y,
- y);
- }
- else
- _clutter_actor_update_transition (self, obj_props[PROP_Y], y);
+ float cur_position = clutter_actor_get_y (self);
- clutter_actor_queue_relayout (self);
+ _clutter_actor_create_transition (self, obj_props[PROP_Y],
+ cur_position,
+ y);
}
else
- clutter_actor_set_y_internal (self, y);
+ _clutter_actor_update_transition (self, obj_props[PROP_Y], y);
clutter_actor_queue_relayout (self);
}
@@ -10028,31 +9938,18 @@ void
clutter_actor_set_opacity (ClutterActor *self,
guint8 opacity)
{
- ClutterActorPrivate *priv;
-
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- priv = self->priv;
-
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, obj_props[PROP_OPACITY]) == NULL)
{
- ClutterTransition *transition;
-
- transition = _clutter_actor_get_transition (self, obj_props[PROP_OPACITY]);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self,
- obj_props[PROP_OPACITY],
- priv->opacity,
- opacity);
- }
- else
- _clutter_actor_update_transition (self, obj_props[PROP_OPACITY], opacity);
-
- clutter_actor_queue_redraw (self);
+ _clutter_actor_create_transition (self, obj_props[PROP_OPACITY],
+ self->priv->opacity,
+ opacity);
}
else
- clutter_actor_set_opacity_internal (self, opacity);
+ _clutter_actor_update_transition (self, obj_props[PROP_OPACITY], opacity);
+
+ clutter_actor_queue_redraw (self);
}
/*
@@ -10350,30 +10247,22 @@ void
clutter_actor_set_depth (ClutterActor *self,
gfloat depth)
{
- const ClutterTransformInfo *tinfo;
-
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- tinfo = _clutter_actor_get_transform_info_or_defaults (self);
-
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, obj_props[PROP_DEPTH]) == NULL)
{
- ClutterTransition *transition;
+ const ClutterTransformInfo *info;
- transition = _clutter_actor_get_transition (self, obj_props[PROP_DEPTH]);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self, obj_props[PROP_DEPTH],
- tinfo->depth,
- depth);
- }
- else
- _clutter_actor_update_transition (self, obj_props[PROP_DEPTH], depth);
+ info = _clutter_actor_get_transform_info_or_defaults (self);
- clutter_actor_queue_redraw (self);
+ _clutter_actor_create_transition (self, obj_props[PROP_DEPTH],
+ info->depth,
+ depth);
}
else
- clutter_actor_set_depth_internal (self, depth);
+ _clutter_actor_update_transition (self, obj_props[PROP_DEPTH], depth);
+
+ clutter_actor_queue_redraw (self);
}
/**
@@ -12985,6 +12874,10 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
const GValue *value,
GParamSpec *pspec)
{
+ GObject *obj = G_OBJECT (actor);
+
+ g_object_freeze_notify (obj);
+
switch (prop_id)
{
case PROP_X:
@@ -13046,9 +12939,11 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
break;
default:
- g_object_set_property (G_OBJECT (actor), pspec->name, value);
+ g_object_set_property (obj, pspec->name, value);
break;
}
+
+ g_object_thaw_notify (obj);
}
static void
@@ -16630,24 +16525,16 @@ clutter_actor_set_background_color (ClutterActor *self,
}
bg_color_pspec = obj_props[PROP_BACKGROUND_COLOR];
- if (clutter_actor_get_easing_duration (self) != 0)
+ if (_clutter_actor_get_transition (self, bg_color_pspec) == NULL)
{
- ClutterTransition *transition;
-
- transition = _clutter_actor_get_transition (self, bg_color_pspec);
- if (transition == NULL)
- {
- transition = _clutter_actor_create_transition (self, bg_color_pspec,
- &priv->bg_color,
- color);
- }
- else
- _clutter_actor_update_transition (self, bg_color_pspec, color);
-
- clutter_actor_queue_redraw (self);
+ _clutter_actor_create_transition (self, bg_color_pspec,
+ &priv->bg_color,
+ color);
}
else
- clutter_actor_set_background_color_internal (self, color);
+ _clutter_actor_update_transition (self, bg_color_pspec, color);
+
+ clutter_actor_queue_redraw (self);
}
/**
@@ -17182,9 +17069,18 @@ _clutter_actor_create_transition (ClutterActor *actor,
info = _clutter_actor_get_animation_info (actor);
+ /* XXX - this will go away in 2.0
+ *
+ * if no state has been pushed, we assume that the easing state is
+ * in "compatibility mode": all transitions have a duration of 0
+ * msecs, which means that they happen immediately. in Clutter 2.0
+ * this will turn into a g_assert(info->states != NULL), as every
+ * actor will start with a predefined easing state
+ */
if (info->states == NULL)
{
clutter_actor_save_easing_state (actor);
+ clutter_actor_set_easing_duration (actor, 0);
call_restore = TRUE;
}
@@ -17228,6 +17124,24 @@ _clutter_actor_create_transition (ClutterActor *actor,
goto out;
}
+ /* if the current easing state has a duration of 0, then we don't
+ * bother to create the transition, and we just set the final value
+ * directly on the actor; we don't go through the Animatable
+ * interface because we know we got here through an animatable
+ * property.
+ */
+ if (info->cur_state->easing_duration == 0)
+ {
+ clutter_actor_set_animatable_property (actor,
+ pspec->param_id,
+ &final,
+ pspec);
+ g_value_unset (&initial);
+ g_value_unset (&final);
+
+ goto out;
+ }
+
interval = clutter_interval_new_with_values (ptype, &initial, &final);
g_value_unset (&initial);