AirGuanZ / imgui-filebrowser

File browser implementation for dear-imgui. C++17 is required.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Selecting items in dialog under linux

MarkusWalzth opened this issue · comments

Hi,

I encounter an issue compiling your library under Ubuntu 18.04. I use the latest version of dear imgui and glfw + opengl3 implementation. Integrating the lib, compiling and everything worked as a charm. also calling and opening the dialog-windows works pretty fine. But here my problem starts: I am not able to select anything. Double-clicking on folders changes the text on the "OK"-Button to "open", but a frame later it disappears again and "OK" is the text again.
Finally clicking in "OK" gives back as "selected" the absolute folder path of the folder, in which the application is started.

I tried compiling it with clang-9.0.1 and gcc-9.0.1.

Here is my code:

#include <iostream>

// dear imgui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)

#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <imfilebrowser.h>
#include <stdio.h>

// About Desktop OpenGL function loaders:
//  Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
//  Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
//  You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h> // Initialize with glewInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> // Initialize with gladLoadGL()
#else
#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif

// Include glfw3.h after our OpenGL definitions
#include <GLFW/glfw3.h>

// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers.
// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma.
// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio.
#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
#pragma comment(lib, "legacy_stdio_definitions")
#endif

static void glfw_error_callback(int error, const char *description)
{
    fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}

int main(int, char **)
{
    // Setup window
    glfwSetErrorCallback(glfw_error_callback);
    if (!glfwInit())
        return 1;

    // GL 3.0 + GLSL 130
    const char *glsl_version = "#version 130";
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 3.2+ only
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);            // 3.0+ only

    // Create window with graphics context
    GLFWwindow *window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", NULL, NULL);
    if (window == NULL)
        return 1;
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1); // Enable vsync

    // Initialize OpenGL loader
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
    bool err = gl3wInit() != 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
    bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
    bool err = gladLoadGL() == 0;
#else
    bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to requires some form of initialization.
#endif
    if (err)
    {
        fprintf(stderr, "Failed to initialize OpenGL loader!\n");
        return 1;
    }

    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO &io = ImGui::GetIO();
    (void)io;
    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
    //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls

    // Setup Dear ImGui style
    ImGui::StyleColorsDark();
    //ImGui::StyleColorsClassic();

    // Setup Platform/Renderer bindings
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init(glsl_version);

    // Our state
    bool show_demo_window = true;
    bool show_another_window = true;
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);

    // Main loop
    while (!glfwWindowShouldClose(window))
    {
        // Poll and handle events (inputs, window resize, etc.)
        // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
        // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
        // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
        // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
        glfwPollEvents();

        // Start the Dear ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // create a window for an iamge
        {

            bool show_bar_file_open = false;
            bool show_bar_file_save = false;
            bool show_bar_file_saveas = false;
            bool show_bar_file_close = false;

            ImGuiWindowFlags window_flags = 0;
            window_flags |= ImGuiWindowFlags_MenuBar;

            ImGuiFileBrowserFlags openFileDialogFlags = 0;
            openFileDialogFlags |= ImGuiFileBrowserFlags_SelectDirectory;
            openFileDialogFlags |= ImGuiFileBrowserFlags_CloseOnEsc;
            openFileDialogFlags |= ImGuiFileBrowserFlags_EnterNewFilename;
            openFileDialogFlags |= ImGuiFileBrowserFlags_CreateNewDir;

            ImGui::FileBrowser openFileDialog(openFileDialogFlags);

            // (optional) set browser properties
            openFileDialog.SetTitle("Open ...");
            // openFileDialog.SetTypeFilters({".png", ".jpg", ".jpeg", ".bmp"});

            bool p_open = true;

            ImGui::Begin("FilterApplier", &p_open, window_flags);

            ImGui::PushItemWidth(ImGui::GetFontSize() * -12);

            // Menu Bar
            if (ImGui::BeginMenuBar())
            {
                if (ImGui::BeginMenu("File"))
                {
                    ImGui::MenuItem("Open", NULL, &show_bar_file_open);
                    ImGui::MenuItem("Save", NULL, &show_bar_file_save);
                    ImGui::MenuItem("Save as..", NULL, &show_bar_file_saveas);
                    ImGui::MenuItem("Close", NULL, &show_bar_file_close);
                    ImGui::EndMenu();
                }
                if (ImGui::BeginMenu("Tools"))
                {
                    ImGui::EndMenu();
                }

                ImGui::EndMenuBar();
            }

            if (show_bar_file_open)
            {
                openFileDialog.Open();
                // show_bar_file_open = false;
                std::cout << "Clicked open dialog" << std::endl;
            }

            openFileDialog.Display();

            if (openFileDialog.HasSelected())
            {
                std::cout << "Selected filename " << openFileDialog.GetSelected().string() << std::endl;
                openFileDialog.ClearSelected();
            }
            ImGui::End();
        }

        // Rendering
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

Hi,
Try to move the ImGui::FileBrowser openFileDialog(openFileDialogFlags) out of the mainloop. Defining it inside the loop will create a new browser instance every frame.

#include <imgui.h>
#include <imfilebrowser.h>

int main()
{
    //...initialize

    // create a file browser instance
    ImGui::FileBrowser openFileDialog(openFileDialogFlags);
    openFileDialog.SetTitle("Open ...");
    
    // mainloop
    while(!glfwWindowShouldClose(window))
    {
        //...
    }

    //...cleanup
}

Yeah! Thats it. Sry for bothering you with something that trivial (on second sight).

Thx for your wrk on the dialog-window!

Greetz Markus