Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
imguifilesystem.h
Go to the documentation of this file.
1// This software is provided 'as-is', without any express or implied
2// warranty. In no event will the authors be held liable for any damages
3// arising from the use of this software.
4// Permission is granted to anyone to use this software for any purpose,
5// including commercial applications, and to alter it and redistribute it
6// freely, subject to the following restrictions:
7// 1. The origin of this software must not be misrepresented; you must not
8// claim that you wrote the original software. If you use this software
9// in a product, an acknowledgment in the product documentation would be
10// appreciated but is not required.
11// 2. Altered source versions must be plainly marked as such, and must not be
12// misrepresented as being the original software.
13// 3. This notice may not be removed or altered from any source distribution.
14
15#ifndef IMGUI_FILESYSTEM_H_
16#define IMGUI_FILESYSTEM_H_
17
18// USAGE EXAMPLE:
19/*
20#include "imguifilesystem.h" // imguifilesystem.cpp must be compiled
21
22// Inside a ImGui window:
23const bool browseButtonPressed = ImGui::Button("..."); // we need a trigger boolean variable
24static ImGuiFs::Dialog dlg; // one per dialog (and must be static)
25const char* chosenPath = dlg.chooseFileDialog(browseButtonPressed); // see other dialog types and the full list of arguments for advanced usage
26if (strlen(chosenPath)>0) {
27 // A path (chosenPath) has been chosen RIGHT NOW. However we can retrieve it later more comfortably using: dlg.getChosenPath()
28}
29if (strlen(dlg.getChosenPath())>0) {
30 ImGui::Text("Chosen file: \"%s\"",dlg.getChosenPath());
31}
32
33// If you want to copy the (valid) returned path somewhere, you can use something like:
34static char myPath[ImGuiFs::MAX_PATH_BYTES];
35if (strlen(dlg.getChosenPath())>0) {
36 strcpy(myPath,dlg.getChosenPath());
37}
38*/
39
40// MISSING FEATURES:
41/*
42-> [File and Folder] Links are NOT supported (they don't show up).
43-> Multiselections in chooseFileDialogs are NOT supported.
44-> Hidden and temporary files don't show up on nix systems (by design). Nothing has been done for Windows about it yet.
45*/
46
47// COMPILING AND TESTING:
48/*
49-> Compiled and tested using "ImGui library v1.17 wip"
50
51-> Successfully compiled using gcc, clang and mingw32 compilers.
52x> Never compiled on any other compiler (Visual C++'s cl.exe included).
53
54-> Tested on Ubuntu 64bit and Wine 32bit.
55x> Never tested on a real Windows OS and on MacOS.
56*/
57
58//#define IMGUIFILESYSTEM_USE_ASCII_SHORT_PATHS_ON_WINDOWS
59 // Optional. Affects Windows users only. Needs recompilation of imguifilesystem.cpp. Disables long UTF8 paths in favour of short ASCII paths.
60 // Unfortunately long paths are NOT 100% functional (in my tests some folders can't be browsed). Patches are welcome. See "dirent_portable.h" for further info.
61 // When experiencing problems on Windows, trying defining this definition is a good start.
62 // Windows users can always define it at the project level, if needed.
63
64#ifndef IMGUI_API
65#include <imgui.h>
66#endif //IMGUI_API
67
68// TODO: Remove this definition: it doesn't work on some systems (= Windows AFAIK)
69//#define IMGUIFS_NO_EXTRA_METHODS // optional, but it makes this header lighter...
70#ifndef IMGUIFS_NO_EXTRA_METHODS
71# include <stdint.h> // this is included by imgui.cpp, and the following headers might redefine incorrectly some types otherwise.
72# include <stdio.h> // just for FILENAME_MAX
73# include <limits.h> // just for PATH_MAX
74# if (defined(__linux__) && !defined(PATH_MAX))
75# include <linux/limits.h>
76# endif //(defined(__linux__) && !defined(PATH_MAX))
77# ifndef PATH_MAX
78# define PATH_MAX 1024 // Or 4096 ?
79# endif //IMGUIFS_NO_EXTRA_METHODS
80# ifndef FILENAME_MAX
81# define FILENAME_MAX PATH_MAX
82# endif //FILENAME_MAX
83# ifdef _WIN32
84# include <windef.h> // On Windows we have MAX_PATH too
85# endif //_WIN32
86# if (defined(MAX_PATH) && MAX_PATH>PATH_MAX)
87# define DIRENT_MAX_PATH MAX_PATH
88# else // (defined(MAX_PATH) && MAX_PATH>PATH_MAX)
89# define DIRENT_MAX_PATH PATH_MAX
90# endif // (defined(MAX_PATH) && MAX_PATH>PATH_MAX)
91#endif//IMGUIFS_NO_EXTRA_METHODS
92
93namespace ImGuiFs {
94
95#ifndef IMGUIFS_NO_EXTRA_METHODS
96# if (!defined(IMGUIFS_MEMORY_USES_CHARS_AS_BYTES) || !defined(IMGUIFILESYSTEM_USE_ASCII_SHORT_PATHS_ON_WINDOWS))
97 const int MAX_FILENAME_BYTES = FILENAME_MAX*4; // Worst case: 4 bytes per char, but huge waste of memory [we SHOULD have used imguistring.h!]
99# else //IMGUIFS_MEMORY_USES_CHARS_AS_BYTES
100 const int MAX_FILENAME_BYTES = FILENAME_MAX+1;
101 const int MAX_PATH_BYTES = DIRENT_MAX_PATH+1;
102# endif //IMGUIFS_MEMORY_USES_CHARS_AS_BYTES
103#else //IMGUIFS_NO_EXTRA_METHODS
104extern const int MAX_FILENAME_BYTES;
105extern const int MAX_PATH_BYTES;
106# ifdef IMGUI_USE_MINIZIP
107# error Please undefine IMGUIFS_NO_EXTRA_METHODS for IMGUI_USE_MINIZIP to work
108# endif //IMGUI_USE_MINIZIP
109#endif //IMGUIFS_NO_EXTRA_METHODS
110
129
130
131struct Dialog {
132 public:
133
134 // default arguments are usually what most users expect (better not touch them in most cases)
135 IMGUI_API Dialog(bool noKnownDirectoriesSection=false,bool noCreateDirectorySection=false,bool noFilteringSection=false,bool detectKnownDirectoriesAtEachOpening=false,bool addDisplayByOption=false,bool dontFilterSaveFilePathsEnteredByTheUser=false);
136 IMGUI_API ~Dialog();
137
138 // "dialogTriggerButton" is usually a bool variable connected to a ImGui::Button(...).
139 // returns the chosen path (internally stored). Users can check when the returned path has strlen()>0.
140 // "fileFilterExtensionString" can be something like ".png;.jpg;.jpeg;.bmp;.tga;.gif;.tiff;.txt". It's case insensitive.
141 // "directory" and "startingFileNameEntry" (only available in saveFileDialog(...)) are quite flexible and can be set to almost everything: the method will use the most resonable choice.
142 IMGUI_API const char* chooseFileDialog(bool dialogTriggerButton,const char* directory=NULL,const char* fileFilterExtensionString=NULL,const char* windowTitle=NULL,const ImVec2& windowSize=ImVec2(-1,-1),const ImVec2& windowPos=ImVec2(-1,-1),const float windowAlpha=0.875f);
143 IMGUI_API const char* chooseFolderDialog(bool dialogTriggerButton,const char* directory=NULL,const char* windowTitle=NULL,const ImVec2& windowSize=ImVec2(-1,-1),const ImVec2& windowPos=ImVec2(-1,-1),const float windowAlpha=0.875f);
144 IMGUI_API const char* saveFileDialog(bool dialogTriggerButton,const char* directory=NULL,const char* startingFileNameEntry=NULL,const char* fileFilterExtensionString=NULL,const char* windowTitle=NULL,const ImVec2& windowSize=ImVec2(-1,-1),const ImVec2& windowPos=ImVec2(-1,-1),const float windowAlpha=0.875f);
145
146 // gets the chosen path (internally stored). It's valid (its strlen()>0) after the user performs a valid selection, until the user performs an invalid selection (e.g. closes the dialog with the close button).
147 IMGUI_API const char* getChosenPath() const;
148 // returns the last directory browsed by the user using this class (internally stored). Can be passed as "directory" parameter in the methods above to reuse last used directory.
149 IMGUI_API const char* getLastDirectory() const;
150 // returns "true" the exact frame a user has clicked "cancel" or the "dialog close button".
151 IMGUI_API bool hasUserJustCancelledDialog() const;
152
153 // static variables that are usually OK as they are
154 static bool WrapMode; // (true)
155 static ImVec2 WindowSize; // (600,400) [initial window size when not defined in argument "windowSize"]
156 static ImVec4 WindowLTRBOffsets;// (0,0,0,0) [it might turn useful when using toolbars]
157 static ImGuiWindowFlags ExtraWindowFlags; // (0) [it might turn useful if we want ImGuiWindowFlags_ShowBorders]
158
159 typedef bool (*DrawFileIconDelegate) (int fileExtensionType,const ImVec4* pOptionalColorOverride); // must return "true" if the icon is set.
161 typedef bool (*DrawFolderIconDelegate) (bool useOpenFolderIconIfAvailable,const ImVec4* pOptionalColorOverride);// must return "true" if the icon is set.
163
164
165 private:
167 friend const char* ChooseFileMainMethod(Dialog& ist,const char* directory,const bool _isFolderChooserDialog,const bool _isSaveFileDialog,const char* _saveFileName,const char* fileFilterExtensionString,const char* windowTitle,const ImVec2& windowSize,const ImVec2& windowPos,const float windowAlpha);
168};
169
170// Extra methods: completely optional, undocumented and NOT guarateed to work as expected:
171#ifndef IMGUIFS_NO_EXTRA_METHODS
172// A bit dangerous typedefs:
175// Handy typedefs:
176typedef ImVector<FilenameString> FilenameStringVector;
177typedef ImVector<PathString> PathStringVector;
178
179// all the strings should be MAX_PATH_BYTES long
180extern bool PathExists(const char* path);
181extern void PathGetAbsolute(const char *path, char *rv);
182extern void PathGetDirectoryName(const char *filePath, char *rv);
183extern void PathGetFileName(const char *filePath, char *rv);
184extern void PathGetFileNameWithoutExtension(const char *filePath, char *rv);
185extern void PathGetExtension(const char* filePath,char *rv);
186extern void PathChangeExtension(const char* filePath, const char *newExtension, char *rv);
187extern void PathAppend(const char* directory,char* rv);
188extern void PathSplit(const char* path,FilenameStringVector& rv,bool leaveIntermediateTrailingSlashes=true);
189
201extern bool DirectoryExists(const char* path);
202extern void DirectoryCreate(const char* directoryName);
203extern void DirectoryGetDirectories(const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut=NULL,Sorting sorting= SORT_ORDER_ALPHABETIC);
204extern void DirectoryGetFiles(const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut=NULL, Sorting sorting= SORT_ORDER_ALPHABETIC);
205extern bool FileExists(const char* path);
206extern bool FileGetContent(const char* path,ImVector<unsigned char>& bufferOut,bool openInTextMode=false,const char* password=NULL); // password is used if it's a file inside a zip path when IMGUI_USE_MINIZIP is defined (e.g. path="C://MyDocuments/myzipfile.zip/myzipFile/something.txt")
207extern bool FileGetContent(const char* path,ImVector<char>& bufferOut,bool openInTextMode=false,const char* password=NULL); // password is used if it's a file inside a zip path when IMGUI_USE_MINIZIP is defined (e.g. path="C://MyDocuments/myzipfile.zip/myzipFile/something.txt")
208extern int FileGetExtensionType(const char* path); // returns one of the FileExtensionType enums, or -1. Slow: you'd better cache the result wherever possible.
209extern void FileGetExtensionTypesFromFilenames(ImVector<int>& fileExtensionTypesOut,const FilenameStringVector& fileNames); // Same as above, except that now FilenameStringVector are chars of MAX_FILENAME_BYTES, usually shorter than MAX_PATH_BYTES
210#if (defined(__EMSCRIPTEN__) && defined(EMSCRIPTEN_SAVE_SHELL))
211extern bool FileDownload(const char* path,const char* optionalSaveFileName);
212#endif // (defined(__EMSCRIPTEN__) && defined(EMSCRIPTEN_SAVE_SHELL))
213#ifdef IMGUI_USE_MINIZIP
214class UnZipFile {
215public:
216UnZipFile(const char* zipFilePath=NULL);
217bool load(const char* zipFilePath,bool reloadIfAlreadyLoaded=true);
218const char* getZipFilePath() const;
219bool isValid() const;
220void close();
221
222// All these paths are inside the zip file (without the "zipFilePath" prefix)
223bool getDirectories(const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut=NULL,Sorting sorting= SORT_ORDER_ALPHABETIC,bool prefixResultWithTheFullPathOfTheZipFile=false) const;
224bool getFiles(const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut=NULL,Sorting sorting= SORT_ORDER_ALPHABETIC,bool prefixResultWithTheFullPathOfTheZipFile=false) const;
225unsigned int getFileSize(const char* filePath) const;
226bool getFileContent(const char* filePath,ImVector<unsigned char>& bufferOut,const char* password=NULL) const;
227bool getFileContent(const char* filePath,ImVector<char>& bufferOut,const char* password=NULL) const;
228bool exists(const char* pathInsideZip, bool reportOnlyFiles=false, bool reportOnlyDirectories=false) const;
229bool fileExists(const char* pathInsideZip) const;
230bool directoryExists(const char* pathInsideZip) const;
231~UnZipFile();
232protected:
233struct UnZipFileImpl* im;
234};
235
236// eg: path="C://MyDocuments/myzipfile.zip/myzipFile/something" -> rv1="C://MyDocuments/myzipfile.zip", rv2="myzipFile/something"
237extern bool PathSplitFirstZipFolder(const char* path, char* rv1,char* rv2,bool rv1IsAbsolutePath=true);
238// eg: path="C://MyDocuments/myzipfile.zip/myzipFile/something"
239extern bool PathExistsWithZipSupport(const char* path, bool reportOnlyFiles=false, bool reportOnlyDirectories=false, bool checkAbsolutePath=true, bool *isInsideAZipFile=NULL);
240// eg: path="C://MyDocuments/myzipfile.zip/myzipFile/something" (regardless if it exists or not)
241extern bool PathIsInsideAZipFile(const char* path);
242// eg: directoryName="C://MyDocuments/myzipfile.zip/myzipFile"
243extern bool DirectoryGetDirectoriesWithZipSupport(const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut=NULL,Sorting sorting= SORT_ORDER_ALPHABETIC,bool prefixResultWithTheFullPathOfTheZipFile=true);
244extern bool DirectoryGetFilesWithZipSupport(const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut=NULL,Sorting sorting= SORT_ORDER_ALPHABETIC,bool prefixResultWithTheFullPathOfTheZipFile=true);
245extern void PathGetDirectoryNameWithZipSupport(const char* path,char* rv,bool prefixResultWithTheFullPathOfTheZipFile=true);
246extern void PathGetAbsoluteWithZipSupport(const char* path,char* rv);
247#endif //IMGUI_USE_MINIZIP
248#endif //IMGUIFS_NO_EXTRA_METHODS
249
250} // namespace ImGuiFs
251
252#endif //IMGUI_FILESYSTEM_H_
#define FILENAME_MAX
#define DIRENT_MAX_PATH
const int MAX_FILENAME_BYTES
void PathGetAbsolute(const char *path, char *rv)
void PathGetFileNameWithoutExtension(const char *filePath, char *rv)
ImVector< FilenameString > FilenameStringVector
void FileGetExtensionTypesFromFilenames(ImVector< int > &fileExtensionTypesOut, const FilenameStringVector &fileNames)
char PathString[MAX_PATH_BYTES]
void PathGetFileName(const char *filePath, char *rv)
const int MAX_PATH_BYTES
void PathChangeExtension(const char *filePath, const char *newExtension, char *rv)
int FileGetExtensionType(const char *path)
@ SORT_ORDER_TYPE_INVERSE
@ SORT_ORDER_ALPHABETIC
@ SORT_ORDER_LAST_MODIFICATION
@ SORT_ORDER_ALPHABETIC_INVERSE
@ SORT_ORDER_LAST_MODIFICATION_INVERSE
@ SORT_ORDER_SIZE_INVERSE
void DirectoryCreate(const char *directoryName)
void PathGetExtension(const char *filePath, char *rv)
bool PathExists(const char *path)
void DirectoryGetDirectories(const char *directoryName, PathStringVector &result, FilenameStringVector *pOptionalNamesOut, Sorting sorting)
void DirectoryGetFiles(const char *directoryName, PathStringVector &result, FilenameStringVector *pOptionalNamesOut, Sorting sorting)
ImVector< PathString > PathStringVector
bool FileGetContent(const char *path, ImVector< unsigned char > &bufferOut, bool openInTextMode, const char *password)
bool DirectoryExists(const char *path)
void PathGetDirectoryName(const char *filePath, char *rv)
void PathAppend(const char *directory, char *rv)
void PathSplit(const char *path, FilenameStringVector &rv, bool leaveIntermediateTrailingSlashes)
char FilenameString[MAX_FILENAME_BYTES]
bool FileExists(const char *path)
IMGUI_API const char * getLastDirectory() const
static ImVec2 WindowSize
IMGUI_API const char * chooseFileDialog(bool dialogTriggerButton, const char *directory=NULL, const char *fileFilterExtensionString=NULL, const char *windowTitle=NULL, const ImVec2 &windowSize=ImVec2(-1,-1), const ImVec2 &windowPos=ImVec2(-1,-1), const float windowAlpha=0.875f)
static DrawFileIconDelegate DrawFileIconCallback
bool(* DrawFolderIconDelegate)(bool useOpenFolderIconIfAvailable, const ImVec4 *pOptionalColorOverride)
IMGUI_API bool hasUserJustCancelledDialog() const
static ImGuiWindowFlags ExtraWindowFlags
IMGUI_API const char * getChosenPath() const
static DrawFolderIconDelegate DrawFolderIconCallback
static ImVec4 WindowLTRBOffsets
IMGUI_API const char * chooseFolderDialog(bool dialogTriggerButton, const char *directory=NULL, const char *windowTitle=NULL, const ImVec2 &windowSize=ImVec2(-1,-1), const ImVec2 &windowPos=ImVec2(-1,-1), const float windowAlpha=0.875f)
bool(* DrawFileIconDelegate)(int fileExtensionType, const ImVec4 *pOptionalColorOverride)
IMGUI_API const char * saveFileDialog(bool dialogTriggerButton, const char *directory=NULL, const char *startingFileNameEntry=NULL, const char *fileFilterExtensionString=NULL, const char *windowTitle=NULL, const ImVec2 &windowSize=ImVec2(-1,-1), const ImVec2 &windowPos=ImVec2(-1,-1), const float windowAlpha=0.875f)
struct Internal * internal
static bool WrapMode
friend const char * ChooseFileMainMethod(Dialog &ist, const char *directory, const bool _isFolderChooserDialog, const bool _isSaveFileDialog, const char *_saveFileName, const char *fileFilterExtensionString, const char *windowTitle, const ImVec2 &windowSize, const ImVec2 &windowPos, const float windowAlpha)