Re: Baseline alignment ideas



On Tue, 2013-02-26 at 21:05 +0100, Alexander Larsson wrote:
On tis, 2013-02-26 at 10:58 -0500, Matthias Clasen wrote:
On Tue, Feb 26, 2013 at 9:30 AM, Alexander Larsson <alexl redhat com> wrote:

Ideas wanted...

I think you basically have to split the height that is returned for
minimal or natural size into an overlength/underlength pair. Then you
can sum them up separately in containers that support baseline
alignment. In containers that don't, you'll always just use the total
height (which is the sum of the two).

Would that work, or am I overlooking something ?

Yeah, thats the way you implement size *request*. The problem comes when
you get to the allocation phase. Let me give a simple example. We're
laying out a hbox with two child vboxes, each with a label and some
other widget. Like this:

+- HBox --------------+
|+-------+            |
||       |            |
||  A    |            |
||       |            |
|+-------+ +--------+ |
||  B    | |    B   | |
|+-------+ +--------+ |
|          |        | |
|          |    D   | |
|          |        | |
|          |        | |
|          +--------+ |
+---------------------+
The labels B are identical, but packed in different order in the vboxes.
To make things easy, lets say all widgets are 100 px wide.
Then:
   min height   nat height  baseline
A: 10           20
B: 20           20          10
C: 20           30

Its quite obvious that the min height of the hbox is 10+20+20 == 50, the
natural height is 20 + 20 + 30 == 70px, and the corresponding baselines
are at 20 and 30. And the width is 200 px.

So, we report this is size_request. Now the size machinery happens and
we get called with the final size of the hbox. It is to be 200x60
pixels.

Now, what size should we allocate to the children?
At least we should fulfill the minimum request which is 50 px tall. But
then we have an extra 10 pixels to distribute. But, how do we distribute
it? Whenever we add size to some particular child that will affect the
baseline of that child in some complex way. For instance, in this case
as the two children point in different direction we should probably give
each child 5 pixels more each which gives a total height of 60. But if
the order of the two children were the same we should give each child 10
pixels, which would then give us 60 pixels.


Ah, I think I understand your question better now.

Use a natural allocation process similar to
gtk_distribute_natural_allocation():
http://git.gnome.org/browse/gtk+/tree/gtk/gtksizerequest.c#n599

Instead of looping over widget size requests, provide a normalized
value for the minimum and natural requests "above" and "below" the
children (after allocating the absolute minimum height).

 o Start by giving equal minimum "above" height to all children and
   equal minimum "below" height to all children

 o Distribute extra allocated space above and below equally until
   one of the sides ("above" or "below") reaches natural allocation

 o Continue to distribute extra allocated space to the remaining side
   until that side fulfills it's natural allocation.

 o Deal with expand space, here we don't have any options such as
   'the widget expands above' or 'below', better I guess keep it
   simple and hand out remaining expand space equally to above and
   below (after both above and below reach the natural requests).

Handing out natural size is indeed iterative, but shouldn't be too
intensive (and possibly simpler than the loop in
gtk_distribute_natural_allocation(), since there is only ever one
"below" and one "above").

Of course, this doesn't cover the gritty details of how the HBox
probably allocates full height to all children, hands out an 
'allocation baseline' to both of it's VBox children which is agreed
upon by both of those VBox 'baseline requests' and the allocated HBox
height... not sure where exactly the above algo fits in all of this
but you probably have an idea ;-)

I'm still interested to see what semantics this brings in, what
the big picture proposal is going to look like, but I guess you're
still grinding out the implementation details :)

Cheers,
       -Tristan





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]