Re: Baseline alignment ideas



On ons, 2013-02-27 at 01:18 +0900, Tristan wrote:

My thoughts are that, when performing get_preferred_height_for_width(),
you need some virtual allocation logic like such that is found in
gtkbox.c (when we are requesting in the 'uncomfortable/opposing'
orientation):

  a.) Calculate how much width exactly would be given to each child
  b.) Calculate height-for-width of each child
  c.) Report the MAX of all child heights.

Now with baselines, this becomes slightly more complex, during
the h4w request phase you need to replace the above 'c' with
something that aligns the requested baseline(s) for all children,
and requests a little bit more height in order to logically fit
all children into that height (which is dependent on the provided
width).

It'd be something like this:
 a.) Calculate how much width exactly would be given to each child
 b.) Calculate height-for-width of each child
 c.) Calculate the baseline-for-width of each child
 d.) For each child, divide the height in two parts, one above baseline
     and one under.
 e.) Report the MAX (above baseline) + MAX (below baseline) of all child
heights.

But this is not really the complex part.

For instance, if you have two children with the baseline at the top,
then all extra space can be assigned to each child. However, if one
has the baseline att the bottom you need to give each half the extra
height.

I don't really see any way to solve this generically. But maybe we can
somehow limit our baseline support so that this works? For instance,
we could always request the naural size for baseline aligned widgets
and never grow them? Would that be enough in practical use? I dunno...

Ideas wanted...

I had some ideas about this, and I'm sure it can be done with
height-for-width in mind, however the "y" baseline(s) need to be
calculated on a per width basis (i.e. as you're problem statement
indicates, one "y" baseline can not rule-them-all as the required "y"
anchor point might differ depending on the width, so probably the
size requesting cache needs to also cache any baselines reported).

Yes, baselines are per-width and needs caching.

I don't think something particularly iterative is needed for this
either, just need to virtually allocate the children in the request
phase.

I don't understand how that helps at all with the size allocate phase.
See the example I gave in my mail to mathias.

Also, I'm not convinced that 'baseline' is the right word for this API,
I would rather consider it in terms of X and Y "anchor points" (if we
handle this complexity in one orientation, we should be able to get
the other orientation with relatively little added effort).

On the contrary, baseline is *obviously* the right thing. Its what
99.9999999% of all uses of this will be, its what people will naturally
look for in the API, and its what other APIs use. I also don't think it
necessarily makes a lot of sense to allow vertical baselines. Vertical
text is extremely uncommon and i can't think of any real life usecases
for this. The size machinery is already slow enough that I don't think
its worth adding theoretically useful functionality making it even
slower.

Another thing, is that we need the ability to calculate more than
a single anchor point in a given orientation per widget. The
one 'baseline' per widget wont pan out in the long run.

I disagree. Sure, there will naturally be several *possible* baseline in
a given child when you're aligning a container. However, only one will
*actually* ever be used, so as long as you can select the proper
baseline on the child widget itself there is no need for the general
layout machinery to know about this.

For instance, multi-line labels obviously have several potential
baselines. But that is solvable by a call like
 gtk_label_set_use_baseline (label, GTK_LABEL_BASELINE_LAST);

Similarly with a vbox like container you would get a potential baseline
per child widget, but as long as you can tell the vbox which child it
should inherit the baseline from you know what the baseline of the vbox
is.

There are cases where there are muliple baselines in a single container.
Like a GtkGrid or GtkTable, where each row has its own baseline. But
that is completely inside the size machinery of the grid implementation
itself. Seen from the *outside*, like when putting the grid itself into
a hbox and baseline aligning it would only have *one* baseline.

+------------------------------------------+
| Horizontal Box (or Grid)                 |
|                                          |
|                +-----------------------+ |
| +---------+    | Vertical Box (or Grid)| |
| | Image   |    |   +--------+          | |
| |         |    |   | Label  |          | |
| +---------+~~~~|~~~+--------+          | |
|                |                       | |
|                |   +---------------+   | |
|                |   | Other Content |   | |
|                |   +---------------+   | |
|                +-----------------------+ |
+------------------------------------------+

      So... in other words the Vertical Box element here must
      report possibly a number of "y anchors" for the anchors
      of it's children, and use the allocated anchors from it's
      parent to properly position the "Label" content it contains.

All you need is gtk_container_set_baseline_widget (vbox, label). I don't
see why the vbox has to ever report to the hbox that there are other
possible baselines. It cares nothing about them.





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