[haiku-development] Re: BBox and layout

  • From: Clemens Zeidler <clemens.zeidler@xxxxxxxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Tue, 15 May 2012 09:56:29 +1200

On Sat, 12 May 2012 03:27:13 +1200, Alex Wilson <yourpalal2@xxxxxxxxx> wrote:


Alright, this thread has sort of morphed into a discussion of three issues:

1: BBox

We have the idea of adding a BView::SetInsets() to deal with this.
That seems unclean to me, especially if layouts already support
insets. Nesting layouts is really easy, and it's also very powerful.
Why add *more* layout features to BView, further confusing things?

I still think adding a BBoxLayout is the best solution; it won't
require adjusting the BBox use in our apps, and doesn't require any
deviation from the other parts of the Interface Kit. Clean and
consistent :) With this idea, there is really no need for a
SetContentLayout() method, since box->GetLayout()->AddItem(myLayout)
(or box->AddChild(myLayout) makes perfect sense, just like you can add
layouts to a BGroupView.

We also have the idea of having BBox manage the insets of its layout,
which would work fine (even without BVIew::SetInsets()). BBox could
call SetInsets() on the layout, using a nested layout if you wanted
extra insets.

After giving it a another thought I still think SetInset should be in BView for consistency reasons. As said before BView is a special layout/layout item. It's somehow an artificial BLayoutItem or BLayout. It can be added into a layout and handled like a normal BLayoutItem. For this reason when adding a SetInset to BLayout it should also be added to BView (similar to the layout related size getter and setter in BView).

I think from the user point of view its seem odd to add an extra BLayout just to add an inset for the inner layout. Note, the placement of an inner layout in a BView and the inset of the inner layout are in general managed by two different classes, thus the BView should not mess with the inset of the inner layout!

In the example of BBox it shows that SetInset make the implementation of the placement into the content frame trivial (BBox just calls SetInset in its constructor). Moreover, the user does not needs any knowledge about layout internals and can just set the single layout using SetLayout.

A BBoxLayout::AddItem call to set a single layout is confusing for the user, i.e. does it means that multiple layouts can be assigned to a BBox?


2: BView::AddChild() -> BLayout::AddItem().

Theoretically, I do like the idea of breaking this behaviour, but the
potential work included isn't something that I want to do. For this
reason, I prefer the proposal of using a view flag to trigger this, or
potentially a flag could be passed to AddChild(). Encouraging people
to learn the API and focus on using the layout over the view is
important, though and breaking this behaviour would do that.

I probably miss some details. What else beside fixing apps has to be done in the layout class?

3: BLayoutItems with a BView must have the BView in the layout's
target view. (layout swapping)

Breaking this guarantee would mean that layout items could be added
before SetLayout() is called. This doesn't seem necessary to me, but
it's a limitation we could remove without too much work, and I don't
think it would cause too many problems. The main one that I can think
of would be memory management, if a view is not part of a hierarchy,
and the layouts it is part of are deleted, then does the view get
deleted? It's impossible to say, because we don't know if the user has
a pointer to it somewhere.

In addition to breaking this guarantee, the layout swapping case would
also require the ability for a layout item to be in multiple layouts
at once. This would again be possible, but doesn't seem very useful.
What if a layout item is in two sibling layouts, and both are enabled?
This is really a weird use case to me, and the adage of 'make simple
things easy, and hard things possible' is already met with the current
API. That saying has some hidden wisdom in it; making hard things
*possible* also means not wasting time trying to cater for every weird
edge case you can think of, as long as the API is flexible enough to
meet them with some work.

yes, lets ignore that special case for now! :)

Regards,
        Clemens

Other related posts: