Popup Menu: unclickable state


#1

Popup Menus can get into a state where the items in the menu are unclickable.

It usually happens when the sub menu opens to the right and then the sub-sub menu opens to the left. Trying to move over the sub-sub menu causes it to close immediately.

In the attached picture, MidiXbar01a (synth) can’t be clicked on, depending in what position the menu opens.

I’m looking into it more to see if I can find out where it’s going wrong.


#2

isOverAnyMenu() is failing, when it is definitely over a menu


#3

That’s really odd… I’ll have to see if I can reproduce it.


#4

With the following code on a 1280x1024 monitor, i can reproduce it 1 in 10 times. The way the users are complaining, it sounds like for some people it happens every time.

[code]#include “stdafx.h”

class AwesomeComponent : public Component
{
public:
AwesomeComponent()
{
}

~AwesomeComponent()
{
}


void paint(Graphics& g)
{
	g.setColour(Colours::black);
	g.drawText(T("...click here...."), 0, 0, getWidth(), getHeight(), Justification::centred, true);
}

void mouseDown(const MouseEvent& e)
{
	PopupMenu m;

	for (int i = 0; i < 10; i++)
		m.addItem(1, T("ignore this item"));

	PopupMenu subsub;
	subsub.addItem(2, T("just try and click this one"));

	PopupMenu sub;
	sub.addSubMenu(T("test"), subsub);

	m.addSubMenu(T("test"), sub);

	for (int i = 0; i < 80; i++)
		m.addItem(1, T("ignore this item"));

	m.showAt(getWidth() - 200, 100);
}

};

class MyApplicationWindow : public DialogWindow
{
public:
MyApplicationWindow() : DialogWindow(T(“Hullo”), Colours::wheat, true)
{
Rectangle rc = Desktop::getInstance().getMainMonitorArea();
setBounds(rc);
setVisible(true);

	setContentComponent(new AwesomeComponent());
}

~MyApplicationWindow()
{
}

void closeButtonPressed()
{
	JUCEApplication::quit();
}

};

class MyJUCEApp : public JUCEApplication
{
MyApplicationWindow* myMainWindow;

public:
MyJUCEApp() : myMainWindow (0)
{
}

~MyJUCEApp()
{
}

void initialise (const String& commandLine)
{
	myMainWindow = new MyApplicationWindow();
}

void shutdown()
{
	delete myMainWindow;
}

const String getApplicationName()
{
	return T("Super JUCE-o-matic");
}

const String getApplicationVersion()
{
	return T("1.0");
}

};

START_JUCE_APPLICATION (MyJUCEApp)[/code]


#5

Well that was a tough one! Thanks for the test code, I did get it to happen with that… Here’s what I think fixes it:

Add a new method to the PopupMenuWindow class:

    void updateMouseOverStatus (const int mx, const int my) throw()
    {
        int rx = mx, ry = my;
        globalPositionToRelative (rx, ry);
        isOver = reallyContains (rx, ry, true);

        if (activeSubMenu != 0)
            activeSubMenu->updateMouseOverStatus (mx, my);
    }

And tweak it here in timerCallback():

        const bool wasDown = isDown;
        bool isOverAny = isOverAnyMenu();

        if (hideOnExit && hasBeenOver && (! isOverAny) && activeSubMenu != 0)
        {
            activeSubMenu->updateMouseOverStatus (mx, my);
            isOverAny = isOverAnyMenu();
        }

        if (hideOnExit && hasBeenOver && ! isOverAny)
        {
            hide (0);

#6