PopupMenu + alt key = hidden choices

I’m trying to find a way to enable/refresh hidden items in my popup menu that are triggered via the ‘alt’ key.
I’ve got a timer running that checks the desktop main mouse source’s modifiers.
if ‘alt’ is pressed, it refreshes the MenuBarComponent.

It works pretty well if I hold down ‘alt’ BEFORE opening the popup menu in the menu bar.
But if a menu is already open, it has no effect. Any ideas on how to get these hidden menu choices to appear after the menu has already appeared? A common example is when you open the Window menu for any app on OS X, and when you press ‘Alt’, the Minimize/Zoom choices changes:

MENU

edit:
ah, it doesn’t work if the menu is open, because this doesn’t refresh the menu if the menu names don’t change:

void MenuBarComponent::menuBarItemsChanged (MenuBarModel* /*menuBarModel*/)
{
    StringArray newNames;

    if (model != nullptr)
        newNames = model->getMenuBarNames();

    if (newNames != menuNames)
    {
        menuNames = newNames;
        repaint();
        resized();
    }
}

Is there a way to refresh the active popup menu when a keypress is detected?

1 Like

I just hacked this together really quick, it has bugs (don’t discard the menu :smiley: ) and is just a quick and dirty example but this does what you want.

Click anywhere, a popup will open, use the Alt key to toggle options

GitHub - benediktadams/PopupMenuWithOptions

This can’t be used with a MenuBarComponent.

What I need is

int MenuBarComponent::getCurrentPopupIndex() const { return currentPopupIndex; }

which doesn’t exist.

I got it working when I added that function to MenuBarComponent though:
popupMenu

That’s via this:

void MenuBarUpdater::timerCallback()
{
    if( mbc != nullptr )
    {
        auto& desktop = Desktop::getInstance();
        bool isAltDown = desktop.getMainMouseSource().getCurrentModifiers().isAltDown();

        if( isAltDown != lastAltStatus )
        {
            lastAltStatus = isAltDown;
            auto currentMenuIndex = mbc->getCurrentPopupIndex();
            if( isAltDown && currentMenuIndex >= 0 )
                activeMenuIndex = currentMenuIndex;
                
            refresh();
        }
    }
}

void MenuBarUpdater::refresh()
{
    mbc->showMenu(-1); //closes current menu
    DBG( "activeMenuIndex: " << activeMenuIndex );
    mbc->showMenu(activeMenuIndex); //forces current menu to be recreated.
}

and doing this in getMenuForIndex():

        if( Desktop::getInstance().getMainMouseSource().getCurrentModifiers().isAltDown() )
        {
            menu.addSeparator();
            menu.addSubMenu("Font",
                            createFontMenu(settingsTree));
        }

CC: @t0m @jules I’ll be submitting a pull request for that MenuBarComponent index getter.

Please don’t tag the JUCE team in your posts (we’ve asked you this before) - we read everything on the forum anyway.

@ed95 @t0m i’m still waiting to get some kind of reply on this Pull Request. I have demonstrated the reason it is needed in the first post and demonstrated how I accomplished it in the 3rd post. Hopefully that provides enough context for why this getter is needed.

I’ve replied in the following post, but perhaps it was buried in the thread:

We’d rather not expose the internals of classes like MenuBarModel for the reasons stated in that post. Doing this properly requires some thought and, with the release of JUCE 6 approaching, there’s no bandwidth on the team to look into it right now. If you can propose a PR which achieves what you want without exposing implementation details like this then we’d happily take a look and perhaps merge it but we won’t accept it as it is - I’ll close the PR on GitHub.

So, a PR that adds the ability to refresh a PopupMenu via the ‘alt’ key without exposing the PopupMenu internals. Got it.

Is this something that is now doable ?

Thanks !

I’d also be interested in the native MacOS implementation. Does anyone maybe came up with a PoC?

I came up with an MVP myself. It wasn’t actually that difficult after all. This is a MVP and should be treated as such

How this works

  1. Setting a menu item to alternate will hide the previous once when holding down option. Therefore, normal and alternate items need to alternating in the PopupMenu you pass to the menu bar. Not sure what happens when you have multiple alternate items in a row
  2. Alternate items need to contain a key combination that include the option/alt key. This is problematic when you enable user defined key commands using the command manager. My code automatically adds the option modifier when the item does not have a key command attached to it.

native_mac_menu_alternatives.patch (3.7 KB)