-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
File system dialogs #88
Comments
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! |
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 |
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.
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.
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).
Well, I'm not sure about it. What I mean is that I use ASCII methods to separate path parts, so that for example: However solving this problem is not a priority for me, as it's going to affect only a very few multibyte characters I guess.
I'm currently using this port: http://softagalleria.net/dirent.php 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.
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 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 What do you think about it ? |
Wow - that's a lot of code! Some rough feedback:
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!
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.
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;
}
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.
Thanks, I'll do it [UPDATE: done].
Wow! I thought it got lost forever! Where did you find it ?
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. |
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. 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. |
Yes, that would probably simplify the code a bit, and we can then remove the additional styles.
[OT] Also it should be handy to have a button that acts like a checkbox (even if it's not used here).
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).
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.
You mean like CTRL+L in the default Ubuntu file browser.
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 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!).
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 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 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 |
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. |
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 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: flibitijibibo/XNAFileDialog@d26c99f#diff-ab42ecf092203a51146d46c5a1eeb9b9 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. 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. |
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(): |
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. 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.
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. |
Btw, if you're using (very) modern C++, you can use |
@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:
That means that it not so straight forward to use it with GCC ATM. 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 Edit: I eventually made my own clean-room solution called osdialog. Instead of defining macros per operating system, you add the relevant |
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 |
@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). |
This might be helpful: |
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 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. |
If someone still looking for some ImGui filesystem navigator - I made it recently. It is tiny, but seems working. |
Please add to Wiki in this location: |
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, but this is something ImGui should avoid. I've tried creating an ImString out of ImVector, but the problem here is that the stringVector class does not work [Actually even ImVectorstd::string does not work, probably because ImVector does not call ctrs/dtrs by default, or maybe for some other odd reason...]. These two classes are mandatory in my code.
-> 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
The text was updated successfully, but these errors were encountered: