[haiku-3rdparty-dev] Re: Layouting question

  • From: Ingo Weinhold <ingo_weinhold@xxxxxx>
  • To: haiku-3rdparty-dev@xxxxxxxxxxxxx
  • Date: Thu, 28 Apr 2016 11:29:46 +0200

On 04/26/2016 06:18 PM, Humdinger (Redacted sender humdingerb for DMARC) wrote:

I have a little problem with a layout...
Have a look at this: https://lut.im/cpHbZgzesI/d0i4bGJjpiz1sRAF.png
(Don't mind the white background, that's on purpose to see how the
views react to resizing.)

I want the icon to stick to the left border and the text+buttons to
stick to the icon. The BTextView is supposed to grow to the right, if
the window is resized horizontally.

Currently with this code:
https://github.com/humdingerb/Filer/blob/newgui/sources/Filer/HelpTab.cpp#L150
the views don't stick as they should. Do I need some .AddGlue()
somewhere or have some of the view put on some "weight"? I tried and
tried, but didn't succeed.

It's a bit hard to analyze layout issue without seeing them in action. Anyway... When a view doesn't grow or shrink as one would expect and the min/max sizes on the view look OK, it is usually something in one of the ancestor groups that causes the restriction. In your case it looks like the BStringViews are to blame. By default a BStringView has a maximum width equal to the width of its text. A vertical group tries avoid violate any minimum and maximum width constraint of its items, i.e. it tries not to grow wider than the least maximum width and not to shrink narrower than the greatest minimum width. In case the two conflict, the latter constraint wins.

So the outcome in your case is that the group width is limited to the minimum width of, I guess, the button group. (*)

Possible solutions:

* Wrap each of the items with maximum width in a horizontal group with glue.
* Set the explicit maximum width of the BStringViews to B_SIZE_UNLIMITED.

Also, there seems to be something wrong with the BTextView fInfo. With
it added to the BHelpTab view, I can vertically resize the window to
cut off the buttons below and a part of the BTextView:
https://lut.im/loe358An12/3e7wMzpzDTuDceND.png
Why is that?

You have to set the window flag B_AUTO_UPDATE_SIZE_LIMITS for the size constraints computed by the layout system to be enforced on the window.

There's a catch in your case, though: You have enabled word wrapping on you BTextView, so the view becomes a height-for-width view, meaning that its min/max height constraints depend on its actual width (narrower text requires more height, wider text less height). The layout system itself supports this concept (via HasHeightForWidth()/GetHeightForWidth()), the app server, however, does not. Since the view is not embedded in any parent that eliminates the effects, the property is propagated up to the root view of the window and due to the missing support in the app server (or even BWindow API to notify it), only the constraints ignoring the height-for-width properties will be enforced on the window. Those are laxer, so it will be possible to resize the windows smaller or greater than it actually needs to be.

You already set a minimum height on the BTextView. It would probably be better to instead define an explicit minimum width for it and use its GetHeightForWidth() method to get the corresponding height constraints. By setting the explicit minimum height respectively you can at least make sure that the window cannot be resized smaller than necessary (you can also set the respective explicit maximum, if you want). However it may still be larger, so the glue you already have at the end of the vertical group may indeed be necessary to compensate.

CU, Ingo

(*) To complete the picture: If a group (or grid) gets more space than it wants (i.e. more than its computed maximum), it aligns its items in the available space according to their BAlignment (Alignment()). Usually that means they are centered. Child groups however have an alignment of B_ALIGN_USE_FULL_WIDTH/B_ALIGN_USE_FULL_HEIGHT, meaning that they will be given the full available space, even if greater than their maximum. This way the excess space is propagated to the innermost groups and may actually benefit items that don't have a smaller maximum constraint. Or at least spacing will distributed at the innermost level, not around outer groups.

Anyway, what I was aiming at: Due to this effect, when resizing a window, an item may in effect grow (somewhat), although its containing group may have a stricter maximum size and thus shouldn't grow at all. Something to keep in mind when analyzing the observed behavior.

Other related posts: