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

Can't open a normal or modal popup inside a MenuBar + Menu inside it #5684

Closed
memory-hunter opened this issue Sep 15, 2022 · 2 comments
Closed
Labels
menus menu bars, menu items popups

Comments

@memory-hunter
Copy link

memory-hunter commented Sep 15, 2022

Version/Branch of Dear ImGui:

Version: 1.88
Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler: cl.exe
Operating System: Windows 10

My Issue/Question:

I am having an issue when trying to make a modal popup inside a Menu bar and a Menu inside it.
I had trouble making a normal popup straight away in the Menu bar, but #331 was of help, so that's fine.
I utilized the same way of making the popup but inside a Menu this time, doesn't seem to work.

Screenshots/Video

image
image

Standalone, minimal, complete and verifiable example:

static bool popup_prompts[] = {false, false};
ImGui::Begin("drinkKahvi", nullptr,
                 ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
                 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoSavedSettings);
    if (ImGui::BeginMenuBar()) {
        if (ImGui::BeginMenu("Settings")) {
            components::directory_modal_handle(popup_prompts[0]);
            if (ImGui::BeginMenu("Theme")) {
                if (ImGui::MenuItem("Dark")) {
                    ImGui::StyleColorsDark();
                }
                if (ImGui::MenuItem("Light")) {
                    ImGui::StyleColorsLight();
                }
                ImGui::EndMenu();
            }
            ImGui::EndMenu();
        }
        components::about_popup_handle(popup_prompts[1]);
        if (ImGui::MenuItem("Exit")) {
            glfwSetWindowShouldClose(win, true);
        }
        ImGui::EndMenuBar();
    }
    ImGui::End();

I have taken out the popup code in an outside header in inline blocks of function

inline void about_popup_handle(bool &open) {
        open = ImGui::MenuItem("About");
        if (open) {
            ImGui::OpenPopup("About");
            open = false;
        }
        ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 2, ImGui::GetIO().DisplaySize.y / 2),
                                ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
        if (ImGui::BeginPopup("About", ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::Text("drinkKahvi");
            ImGui::Separator();
            ImGui::Text("A simple KahviBreak entry exporter to .zip for curations");
            ImGui::Text("Made by: memoryhunter");
            ImGui::EndPopup();
        }
    }

    inline void directory_modal_handle(bool &open) {
        open = ImGui::MenuItem("KahviBreak directory");
        if (open) {
            ImGui::OpenPopup("KahviBreak directory");
            open = false;
        }
        ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 2, ImGui::GetIO().DisplaySize.y / 2),
                                ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
        if (ImGui::BeginPopup("KahviBreak directory", ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::Text("KahviBreak directory");
            ImGui::Separator();
            ImGui::Text("Please select the KahviBreak directory:");
            std::string directory{};
            ImGui::InputText("##KahviBreak directory", &directory);
            ImGui::EndPopup();
        }
    }
@PathogenDavid
Copy link
Contributor

The issue is that you're submitting the popup within the scope of the if statement for ImGui::BeginMenu("Settings"): As soon as the menu closes when you click the button, BeginMenu no longer returns true so your code for submitting the popup is no longer being executed.

Unfortunately this isn't as simple as moving your BeginPopup..EndPopup outside of the menu because OpenPopup(const char*) opens a popup in the current ID stack scope, and BeginMenu creates a new ID stack scope.

You can either use the OpenPopup(ImGuiID) overload instead (which uses an explicit unscoped ID) or you can keep track of the open state yourself and manually open it before you call BeginPopup. (For more detailed examples, see the last section of my comment here: #5468 (comment) starting with "However an issue you're likely to run into".)

@ocornut ocornut added popups menus menu bars, menu items labels Sep 15, 2022
@memory-hunter
Copy link
Author

memory-hunter commented Sep 15, 2022

The issue is that you're submitting the popup within the scope of the if statement for ImGui::BeginMenu("Settings"): As soon as the menu closes when you click the button, BeginMenu no longer returns true so your code for submitting the popup is no longer being executed.

Unfortunately this isn't as simple as moving your BeginPopup..EndPopup outside of the menu because OpenPopup(const char*) opens a popup in the current ID stack scope, and BeginMenu creates a new ID stack scope.

You can either use the OpenPopup(ImGuiID) overload instead (which uses an explicit unscoped ID) or you can keep track of the open state yourself and manually open it before you call BeginPopup. (For more detailed examples, see the last section of my comment here: #5468 (comment) starting with "However an issue you're likely to run into".)

Thank you a lot for the reply. Got it working. So, now I know to handle the popups outside the Begin()

Solution for others to look:

if (ImGui::BeginMenuBar()) {
        if (ImGui::BeginMenu("Settings")) {
            if (ImGui::MenuItem("KahviBreak directory")) {
                popups.kahvi_dir_popup = true;
            }
            if (ImGui::BeginMenu("Theme")) {
                if (ImGui::MenuItem("Dark")) {
                    ImGui::StyleColorsDark();
                }
                if (ImGui::MenuItem("Light")) {
                    ImGui::StyleColorsLight();
                }
                ImGui::EndMenu();
            }
            ImGui::EndMenu();
        }
        if (ImGui::MenuItem("About")) {
            popups.about_popup = true;
        }
        if (ImGui::MenuItem("Exit")) {
            glfwSetWindowShouldClose(win, true);
        }
        ImGui::EndMenuBar();
    }
    ImGui::End();
    if (popups.about_popup) {
        ImGui::OpenPopup("About");
    }
    components::about_popup_handle();
    if (popups.kahvi_dir_popup) {
        ImGui::OpenPopup("KahviBreak directory");
    }
    components::directory_modal_handle();
    ImGui::ShowDemoWindow();

I modified the components blocks this way:

inline void about_popup_handle() {
        ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 2, ImGui::GetIO().DisplaySize.y / 2),
                                ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
        if (ImGui::BeginPopup("About", ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::Text("drinkKahvi");
            ImGui::Separator();
            ImGui::Text("A simple KahviBreak entry exporter to .zip for curations");
            ImGui::Text("Made by: memoryhunter");
            ImGui::EndPopup();
        }
    }

    inline void directory_modal_handle() {
        ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 2, ImGui::GetIO().DisplaySize.y / 2),
                                ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
        if (ImGui::BeginPopup("KahviBreak directory", ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::Text("KahviBreak directory");
            ImGui::Separator();
            ImGui::Text("Please select the KahviBreak directory:");
            std::string directory{};
            ImGui::InputText("###KahviBreak directory", &directory);
            ImGui::EndPopup();
        }
    }

Just a slight change, to have every boolean named for each popup, instead of array, I created a struct with booleans named accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
menus menu bars, menu items popups
Projects
None yet
Development

No branches or pull requests

3 participants