docs: Add a simple description of the size negotiation mechanism
Describe (with an example) the ordering and meaning of flags for the size negotiation in ClutterActor.
This commit is contained in:
parent
123bd41e6c
commit
c1951ab17a
85
doc/size-negotiation.txt
Normal file
85
doc/size-negotiation.txt
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
Size negotiation in Clutter
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Clutter uses a two-pass size negotiation mechanism. Each parent will ask its
|
||||||
|
children (if any) for their preferred size, which will affect the parent's own
|
||||||
|
preferred size; once this preferred size query returns to the stage, the stage
|
||||||
|
will allocate the size of each child, which in turn will allocate each one of
|
||||||
|
their own children, until it reaches the end of the scene graph.
|
||||||
|
|
||||||
|
The preferred size of an actor is defined through the:
|
||||||
|
|
||||||
|
get_preferred_width()
|
||||||
|
get_preferred_height()
|
||||||
|
|
||||||
|
virtual functions that should be implemented by every actor. The virtual
|
||||||
|
functions will only be invoked if the corresponding flags:
|
||||||
|
|
||||||
|
needs_width_request
|
||||||
|
needs_height_request
|
||||||
|
|
||||||
|
are set; otherwise, the preferred size will be cached inside ClutterActor
|
||||||
|
itself.
|
||||||
|
|
||||||
|
Actors can inform their parents that their preferred size has changed by using:
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout()
|
||||||
|
|
||||||
|
on themselves. This function will "bubble up" through the scene graph, and it
|
||||||
|
will clear the:
|
||||||
|
|
||||||
|
needs_width_request
|
||||||
|
needs_height_request
|
||||||
|
needs_allocation
|
||||||
|
|
||||||
|
flags inside the actor and its parents up to the stage.
|
||||||
|
|
||||||
|
At the beginning of the next frame, the stage will check if there is a relayout
|
||||||
|
pending, and it will ask each child for its preferred size; depending on the
|
||||||
|
state of the flags, the implementations for the virtual functions:
|
||||||
|
|
||||||
|
get_preferred_width()
|
||||||
|
get_preferred_height()
|
||||||
|
allocate()
|
||||||
|
|
||||||
|
will be invoked in that order. Each parent is responsible for calling
|
||||||
|
clutter_actor_allocate() on its children.
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
Let's consider a scene composed by actors following this layout:
|
||||||
|
|
||||||
|
+---------------------------------------+
|
||||||
|
|3 +=============+ +==+ +=============+ |
|
||||||
|
| | +-+ +-+ +-+ | | | |2 +-+ +----+ | |
|
||||||
|
| | | | | | | | | | | | |1| | | | |
|
||||||
|
| | +-+ +-+ +-+ | | | | +-+ +----+ | |
|
||||||
|
| +=============+ +==+ +=============+ |
|
||||||
|
+---------------------------------------+
|
||||||
|
|
||||||
|
The actor (1) calls queue_relayout(), which clears the needs_* flags on its
|
||||||
|
parent (2), and its grand-parent (3); the state of the other siblings will be
|
||||||
|
left untouched.
|
||||||
|
|
||||||
|
+---------------------------------------+
|
||||||
|
|a +=============+ +==+ +=============+ |
|
||||||
|
| |b+-+ +-+ +-+ | |f | |g +---+ +--+ | |
|
||||||
|
| | |c| |d| |e| | | | | |h | |i | | |
|
||||||
|
| | +-+ +-+ +-+ | | | | +---+ +--+ | |
|
||||||
|
| +=============+ +==+ +=============+ |
|
||||||
|
+---------------------------------------+
|
||||||
|
|
||||||
|
At the beginning of the following frame, clutter_actor_allocate() will be called
|
||||||
|
starting from the actor (a). Since its needs_* flags have been cleared, the
|
||||||
|
allocate() virtual function will be invoked. This will cause
|
||||||
|
clutter_actor_allocate() to be called on its children, starting from (b). The
|
||||||
|
size computed by the parent (a) for its child (b) hasn't changed, and its
|
||||||
|
needs_* flags haven't been cleared, so clutter_actor_allocate() will
|
||||||
|
short-circuit, and will not cause the implementation of the allocate() virtual
|
||||||
|
function for (b) to be called, effectively skipping the branch of the scene
|
||||||
|
graph. The same will happen for (f).
|
||||||
|
|
||||||
|
The child (g) has the same size, but its needs_* flags will have been cleared,
|
||||||
|
so its allocate() implementation will be invoked; this will cause the (h) and
|
||||||
|
(i) children to be allocated as well.
|
Loading…
x
Reference in New Issue
Block a user