clutter/clone: Build scale factor for transformation during allocation
For ClutterClones we need to apply a scale to the texture of the clone to ensure the painted texture of the source actor actually fits the allocation of the clone. We're doing this using the transformation matrix instead of using the scale_x/scale_y properties of ClutterActor to allow users to scale ClutterClones using that API independently. Now it's quite a bad idea to get the allocation boxes for calculating that scale using clutter_actor_get_allocation_box(), since that method will internally do an immediate relayout of the stage in case the actor isn't allocated. Another side effect of that approach is that it makes it impossible to invalidate the transform (which will be needed when we start caching those matrices) properly. So since we eventually allocate both the source actor and the clone ourselves anyway, we can simply use the allocation box inside clutter_clone_allocate() (which is definitely updated and valid at that point) to calculate the scale factor. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1181
This commit is contained in:
parent
0c1e5b4ee5
commit
6ea0f8facc
@ -52,6 +52,8 @@
|
||||
struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
float x_scale, y_scale;
|
||||
|
||||
gulong source_destroy_id;
|
||||
};
|
||||
|
||||
@ -122,8 +124,6 @@ static void
|
||||
clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorBox box, source_box;
|
||||
gfloat x_scale, y_scale;
|
||||
|
||||
/* First chain up and apply all the standard ClutterActor
|
||||
* transformations... */
|
||||
@ -134,21 +134,7 @@ clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
/* get our allocated size */
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
|
||||
/* and get the allocated size of the source */
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (&box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (&box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
cogl_matrix_scale (matrix, x_scale, y_scale, 1.f);
|
||||
cogl_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -244,6 +230,8 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorClass *parent_class;
|
||||
ClutterActorBox source_box;
|
||||
float x_scale, y_scale;
|
||||
|
||||
/* chain up */
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
|
||||
@ -259,6 +247,23 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
!clutter_actor_has_allocation (priv->clone_source))
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
|
||||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
|
||||
{
|
||||
priv->x_scale = x_scale;
|
||||
priv->y_scale = y_scale;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX - this is wrong: ClutterClone cannot clone unparented
|
||||
* actors, as it will break all invariants
|
||||
@ -364,6 +369,9 @@ static void
|
||||
clutter_clone_init (ClutterClone *self)
|
||||
{
|
||||
self->priv = clutter_clone_get_instance_private (self);
|
||||
|
||||
self->priv->x_scale = 1.f;
|
||||
self->priv->y_scale = 1.f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user