actor: Make :allocation animatable
Calling clutter_actor_allocate() should transition between the current allocation and the new allocation, by using the defined implementation of the easing state. This means that: clutter_actor_save_easing_state (actor); clutter_actor_allocate (actor, &new_alloc, flags); clutter_actor_restore_easing_state (actor); will cause "actor" to transition between the current allocation and the desired new allocation. The trick is to ensure that this happens without invalidating the entire actor tree, but only the portion of the tree that has the transitioned actor as the local root. For this reason, we just call the allocate() implementation from within the transition frame advancement, without invalidating flags: the actor, after all, *has* a valid allocation for the duration of the transition.
This commit is contained in:
parent
8cb9725699
commit
8ef2c46baa
@ -5851,7 +5851,9 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
P_("Allocation"),
|
||||
P_("The actor's allocation"),
|
||||
CLUTTER_TYPE_ACTOR_BOX,
|
||||
CLUTTER_PARAM_READABLE);
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
CLUTTER_PARAM_ANIMATABLE);
|
||||
|
||||
/**
|
||||
* ClutterActor:request-mode:
|
||||
@ -8629,6 +8631,26 @@ clutter_actor_adjust_allocation (ClutterActor *self,
|
||||
*allocation = adj_allocation;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_allocate_internal (ClutterActor *self,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
ClutterActorClass *klass;
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
CLUTTER_NOTE (LAYOUT, "Calling %s::allocate()",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (self);
|
||||
klass->allocate (self, allocation, flags);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
clutter_actor_queue_redraw (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_allocate:
|
||||
* @self: A #ClutterActor
|
||||
@ -8652,11 +8674,10 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterActorClass *klass;
|
||||
ClutterActorBox old_allocation, real_allocation;
|
||||
gboolean origin_changed, child_moved, size_changed;
|
||||
gboolean stage_allocation_changed;
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
if (G_UNLIKELY (_clutter_actor_get_stage_internal (self) == NULL))
|
||||
@ -8734,18 +8755,20 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
if (child_moved)
|
||||
flags |= CLUTTER_ABSOLUTE_ORIGIN_CHANGED;
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
|
||||
/* store the flags here, so that they can be propagated by the
|
||||
* transition code
|
||||
*/
|
||||
self->priv->allocation_flags = flags;
|
||||
|
||||
CLUTTER_NOTE (LAYOUT, "Calling %s::allocate()",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (self);
|
||||
klass->allocate (self, &real_allocation, flags);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
if (stage_allocation_changed)
|
||||
clutter_actor_queue_redraw (self);
|
||||
if (_clutter_actor_get_transition (self, obj_props[PROP_ALLOCATION]) == NULL)
|
||||
{
|
||||
_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
|
||||
&priv->allocation,
|
||||
&real_allocation);
|
||||
}
|
||||
else
|
||||
_clutter_actor_update_transition (self, obj_props[PROP_ALLOCATION],
|
||||
&real_allocation);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -13342,6 +13365,12 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
|
||||
clutter_actor_set_size_internal (actor, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_ALLOCATION:
|
||||
clutter_actor_allocate_internal (actor,
|
||||
g_value_get_boxed (value),
|
||||
actor->priv->allocation_flags);
|
||||
break;
|
||||
|
||||
case PROP_DEPTH:
|
||||
clutter_actor_set_depth_internal (actor, g_value_get_float (value));
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user