[actor] Use flags to control allocations

Instead of passing a boolean value, the ::allocate virtual function
should use a bitmask and flags. This gives us room for expansion
without breaking API/ABI, and allows to encode more information to
the allocation process instead of just changes of absolute origin.
This commit is contained in:
Emmanuele Bassi 2009-06-03 14:02:06 +01:00
parent 0d5e17ecd1
commit 0187bb3965
13 changed files with 128 additions and 109 deletions

View File

@ -1541,9 +1541,9 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
}
static void
clutter_actor_real_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean absolute_origin_changed)
clutter_actor_real_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterActorPrivate *priv = self->priv;
gboolean x1_changed, y1_changed, x2_changed, y2_changed;
@ -4697,25 +4697,24 @@ clutter_actor_get_allocation_geometry (ClutterActor *self,
* clutter_actor_allocate:
* @self: A #ClutterActor
* @box: new allocation of the actor, in parent-relative coordinates
* @absolute_origin_changed: whether the position of the parent has
* changed in stage coordinates
* @flags: flags that control the allocation
*
* Called by the parent of an actor to assign the actor its size.
* Should never be called by applications (except when implementing
* a container or layout manager).
*
* Actors can know from their allocation box whether they have moved
* with respect to their parent actor. The absolute_origin_changed
* parameter additionally indicates whether the parent has moved with
* respect to the stage, for example because a grandparent's origin
* has moved.
* with respect to their parent actor. The @flags parameter describes
* additional information about the allocation, for instance whether
* the parent has moved with respect to the stage, for example because
* a grandparent's origin has moved.
*
* Since: 0.8
*/
void
clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean absolute_origin_changed)
clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterActorPrivate *priv;
ClutterActorClass *klass;
@ -4724,7 +4723,6 @@ clutter_actor_allocate (ClutterActor *self,
g_return_if_fail (CLUTTER_IS_ACTOR (self));
priv = self->priv;
klass = CLUTTER_ACTOR_GET_CLASS (self);
child_moved = (box->x1 != priv->allocation.x1 ||
box->y1 != priv->allocation.y1);
@ -4743,7 +4741,7 @@ clutter_actor_allocate (ClutterActor *self,
*/
if (!priv->needs_allocation &&
!absolute_origin_changed &&
!(flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED) &&
!child_moved &&
box->x2 == priv->allocation.x2 &&
box->y2 == priv->allocation.y2)
@ -4752,13 +4750,17 @@ clutter_actor_allocate (ClutterActor *self,
return;
}
/* When absolute_origin_changed is passed in to
/* When ABSOLUTE_ORIGIN_CHANGED is passed in to
* clutter_actor_allocate(), it indicates whether the parent has its
* absolute origin moved; when passed in to ClutterActor::allocate()
* virtual method though, it indicates whether the child has its
* absolute origin moved. So we set it to TRUE if child_moved.
* absolute origin moved. So we set it when child_moved is TRUE
*/
klass->allocate (self, box, absolute_origin_changed || child_moved);
if (child_moved)
flags |= CLUTTER_ABSOLUTE_ORIGIN_CHANGED;
klass = CLUTTER_ACTOR_GET_CLASS (self);
klass->allocate (self, box, flags);
}
/**
@ -8202,8 +8204,7 @@ clutter_actor_get_stage (ClutterActor *actor)
* actor's natural width
* @available_height: the maximum available height, or -1 to use the
* actor's natural height
* @absolute_origin_changed: whether the position of the parent has
* changed in stage coordinates
* @flags: flags controlling the allocation
*
* Allocates @self taking into account the #ClutterActor<!-- -->'s
* preferred size, but limiting it to the maximum available width
@ -8243,7 +8244,7 @@ clutter_actor_get_stage (ClutterActor *actor)
* box.x1 = x; box.y1 = y;
* box.x2 = box.x1 + available_width;
* box.y2 = box.y1 + available_height;
* clutter_actor_allocate (self, &amp;box, absolute_origin_changed);
* clutter_actor_allocate (self, &amp;box, flags);
* ]|
*
* This function can be used by fluid layout managers to allocate
@ -8253,12 +8254,12 @@ clutter_actor_get_stage (ClutterActor *actor)
* Since: 1.0
*/
void
clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x,
gfloat y,
gfloat available_width,
gfloat available_height,
gboolean absolute_origin_changed)
clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x,
gfloat y,
gfloat available_width,
gfloat available_height,
ClutterAllocationFlags flags)
{
ClutterActorPrivate *priv;
gfloat width, height;
@ -8302,14 +8303,13 @@ clutter_actor_allocate_available_size (ClutterActor *self,
box.y1 = y;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
clutter_actor_allocate (self, &box, absolute_origin_changed);
clutter_actor_allocate (self, &box, flags);
}
/**
* clutter_actor_allocate_preferred_size:
* @self: a #ClutterActor
* @absolute_origin_changed: whether the position of the parent has
* changed in stage coordinates
* @flags: flags controlling the allocation
*
* Allocates the natural size of @self.
*
@ -8327,8 +8327,8 @@ clutter_actor_allocate_available_size (ClutterActor *self,
* Since: 0.8
*/
void
clutter_actor_allocate_preferred_size (ClutterActor *self,
gboolean absolute_origin_changed)
clutter_actor_allocate_preferred_size (ClutterActor *self,
ClutterAllocationFlags flags)
{
gfloat actor_x, actor_y;
gfloat natural_width, natural_height;
@ -8349,7 +8349,7 @@ clutter_actor_allocate_preferred_size (ClutterActor *self,
actor_box.x2 = actor_box.x1 + natural_width;
actor_box.y2 = actor_box.y1 + natural_height;
clutter_actor_allocate (self, &actor_box, absolute_origin_changed);
clutter_actor_allocate (self, &actor_box, flags);
}
/**

View File

@ -120,6 +120,24 @@ typedef enum
CLUTTER_ACTOR_VISIBLE = 1 << 4
} ClutterActorFlags;
/**
* ClutterAllocationFlags:
* @CLUTTER_ALLOCATION_NONE: No flag set
* @CLUTTER_ABSOLUTE_ORIGIN_CHANGED: Whether the absolute origin of the
* actor has changed; this implies that any ancestor of the actor has
* been moved
*
* Flags passed to the #ClutterActor::allocate() virtual function and
* to the clutter_actor_allocate() function
*
* Since: 1.0
*/
typedef enum
{
CLUTTER_ALLOCATION_NONE = 0,
CLUTTER_ABSOLUTE_ORIGIN_CHANGED = 1 << 1
} ClutterAllocationFlags;
/**
* ClutterActorBox:
* @x1: X coordinate of the top left corner
@ -241,17 +259,17 @@ struct _ClutterActorClass
ClutterActor *leaf_that_queued);
/* size negotiation */
void (* get_preferred_width) (ClutterActor *actor,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p);
void (* get_preferred_height) (ClutterActor *actor,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p);
void (* allocate) (ClutterActor *actor,
const ClutterActorBox *box,
gboolean absolute_origin_changed);
void (* get_preferred_width) (ClutterActor *actor,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p);
void (* get_preferred_height) (ClutterActor *actor,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p);
void (* allocate) (ClutterActor *actor,
const ClutterActorBox *box,
ClutterAllocationFlags flags);
/* event signals */
gboolean (* event) (ClutterActor *actor,
ClutterEvent *event);
@ -320,15 +338,15 @@ void clutter_actor_get_preferred_size (ClutterActor
gfloat *natural_height_p);
void clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean absolute_origin_changed);
ClutterAllocationFlags flags);
void clutter_actor_allocate_preferred_size (ClutterActor *self,
gboolean absolute_origin_changed);
ClutterAllocationFlags flags);
void clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x,
gfloat y,
gfloat available_width,
gfloat available_height,
gboolean absolute_origin_changed);
ClutterAllocationFlags flags);
void clutter_actor_get_allocation_coords (ClutterActor *self,
gint *x_1,
gint *y_1,

View File

@ -172,16 +172,16 @@ clutter_clone_paint (ClutterActor *self)
}
static void
clutter_clone_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_clone_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorClass *parent_class;
/* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
parent_class->allocate (self, box, origin_changed);
parent_class->allocate (self, box, flags);
if (G_UNLIKELY (priv->clone_source == NULL))
return;
@ -194,10 +194,7 @@ clutter_clone_allocate (ClutterActor *self,
* paint cycle, we can safely give it as much size as it requires
*/
if (clutter_actor_get_parent (priv->clone_source) == NULL)
{
clutter_actor_allocate_preferred_size (priv->clone_source,
origin_changed);
}
clutter_actor_allocate_preferred_size (priv->clone_source, flags);
}
static void

View File

@ -279,15 +279,15 @@ clutter_fixed_layout_get_preferred_height (GList *children,
}
static void
clutter_fixed_layout_allocate (GList *children,
gboolean absolute_origin_changed)
clutter_fixed_layout_allocate (GList *children,
ClutterAllocationFlags flags)
{
GList *l;
for (l = children; l != NULL; l = l->next)
{
ClutterActor *child = l->data;
clutter_actor_allocate_preferred_size (child, absolute_origin_changed);
clutter_actor_allocate_preferred_size (child, flags);
}
}
@ -320,22 +320,21 @@ clutter_group_get_preferred_height (ClutterActor *self,
}
static void
clutter_group_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_group_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
/* chain up to set actor->allocation */
CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->allocate (self, box,
origin_changed);
CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->allocate (self, box, flags);
/* Note that fixed-layout allocation of children does not care what
* allocation the container received, so "box" is not passed in
* here. We do not require that children's allocations are completely
* contained by our own.
*/
clutter_fixed_layout_allocate (priv->children, origin_changed);
clutter_fixed_layout_allocate (priv->children, flags);
}
static void

View File

@ -143,7 +143,7 @@ _clutter_stage_maybe_relayout (ClutterActor *stage)
(int) natural_width,
(int) natural_height);
clutter_actor_allocate (stage, &box, FALSE);
clutter_actor_allocate (stage, &box, CLUTTER_ALLOCATION_NONE);
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_IN_RELAYOUT);
}

View File

@ -157,11 +157,14 @@ clutter_stage_get_preferred_height (ClutterActor *self,
natural_height_p);
}
static void
clutter_stage_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_stage_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
gboolean origin_changed;
origin_changed = (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED) ? TRUE : FALSE;
g_assert (priv->impl != NULL);
@ -180,10 +183,10 @@ clutter_stage_allocate (ClutterActor *self,
origin_changed ? "changed" : "not changed");
klass = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class);
klass->allocate (self, box, origin_changed);
klass->allocate (self, box, flags);
klass = CLUTTER_ACTOR_GET_CLASS (priv->impl);
klass->allocate (priv->impl, box, origin_changed);
klass->allocate (priv->impl, box, flags);
}
else
{
@ -193,7 +196,7 @@ clutter_stage_allocate (ClutterActor *self,
/* propagate the allocation */
klass = CLUTTER_ACTOR_GET_CLASS (priv->impl);
klass->allocate (self, box, origin_changed);
klass->allocate (self, box, flags);
/* get the preferred size from the backend */
clutter_actor_get_preferred_size (priv->impl,
@ -216,7 +219,7 @@ clutter_stage_allocate (ClutterActor *self,
/* and store the overridden allocation */
klass = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class);
klass->allocate (self, &override, origin_changed);
klass->allocate (self, &override, flags);
}
}
@ -382,7 +385,9 @@ clutter_stage_real_fullscreen (ClutterStage *stage)
box.x2 = natural_width;
box.y2 = natural_height;
clutter_actor_allocate (CLUTTER_ACTOR (stage), &box, FALSE);
clutter_actor_allocate (CLUTTER_ACTOR (stage),
&box,
CLUTTER_ALLOCATION_NONE);
}
static gboolean

View File

@ -1548,9 +1548,9 @@ clutter_text_get_preferred_height (ClutterActor *self,
}
static void
clutter_text_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_text_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterText *text = CLUTTER_TEXT (self);
ClutterActorClass *parent_class;
@ -1563,7 +1563,7 @@ clutter_text_allocate (ClutterActor *self,
box->y2 - box->y1);
parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class);
parent_class->allocate (self, box, origin_changed);
parent_class->allocate (self, box, flags);
}
static gboolean

View File

@ -428,20 +428,21 @@ clutter_texture_get_preferred_height (ClutterActor *self,
}
static void
clutter_texture_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_texture_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterTexturePrivate *priv = CLUTTER_TEXTURE (self)->priv;
/* chain up to set actor->allocation */
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->allocate (self, box,
origin_changed);
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->allocate (self,
box,
flags);
/* If we adopted the source fbo then allocate that at its preferred
size */
if (priv->fbo_source && clutter_actor_get_parent (priv->fbo_source) == self)
clutter_actor_allocate_preferred_size (priv->fbo_source, origin_changed);
clutter_actor_allocate_preferred_size (priv->fbo_source, flags);
}
static void

View File

@ -420,9 +420,9 @@ clutter_stage_osx_get_preferred_height (ClutterActor *actor,
}
static void
clutter_stage_osx_allocate (ClutterActor *actor,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_stage_osx_allocate (ClutterActor *actor,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
ClutterActorClass *parent_class;
@ -452,7 +452,7 @@ clutter_stage_osx_allocate (ClutterActor *actor,
/* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class);
parent_class->allocate (actor, box, origin_changed);
parent_class->allocate (actor, box, flags);
}
/*************************************************************************/

View File

@ -132,9 +132,9 @@ clutter_stage_sdl_get_preferred_height (ClutterActor *self,
}
static void
clutter_stage_sdl_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_stage_sdl_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (self);
gint new_width, new_height;
@ -162,7 +162,7 @@ clutter_stage_sdl_allocate (ClutterActor *self,
}
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class);
parent_class->allocate (self, box, origin_changed);
parent_class->allocate (self, box, flags);
}
static void

View File

@ -187,18 +187,18 @@ _clutter_stage_win32_get_min_max_info (ClutterStageWin32 *stage_win32,
}
static void
clutter_stage_win32_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_stage_win32_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (self);
gint new_width, new_height;
new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1));
new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1));
new_width = ABS (box->x2 - box->x1);
new_height = ABS (box->y2 - box->y1);
if (new_width != stage_win32->win_width
|| new_height != stage_win32->win_height)
if (new_width != stage_win32->win_width ||
new_height != stage_win32->win_height)
{
/* Ignore size requests if we are in full screen mode */
if ((stage_win32->state & CLUTTER_STAGE_STATE_FULLSCREEN) == 0)
@ -226,7 +226,7 @@ clutter_stage_win32_allocate (ClutterActor *self,
}
CLUTTER_ACTOR_CLASS (clutter_stage_win32_parent_class)
->allocate (self, box, origin_changed);
->allocate (self, box, flags);
}
static void

View File

@ -247,9 +247,9 @@ clutter_stage_x11_get_preferred_height (ClutterActor *self,
}
static void
clutter_stage_x11_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
clutter_stage_x11_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
ClutterActorClass *parent_class;
@ -300,7 +300,7 @@ clutter_stage_x11_allocate (ClutterActor *self,
/* chain up to fill in actor->priv->allocation */
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class);
parent_class->allocate (self, box, origin_changed);
parent_class->allocate (self, box, flags);
}
static inline void

View File

@ -369,17 +369,16 @@ my_thing_get_preferred_height (ClutterActor *self,
}
static void
my_thing_allocate (ClutterActor *self,
const ClutterActorBox *box,
gboolean origin_changed)
my_thing_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
MyThingPrivate *priv;
gfloat current_x, current_y, max_row_height;
GList *l;
/* chain up to set actor->allocation */
CLUTTER_ACTOR_CLASS (my_thing_parent_class)->allocate (self, box,
origin_changed);
CLUTTER_ACTOR_CLASS (my_thing_parent_class)->allocate (self, box, flags);
priv = MY_THING (self)->priv;
@ -418,7 +417,7 @@ my_thing_allocate (ClutterActor *self,
child_box.x2 = child_box.x1 + natural_width;
child_box.y2 = child_box.y1 + natural_height;
clutter_actor_allocate (child, &child_box, origin_changed);
clutter_actor_allocate (child, &child_box, flags);
/* if we take into account the transformation of the children
* then we first check if it's transformed; then we get the
@ -435,7 +434,7 @@ my_thing_allocate (ClutterActor *self,
ClutterActorBox transformed_box = { 0, };
/* origin */
if (!origin_changed)
if (!(flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED))
{
v1.x = 0;
v1.y = 0;