From 2dbbee28d5588bf47e9af8820bfab199c2878756 Mon Sep 17 00:00:00 2001 From: Matthew Allum Date: Tue, 17 Jun 2008 13:49:40 +0000 Subject: [PATCH] 2008-06-17 Matthew Allum * clutter/clutter-actor.c: * clutter/clutter-actor.h: Clean up of parenting code (see #972) Doc updates to section intro. Add clutter_actor_allocate_preferred_size () utility call * clutter/clutter-group.c: (clutter_fixed_layout_allocate): Use clutter_actor_allocate_preferred_size () * doc/clutter-actor-invariants.txt: Add some more notes --- ChangeLog | 14 +++++ clutter/clutter-actor.c | 99 +++++++++++++++++++++++++------- clutter/clutter-actor.h | 4 ++ clutter/clutter-group.c | 22 +------ doc/clutter-actor-invariants.txt | 20 ++++++- 5 files changed, 115 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 59d599dff..ae65a64de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-06-17 Matthew Allum + + * clutter/clutter-actor.c: + * clutter/clutter-actor.h: + Clean up of parenting code (see #972) + Doc updates to section intro. + Add clutter_actor_allocate_preferred_size () utility call + + * clutter/clutter-group.c: (clutter_fixed_layout_allocate): + Use clutter_actor_allocate_preferred_size () + + * doc/clutter-actor-invariants.txt: + Add some more notes + 2008-06-17 Emmanuele Bassi * clutter/clutter-actor.c: diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index e430f53ae..97d9b9c10 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -32,22 +32,28 @@ * be a #ClutterActor, either by using one of the classes provided by * Clutter, or by implementing a new #ClutterActor subclass. * - * Every actor is a 2D surface in a 3D environment. The surface is contained - * inside its bounding box, described by the #ClutterActorBox structure: + * Every actor is a 2D surface positioned and optionally transformed + * in 3D space. The actor is positioned relative to top left corner of + * it parent with the childs origin being its anchor point (also top + * left by default). + * + * The actors 2D surface is contained inside its bounding box, + * described by the #ClutterActorBox structure: * *
* Bounding box of an Actor * *
* - * The actor box represents the untransformed area occupied by an actor. Each - * visible actor that has been put on a #ClutterStage also has a transformed - * area, depending on the actual transformations applied to it by the - * developer (scale, rotation), the transformations applied by its - * containers, the transformations applied to the containers themselves and, - * finally, the perspective transformations applied to the #ClutterStage. + * The actor box represents the untransformed area occupied by an + * actor. Each visible actor that has been put on a #ClutterStage also + * has a transformed area, depending on the actual transformations + * applied to it by the developer (scale, rotation). Tranforms will + * also be applied to any child actors. Also applied to all actors by + * the #ClutterStage is a perspective transformation. API is provided + * for both tranformed and untransformed actor geometry information. * - * The OpenGL modelview matrix for the actor is constructed from + * The 'modelview' transform matrix for the actor is constructed from * the actor settings by the following order of operations: * * Translation by actor x, y coords, @@ -58,19 +64,19 @@ * Rotation around y axis, * Rotation around x axis, * Translation by actor depth (z), - * Clip stencil is applied (this is not an operation on + * Rectangular Clip is applied (this is not an operation on * the matrix as such, but it is done as part of the transform set * up). * * - * The position of any children is referenced from the top-left corner of - * the parent, not the parent's anchor point. - * * An actor can either be explicitly sized and positioned, using the * various size and position accessors, like clutter_actor_set_x() or * clutter_actor_set_width(); or it can have a preferred width and * height, which then allows a layout manager to implicitly size and - * position it by "allocating" an area for an actor. + * position it by "allocating" an area for an actor. This allows for + * actors to be manipulate in both a fixed or static parent container + * (i.e. children of #ClutterGroup) and a more automatic or dynamic + * layout based parent container. * * When accessing the position and size of an actor, the simple accessors * like clutter_actor_get_width() and clutter_actor_get_x() will return @@ -81,7 +87,9 @@ * layout manager, you should either use the simple accessors or use the * size negotiation API. * - * Events are handled in the following ways: + * Clutter actors are also able to receive input events and react to + * them. Events are handled in the following ways: + * * * Actors emit pointer events if set reactive, see * clutter_actor_set_reactive() @@ -117,7 +125,7 @@ * Every '?' box in the diagram above is an entry point for application * code. * - * For implementing a new actor class, please read the corresponding section * of the API reference. */ @@ -5646,6 +5654,7 @@ clutter_actor_unparent (ClutterActor *self) { ClutterActorPrivate *priv; ClutterActor *old_parent; + gboolean show_on_set_parent_enabled = TRUE; g_return_if_fail (CLUTTER_IS_ACTOR (self)); @@ -5684,6 +5693,18 @@ clutter_actor_unparent (ClutterActor *self) if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_REPARENT)) g_signal_emit (self, actor_signals[PARENT_SET], 0, old_parent); + /* Queue a redraw on old_parent */ + if (CLUTTER_ACTOR_IS_VISIBLE (old_parent)) + clutter_actor_queue_redraw (old_parent); + + /* Could also need to relayout */ + if (old_parent->priv->needs_width_request || + old_parent->priv->needs_height_request || + old_parent->priv->needs_allocation) + { + clutter_actor_queue_relayout (old_parent); + } + /* remove the reference we acquired in clutter_actor_set_parent() */ g_object_unref (self); } @@ -5730,13 +5751,14 @@ clutter_actor_reparent (ClutterActor *self, if (CLUTTER_IS_CONTAINER (priv->parent_actor)) { ClutterContainer *parent = CLUTTER_CONTAINER (priv->parent_actor); - + /* Note, will call unparent() */ clutter_container_remove_actor (parent, self); } else clutter_actor_unparent (self); if (CLUTTER_IS_CONTAINER (new_parent)) + /* Note, will call parent() */ clutter_container_add_actor (CLUTTER_CONTAINER (new_parent), self); else clutter_actor_set_parent (self, new_parent); @@ -5747,9 +5769,6 @@ clutter_actor_reparent (ClutterActor *self, g_object_unref (self); CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_REPARENT); - - if (CLUTTER_ACTOR_IS_VISIBLE (self)) - clutter_actor_queue_redraw (self); } } /** @@ -7340,3 +7359,43 @@ clutter_actor_get_stage (ClutterActor *actor) return actor; } + +/** + * clutter_actor_allocate_preferred_size: + * @actor: a #ClutterActor + * @absolute_origin_changed: whether the position of the parent has + * changed in stage coordinates + * + * Utility call for Actor implementations that allocates the actors + * preffered natural size. + * + * Since: 0.8 + */ +void +clutter_actor_allocate_preferred_size (ClutterActor *actor, + gboolean absolute_origin_changed) +{ + ClutterUnit actor_x, actor_y; + ClutterUnit natural_width, natural_height; + ClutterActorBox actor_box; + + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + actor_x = clutter_actor_get_xu (actor); + actor_y = clutter_actor_get_yu (actor); + + /* All actorren get their position and natural size (the + * container's allocation is flat-out ignored). + */ + clutter_actor_get_preferred_size (actor, + NULL, NULL, + &natural_width, + &natural_height); + + actor_box.x1 = actor_x; + actor_box.y1 = actor_y; + actor_box.x2 = actor_box.x1 + natural_width; + actor_box.y2 = actor_box.y1 + natural_height; + + clutter_actor_allocate (actor, &actor_box, absolute_origin_changed); +} diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 29e79a9b6..44a21feb2 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -555,6 +555,10 @@ void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, ClutterActor *ancestor, ClutterVertex *point, ClutterVertex *vertex); + +void clutter_actor_allocate_preferred_size (ClutterActor *actor, + gboolean absolute_origin_changed); + G_END_DECLS #endif /* _HAVE_CLUTTER_ACTOR_H */ diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index 389f9fa6f..c90cea3b8 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -298,27 +298,7 @@ clutter_fixed_layout_allocate (GList *children, for (l = children; l != NULL; l = l->next) { ClutterActor *child = l->data; - ClutterUnit child_x, child_y; - ClutterUnit natural_width, natural_height; - ClutterActorBox child_box; - - child_x = clutter_actor_get_xu (child); - child_y = clutter_actor_get_yu (child); - - /* All children get their position and natural size (the - * container's allocation is flat-out ignored). - */ - clutter_actor_get_preferred_size (child, - NULL, NULL, - &natural_width, - &natural_height); - - child_box.x1 = child_x; - child_box.y1 = child_y; - child_box.x2 = child_box.x1 + natural_width; - child_box.y2 = child_box.y1 + natural_height; - - clutter_actor_allocate (child, &child_box, absolute_origin_changed); + clutter_actor_allocate_preferred_size (child, absolute_origin_changed); } } diff --git a/doc/clutter-actor-invariants.txt b/doc/clutter-actor-invariants.txt index 3ffe2d8c4..accf5d932 100644 --- a/doc/clutter-actor-invariants.txt +++ b/doc/clutter-actor-invariants.txt @@ -4,6 +4,8 @@ ClutterActor Invariants ClutterActor behaviour has invariants that will be kept with the same API and ABI guarantees as the whole Clutter library. +This document refers to the 0.8 release of Clutter. + Sections: i. Flags @@ -27,7 +29,9 @@ ClutterActor. CLUTTER_ACTOR_REALIZED Set by clutter_actor_realize(), unset by clutter_actor_unrealize(). - Means: the actor has memory associated to its paint cycle. + Means: the actor has GPU resources associated to its paint cycle. + Once realized an actor needs to be explicitly unrealized unless + being destroyed. Hide, reparent etc will not unrealize. CLUTTER_ACTOR_MAPPED Set by clutter_actor_show(), unset by clutter_actor_hide() @@ -42,11 +46,18 @@ CLUTTER_ACTOR_VISIBLE CLUTTER_ACTOR_REACTIVE Set and unset by clutter_actor_set_reactive() Means: the actor is now reactive to events. + Notes: + * If parents need to be reactive for child its up to the + parent implementation. In the case of ClutterGroup it + being marked unreactive does not mark all children unreactive. + * Clutter stage is always reactive. + b. Private ClutterActor flags CLUTTER_ACTOR_IN_DESTRUCTION - Set internally by clutter_actor_destroy() + Set internally by clutter_actor_destroy(). + Used to avoid uneeded overhead when freeing GPU resources on unrealize CLUTTER_ACTOR_IS_TOPLEVEL Set internally by the initialization of ClutterStage @@ -110,6 +121,7 @@ In the following calling clutter_actor_unparent() on an actor will hide the actor; calling clutter_actor_reparent() on an actor will leave the actor in the same state. + Niether will unrealize. iii. State changes ------------------------------------------------------------------------------- @@ -171,12 +183,14 @@ Notes: * clutter_actor_unparent() will hide the actor except in the special case when CLUTTER_ACTOR_IN_REPARENT is set. +* 'Composite' Clutter actors need to pass down any allocations to children. + c. Initial state When creating an actor, the initial state is: 1. !CLUTTER_ACTOR_REALIZED 2. !CLUTTER_ACTOR_MAPPED - + 3. !CLUTTER_ACTOR_REACTIVE =============================================================================== $LastChangedDate$