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

How to open dialog box without ImGui::Button #19

Closed
traw opened this issue Jul 7, 2017 · 8 comments
Closed

How to open dialog box without ImGui::Button #19

traw opened this issue Jul 7, 2017 · 8 comments

Comments

@traw
Copy link

traw commented Jul 7, 2017

I am trying to open dialog box on pressing ImGui::MenuItem or by simple bool variable, but it doesn't work.

// Inside a ImGui window:
const bool browseButtonPressed = ImGui::Button("...");                          // we need a trigger boolean variable
static ImGuiFs::Dialog dlg;                                                     // one per dialog (and must be static)
const char* chosenPath = dlg.chooseFileDialog(browseButtonPressed);             // see other dialog types and the full list of arguments for advanced usage
if (strlen(chosenPath)>0) {
    // A path (chosenPath) has been chosen RIGHT NOW. However we can retrieve it later more comfortably using: dlg.getChosenPath()
}
if (strlen(dlg.getChosenPath())>0) {
    ImGui::Text("Chosen file: \"%s\"",dlg.getChosenPath());
}

// If you want to copy the (valid) returned path somewhere, you can use something like:
static char myPath[ImGuiFs::MAX_PATH_BYTES];
if (strlen(dlg.getChosenPath())>0) {
    strcpy(myPath,dlg.getChosenPath());
}
@Flix01
Copy link
Owner

Flix01 commented Jul 8, 2017

Well, as far as I can see, you have just copied what's written at the top of imguifilesystem.h, and you haven't explained the problem you've experiencing (you're just saying: it doesn't work). Your post is not very useful 😢 .

Anyway:

  • Have you tried to compile the first demo (examples/addon_examples/main.cpp) ? Does it work? It contains the following code:
        const char* startingFolder = "./";
        const char* optionalFileExtensionFilterString = "";//".jpg;.jpeg;.png;.tiff;.bmp;.gif;.txt";

        //------------------------------------------------------------------------------------------
        // 1 - ChooseFileDialogButton setup:
        //------------------------------------------------------------------------------------------
        ImGui::Text("Please choose a file: ");ImGui::SameLine();
        const bool browseButtonPressed = ImGui::Button("...");
        static ImGuiFs::Dialog fsInstance;
        const char* chosenPath = fsInstance.chooseFileDialog(browseButtonPressed,startingFolder,optionalFileExtensionFilterString);
        if (strlen(chosenPath)>0) {
            // A path (chosenPath) has been chosen right now. However we can retrieve it later using: fsInstance.getChosenPath()
        }
        if (strlen(fsInstance.getChosenPath())>0) ImGui::Text("Chosen path: \"%s\"",fsInstance.getChosenPath());

One thing that is worth noting is that the line with: fsInstance.chooseFileDialog(...) must be executed on every frame (modal dialogs in imgui can't just stop the main loop and wait for user selection).

@traw
Copy link
Author

traw commented Jul 8, 2017

Yes I just copied the same code, It works fine when There is ImGui::Button("...");, but when I modify code like following it doesn't work. You can note the usage of showDialog in line 1, 4 and 22.

if(showDialog)
    {
// Inside a ImGui window:
        const bool browseButtonPressed = showDialog;                          // we need a trigger boolean variable
        static ImGuiFs::Dialog dlg;                                                     // one per dialog (and must be static)
        const char* chosenPath = dlg.chooseFileDialog(browseButtonPressed);             // see other dialog types and the full list of arguments for advanced usage
        if (strlen(chosenPath)>0)
        {
            // A path (chosenPath) has been chosen RIGHT NOW. However we can retrieve it later more comfortably using: dlg.getChosenPath()
        }
        if (strlen(dlg.getChosenPath())>0)
        {
            ImGui::Text("Chosen file: \"%s\"",dlg.getChosenPath());
        }

// If you want to copy the (valid) returned path somewhere, you can use something like:
        static char myPath[ImGuiFs::MAX_PATH_BYTES];
        if (strlen(dlg.getChosenPath())>0)
        {
            strcpy(myPath,dlg.getChosenPath());
        }
        showDialog = false;
    }

@Flix01
Copy link
Owner

Flix01 commented Jul 8, 2017

While it's not clear to me what showDialog is, browseButtonPressed must be true only in a single frame, while dlg.chooseFileDialog(browseButtonPressed); must be called always (every frame). So if showDialog is set so that it's correctly true only in a single frame, you should try removing the if statement at line 1, so that dlg.chooseFileDialog(browseButtonPressed); is always called.
Maybe something like:

        static ImGuiFs::Dialog dlg;                                                     // one per dialog (and must be static)
        const char* chosenPath = dlg.chooseFileDialog(showDialog);             // see other dialog types and the full list of arguments for advanced usage
        if (strlen(chosenPath)>0)
        {
            // A path (chosenPath) has been chosen RIGHT NOW. However we can retrieve it later more comfortably using: dlg.getChosenPath()
        }
        if (strlen(dlg.getChosenPath())>0)
        {
            ImGui::Text("Chosen file: \"%s\"",dlg.getChosenPath());
        }
    if (showDialog) showDialog=false;

@traw
Copy link
Author

traw commented Jul 9, 2017

Thanks it' working now. With changes you suggested. Just little doubt why static ImGuiFs::Dialog dlg; need to static?

Note for Future reference:

browseButtonPressed must be true only in a single frame, while dlg.chooseFileDialog(browseButtonPressed); must be called always (every frame).

@Flix01
Copy link
Owner

Flix01 commented Jul 9, 2017

why static ImGuiFs::Dialog dlg; need to static?

Well, it can't be a local variable, because it keeps a lot of state variables inside (for example the navigation history while the dialog is open). [Obviously, it can be a global variable too].

browseButtonPressed must be true only in a single frame, while dlg.chooseFileDialog(browseButtonPressed); must be called always (every frame).

Yes. One thing that is worth noting is that the line with: fsInstance.chooseFileDialog(...) must be executed on every frame (modal dialogs in imgui can't just stop the main loop and wait for user selection).

@Flix01 Flix01 closed this as completed Jul 9, 2017
@tolstenko
Copy link

tolstenko commented Apr 12, 2018

Hello there, I have similar question here. Could you kindly provide me an example using chooseFileDialog inside BeginMenu as menuitem, instead of a button?

Here is my ugly solution, it works, but the selection area is smaller than the others MenuItems:

if (ImGui::BeginMenu("File"))
  {
    ImGui::PushStyleColor(ImGuiCol_Button,ImVec4(0,0,0,0));
    const bool browseButtonPressed = ImGui::Button("Open...");
    static ImGuiFs::Dialog dlg;
    const char* chosenPath = dlg.chooseFileDialog(browseButtonPressed, nullptr, nullptr);
    ImGui::PopStyleColor(1);
    ImGui::EndMenu();
}

@Flix01
Copy link
Owner

Flix01 commented Apr 12, 2018

I'd do something like:

        bool browseButtonPressed = false;
        if (ImGui::BeginMenu("File"))   {
            browseButtonPressed = ImGui::MenuItem("Open...", "CTRL+O");
            ImGui::EndMenu();
        }
        static ImGuiFs::Dialog dlg;
        const char* chosenPath = dlg.chooseFileDialog(browseButtonPressed);

Does it work better or not ?

@tolstenko
Copy link

That's awesome! Thank you!

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

No branches or pull requests

3 participants