ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
61.02k stars 10.28k forks source link

Could not open popup from a menu bar #1422

Closed Jimmyee closed 6 years ago

Jimmyee commented 7 years ago

Good afternoon. As title of this thread says... I click one of menu items that is intended to open a popup and nothing happens. Here's my code:

void MapEditor::GUI()
{
    S &s = S::GetInstance();

    if(!ImGui::Begin("Map editor", 0, ImGuiWindowFlags_MenuBar | ImGuiWindow)) { return; }

    if(ImGui::BeginMenuBar())
    {
        if(ImGui::BeginMenu("File"))
        {
            if(ImGui::MenuItem("New"))
            {
                ImGui::OpenPopup("FilePopup");

                if (ImGui::BeginPopup("FilePopup"))
                {
                    ImGui::Button("Test");
                    ImGui::EndPopup();
                }
            }

            if(ImGui::MenuItem("Load...")) {}
            if(ImGui::MenuItem("Save...")) {}
            if(ImGui::MenuItem("Save As...")) {}
            if(ImGui::MenuItem("Exit")) {}

            ImGui::EndMenu();
        }

        ImGui::EndMenuBar();
    }

    ImGui::End();
}

// and this is how MapEditor::GUI is executed:
void GUI::Process()
{
    S &s = S::GetInstance();
    if(this->state == State::Editor)
    {
        s.map_editor->GUI();
    }
}
ocornut commented 7 years ago

After you click the MenuItem the menus will be closed so your code will stop executing...

You want the BeginPopup code to be always executing. Also be aware that due to how the id-stack works you currently need the id-stack-location of OpenPopup to match the location BeginPopup(). See #331 or generally use the search engine with “popup” “menu” etc.

Jimmyee commented 7 years ago

Solved. Here's the code that works for me:

void MapEditor::GUI()
{
    S &s = S::GetInstance();

    std::string menu_action = "";
    if(ImGui::BeginMainMenuBar())
    {
        if(ImGui::BeginMenu("File"))
        {
            if(ImGui::MenuItem("New")) menu_action = "New";
            if(ImGui::MenuItem("Load...")) menu_action = "Load";
            if(ImGui::MenuItem("Save...")) menu_action = "Save";
            if(ImGui::MenuItem("Save As...")) menu_action = "SaveAs";
            if(ImGui::MenuItem("Exit")) menu_action = "Exit";

            ImGui::EndMenu();
        }

        ImGui::EndMainMenuBar();
    }

    if(menu_action == "New") ImGui::OpenPopup("New");
    if(menu_action == "Load") ImGui::OpenPopup("Load");
    if(menu_action == "Save")
    {
        if(s.map.get())
        {
            if(s.map->id == 0) ImGui::OpenPopup("SaveAs");
            else if(s.map->id > 0) s.map->Save();
        }
    }
    if(menu_action == "SaveAs" && s.map.get()) ImGui::OpenPopup("SaveAs");
    if(menu_action == "Exit") s.gui->SetState(GUI::State::MainMenu);

    if (ImGui::BeginPopup("New"))
    {
        static int i_id = 1;
        static int i_w = 1;
        static int i_h = 1;
        static int i_fill = 0;
        static char str_name[128] = "";

        ImGui::Text("Create new map.");

        ImGui::InputInt("ID", &i_id);
        ImGui::InputText("Name", str_name, IM_ARRAYSIZE(str_name));
        ImGui::InputInt("Width", &i_w);
        ImGui::InputInt("Height", &i_h);
        ImGui::InputInt("Fill tile", &i_fill);

        if(ImGui::Button("Create"))
        {
            s.map.reset();
            s.map = std::make_unique<Map>();
            s.map->id = i_id;
            s.map->name = str_name;
            s.map->width = i_w;
            s.map->height = i_h;
            s.map->fill_tile = i_fill;
            ImGui::CloseCurrentPopup();
        }
        ImGui::SameLine();
        if(ImGui::Button("Cancel")) ImGui::CloseCurrentPopup();

        ImGui::EndPopup();
    }
    if(ImGui::BeginPopup("Load"))
    {
        static int i_id = 1;

        ImGui::Text("Load map.");
        ImGui::InputInt("ID", &i_id);
        if(ImGui::Button("Load"))
        {
            s.map.reset();
            s.map = std::make_unique<Map>(i_id);
            if(!s.map->Exists())
            {
                s.map.reset();
                menu_action = "ErrorLoad";
            }
            else ImGui::CloseCurrentPopup();
        }

        if(menu_action == "ErrorLoad") ImGui::OpenPopup("ErrorLoad");

        if(ImGui::BeginPopupModal("ErrorLoad", NULL, ImGuiWindowFlags_NoResize))
        {
            ImGui::Text("Could not load map file of given ID.");
            if(ImGui::Button("OK")) ImGui::CloseCurrentPopup();

            ImGui::EndPopup();
        }
        if(ImGui::Button("Cancel")) ImGui::CloseCurrentPopup();

        ImGui::EndPopup();
    }
    if (ImGui::BeginPopup("SaveAs"))
    {
        if(s.map.get())
        {
            static int i_id = s.map->id;

            ImGui::InputInt("ID", &i_id);
            if(ImGui::Button("Save"))
            {
                s.map->Save();
                ImGui::CloseCurrentPopup();
            }
            ImGui::SameLine();
            if(ImGui::Button("Cancel")) ImGui::CloseCurrentPopup();
        }
        ImGui::EndPopup();
    }
}