Layout menus

I quite like using the layout kit for menus, but it has some edge cases that make it a bit annoying.

Here is one, maybe someone has an idea if this can be patched or if there is another "nice way.

Example code:
BMenuBar* mainMenu = new BMenuBar("mainMenu");

BLayoutBuilder::Menu<>(mainMenu)
.AddMenu(B_TRANSLATE("App”))
.AddItem(B_TRANSLATE("About"), B_ABOUT_REQUESTED)
.End()

Now, the problem here is if this is a menu bar in the context of my MainWindow that this targets the Window, not the App. One way around this is to forward declare the item

item = new BMenuItem(B_TRANSLATE("About"), new BMessage(B_ABOUT_REQUESTED)));

item->SetTarget(myAPp);

.AddItem(item)

Or to add some case in MessageReceived() that forwards this to the app.

I think both cases are a bit ugly, and this is quite a common case.

Can’t we expand builder AddItem() to offer a variant accepting a “target” parameter?

Maybe, that is what I am asking here. Since I have no clue how the whole BLayoutBuilder works :smiley: (That is, how it works internally)

I have a patch for that that I have not yet submitted for review. I’ll submit it later today when I get to my Haiku computer.

Pushed the change to gerrit https://review.haiku-os.org/c/haiku/+/11840

1 Like

Do you have an example of how your patch can be used?
I had assumed that this would be a new overloaded method for creating the item, but it seems your patch does something different. I also know the SetMarked function and such is often used in e.g StyledEdit, but there the BMenuItems are forward declared so they are a member of the class to later let the Mark status be set/unset

EDIT: it seems the previous “.SetEnabled” is used in Terminal (didn’t find it anywhere else)

	`.AddItem(B_TRANSLATE("Find previous"), MENU_FIND_PREVIOUS, 'G',
			B_SHIFT_KEY)
		.GetItem(fFindPreviousMenuItem)
		.SetEnabled(false)`

I assumed it is better for it to behave the same way as SetEnabled instead of adding another overloaded method.

You can use it just like SetEnabled. You can use it like this too:

BLayoutBuilder::Menu<>(menuBar)
		.AddMenu(new BMenu(B_TRANSLATE("File")))
			.AddItem(new BMenuItem(B_TRANSLATE("New"), new BMessage(DOC_APP_NEW_WINDOW))).SetTarget(be_app)

Yes, that makes sense. I just did not know about this posibility :slight_smile:

merged, thanks!

Thanks.

One of the reasons I sat on that change without submitting was that I was thinking should I add same kind of convience functions to other things that send BMessages so the API would behave equally on different controls. What do you think about that? The other reason was just forgetting and not having time to work on Haiku stuff.

I think some parts of the API do need some simplifications or convenience functions. It just depends on what :slight_smile:

As for the menu stuff itself, It is not that widely used yet, also because documentation is completely lacking…