Any one has a working example of menu bar?

As the title.

Does anyone have a working example of menu bar? Preferably simple ones. I have modified and tried the given example. And copied directly into my project, some how it doesn’t work.

I also have written the menu bar on my own, but of course it doesn’t, since there is no documentation on it.

IIRC There is small examples in my Dummy repository on GitHub (Bip / MenuCrash).

1 Like

modified and tried the “given” example

Are you referring to the Menus Demo in the DemoRunner? I think I got my menubars in my app, and my plugin, working by examining this and incorporating examples from it.

But if I recall, I also looked at the Projucer source code extensively for how to get it all working. That’s a great place to look.

There are a lot of inter-related pieces to the puzzle. It’s really quite complicated, with the ApplicationCommandTargets, MenuBarModels, etc. More so than it should be… but what do I know… :wink:

2 Likes

I also often look into the Projucer when i don’t understand something with the documentation. :laughing:

2 Likes

@ 2042third - you’re also welcome to look at this.

I made a test project awhile back, it’s basically just turning the MenusDemo from DemoRunner into a VST3 plugin. So you have a plugin with a menubar inside the window. I was testing out how to implement submenus as well, so there are are a few in there with items that don’t do anything.

MenusDemoPlugin.zip (35.9 KB)

EDIT: or this one, if you’re making a GUI App. I made this to show a bug to the JUCE team, but again it’s basically the MenusDemo, extracted and made into a GUI App:

MenusDemoFlash.zip (18.5 KB)

2nd EDIT: caveat: I never ran either of these on Windows, I mainly work on Mac first. But I don’t see why they wouldn’t work, you may need to add VS Exporters in Projucer.

2 Likes

None of the projects has menu showing up… I think there might be something wrong with the latest release or something.

Bip from your project still wouldn’t show menu for whatever reason, there might be something wrong with the latest release.
However, the thing is that the demo menus compiles and shows menus normally. Really confused.

There might be something wrong with your installation. I ran them both here before I uploaded them, with JUCE 7.0.2. The menubar showed up and worked as expected.

I managed to get the menu in your example to show by pressing “shift+w” after start up.

I tried to do everything that pressing "shift + w " did on the demo (setting menuBar->setVisible(); call menu changed(), and call resizerd() ). Even after adding those nothing visible shows up. I made break point after press “shift+w”, which responds as expected and no errors shown, but it just would not show the menu. It seems that all objects are created normally, but there might be something that I did wrong to keep it from showing up.

Also, do you have a source that can be used as reference that can be used as documentation? The official docs really didn’t show anything about how why and where things are happening. I still don’t understand why we don’t need to call setMenuBarComponent() in the main component eventhough the docs talked a lot about how it can do what I needed to (just having a menu to show up).

Another question; do you know if we need another command target to have the menu to show up? I currently only have the main component to respond to menu events. I don’t see why it wouldn’t work though.

Just so I understand:
Are you building on Mac or Windows?
Are you making a GUI App or a plugin?

The MenusDemo on a Mac defaults to showing the Global MenuBar at the top of the display, like all Mac Apps. Shift+W puts it into the app’s window, ala Windows-style.

If running on Windows, it should not need shift+w because there is no global menubar and I think the code provides for the difference between Mac and Windows. So the menubar should show up inside the window.

Since these were simply experiments I built for my own understanding, they may not work right on Windows (which I didn’t try), if that is what you are using. For example, in MenusDemoFlash (the project for the GUI app), there is this line in the constructor:

        setMenuBarPosition (MenuBarPosition::global);

That’s not going to work on Windows. You should likely change that to:

        setMenuBarPosition (MenuBarPosition::window);

… and then hopefully it will start up with the menubar in the window and not need shift+w. Since it’s the MenusDemo (basically), it’s got a bunch of unnecessary stuff like the ability to switch to a burger menu, switch to the global menu for Mac, etc.

Sorry, I didn’t mention that I am on windows. I am building and targeting the windows-style menu bar for my project.

From the code, I traced all the operations of calling

setMenuBarPosition (MenuBarPosition::global);

in the constructor. And I translated that to calling

setMenuBarPosition (MenuBarPosition::window);

in the constructor. So that I can eliminate calling “setMenBarPosition()”. Specifically, in the constructor I did

menuComponent.reset(new juce::MenuBarComponent());
    note_editor.reset(new NotesEditor( ));
...
  menuComponent->setBounds(getLocalBounds().removeFromTop(juce::LookAndFeel::getDefaultLookAndFeel().getDefaultMenuBarHeight()));
    addAndMakeVisible(menuComponent.get());
    
    // Settingss
    setApplicationCommandManagerToWatch(&commandManager);
    commandManager.registerAllCommandsForTarget(this);
    commandManager.setFirstCommandTarget(this);
    addKeyListener(commandManager.getKeyMappings());
    setWantsKeyboardFocus(true);

    menuComponent->setVisible(1);
    menuItemsChanged();
...

The menu doesn’t show up by doing these.
Do you see anything that I should change to make it more likely to appear?

Currently it looks like this.

You can see the area on top where the menu should be, but doesn’t show up.

Is that the constructor? If so, you definitely don’t want to be setting bounds of any child components there. Take that setBounds() and put it in resized().

In the MainComponent constructor, you addAndMakeVisible() your child components. But all setting of the bounds of those components must be done in your MainComponent::resized(), which may be called multiple times while various initializations are done and the menuComponent has children of its own that won’t get set up properly. Also, you were setting the bounds before addAndMakeVisible() so the component is not even there yet (but it’s still the wrong place).

So in any case, that’s likely the problem.

Hello, thank you for the response.
I have removed all setBounds() calls in the constructor (I used to just copy and paste everything in the resized() to the constructor…). And still no menu… There might be something fundamentally wrong with how my project is setup. I will try to convert your project and reskin to my project and see if that works.

Problem solved!!!

It is in the constructor. For MenuBarComponent to register with the component it displays on it has to be initialized with the reference to the displaying component.

...
menuComponent.reset (new MenuBarComponent (this)); // Works!!!
...
...
menuComponent.reset (new MenuBarComponent ()); // Doesn't work...
...

Cannot believe I didn’t notice that.

Glad you figured it out. And moving forwards, don’t put the resized() stuff in the constructor; resized() exists for a reason. :wink:

Thank you for the note! And thank you for the responses.

1 Like