PopupMenu not showing on AUv3 plugin

Here’s a minimal example project: Click here

It’s basically the Projucer Audio Plugin template, really the only changes are in PluginEditor.h/.cpp.

When I run it as an AUv3 app extension in iOS GarageBand, the PopupMenu doesn’t show. It shows correctly on the AUv3 standalone.

1 Like

Yep. In GarageBand your plugin is running as a separate process, and its window is embedded in GarageBand. If you start trying to create other windows, like a menu, then that window belongs to a completely different app and can’t possibly appear in the GB process.

Thanks for the reply. So that’s why it doesn’t work…Is there any way, or a plan to make menus that work in AUv3 plugins? Or would it be best for me to make my own menu Component that isn’t a window?

You’d need to use sub-components within your editor window. PopupMenus aren’t so good for that, as they expect to be on the desktop, but perhaps if there’s demand for it, we could modify them to allow them to be given a parent Component to live inside.

PopupMenus and ComboBoxes in JUCE have needed to be fixed for plugins anyway… so this may be a good time to address the issue…

Cheers,

Rail

1 Like

i would also like the idea of having more controls on popups, or having them inside other components, while still keeping the scrolling and centering functionality

There is definitely a need for popup menus. How else would the user be able to select presets? Popups are definitely an essential part of any synth plugin.

See screenshots of Arturia iSem with popups inside of GarageBand as an AUv3 Plugin

As you see from the screenshots in Arturia, the popups are not real popups (i.e. separate native windows). They just draw a component on top of the main component. You could implement something like this with a ListBox in JUCE.

If work is done on PopupMenu, using a model class so we don’t have to compute the whole menu at construction would be great as well.

my 2 cents

OK. On the latest develop tip we’ve added support to “popup” a menu inside a parent component without the requirement of opening a separate window.

This can be done in two ways:

  1. via the the new withParentComponent PopupMenu::Options option. For example, creating a popup embedded in the top-level component could be done in the following way:

    menu.showMenuAsync (PopupMenu::Options().withParentComponent (target.getTopLevelComponent())
    .withTargetComponent (target), myCallback);

or
2) Override this option for all menus with a new LookAndFeel method:

  Component* getParentComponentForMenuOptions (const PopupMenu::Options& options);

For example, in an AUv3 plug-in this could be used in the following way:

class PopupMenuPluginAudioProcessorEditor  : public AudioProcessorEditor
{
public:
       PopupMenuPluginAudioProcessorEditor (AudioProcessor& processor)
            : AudioProcessorEditor (processor)
       {
           ....
           setLookAndFeel (&lf);
          setSize (300, 200);
       }
       .
       .
       .
private:
     class ForcePopupsInParentWindow : public LookAndFeel_V2
     {
     public:
         Component* getParentComponentForMenuOptions (const PopupMenu::Options& options) override
         {
        #if JUCE_IOS
            if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_AudioUnitv3)
            {
                 if (options.getParentComponent() == nullptr && options.getTargetComponent() != nullptr)
                     return options.getTargetComponent()->getTopLevelComponent();
            }
        #endif
        
           return LookAndFeel_V2::getParentComponentForMenuOptions (options);
         }
      };
 
     ForcePopupsInParentWindow lf;
};
5 Likes

Thanks so much guys…This was fast!

Also, great look on prioritizing AUv3 over AudioBus. Many of my users are requesting this more as the flexibility is definitely better.

I just wish iOS wouldn’t restrict us to that ugly 2048 × 670 with that big keyboard on the screen. It makes you have to create a new view just for it, but great work again guys!

Great! And I’m glad it’s so easy to use globally or on an individual basis.

It was necessary for me to remove the #if JUCE_IOS and #endif statements so this would fix a crash in OS X too.

I’m having this very same issue with a AUv3 plugin that I’m updating, the ComboBox is never shown, so I’m applying this workaround but still the ComboBox isn’t shown and apparently that overridden function is never called. Even trying to run this under Windows (with the if removed) that point is never hit by the debugger.

2 Likes

I solved it by overriding getOptionsForComboBoxPopupMenu in my lookAndFeel. I added .withParentComponent(mainComponent), where mainComponent is the component I apply lookAndFeel to.

Currently struggling with this here … @vadimrostok do you perhaps have an example/working code you might share? I’d rather not have to re-do the UI of our plugins to avoid ComboBox if possible …

@anon48770766, sure.
In lookAndFeel is have:

juce::PopupMenu::Options getOptionsForComboBoxPopupMenu (ComboBox &combobox, Label &label) override {
    return PopupMenu::Options().withTargetComponent (&combobox)
      .withParentComponent(mainComponent)
      .withItemThatMustBeVisible (combobox.getSelectedId())
      .withInitiallySelectedItem (combobox.getSelectedId())
      .withMinimumWidth (combobox.getWidth())
      .withMaximumNumColumns (1)
      .withStandardItemHeight (label.getHeight());
  }

And in my parent component, where I’m setting lookAndFeel I have:

lookAndFeel.mainComponent = this;
setLookAndFeel (&lookAndFeel);
2 Likes

Thanks for that - I have pretty much the same code, but its not quite working. I guess I have something else to debug vis-a-vis my Components use of LaF. I really appreciate your help anyway, thanks!

1 Like