[haiku-development] Re: Layout Builder classes

  • From: Ingo Weinhold <ingo_weinhold@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Thu, 24 Jun 2010 23:06:08 +0200

On 2010-06-24 at 19:02:35 [+0200], Alex Wilson <yourpalal2@xxxxxxxxx> wrote:
> Hi all, I'm working on the Layout API for GSoC, and one of the things
> I've been doing is deriving BLayout from BLayoutItem, so that one can
> have multiple layouts in a BView without the need for intermediate,
> purely organizational BViews. Anyway, that is pretty much done, but
> one of the places where this will most come in handy is when using the
> layout builder classes. To that end, I started modifiying these
> classes to use this feature. Along the way, I noticed that there are
> two separate types of layout builders in the repository: the
> templatized ones (living in headers/os/interface/LayoutBuilder.h) and
> the non-templatized ones (living in
> headers/os/interface/GroupLayoutBuilder.h, GridLayoutBuilder.h etc.).
> Seeing these two solutions, I can't help but wonder why the
> templatized classes are necessary. The advantage to them seems fairly
> small:
> 
> Instead of writing this:
> 
> GroupLayoutBuilder(B_HORIZONTAL)
>     .Add(new BButton("in group"))
>     .Add(GridLayoutBuilder(3.0f, 3.0f)
>              .Add(new BButton("in grid"), 0, 0)
>              .Add(new BButton("also in grid"), 0, 1)
>            )
>      .Add(new BButton("also in group"));
> 
> one would write:
> 
> BLayoutBuilder::Group<>(B_HORIZONTAL)
>     .Add(new BButton("in group"))
>     .AddGrid(3.0f, 3.0f)
>          .Add(new BButton("in grid"), 0, 0)
>          .Add(new BButton("also in grid"), 0, 1)
>      .End()
>      .Add(new BButton("also in group"));
> 
> granted, the seond one is somewhat cleaner, but I see two problems with it.
> *it discourages subclassing of BLayout because using classes that
> aren't already part of this method looks like you are cheating:
> 
> BLayoutBuilder::Group<>(B_HORIZONTAL)
>     .AddGroup(B_VERTICAL)
>          .Add(new BButton("button"))
>     .End()
>     .Add(MyOwnLayoutBuilder(FLOW_DOWN)
>                 .Add(new BButton("in my layout"))
>            )
>      );

If there was a way to integrate custom layout builders more smoothly, that 
would be nice, of course, but the way it works now is hardly *discouraging* 
BLayout subclassing. Besides custom BLayouts should really be the exception, 
not the rule (and layout builders for those even more so). Otherwise we 
should probably extend the set of standard layouts.

> *it duplicates the functionality of the other layout builders, but
> with a little extra syntactic sugar. Developers who find both types of
> layout builder may get confused about which they should be using.

Indeed. That's why the old (non-templatized) layout builders should be 
removed.

> Another feature that the templatized builders have is the Grid builder
> has an AddTextControl method and AddMenuField method (both
> BTextControl and BMenuField have the option of creating separate
> BLayoutItems for their label and body). This is convenient I suppose,
> but it seems a little odd to have special methods for these two
> widgets.

Sure, a bit odd, but very convenient. :-)

> What I'm wondering is should the templatized builders be moved to
> headers/private...., removed and replaced with their non-templatized
> counterparts, or just left as is? (FWIW I probably prefer making them
> private)

The other way around. I intended for the non-templatized builders to be 
phased out. The templatized builders have another advantage, which is one of 
the main reasons I wrote them: They are exception safe, since they build the 
view/layout tree in pre-order. I.e. as long as the root layout builder uses 
a view/layout/window owned by the API user, nothing will be leaked (by the 
builders) when an exception is thrown. When nesting the non-templatized 
builders on the other hand, the view/layout tree is built in post-order, 
i.e. all already created views are leaked when an exception is thrown. So 
for developers who want to code exception aware (I did that pretty 
consequently in Debugger, BTW), the old layout builders are simply a no-go.

CU, Ingo

Other related posts: