PopupMenu under button

I’m using showAt for showing PopupMenu under the button.
Is there are way to get the same functionality with the showMenuAsync?

You can use Options::withTargetScreenArea or Options::withTargetComponent to specify the location of the popup menu.

Thanks, but with Options::withTargetComponent it will show up where the cursor is, not uniformly under the button, and for Options::withTargetScreenArea how to find a screen coordinate of my button?

Can you show the code you’re using? withTargetComponent should position the menu directly next to the target component.

You are right, withTargetComponent behave exactly like showAt.
Code I’m using:
m.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(menuButton), juce::ModalCallbackFunction::forComponent(menuInvocationCallback, this));

I’m not sure why the behavior was different before.
Thank you

I have a similar requirement and face the similar problem. Now the popup opens at the position of the mouse-click. We used to have more flexibility with the positioning.

I see there’s an option for withTargetScreenArea, but how do we know beforehand the size of the popup?

I think withTargetScreenArea defines an area directly adjacent to the menu. It’s not the area of the menu itself.

If you pass the area of a button to withTargetScreenArea, then the menu find the best location to display that is next to the button.

I’m trying that, but somehow the rectangle I am passing gets its width and height set to 0 and then the default (cursor) position is used.

Can you post the code you’re using? It’s difficult to say what the problem might be without knowing exactly what you’re doing.

    PopupMenu m;
    m.addItem(PopupMenu::Item ("Item 1").setAction ([this] {
        // action 1
    }));
    m.addItem(PopupMenu::Item ("Item 2").setAction ([this] {
        // action 2
    }));
    m.addItem(PopupMenu::Item ("Item 3").setAction ([this] {
        // action 3
    }));

    PopupMenu::Options options;
    options.withTargetScreenArea(Rectangle<int>(10, 200, 2, 2));
    m.showMenuAsync(options);

I tried with a random positioning on screen before using more specific coordinates.

Options::withTargetScreenArea returns a new Options instance with the requested property.

You could write the above as:

m.showMenuAsync (PopupMenu::Options{}.withTargetScreenArea ({ 10, 200, 2, 2 }));

Oh, indeed. Thanks for the hint. Works perfectly.

We’ve now added a NODISCARD macro on some of these “builder”-style function calls:

If you are building in C++17 mode, the compiler should now emit a warning when the result of one of these function calls goes unused.

1 Like