Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popup menu right click behavior #439

Closed
ghost opened this issue Dec 14, 2015 · 11 comments
Closed

Popup menu right click behavior #439

ghost opened this issue Dec 14, 2015 · 11 comments

Comments

@ghost
Copy link

ghost commented Dec 14, 2015

Hi

I try to open a context menu, the first time I "right click" it open, so it is ok.

The next time I right click at another position, the current menu stay open and the menu does not re-open at the new position. How to fix that ? It should be the default behaviour (Just try with a right click on your browser by example).

    if (ImGui::BeginPopupContextWindow())
    {
        if (ImGui::MenuItem("New camera"))
        {
        }

        ImGui::EndPopup();
    }
@thennequin
Copy link

Until better solution

#include "imgui_internal.h"
if (ImGui::GetIO().MouseClicked[1])
{
    ImGuiState& g = *GImGui;
    if (g.OpenedPopupStack.size() > 0)
        g.OpenedPopupStack.pop_back();

    ImGui::OpenPopup("test");
}

@ghost
Copy link
Author

ghost commented Dec 14, 2015

Thanks a lot ;-)

@ghost ghost closed this as completed Dec 18, 2015
@ocornut
Copy link
Owner

ocornut commented Dec 18, 2015

I'll keep this open as I would like to fix that in the core library eventually!

@ocornut ocornut reopened this Dec 18, 2015
@ocornut
Copy link
Owner

ocornut commented Dec 20, 2015

I have a little problem here, I can make subsequent calls to OpenPopup() recreate the popup but that would break cases of people calling OpenPopup every frame.. Of course that later pattern already had issues and wasn't recommended so breaking it more severely may be desirable? I'm just not sure of the side effects in real codebases.

Plan B is to add an additional parameter to OpenPopup bool reopen_existing = false and the BeginPopupContext functions would enable this option.

Looking into this.

@ghost
Copy link
Author

ghost commented Dec 20, 2015

My 2 cents is that you current version logic is good, so an additional parameter for "special cases" like popup menu looks to be the less destructive and more flexible one. If needed, later you can just switch the default value of this flag !

@ocornut
Copy link
Owner

ocornut commented Dec 20, 2015

EDIT
There's actually another problem, functions like IsItemHovered() which are used in e.g. BeginPopupContextItem always return false when hovering windows behind the popup, aka most certainly the item that opened the popup in the first place.

So while BeginPopupContextItem() could query the Hovered information in another way it would introduce some inconsistency with the api - e.g. the underlying button wouldn't appear hovered but right-click still functions? I'll need to think about different use cases a little more.

ocornut added a commit that referenced this issue Dec 20, 2015
ocornut added a commit that referenced this issue Dec 20, 2015
@ocornut
Copy link
Owner

ocornut commented Dec 20, 2015

I made it work for BeginPopupContextWindow and BeginPopupContextVoid but not for BeginPopupContextItem, that third one would probably need an extra parameter. Not happy about adding an extra boolean at the end considering BeginPopupContextWindow has a boolean at the first parameter. Boolean parameters in API are truly a mistake :/

I think it's mostly useful for those two cases and a little less so for BeginPopupContextItem() but I can definitively see cases what that would also be useful.

@ocornut
Copy link
Owner

ocornut commented Dec 20, 2015

Added the following comment to BeginPopupContextItem()

// This is a helper to handle the most simple case of associating one named popup to one given widget.
// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling 
//    this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers.
// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect().
//    Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that 
//    the item isn't interactable (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu
//    driven by click position.
bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button)
{
    if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(mouse_button))
        ImGui::OpenPopupEx(str_id, false);
    return ImGui::BeginPopup(str_id);
}

I think it is reasonable to say that the function is an optional helper and more intricate behaviour can be assembled by doing it manually. I added declared OpenPopupEx() in imgui_internal.h now because I don't want to take the decision right away of whether adding the additional boolean flag is a future proof solutions (boolean rarely are). I could either decide that OpenPopupEx() become public API (as is, or with modifications) either add a new entry point aside from BeginPopupContextItem to specify the different behaviour. I think we could decide on that later and with the latest commit the situation is at least unblockable.

Let me know!

@ocornut
Copy link
Owner

ocornut commented Dec 21, 2015

// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect().

should be:

// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect()
//    and passing true to the OpenPopupEx().

Will turn that into a public thing later.

@ocornut ocornut closed this as completed Jan 26, 2016
@ocornut ocornut added the popups label Aug 16, 2017
ocornut added a commit that referenced this issue Oct 20, 2017
ocornut added a commit that referenced this issue Oct 20, 2017
… more specific behavior. Will enable improvements for popups/context menus and drag'n drop. (relate ~#439, #1013, #143, #925)

The legacy confusing IsItemRectHovered(), IsWindowRectHovered() can be completely removed now.
Changed IsWindowHovered() behavior with default parameter: it now return false is the window is blocked by a popup.
Demo: Added tests for those two functions.
ocornut added a commit that referenced this issue Oct 20, 2017
…duced IsItemHovered() flags to allow reopening another context menu (over same or not same item) with right-click. (#439) (+1 squashed commits)
ocornut added a commit that referenced this issue Oct 20, 2017
…ne level of popups in a popups stack won't close the whole stack. This is done by properly refocusing the lower level popup. Fixes 87ae408 (~#439)
ocornut added a commit that referenced this issue Oct 20, 2017
… a popup stack from truncating the whole stack. This is done by properly refocusing the lower level popup. (~#439)
@ocornut
Copy link
Owner

ocornut commented Oct 20, 2017

FYI @ghost @thennequin the current version has this supported by BeginPopupContextWindow().

ocornut added a commit that referenced this issue Jan 7, 2018
…ContextVoid(), OpenPopupOnItemClick() all react on mouse release instead of mouse click. Note that they don't use the full ButtonBehavior() or tracking aabb on both click and release. Applications I've tried seems to behave inconsistently there but on-release-without-tracking is both fairly common and doesn't require extra code for the id tracking. (~#439)
ocornut added a commit that referenced this issue Jan 7, 2018
…d a default. 2) The if is definitively faulty and would have been all true. 3) It looks like possibly the following commit 6ab737a could have made this unnecessary. Not absolutly certain. (~#439)
@ocornut
Copy link
Owner

ocornut commented Jun 15, 2020

Dear journal,

Interestingly, today I noticed that this old commit in 63e4677, effectively changing IsMouseClicked(1) to IsMouseReleased(1) in the BeginPopupContextxxx functions, as a side-effect made the ImGuiHoveredFlags_AllowWhenBlockedByPopup flag unnecessary in most situation when dealing with context menus, since right-mouse-down will close popups, and right-mouse-up will reopen a new one.

It's quite convenient as I was trying to solve a small puzzle when custom context menu handling in Tables, and the fact that ImGuiHoveredFlags_AllowWhenBlockedByPopup isn't actually required for context menus really simplified the problem for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants