imgui icon indicating copy to clipboard operation
imgui copied to clipboard

MenuItem close parent popups, making stacked popups difficult to use

Open ghost opened this issue 7 years ago • 6 comments

Version/Branch of Dear ImGui:

165

Back-end file/Renderer/OS: (or specify if you are using a custom engine back-end)

Back-ends: imgui_impl_win32cpp + imgui_impl_opengl3.cpp OS: win10 Compiler: XXX (if the question is related to building) visual studio 2017 My Issue/Question: (please provide context) I have a BeginPopupContextItem and inside have 3 MenuItem, which duplicate , rename and delete my rename will call BeginPopupModal with OpenPopup. however my BeginPopupModal, don't show up.

for below code i remove for tandalone, minimal, complete and verifiable example. which MenuItem contain only rename and just wnat to pop up the BeginPopupModal. Standalone, minimal, complete and verifiable example: (see CONTRIBUTING.md)

if (ImGui::BeginPopupContextItem("BeginPopupContextItem"))
{
	ImGui::PushItemWidth(-1);
	if (ImGui::MenuItem("Rename"))
	{
		ImGui::OpenPopup("OpenPopup");
	}
ImGui::PopItemWidth();
	if (ImGui::BeginPopupModal("OpenPopup"))
	{
		static char buf2[64] = "";
		ImGuiInputTextFlags text_flag1 = ImGuiInputTextFlags_None;
		ImGui::PushItemWidth(100);
		ImGui::Text("New Name:");
ImGui::SameLine();

ImGui::InputText("##EditorContentBrowser", buf2, 64, text_flag1, NULL, NULL);
		ImGui::PopItemWidth();
		Std::string new_name = buf2;
		ImGui::Separator();
		if (ImGui::Button("Apply", ImVec2(120, 0))) 
		{ 
			ImGui::CloseCurrentPopup(); 
		}
		ImGui::SetItemDefaultFocus();
		ImGui::SameLine();
		if (ImGui::Button("Cancel", ImVec2(120, 0))) 
		{ 					
			ImGui::CloseCurrentPopup(); 
		}
		ImGui::EndPopup();
	}
							
}

Screenshots/Video (you can drag files here)

ghost avatar Nov 19 '18 17:11 ghost

Please provide a standalone repro that demonstrate the issue with no unnecessary code.

ocornut avatar Nov 19 '18 17:11 ocornut

editted the code

ghost avatar Nov 19 '18 17:11 ghost

I had the same issue. The problem is that when you call OpenPopup the Context menu go away. So the popup is not shown. My solution was to create the popup in a different block. An example:

bool openMyPopup = false;
if (ImGui::BeginPopupContextItem("BeginPopupContextItem")) {
    if (ImGui::MenuItem("Rename")) {
        openMyPopup = true;
    }
    ImGui::EndPopup(); // <--- remember this
}
if (openMyPopup) {
    ImGui::OpenPopup("OpenPopup");
}
if (ImGui::BeginPopupModal("OpenPopup")) {
    // ...
    ImGui::EndPopup();
}

aarcangeli avatar Nov 20 '18 10:11 aarcangeli

@digiminteck This is a bit of a tricky issue due to how popups currently works. By default when pressing a Selectable or MenuItem inside a popup it automatically closes it, so the chain of events is:

Click "Rename" -> Will close context popup -> User code create new popup using the current context popup scope.

  1. The solution provided by @aarcangeli is one possible solution that works ok.
  2. The other solution is too NOT close the context menu when clicking rename, which you can currently only do by using imgui_internal.h undocumented API:
ImGui::PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
if (ImGui::MenuItem("Rename"))
{
    ImGui::OpenPopup("OpenPopup");
}
ImGui::PopItemFlag();

This needs to reworked into a more satisfying solution or at least into a way for the programmer to understand what's going on, because it can be confusing to understand what's going on there.

Here's your code reworked with it and with the EndPopup() call you omitted. (When you build a repro always try to test/paste it in another place of your code to make sure the repro is complete)

ImGui::Button("BUTTON");
if (ImGui::BeginPopupContextItem("BeginPopupContextItem"))
{
    ImGui::PushItemWidth(-1);
    ImGui::PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
    if (ImGui::MenuItem("Rename"))
    {
        ImGui::OpenPopup("OpenPopup");
    }
    ImGui::PopItemFlag();
    ImGui::PopItemWidth();

    if (ImGui::BeginPopupModal("OpenPopup"))
    {
        static char buf2[64] = "";
        ImGui::AlignTextToFramePadding();
        ImGui::Text("New Name:");
        ImGui::SameLine();

        ImGui::PushItemWidth(100);
        bool apply = ImGui::InputText("##EditorContentBrowser", buf2, 64, ImGuiInputTextFlags_EnterReturnsTrue, NULL, NULL);
        ImGui::PopItemWidth();
        ImGui::SetItemDefaultFocus(); // Unfortunately this doesn't activate the InputText as desirable, and SetKeyboardFocusHere() is currently a mess.
        //Std::string new_name = buf2;
        ImGui::Separator();
        apply |= ImGui::Button("Apply", ImVec2(120, 0));
        if (apply)
        {
            ImGui::CloseCurrentPopup();
        }
        ImGui::SameLine();
        if (ImGui::Button("Cancel", ImVec2(120, 0)))
        {
            ImGui::CloseCurrentPopup();
        }
        ImGui::EndPopup();
    }
    ImGui::EndPopup();
}

ocornut avatar Nov 21 '18 15:11 ocornut

thank is solve my issue with

ImGui::PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);

ngminteck avatar Nov 28 '18 17:11 ngminteck

FYI it is now possible to control auto-closure for Selectable, MenuItem() using the public API:

ImGui::PushItemFlag(ImGuiItemFlags_AutoClosePopups, false);
ImGui::MenuItem(....);
ImGui::PopItemFlags();

ocornut avatar Jul 30 '24 14:07 ocornut