ComboBox.hidePopup() does not work!


#1

I have the problem that the ComboBox Popup window stays open (if no item is selected) and at its position as soon as the plugin window is moved.

To make sure that the popup closes I’m using a mouseExit listener on the combobox.
The mouse listener works, but hidePopup() has no effect.

Well, even “PopupMenu::dismissAllActiveMenus();” does not work but that is anyway called by hidePopup().

As a side note:
showPopup() works but isPopupActive() always returns false.

Please refer to the simple code example below:

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
PopupMenuAudioProcessorEditor::PopupMenuAudioProcessorEditor (PopupMenuAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p)
{
    setSize (400, 300);

	addAndMakeVisible(&comboBox);
	comboBox.addItem("Item 1", 1);
	comboBox.addItem("Item 2", 2);
	comboBox.setSelectedId(1);

	comboBox.addMouseListener(this, true);
}

PopupMenuAudioProcessorEditor::~PopupMenuAudioProcessorEditor()
{
}

void PopupMenuAudioProcessorEditor::paint (Graphics& g)
{
    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
}

void PopupMenuAudioProcessorEditor::resized()
{
	comboBox.setBounds(100, 100, 100, 20);
}

// ---- Handle Mouse Exit Event ----
void PopupMenuAudioProcessorEditor::mouseExit(const MouseEvent & event)
{
	comboBox.hidePopup();
}

#2

Your post title is pretty misleading - the issue here isn’t that hidePopup() isn’t working, it’s that the mouseExit() callback is not being called. You can easily verify this by setting a breakpoint in the method and seeing if it gets hit when your mouse leaves the plug-in editor when the combo box menu is open - it won’t and therefore the hidePopup() method is never being called.

“showPopup() works but isPopupActive() always returns false.” is also incorrect, if you just add a timer callback to your editor like so:

void NewProjectAudioProcessorEditor::timerCallback()
{
    if (comboBox.isPopupActive())
        DBG ("active");
}

and kick off a timer in the editor’s constructor, then you’ll see that when the popup is showing isPopupActive() returns true.

Anyway, the reason that your code isn’t working is that the combo box shows it’s popup modally and therefore mouse events to other components (ie your editor) are blocked by this line. In order to implement the behaviour that you are after, you could either subclass ComboBox and override its virtual showPopup() method to replace the popup menu with your own custom PopupMenu class which in turn overrides the virtual Component::canModalEventBeSentToComponent() method to allow modal events to be sent to your editor, or (much less complicated IMHO) you can do something like this in your editor:

//==============================================================================
PopupMenuAudioProcessorEditor::PopupMenuAudioProcessorEditor (PopupMenuAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p)
{
    setSize (400, 300);

	addAndMakeVisible(&comboBox);
	comboBox.addItem("Item 1", 1);
	comboBox.addItem("Item 2", 2);
	comboBox.setSelectedId(1);

	comboBox.addMouseListener(this, true);
}

PopupMenuAudioProcessorEditor::~PopupMenuAudioProcessorEditor()
{
}

void PopupMenuAudioProcessorEditor::paint (Graphics& g)
{
    g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
}

void PopupMenuAudioProcessorEditor::resized()
{
	comboBox.setBounds(100, 100, 100, 20);
}

void PopupMenuAudioProcessorEditor::mouseDown (const MouseEvent& e)
{
    if (comboBox.isPopupActive())
        startTimerHz (25);
}

void PopupMenuAudioProcessorEditor::timerCallback()
{
    if (! getScreenBounds().contains (Desktop::getInstance().getMousePosition()))
    {
        comboBox.hidePopup();
        stopTimer();
    }
}

#3

My fault!
Thank you for your fast help.

Well, I don’t know whether it would be helpfull if the modal ComboBox popup would close automatically as soon as the Plugin-Window has been left or is moved. But that would most likely limit other applications for it.


#4

Changing the ComboBox's behaviour isn’t something that we’d want to do as it’d silently break a lot of people’s existing code, but it should be relatively simple to implement that behaviour in your plug-in using the code I posted above.