Hi,

On Mon, Feb 25, 2008 at 5:16 PM, Matthew Allum <[EMAIL PROTECTED]> wrote:
>  Am I correct in understanding that adding this patch wouldn't (at least
>  by intention) have any affect/change on how clutter is currently used
>  (from a fixed pov) nor any kind of performance impact ? And in that its
>  actually pretty cool ?

That is my hope, right. I think the model here is pretty well-tested;
it's a fine-tuning of the GTK model, and basically the same as the
fine-tuning used in HippoCanvas. With some Clutter-specific twists,
namely the transform (done independently of layout), the "do what I
mean" x/y/width/height properties, and the automatic use of fixed
layout if no other layout mechanism has been set up.

>  Thanks for bearing with me on this. I really have no experience of
>  layouts and I guess much of my fear is in something I cant really
>  visualise. In that Im worried that we're perhaps missing something
>  really obviously dangerous here. I really need to study the patch
>  closer, and if you feel the motivation to give (or point at) a quick
>  layouts for dummys it would be much appreciated.

Sure, one thing that might help is this discussion of HippoCanvas layout:
http://log.ometer.com/2006-10.html#14

Conceptually:

1) each actor has a "request" which is simply a set of hints to a
layout manager. The patch adds a particular kind of request,
get_width_request/get_height_request, which is called
"height-for-width" because the layout manager first asks for width,
then decides on what width an actor will get, then asks the actor what
height it wants for that width.

So for a label for example, the label will say "OK, my min width is
say 5 characters, but my natural width is the entire width of the
string"

If the layout manager can give all labels their natural width, then it
will. If not it will start chopping some down to their min width. It
decides what width each gets, then asks each what height it wants at
that width. To ask for a height, a label says "OK, I have 10 chars of
width; so now I have to ellipsize or wrap, and that means I need XYZ
height."

GTK can't do this because it requires labels to ask for width and
height at the same time, so the label has to predetermine whether to
wrap, not knowing how much width is available. The blog post I linked
to above illustrates the problem this creates with ellipsization.

2) this height-for-width kind of request is not the only possible one,
but is by far the most common and useful, and is a superset of what
the GTK model allows. So it should cover 99% of cases. However, a
layout manager is always free to ignore the request, so if an app
author did not like get_width_request/get_height_request they could do
something else just as they can today.

Most layout managers have additional hints specific to the layout
manager. For example, GtkFixed has the x,y position. GtkBox has the
expand and fill flags. A layout manager container will have to provide
a way to set these additional hints for actors.

3) each actor has an "allocation" which is where the actor is in fact
currently located. The allocation is used for painting and for event
delivery. The actor does not set the allocation though, the actor
instead provides the request, and the layout manager sets the
allocation.

In window manager terms, the request is XSizeHints, the layout manager
is the WM, and the allocation is the actual size of the X window. X
clients can't set their size directly, they send a request to the WM,
which then gives them a size. Same thing with actors and the layout
manager.

The x,y position for GtkFixed, or the expand/fill flags for GtkBox,
are like additional hints used only by some WMs. Something like
_NET_WM_WINDOW_TYPE or whatever.

4) by default, the patch hardcodes a layout manager which is like a
policy-free WM - it gives every actor exactly what the actor asks for.
In addition, ClutterGroup will always apply this policy-free fixed
layout manager anytime the "x,y" hint is set on an actor. So, any
actor that sets a position gets it, and overrides the layout manager.

5) ClutterActor has properties that override whatever
get_width_request/get_height_request would normally return. If you set
the width and height, then the fixed layout manager will use what you
explicitly set. But if you don't set it, the natural width and height
reported by get_width_request/get_height_request will be used. This is
useful to say force a label to always use exactly some number of
pixels, and it's also useful for actors that don't have any natural or
inherent size, such as the Rectangle actor.

6) "natural size" btw is defined as the size where alignment would do
nothing, i.e. there's no need for padding, so no need to align the
actor's visible content left/right/center. (Left/right/center
alignment would all look the same - the actor is displaying as much as
it could ever want to display.) "min size" is the smallest size an
actor can handle, so for an ellipsizable label it's 0 or close to it,
while for a non-ellipsizable non-wrapped label, it's the same as the
natural size.

7) implementation wise, the way layout works is that for the root item
(the stage) we ask for the size request, then assign a size
allocation. Those two operations are recursive; for each child, the
stage will ask for request. Then when the stage gets its allocation,
for each child it assigns an allocation. By default again this uses
the "fixed" layout mechanism, so the stage will give every child
exactly the size it asked for. But if you had say a box container, the
box would decide for the children where to put them and whether to
give them extra space. A box is like a tiling WM or something.

Notably, for a toplevel window the request is used to set XSizeHints,
and ConfigureNotify is used to assign the allocation. (This is
probably not quite right still in Clutter with my patch; I remember it
being a world of hurt to get just right in GTK, though Clutter lacks
some of the weird GTK APIs that made it especially hard.) So the WM
really does work into the overall layout loop, it's not only an
analogy.

8) an important invariant is to do the layout before painting, so
stuff isn't drawn in the wrong place then moved. This is why the
allocation is always up-to-date inside paint().

9) In theory, it's important whenever you think "I want the size of
this actor" to know whether you want the request or the allocation. If
you want the request, the use case is probably layout-related. If you
want the allocation, you're probably painting, or directing an event.
This creates some complexity, but the saving grace is that if an app
author doesn't understand this, and just uses fixed layout, the
request and allocation will always be the same anyway; so they can
keep getting this "wrong" but it won't matter. It's kind of like an
app that assumes the WM will never override its ConfigureRequest; the
app is conceptually wrong, but if the WM is really policy-free (as the
Clutter fixed layout is), the app will not break. Anyhow, so I left
clutter_actor_get_size() as a "do what I mean" that just gets the
request or allocation, whichever is most up to date.

I probably said some boring stuff you know in there, and some stuff
that didn't make sense, but hopefully addressed some questions in
there too ...

Havoc
-- 
To unsubscribe send a mail to [EMAIL PROTECTED]

Reply via email to