This is not really an issue.
It's just something I've been making for the last couple of weeks.
It's not finished yet (I think I could make a pull request or something like that when I'll stop working on it, probably in a week or two).
I'd just like to know if there is already something like that in some ImGui roadmap, if the maintainer has some interest in it, and if and how it could be merged with the main ImGui code (a separate adding folder ? or should we merge all the code inside imgui.h/imgui.cpp ?).
Also I'm facing a lot of issues with the code:
-> it needs a "string" and a "stringVector" class. Currently I use STL string and vector
-> I use Ascii methods to separate '/','\','.' chars from strings: that means that multibyte paths that contain these characters won't work as expected.
-> My coding is very dirty and rough compared to the ImGui standard. Also the implementation is not robust enough and it could contain memory leaks (for these I'm confident that ImGui users will help fixing them).
Currently I'm testing my code on Ubuntu 64bit and Wine (through Mingw32). It seems to work.
It uses direct.h (no additional dependency on any system). Only Visual C++ does not ship it by default, so I'll include it for Windows users (to be honest my old version of Mingw32 includes an incomplete version of this file: another reason for adding it).
Please tell me what you think about this topic and what should I do with the code.
Early screenshot

It would be nice having an example showcasing this type of UI but it would need to be clean code, clean visual and avoid extra dependencies. Why do you need a string class in the first place? Why the odd font and coloring in your example?
By the look of it and your question (use of a string class) my gut feeling is that the code won't be suited for integration in imgui.cpp. Also it may naturally be "too big" to include (I can imagine that a nice file browser ui may have lots of features). However, what we should improve as a community is a way to share uncurated code and example of different way to use ImGui. In this context your code sample could be shared so others can reuse it or improve it. There is a lack of sample code using ImGui at the moment. I myself wrote a fair amount of tools in my old company but unfortunately haven't got to release screenshots or code for them. Now writing new tools for a new job so I'll see what I can publish.
ImGui currently lack a concept of selectable items (and multi-selection), keyboard navigation, etc. Those thing would made a file selector better. I understand you are using buttons here. Perhaps the button could be fixed size? I would add a text filter personally.
ImGui only manipulate and should be fed UTF-8, so your Ascii methods will work on that.
PS: for now you could post your code as a gist so we can look and comment on it!
https://gist.github.com/
Also unfortunately dirent.h is not portable under normal MSVC/Windows. Bit of a tragedy that in 2014 there isn't a portable API to list directory.
The function static char **readdir_raw(char *dir, int return_subdirs, char *mask)
In https://github.com/nothings/stb/blob/master/stb.h
Does that using ifdefs.
Why the odd font and coloring in your example?
That's just a wip screenshot: that font is the one I'm currently using, and it includes the euro '€' glyph, so that I can test the correct handling of UTF8 multi-byte characters in file paths.
The coloring is something I changed because directories should be yellow and files gray and because the split-path string at the top now looks better... but all these are details for me...
Why do you need a string class in the first place?
Because it would be too difficult for me otherwise. Probably a good programmer could just use char* strings and ImVector (or maybe just a concatenation of zero terminated chars ending with '\0\0' to simulate a stringVector): but that's too much work for me!
What I think I could do is to hide the string and stringVector classes in the implementation, leaving a string-free API, so that if somebody feels brave enough, he can later change the implementation without breaking existent code. However I'm still evalutating if this is something good or not.
ImGui currently lacks a concept of selectable items (and multi-selection), keyboard navigation, etc. Those thing would made a file selector better. I understand you are using buttons here. Perhaps the button could be fixed size? I would add a text filter personally.
Yes, I'm using buttons and I'm just at the beginning... I can't make multi-selectable entries because I can't catch single/double clicks and detect the CTRL key pressure on buttons, so I've just limited it to single file selections (and you're right: more base controls inside Imgui would simplify this task). Also text filters should be useful here (I've seen that some windows in the imgui demo have some sort of text filtering: I'll see if that can help me).
ImGui only manipulate and should be fed UTF-8, so your Ascii methods will work on that.
Well, I'm not sure about it. What I mean is that I use ASCII methods to separate path parts, so that for example:
/home/user/Desktop/MyDirectory€One/Myfile.text
becomes the 6 strings:
/ home user Desktop MyDirectory€One Myfile.text
Now suppose that the (multibyte) euro glyph contains a '/' character inside it (this is NOT the case).
With ASCII processing we would end up with an additional split inside MyDirectory€One.
However solving this problem is not a priority for me, as it's going to affect only a very few multibyte characters I guess.
Also unfortunately dirent.h is not portable under normal MSVC/Windows.
I'm currently using this port: http://softagalleria.net/dirent.php
The only problem is that the scandir method is missing (but I've found a good replacement in the (MIT licensed) musl library code).
However I'm currently having another issue with the Windows version: when I use long paths they end up shortened up in a very bad way (although I can seem to be able to navigate inside them). This does not happen in Ubuntu.
Another possible problem is that if something works under Wine, it is not guaranteed to work under a real Windows system. But I can't do anything about it, so it's not my problem.
As you can see, I'm still far away from a portable and usable implementation.
PS: for now you could post your code as a gist so we can look and comment on it!
https://gist.github.com/
I'll consider https://gist.github.com/ then.
Here is the source code: https://gist.github.com/Flix01/f34b5efa91e50a241c1b
It's composed by three files:
It needs testing and feedback (expecially for Windows/VisualC++ and MacOS).
It does not use any C++ string class: so it should be straightforward to merge its code
into imgui.h/imgui.cpp if we want to (and if the code is robust enough).
P.S. I suggest we can just have an addon system like the following:
#ifdef IMGUI_ADDON_FILESYSTEM
#include "./addons/imguifilesystem/imguifilesystem.h"
#endif //IMGUI_ADDON_FILESYSTEM
#ifdef IMGUI_ADDON_FILESYSTEM
#include "./addons/imguifilesystem/imguifilesystem.cpp.inl"
#endif //IMGUI_ADDON_FILESYSTEM
Now, in client code, we should be able to use the addon by defining IMGUI_ADDON_FILESYSTEM
at the project label, without including any additional folder and compiling any additional file, and
without polluting or breaking the imgui.h/.cpp files (by default all the addons definitions should NOT be defined).
What do you think about it ?
Wow - that's a lot of code!
Some rough feedback:
Your screenshot

I don't think this can be made part of an imgui distribution at the moment, it is too custom and a big verbose. But again we need to provide a way to share user's code for people to grab.
I may have a go at writing a file open/save dialog at some point to see the challenge in making a standard-looking dialog. I would want to make something that as close as possible as the windows dialog, could be helpful for non-standard OSes.
Thanks for your quick feedback!
However, first of all I have to say that my main concern is to have some feedback from some "pure" Windows user (and possible issues about compiling with cl.exe): have somebody tried it yet?
Now:
Why is there such system to setup the dialog style? Couldn't it inherit the normal ImGui styling? There's lots of code for that at the moment.
Well, it's just because there are new controls. You can see that at the top of the screen and in the "sorting" section there are some buttons that expose a kind of tab-like functionality: all these components have their own style. Another reason is that the buttons that display directory and file names must have a different colouring, and that is exposed in the style section too.
Why adding a ImCustomVector? I'll switch to using protected instead of private for ImVector if that's helpful, that's not a relevant issue. Not sure what you are doing with this push_back() that couldn't be done from outside.
Well, then just go ahead and replace ImCustomVector with ImVector. It won't work. If the vector has an array of chars as elements, I can't just use a normal push_back(), because of the lack of an assignment operator. Here is an example to understand it better:
int main() {
const char tmp[4]= "a\0";
char tmp2[4];
tmp2 = tmp; // gcc: error: invalid array assignment
//clang: error: array type 'char [4]' is not assignable
return 0;
}
stat() is a costly call it's probably not a good idea to do it in the comparer function for multiple sort. You probably want to cache the info somehow.
Yes, I've wriitten it as a comment in the source code: but in my tests this did not cause any delay, since actually what happens is that the file data gets cached (the info are stored somewhere and reused, the disk is NOT accessed on every call). So I'll consider caching the data myself only if somebody really experiences a slowdown. Also note that sorting is done only the frame one clicks on the sorting buttons: waiting some fraction of second shouldn't be too harmful.
For the "File" bit of text that aligned too high, call ImGui::AlignFirstTextHeightToWidgets() once.
Thanks, I'll do it [UPDATE: done].
Your screenshot
Wow! I thought it got lost forever! Where did you find it ?
I don't think this can be made part of an imgui distribution at the moment, it is too custom and a big verbose. But again we need to provide a way to share user's code for people to grab.
I may have a go at writing a file open/save dialog at some point to see the challenge in making a standard-looking dialog. I would want to make something that as close as possible as the windows dialog, could be helpful for non-standard OSes.
Ok then. I just would like filesystem dialogs to be part of the library, but I don't care if you use my version or you roll up your own.
I'm sure that many people that use ImGui for some kind of editor need this functionality.
ImGui probably needs a "selected" button concept so buttons can be used the same way as radio buttons. This is actually something that's been discussed in the custom-texture discussion lately. Then there would be standard styling for the ribbon with the sort options, so user can visualize that the "Name" button is also the active selection.
For folder themselves may I suggest adding a / suffix to them.
I don't understand your push_back() / char[] example. You can assign over a const here.
If you want to concatenate a string to a vector of char you can resize the vector using resize(new_len+1) and then memcpy/strcpy the new data at the right location.
I have made the members protected now so you can also inherit.
What I would suggest to attempt - may be a bit tricky - for the line forming the "path" button is to try to align them so that they form a continuous string even tho they are made of individual buttons. And clicking on the right of it would replace all the buttons with a text edit box and the text would fit the same space. That would allow both text edition and clicking buttons to go back to a parent folder. Could be done with using SameLine with 0 spacing ?
This is all interesting stuff in term of how we can improve core ImGui to help implementing comlex dialog with minimal compromise.
The screenshot was in the notification e-mail.
ImGui probably needs a "selected" button concept so buttons can be used the same way as radio buttons. This is actually something that's been discussed in the custom-texture discussion lately. Then there would be standard styling for the ribbon with the sort options, so user can visualize that the "Name" button is also the active selection.
Yes, that would probably simplify the code a bit, and we can then remove the additional styles.
Currently there are 3 controls that are like that:
[OT] Also it should be handy to have a button that acts like a checkbox (even if it's not used here).
For folder themselves may I suggest adding a / suffix to them.
You mean the "browsing" folders? Well, I've used yellow buttons and gray buttons for files: it looks nice. Yes, the only problem is that I've added additional styles for them (and to be honest, even for the buttons inside the "Known Directories" section, but they can simply be copied from the "Directory button styles" if we want to remove as much additional style data as possible).
I don't understand your push_back() / char[] example. You can assign over a const here.
If you want to concatenate a string to a vector of char you can resize the vector using resize(new_len+1) and then memcpy/strcpy the new data at the right location.
I have made the members protected now so you can also inherit.
Yes, you're probably right here. I'll try using the standard ImVector and replacing push_back() calls to resize()+strcpy() and see if it works.
What I would suggest to attempt - may be a bit tricky - for the line forming the "path" button is to try to align them so that they form a continuous string even tho they are made of individual buttons. And clicking on the right of it would replace all the buttons with a text edit box and the text would fit the same space. That would allow both text edition and clicking buttons to go back to a parent folder. Could be done with using SameLine with 0 spacing ?
You mean like CTRL+L in the default Ubuntu file browser.
Well, we can try appending an invisible button somewhere at the right of the split-path control, and adding a static bool variable that replaces the whole split-path control with a textbox.
I'll make some experiments...
The screenshot was in the notification e-mail.
After having added it, I was no longer able to see it or retrieve it; don't know why. Now I've updated Firefox and I hope everything will work again.
P.S: If your main concern is the code integration, you can evalutate the idea of imgui addons I exposed a few posts above.
Very cool
https://github.com/mlabbe/nativefiledialog
I still think there's use for an imgui dialog, both for portability to consoles/embedded systems and for some form of super kick access. But this is very useful.
Very cool https://github.com/mlabbe/nativefiledialog
I still think there's use for an imgui dialog, both for portability to consoles/embedded systems and for some form of super kick access. But this is very useful.
I agree this library is very good (thanks for having found it!).
But, as you have pointed out, It needs these additional dependencies:
On Linux, you must compile and link against GTK+. Recommend use of pkg-config --cflags --libs gtk+-3.0.
On Mac OS X, add AppKit to the list of frameworks.
On Windows, ensure you are building against comctl32.lib.
BTW: I still haven't updated my gist. However I've managed to remove ALL the styles, to remove the ImCustomVector class and to implement the "location edit field" control (even if the text inside the edit box does not match the length of the split-path: it's shorter, see the attachments).
However now I've entered a major code-refactoring phase of the internal navigation logic that will probably take some time.


Done. Here it is: https://gist.github.com/Flix01/f34b5efa91e50a241c1b
Final look:

P.S. I've just found out that by setting up the files imgui_user.h and imgui_user.inl in the proper way, and by defining IMGUI_INCLUDE_IMGUI_USER_H and IMGUI_INCLUDE_IMGUI_USER_INL
at the project level, it should be possible to seamlessly integrate imguifilesystem into the imgui "trunk", in a way similiar to the one I described in a previous post.
I still have to test it, but to me it's no more a priority the integration of file system dialogs into imgui.
Maybe this can be considered https://github.com/cschreib/lxgui/tree/v1.2/utils/src
There's a few available sources to list file-system in a portable way, it's a simple thing to solve.
I kept this thread open as a reminder that
mame's micko has been looking into writing a commander-style interface using imgui

I am also looking for a cross platform file selection dialog that I could use in an existing imgui project. So far https://github.com/mlabbe/nativefiledialog looks the most interesting to me.
A pure imgui solution would be nice though. My favorite API for this would be one that allows me to hook my own dir listing functions, so that the library itself would be totally platform independent.
For a desktop application with typical Open/Save requirements I would probably rely on the OS interface.
That said I appreciate we could have an ImGui one and we should be able to share it as an "extension", it's just unlikely I am going to write one myself soon.
That thread is old and since flix01 started it, I have introduced more API calls and imgui_internal.h to access more of imgui internal functions and state so it should be easier now to just make a piece of code that we can share.
I fully agree here. For better or worse the users of your application is usually used to how to handle the OS version while the ImGui one wouldn't likely map 100% to that one.
Just wanted to stop by and say that I ended up using imguifilesystem in the latest TowerFall update for Linux/Mac, to replace some use of System.Windows.Forms:
https://github.com/flibitijibibo/XNAFileDialog
We pull in the vertex buffers as well as the font texture data and push them to the XNA/FNA GraphicsDevice, making it a lot easier to use than a pop-up dialog (which is a big no-no for SteamOS in particular). It's basically used for the level editor and snippets of Steam Workshop stuff, and it pretty much worked right away. I only changed it a couple times, and you can find both commits here:
https://github.com/flibitijibibo/XNAFileDialog/commit/d26c99fa47a91911112b102bdf48d24b727519c6#diff-ab42ecf092203a51146d46c5a1eeb9b9
https://github.com/flibitijibibo/XNAFileDialog/commit/a4ea6b17a68e1364e25b7f51aee23d769a0e83d4
The latter case is, as it says, just for getting OSX to build, but the former has a few quick changes that I needed to get it out the door, but might be worth considering for the header file.
This might get some further changes if I ever need to, for example, add controller support to it, but that'll probably be in the XNAFileDialog files rather than the ImGui files. If that changes I'll keep you updated.
Now I'm trying to modify my old code to use modal windows instead of normal windows.
However it's the first time I use PopupModal and I can't make it work properly.
Basically when I click the close button in the window title instead of choosing a file everything works as expected, but when I choose the file, then the background colour returns normal, but I can't interact with ANY window anymore.
Of course my code is very complex and I can't extract relevant parts here, but basically I always use something like:
ImGui::OpenPopup(I.wndTitle);
const bool popupOk = ImGui::BeginPopupModal(I.wndTitle, &I.open);//, I.wndSize,windowAlpha);
if (!popupOk) return rv;
// .....
// .....
// .....
ImGui::EndPopup();
In my old code I simply used:
ImGui::Begin(I.wndTitle, &I.open, I.wndSize,windowAlpha);
// .....
// .....
// .....
ImGui::End();
without branches. I'm not sure what's happening: maybe it's something that is happening when I.open changes its value, but I'm not sure about it...
Any hint ?
You probably don't want to call OpenPopup() every frame.
Also you may not need to use a Modal maybe just a regular popup.
Otherwise it's hard to tell without an actual repro.
Ok, I'll try to call OpenPopup just once for now.
Unfortunately calling OpenPopup only once does not seem to solve the problem.
By using BeginPopup() the window is too small for me to select a file so I cannot tell if this works or not.
I'll try to investigate further what changes when a file is selected and how the code exits afterwards, but that will take some time.
BTW: I had to add the "popupOk" flag above to exit because otherwise I had an assert in EndPopup():
_IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup);_.
Is it normal ?
Not normal at all. Probably means you have a conflict with a non-popup adn a popup with the same name or something?
Yes, I might have some code paths that end up with mismatches in Begin()/End() calls.
I'll check it later. Thanks for your support!
Probably some method: CloseAllPopups() would have been helpful in my case, although it's always better to fix things in the correct way...
Right now I'm managing to solve the problem regarding my dialogs not working as PopupModal.But I need some info on the ImGui internals....
Basically, to summarize my issue, when a dialog is launched as popup modal, it used to work only when I closed it using the close button, but when I actually selected a file, after EndPopup() the main window remained blocked... forever.
Tracking down the calls to OpenPopup(), BeginPopupModal() and EndPopup() did not show any particular issue (OpenPopup() was called only once at the beginning).
I've just managed to fix it by calling (when I select a file) ClosePopupToLevel(0). This is a hidden static function inside imgui.cpp. Digging further I've found out that it also works with: ImGui::FocusWindow(GImGui->OpenPopupStack[0].ParentWindow); (which is better because it's not "buried" into imgui.cpp).
So my question is: what does ImGui::FocusWindow(GImGui->OpenPopupStack[0].ParentWindow) mean ? It's always safe to call it ?
P.S. of course I know that my ImGui popup window by itself is agnostic about whether I select a file or not (AFAIK) and so the problem should be on my side... but here I'm just trying to have a fix that is reliable...
I think I've found the correct way to solve this issue.
Basically I've read the docs in imgui.h and I've called:
ImGui::CloseCurrentPopup();
between:
ImGui::BeginPopupModal(...);
and
ImGui::EndPopup();
when I must close the modal window. That seems to work, and I guess this solution works even in nested modal dialogs...
I'm not sure to understand your two messages above, could you provide an explanation in the form of a repro?
Never mind, it was my fault.
I didn't know I had to call ImGui::CloseCurrentPopup().
With that call everything works as expected (the main problem was that my code was written long before modal dialogs were present, and I forgot to add CloseCurrentPopup() when I tried to convert them).
Btw, if you're using (very) modern C++, you can use <experimental/filesystem> (VS and GCC already heave it) which makes listing files and directories very simple and works across lots of platforms.
@EliasD I didn't know that gcc supported it...
However from http://stackoverflow.com/questions/30103209/why-cant-i-use-experimental-filesystem-with-g-4-9-2:
GCC 5.3 includes an implementation of the Filesystem library defined by the technical specification ISO/IEC TS 18822:2015. Because this is an experimental library extension, not part of the C++ standard, it is implemented in a separate library, libstdc++fs.a, and there is no shared library for it. To use the library you should include and link with -lstdc++fs. The library implementation is incomplete on non-POSIX platforms, specifically Windows support is rudimentary.
Due to the experimental nature of the Filesystem library the usual guarantees about ABI stability and backwards compatibility do not apply to it. There is no guarantee that the components in any header will remain compatible between different GCC releases.
That means that it not so straight forward to use it with GCC ATM.
Moreover I'm not sure CLANG supports it, and in any case it requires a modern compiler (and maybe C++11 or so).
I think using dirent is more portable ATM, because it is supported by all POSIX systems AFAIK, and can be used in Windows systems to (by wrapping native calls in cl.exe, or by using Mingw).
Furthermore, as I rule of the thumb, I consider portable code that works on Linux, Windows and that can be compiled to html through the emscripten compiler: and my dialogs seem to work.
So my point of view is that now is a bit too early to use experimental/filesystem. Things might change in the future...
Necroing this thread because I found it useful since it led me to nativefiledialogs. However I ended up using noc_file_dialogs.h https://github.com/guillaumechereau/noc
Perhaps someone would prefer it over nativefiledialogs
Edit: I eventually made my own clean-room solution called osdialog. Instead of defining macros per operating system, you add the relevant osdialog-*.c file to the build system and include osdialog.h in your headers.
Help needed with adding better and additional OS support!
@AndrewBelt:
I ended up using noc_file_dialogs.h https://github.com/guillaumechereau/noc
Nice, clean and compact code!
A 3rd alternative is here: http://tinyfiledialogs.sourceforge.net
I shared some code snippets that include a file IO window (e.g. save and load). Maybe you find it useful.
@gileoo Could you post an example of how to use the file IO window?
@flix01 There's a question here about your ImGuiFileSystem extension
https://discourse.dearimgui.org/t/how-to-use-the-imguifilesystem/70
(I don't have your e-mail address or couldn't find a way to contact you privately)
@ocornut Thanks.
Well, in the addons branch there's a Issue section, and I'd rather answer questions there whenever possible.
So that other people using my branch can benefit from it.
Hope it makes sense.
Just leaving a note here about a new implementation I am working on, Portable File Dialogs, which may be of interest to some developers.
The API is still very WIP, and I’m welcoming comments/suggestions/patches (for instance, there is no OS X port yet).
Also unfortunately dirent.h is not portable under normal MSVC/Windows. Bit of a tragedy that in 2014 there isn't a portable API to list directory.
The function *static char *readdir_raw(char _dir, int return_subdirs, char _mask)__
In https://github.com/nothings/stb/blob/master/stb.h
Does that using ifdefs.
This might be helpful:
https://github.com/tronkko/dirent
C++17 introduced filesystem operations. I created a filesystem dialog using mostly C++17 operations:
https://github.com/grumpycoders/pcsx-redux/blob/master/src/gui/widgets/filedialog.cc
https://github.com/grumpycoders/pcsx-redux/blob/master/src/gui/widgets/filedialog.h
In action: https://youtu.be/FLYp4MT6VFM
Code is GPL due to being polluted from pcsx, but I wouldn't mind relicensing it by dropping it elsewhere if there was a repository of third party imgui widgets somewhere.
Most helpful comment
Just leaving a note here about a new implementation I am working on, Portable File Dialogs, which may be of interest to some developers.
The API is still very WIP, and I’m welcoming comments/suggestions/patches (for instance, there is no OS X port yet).