21#undef IMGUI_DEFINE_MATH_OPERATORS
22#define IMGUI_DEFINE_MATH_OPERATORS
23#include <imgui_internal.h>
30#ifdef DIRENT_USES_UTF8_CHARS
31# warning DIRENT_USES_UTF8_CHARS is deprecated and has become the default. (IMGUIFILESYSTEM_USE_ASCII_SHORT_PATHS_ON_WINDOWS can be used to disable it).
36# ifndef CSIDL_MYPICTURES
37# define CSIDL_MYPICTURES 0x0027
40# define CSIDL_MYMUSIC 0x000d
43# define CSIDL_MYVIDEO 0x000e
52#define IMGUIFS_CDECL __cdecl
57#ifdef IMGUIFS_NO_EXTRA_METHODS
62# if (defined(__linux__) && !defined(PATH_MAX))
63# include <linux/limits.h>
69# define FILENAME_MAX PATH_MAX
74# if (defined(MAX_PATH) && MAX_PATH>PATH_MAX)
75# define DIRENT_MAX_PATH MAX_PATH
77# define DIRENT_MAX_PATH PATH_MAX
82# if (!defined(IMGUIFS_MEMORY_USES_CHARS_AS_BYTES) || !defined(IMGUIFILESYSTEM_USE_ASCII_SHORT_PATHS_ON_WINDOWS))
113#ifdef IMGUIFILESYSTEM_USE_ASCII_SHORT_PATHS_ON_WINDOWS
114#undef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
115#define DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
126#if (defined(_MSC_VER) && !defined(strcasecmp))
127# define strcasecmp _stricmp
164 if (rv.Size == rv.Capacity) rv.reserve(rv._grow_capacity(rv.Size+1));
165 const size_t sz = rv.size();
167 strcpy(&rv[sz][0], s ? s :
"\0");
169# if (FILENAME_MAX!=DIRENT_MAX_PATH)
171 const size_t sz = rv.size();
173 strcpy(&rv[sz][0], s ? s :
"\0");
176 inline static void Substr(
const char* text,
char* rv,
int start,
int count=-1) {
178 if (count<0) count = (int) strlen(text) - start;
179 if (count>0) strncpy(rv,&text[start],count);
182 inline static int Find(
const char* text,
const char toFind,
int beg=0) {
183 if (!text)
return -1;
184 for (
size_t i=beg,len=strlen(text);i<len;i++) {
185 if (text[i]==toFind)
return i;
189 inline static int FindLastOf(
const char* text,
const char toFind) {
190 if (!text)
return -1;
191 for (
int i=(
int)strlen(text)-1;i>=0;i--) {
192 if (text[i]==toFind)
return i;
196 inline static void ToLower(
const char* text,
char* rv) {
201 const size_t len = strlen(text);
202 for (
size_t i=0;i<len;i++) {
203 rv[i]=tolower(text[i]);
209 for (
size_t i=0,len = strlen(text);i<len;i++) {
217 const int len = (int)strlen(text);
220 for (
int i=0;i<len;i++) {
221 const char ch = text[i];
223 Substr(text,tmp,beg,i-beg);
229 Substr(text,tmp,beg,len-beg);
233 inline static void Replace(
const char* baseText,
const char textToReplace,
const char replacement,
char* rv) {
237 inline static void ReplaceInPlace(
char* text,
const char toReplace,
const char replacement) {
239 for (
size_t i=0,len = strlen(text);i<len;i++) {
241 if (c==toReplace) c=replacement;
247 inline static void wide_to_utf8(
const wchar_t* wstr,
char* rv) {
250 int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
251 WideCharToMultiByte (CP_UTF8, 0, wstr, -1, &rv[0], size_needed, NULL, NULL);
256 inline static void utf8_to_wide(
const char* str,
wchar_t* rv) {
259 int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
260 MultiByteToWideChar (CP_UTF8, 0, str, -1, &rv[0], size_needed);
274 if (!path || strlen(path)==0) {
284 static wchar_t buffer[bufferSize];
285 static wchar_t wpath[bufferSize];
286 String::utf8_to_wide((path && strlen(path)>0) ? path :
"./",wpath);
287 ::GetFullPathNameW(&wpath[0],bufferSize,&buffer[0],NULL);
288 String::wide_to_utf8(&buffer[0],rv);
292 while ( (len=strlen(rv))>0 && rv[len-1]==
'/') rv[len-1]=
'\0';
297 rv[0]=
'\0';
if (!filePath)
return;
298 const int sz = strlen(filePath);
299 if (sz==0 || strcmp(filePath,
"/")==0 || strcmp(filePath,
"\\")==0) {
303 const char c = filePath[sz-1];
304 if (c ==
'/' || c==
'\\') {
317 beg=(beg>beg2?beg:beg2);
332 beg=(beg>beg2?beg:beg2);
344 beg=(beg>beg2?beg:beg2);
363 if (beg3!=-1) beg2 = beg3;
364 else beg2 = beg2 > beg3 ? beg2 : beg3;
366 else if (beg3!=-1) beg2 = beg3;
390 if (beg3!=-1) beg2 = beg3;
391 else beg2 = beg2 > beg3 ? beg2 : beg3;
393 else if (beg3!=-1) beg2 = beg3;
396 strcpy(&rv[beg],newExtension);
402 strcpy(&rv[beg],newExtension);
409 static const int dot = (int)
'.';
410 const char * p1 = strrchr(filePath, dot );
411 if (!p1)
return false;
412 const int len = strlen(p1);
413 if (len!=4)
return false;
414 static const char lower[]=
".zip";
static const char upper[]=
".ZIP";
416 for (
int i=1;i<4;i++) {
418 if (c!=lower[i] && c!=upper[i])
return false;
422 static void Combine(
const char* directory,
const char* fileName,
char* rv,
bool appendMode=
true) {
423 if (!appendMode) rv[0]=
'\0';
424 const size_t size= directory ? strlen(directory) : 0;
429 strcat(rv,directory);
430 if (directory[size-1]!=
'\\' && directory[size-1]!=
'/') {
434 else strcat(rv,fileName);
437 static void Append(
const char* directory,
char* rv) {
438 if (!directory || strlen(directory)==0)
return;
439 size_t size = strlen(rv);
440 if (size>0 && (rv[size-1]!=
'\\' && rv[size-1]!=
'/')) {strcat(rv,
"/");++size;}
441 strcat(rv,directory);
443 while (size>0 && (rv[size-1]==
'\\' || rv[size-1]==
'/')) {rv[size-1]=
'\0';--size;}
444 if (size==0 || rv[size-1]==
':') strcat(rv,
"/");
450 size_t len = strlen(tex);
453 while ((len = strlen(tex))>0 && tex[len-1]==
'/') {
454 strncpy(tex2,tex,len+1);
462 String::Substr(tex,tmp,0,leaveIntermediateTrailingSlashes ? beg+1 : beg);
468 if (rv.size()>0 && strlen(rv[0])==0) strcpy((
char*)&rv[0][0],
"/\0");
470 if (rv.size()==1 && strlen(rv[0])>0 && rv[0][strlen(rv[0])-1]==
':') strcat((
char*)&rv[0][0],
"/");
496 const int isort =(int) sorting;
508 return strcasecmp((*e1)->d_name,(*e2)->d_name);
511 return -
strcasecmp((*e1)->d_name,(*e2)->d_name);
515 if (stat((*e1)->d_name,&
stat1)==-1)
return -1;
516 if (stat((*e2)->d_name,&
stat2)==-1)
return 1;
520 if (stat((*e1)->d_name,&
stat1)==-1)
return 1;
521 if (stat((*e2)->d_name,&
stat2)==-1)
return -1;
525 if (stat((*e1)->d_name,&
stat1)==-1)
return -1;
526 if (stat((*e2)->d_name,&
stat2)==-1)
return 1;
530 if (stat((*e1)->d_name,&
stat1)==-1)
return 1;
531 if (stat((*e2)->d_name,&
stat2)==-1)
return -1;
536 static const int dot = (int)
'.';
537 const char * p1 = strrchr((
const char*) (*e1)->d_name, dot );
538 const char * p2 = strrchr((
const char*) (*e2)->d_name, dot );
539 if (!p1)
return (!p2?0:-1);
540 else if (!p2)
return 1;
544 static const int dot = (int)
'.';
545 const char * p1 = strrchr((
const char*) (*e1)->d_name, dot );
546 const char * p2 = strrchr((
const char*) (*e2)->d_name, dot );
547 if (!p1)
return (!p2?0:1);
548 else if (!p2)
return -1;
555struct stat SortingHelper::stat1;
560 result.clear();
if (pOptionalNamesOut) pOptionalNamesOut->clear();
562 struct dirent **eps = NULL;
564 sz = strlen(directoryName);
566 strcpy(directoryName2,directoryName);
568 if (sz>0 && directoryName[sz-1]==
':') {directoryName2[sz]=
'\\';directoryName2[sz+1]=
'\0';}
570 const int n = scandir (directoryName2, &eps, DirentGetDirectories, SortingHelper::SetSorter(sorting));
573 if (sz>0 && directoryName[sz-1] ==
'/') String::Substr(directoryName,directoryNameWithoutSlash,0,sz-1);
574 else strcpy(directoryNameWithoutSlash,directoryName);
577 result.reserve((
size_t)n);
578 if (pOptionalNamesOut) pOptionalNamesOut->reserve((
size_t)n);
579 for (
int cnt = 0; cnt < n; ++cnt) {
580 const char*
pName = &eps[cnt]->d_name[0];
584# ifdef __EMSCRIPTEN__
586 strcmp(
pName,
"fd")==0 && strcmp(directoryNameWithoutSlash,
"/proc/self")==0
590 strcpy(tempString,directoryNameWithoutSlash);
591 strcat(tempString,
"/");
592 strcat(tempString,
pName);
593 String::PushBack(result,tempString);
594 if (pOptionalNamesOut) String::PushBack(*pOptionalNamesOut,
pName);
600 if (eps) {free(eps);eps=NULL;}
603 result.clear();
if (pOptionalNamesOut) pOptionalNamesOut->clear();
605 struct dirent **eps = NULL;
607 sz = strlen(directoryName);
609 strcpy(directoryName2,directoryName);
611 if (sz>0 && directoryName[sz-1]==
':') {directoryName2[sz]=
'\\';directoryName2[sz+1]=
'\0';}
613 const int n = scandir (directoryName2, &eps, DirentGetFiles, SortingHelper::SetSorter(sorting));
616 if (sz>0 && directoryName[sz-1] ==
'/') String::Substr(directoryName,directoryNameWithoutSlash,0,sz-1);
617 else strcpy(directoryNameWithoutSlash,directoryName);
620 result.reserve((
size_t)n);
621 if (pOptionalNamesOut) pOptionalNamesOut->reserve((
size_t)n);
622 for (
int cnt = 0; cnt < n; ++cnt) {
623 const char*
pName = &eps[cnt]->d_name[0];
627 strcpy(tempString,directoryNameWithoutSlash);
628 strcat(tempString,
"/");
629 strcat(tempString,
pName);
630 String::PushBack(result,tempString);
631 if (pOptionalNamesOut) String::PushBack(*pOptionalNamesOut,
pName);
637 if (eps) {free(eps);eps=NULL;}
644 GetFiles(path,filesIn,&namesIn,sorting);
645 if ((wantedExtensions==0 || strlen(wantedExtensions)==0) && (unwantedExtensions==0 || strlen(unwantedExtensions)==0)) {files = filesIn;
return;}
646 files.clear();
if (pOptionalNamesOut) pOptionalNamesOut->clear();
649 char woext[
MAX_PATH_BYTES];String::ToLower(unwantedExtensions,woext);
652 if (wantedExtensions && strlen(wantedExtensions)>0) {
653 files.reserve(filesIn.size());
654 if (pOptionalNamesOut) pOptionalNamesOut->reserve(namesIn.size());
656 const size_t wExtsSize = wExts.size();
658 for (
size_t i = 0,sz = filesIn.size();i<sz;i++) {
659 Path::GetExtension(filesIn[i],ext);
660 for (
size_t e=0;e<wExtsSize;e++) {
661 if (strcmp(ext,wExts[e])==0) {
662 String::PushBack(files,filesIn[i]);
663 if (pOptionalNamesOut) String::PushBack(*pOptionalNamesOut,namesIn[i]);
670 else if (unwantedExtensions && strlen(unwantedExtensions)>0) {
673 const size_t woExtsSize = woExts.size();
674 if (woExts.size()==0) {files = filesIn;
return;}
676 for (
size_t i = 0,sz = filesIn.size();i<sz;i++) {
677 Path::GetExtension(filesIn[i],ext);
679 for (
size_t e=0;e<woExtsSize;e++) {
680 if (strcmp(ext,woExts[e])==0) {
686 String::PushBack(files,filesIn[i]);
687 if (pOptionalNamesOut) String::PushBack(*pOptionalNamesOut,namesIn[i]);
693 if (pOptionalNamesOut) *pOptionalNamesOut = namesIn;
697 inline static void Create(
const char* directoryName) {
699 const mode_t mode = S_IFDIR | S_IREAD | S_IWRITE | S_IRWXU | S_IRWXG | S_IRWXO;
700 mkdir(directoryName,mode);
703 String::utf8_to_wide(directoryName,name);
704 ::CreateDirectoryW(name,NULL);
708 inline static bool Exists(
const char* path) {
710 return (stat(path, &statbuf) != -1 && S_ISDIR(statbuf.st_mode));
713 static bool init =
false;
717 static int numberKnownUserDirectoriesExceptDrives = 0;
718 if (pOptionalUserKnownDirectoryDisplayNamesOut) *pOptionalUserKnownDirectoryDisplayNamesOut = &dn;
719 if (pOptionalNumberKnownUserDirectoriesExceptDrives) *pOptionalNumberKnownUserDirectoriesExceptDrives = &numberKnownUserDirectoriesExceptDrives;
720 if (init && !forceUpdate)
return rv;
722 rv.clear();dn.clear();
724 static const int csid[] = {
733 static const char* name[] = {
742 static const int csidSize =
sizeof(csid)/
sizeof(csid[0]);
743 static const int nameSize =
sizeof(name)/
sizeof(name[0]);
745 if (csidSize!=nameSize) fprintf(stderr,
"ERROR in file: imguifilesystem.cpp. Directory::GetUserKnownDirectories(...) csidSize!=nameSize.\n");
746 char tmp[
MAX_PATH_BYTES] =
"C:/";
while (tmp[0]<=
'Z') {
if (Directory::Exists(tmp)) String::PushBack(mediaFolders,tmp);tmp[0]=(char)((
int)tmp[0]+1);}
747 rv.reserve(csidSize+mediaFolders.size());
748 dn.reserve(csidSize+mediaFolders.size());
749 WCHAR path[MAX_PATH+1];
750 for (
int i=0;i<csidSize;i++) {
751 if (!GetSpecialFolderPathW(csid[i],&path[0],NULL))
continue;
753 String::wide_to_utf8(&path[0],tmp2);
754 String::PushBack(rv,tmp2);
755 String::PushBack(dn,name[i]);
757 numberKnownUserDirectoriesExceptDrives = (int) rv.size();
759 for (
int i=0,msz=mediaFolders.size();i<msz;i++) {
760 const char* mediaFolder = mediaFolders[i];
761 String::PushBack(rv,mediaFolder);
762 String::Substr(mediaFolder,mediaFolderName,0,strlen(mediaFolder)-1);
763 String::PushBack(dn,mediaFolderName);
766 const char* homedir = NULL;
767 if ((homedir = getenv(
"HOME")) == NULL) {
768 homedir = getpwuid(getuid())->pw_dir;
770 if (homedir==NULL)
return rv;
772 char userString[
MAX_PATH_BYTES];Path::GetFileName(homeString,userString);
782 static const int folderSize =
sizeof(folder)/
sizeof(folder[0]);
783 rv.reserve(folderSize+1);
784 dn.reserve(rv.size());
785 String::PushBack(rv,homeString);
788 String::PushBack(dn,temp);
789 for (
int i=0;i<folderSize;i++) {
790 Path::Combine(homeString,folder[i],temp,
false);
791 if (Directory::Exists(temp)) {
792 String::PushBack(rv,temp);
793 String::PushBack(dn,folder[i]);
796 numberKnownUserDirectoriesExceptDrives = (int) rv.size();
798 static const char* mountLocations[] = {
"/media",
"/mnt",
"/Volumes",
"/vol",
"/data"};
799 static const int mountLocationSize =
sizeof(mountLocations)/
sizeof(mountLocations[0]);
800 static const bool ifHomeSubfolerIsFoundInMountLocationsForgetThatRootMountLocation =
true;
802 for (
int mntLocIndex=0,sz = 2*mountLocationSize;mntLocIndex<sz;mntLocIndex++) {
803 const int index = mntLocIndex/2;
804 const char* mntLocString = mountLocations[index];
805 const bool useUserSuffix = (mntLocIndex%2)==0;
807 Path::Combine(mntLocString,userString,userMediaString,
false);
808 strcpy(temp,userMediaString);
810 else if (lastGood && ifHomeSubfolerIsFoundInMountLocationsForgetThatRootMountLocation) {lastGood =
false;
continue;}
811 else strcpy(userMediaString,mntLocString);
812 lastGood = Directory::Exists(userMediaString);
813 if (!lastGood)
continue;
814 Directory::GetDirectories(userMediaString,mediaFolders);
815 if (mediaFolders.size()==0)
continue;
816 rv.reserve(rv.size()+mediaFolders.size());
817 dn.reserve(rv.size());
818 for (
int i=0,msz=mediaFolders.size();i<msz;i++) {
819 if (strcmp(mediaFolders[i],temp)==0)
continue;
820 String::PushBack(rv,mediaFolders[i]);
822 Path::GetFileName(mediaFolders[i],tmp);
823 String::PushBack(dn,tmp);
836 if (de->d_type==DT_DIR)
return 1;
840 if (de->d_type==DT_REG)
return 1;
845 static bool GetSpecialFolderPathW(
int specialFolderCSIDL,WCHAR* pathOutWithSizeMaxPathPlusOne,HWND parent) {
854 WCHAR* temp_path = pathOutWithSizeMaxPathPlusOne;
856 LPITEMIDLIST pidl=NULL;
857 if (!SUCCEEDED(::SHGetSpecialFolderLocation(parent,specialFolderCSIDL, &pidl)))
859 temp_path[0]=L
'\0';
return false;
861 bool ok=SUCCEEDED(::SHGetPathFromIDListW(pidl,&temp_path[0]));
864 if ( ::SHGetMalloc( & mal ) == E_FAIL || !mal ) ::free( pidl );
872 temp_path[0]=L
'\0';
return false;
879#ifndef IMGUIFS_NO_EXTRA_METHODS
880#ifdef IMGUI_USE_MINIZIP
881struct UnZipFileImpl {
885 struct unz_file_info64_plus {
889 void assign(
const char* _path,
const char* _name,
const unz_file_info64& _info) {
890 strcpy(path,_path);strcpy(name,_name);
891 memcpy(&info,&_info,
sizeof(info));
893 static void Sort(ImVector<unz_file_info64_plus>& fileInfos,Sorting sorting) {
894 if (fileInfos.size()==0)
return;
895 typedef int (*Sorter)(
const void *,
const void *);
896 Sorter sorter = NULL;
908 if (sorter) qsort(&fileInfos[0],fileInfos.size(),
sizeof(unz_file_info64_plus),sorter);
911 inline static int IMGUIFS_CDECL Alphasort(
const void* e1,
const void* e2) {
912 return strcasecmp(
static_cast<const unz_file_info64_plus*
>(e1)->name,
static_cast<const unz_file_info64_plus*
>(e2)->name);
914 inline static int IMGUIFS_CDECL Alphasortinverse(
const void* e1,
const void* e2) {
915 return -
strcasecmp(
static_cast<const unz_file_info64_plus*
>(e1)->name,
static_cast<const unz_file_info64_plus*
>(e2)->name);
917 inline static int IMGUIFS_CDECL LastModsort(
const void* e1,
const void* e2) {
918 const uLong& dosDate1 =
static_cast<const unz_file_info64_plus*
>(e1)->info.
dosDate;
919 const uLong& dosDate2 =
static_cast<const unz_file_info64_plus*
>(e2)->info.dosDate;
920 return (dosDate1<dosDate2) ? -1 : (dosDate1>dosDate2) ? 1 : 0;
922 inline static int IMGUIFS_CDECL LastModsortinverse(
const void* e1,
const void* e2) {
923 const uLong& dosDate1 =
static_cast<const unz_file_info64_plus*
>(e1)->info.
dosDate;
924 const uLong& dosDate2 =
static_cast<const unz_file_info64_plus*
>(e2)->info.dosDate;
925 return (dosDate1<dosDate2) ? 1 : (dosDate1>dosDate2) ? -1 : 0;
927 inline static int IMGUIFS_CDECL Sizesort(
const void* e1,
const void* e2) {
929 const ZPOS64_T& size2 =
static_cast<const unz_file_info64_plus*
>(e2)->info.uncompressed_size;
930 return (size1<size2) ? -1 : (size1>size2) ? 1 : 0;
932 inline static int IMGUIFS_CDECL Sizesortinverse(
const void* e1,
const void* e2) {
934 const ZPOS64_T& size2 =
static_cast<const unz_file_info64_plus*
>(e2)->info.uncompressed_size;
935 return (size1<size2) ? 1 : (size1>size2) ? -1 : 0;
937 inline static int IMGUIFS_CDECL Typesort(
const void* e1,
const void* e2) {
938 static const int dot = (int)
'.';
939 const char * p1 = strrchr((
const char*)
static_cast<const unz_file_info64_plus*
>(e1)->name, dot );
940 const char * p2 = strrchr((
const char*)
static_cast<const unz_file_info64_plus*
>(e2)->name, dot );
941 if (!p1)
return (!p2?0:-1);
942 else if (!p2)
return 1;
945 inline static int IMGUIFS_CDECL Typesortinverse(
const void* e1,
const void* e2) {
946 static const int dot = (int)
'.';
947 const char * p1 = strrchr((
const char*)
static_cast<const unz_file_info64_plus*
>(e1)->name, dot );
948 const char * p2 = strrchr((
const char*)
static_cast<const unz_file_info64_plus*
>(e2)->name, dot );
949 if (!p1)
return (!p2?0:-1);
950 else if (!p2)
return -1;
955 bool getFilesOrDirectories(
bool fileMode,
const char* directoryName,PathStringVector& result,FilenameStringVector* pOptionalNamesOut,Sorting sorting,
bool prefixResultWithTheFullPathOfTheZipFile)
const {
956 result.clear();
if (pOptionalNamesOut) pOptionalNamesOut->clear();
957 if (!uf)
return false;
961 size_t dirNameLen = 0;
963 dirNameLen = strlen(directoryName);
964 if (dirNameLen>1 && directoryName[0]==
'.' && (directoryName[1]==
'/' || directoryName[1]==
'\\')) {
965 strcpy(dirName,&directoryName[2]);
967 else strcpy(dirName,directoryName);
969 else strcpy(dirName,directoryName ? directoryName :
"");
970 dirNameLen = strlen(dirName);
971 while (dirNameLen>0 && (dirName[dirNameLen-1]==
'/' || dirName[dirNameLen-1]==
'\\')) {dirName[dirNameLen-1]=
'\0';--dirNameLen;}
977 fprintf(stderr,
"error %d with zipfile in unzGetGlobalInfo \n",err);
981 ImVector<unz_file_info64_plus> fileInfos;
988 fprintf(stderr,
"error %d with zipfile in unzGoToFirstFile",err);
995 fprintf(stderr,
"Error %d with zipfile in unzGetCurrentFileInfo\n",err);
1000 size_t filename_inzip_len = strlen(filename_inzip);
1002 const bool isDirectory = filename_inzip_len>0 && (filename_inzip[filename_inzip_len-1]==
'/' || filename_inzip[filename_inzip_len-1]==
'\\');
1003 ok = fileMode ? (!isDirectory && !hasZeroSize) : (isDirectory && hasZeroSize) ? true :
false;
1007 if (dirNameLen>=filename_inzip_len) ok =
false;
1008 if (strncmp(dirName,filename_inzip,dirNameLen)!=0) ok =
false;
1009 if (filename_inzip[dirNameLen]!=
'/' && filename_inzip[dirNameLen]!=
'\\') ok =
false;
1010 if (!fileMode && dirNameLen+1 == filename_inzip_len) ok =
false;
1014 if (filename_inzip_len>0 && (filename_inzip[filename_inzip_len-1]==
'/' || filename_inzip[filename_inzip_len-1]==
'\\')) {filename_inzip[filename_inzip_len-1]=
'\0';--filename_inzip_len;}
1016 strcpy(tmp,dirNameLen>0 ? &filename_inzip[dirNameLen+1] : filename_inzip);
1017 size_t tmpLen = strlen(tmp);
1018 for (
size_t k=0;k<tmpLen;k++) {
1019 if (tmp[k]==
'/' || tmp[k]==
'\\') {
1020 if (fileMode || k!=tmpLen-1)
1025 if ((file_info.
flag & 1) != 0) strcat(tmp,charCrypt);
1027 size_t fileInfosSize = fileInfos.size();
1028 fileInfos.resize(fileInfosSize+1);
1029 fileInfos[fileInfosSize].assign(filename_inzip,tmp,file_info);
1038 fprintf(stderr,
"error %d with zipfile in unzGoToNextFile\n",err);
1045if (fileInfos.size()>0) {
1047 if (!fileMode && sorting >= SORT_ORDER_SIZE) sorting = (
Sorting)(sorting%2);
1048 unz_file_info64_plus::Sort(fileInfos,sorting);
1050 for (
size_t j=0,jsz=fileInfos.size();j<jsz;j++) {
1051 const unz_file_info64_plus& fip = fileInfos[j];
1054 const size_t resultSize = result.size();
1055 result.resize(resultSize+1);
1056 char* pResult = &result[resultSize][0];
1058 if (prefixResultWithTheFullPathOfTheZipFile) {
1059 strcpy(pResult,zipFilePath);
1060 strcat(pResult,
"/");
1062 strcat(pResult,fip.path);
1065 if (pOptionalNamesOut) {
1066 pOptionalNamesOut->resize(resultSize+1);
1067 char*
pName = &(*pOptionalNamesOut)[resultSize][0];
1068 strcpy(
pName,fip.name);
1095 fprintf(stderr,
"error %d with zipfile in unzGoToFirstFile",err);
1103 static bool PathSplitFirstZipFolder(
const char* path,
char* rv1,
char* rv2,
bool rv1IsAbsolutePath=
true) {
1104 rv1[0]=
'\0';rv2[0]=
'\0';
1107 const char* lowerZip =
".zip";
const char* upperZip =
".ZIP";
const int numCharsToMath = (int)strlen(lowerZip);
1109 for (
int i=0,isz=(
int)strlen(path)-numCharsToMath;i<=isz;i++) {
1112 while (c==lowerZip[gc] || c==upperZip[gc]) {
1113 if (++gc==numCharsToMath) {
1114 gc=i+numCharsToMath;
1115 while (gc<isz && (path[gc]==
'/' || path[gc]==
'\\')) ++gc;
1116 strcpy(rv2,&path[gc]);
1118 if (rv1IsAbsolutePath) {
1120 strncpy(rv3,path,i+numCharsToMath);
1121 rv3[i+numCharsToMath]=
'\0';
1123 Path::GetAbsolutePath(rv3,rv1);
1126 strncpy(rv1,path,i+numCharsToMath);
1127 rv1[i+numCharsToMath]=
'\0';
1138 if (rv1IsAbsolutePath) Path::GetAbsolutePath(path,rv1);
1139 else strcpy(rv1,path);
1143 static bool PathExistsWithZipSupport(
const char* path,
bool reportOnlyFiles,
bool reportOnlyDirectories,
bool checkAbsolutePath=
true,
bool* isInsideAZipFile=NULL) {
1145 if (PathSplitFirstZipFolder(path,rv1,rv2,checkAbsolutePath)) {
1146 if (isInsideAZipFile) *isInsideAZipFile =
true;
1148 return unz.exists(rv2,reportOnlyFiles,reportOnlyDirectories);
1151 if (isInsideAZipFile) *isInsideAZipFile =
false;
1156bool UnZipFile::load(
const char* zipFilePath,
bool reloadIfAlreadyLoaded) {
1157 if (!reloadIfAlreadyLoaded && isValid() && strcmp(zipFilePath,im->zipFilePath)==0)
return true;
1164 return im->uf!=NULL;
1166const char* UnZipFile::getZipFilePath()
const {
1167 return im->zipFilePath;
1169bool UnZipFile::isValid()
const {
1170 return im->uf!=NULL;
1172void UnZipFile::close() {
1173 if (im->uf) {
unzClose(im->uf);im->uf=NULL;}
1176 return im->getFilesOrDirectories(
false,directoryName,result,pOptionalNamesOut,sorting,prefixResultWithTheFullPathOfTheZipFile);
1179 return im->getFilesOrDirectories(
true,directoryName,result,pOptionalNamesOut,sorting,prefixResultWithTheFullPathOfTheZipFile);
1181unsigned int UnZipFile::getFileSize(
const char* filePath)
const {
1182 if (!im->uf || !filePath)
return 0;
1186 if (err!=
UNZ_OK)
return 0;
1191template<
typename CharType>
static bool UnZipFileGetFileContentBase(ImGuiFs::UnZipFileImpl* im,
const char* filePath,ImVector<CharType>& bufferOut,
const char* password) {
1193 if (!im->uf || !filePath)
return false;
1198 fprintf(stderr,
"Error while unzipping: \"%s\": %d with zipfile in unzGetCurrentFileInfo\n",filePath,err);
1204 fprintf(stderr,
"Error while unzipping: \"%s\": %d with zipfile in unzOpenCurrentFilePassword\n",filePath,err);
1209 fprintf(stderr,
"Error while unzipping: \"%s\": file is too big.\n",filePath);
1210 ImVector<CharType> tmp;bufferOut.swap(tmp);
1216 fprintf(stderr,
"Error while unzipping: \"%s\": %d with zipfile in unzReadCurrentFile\n",filePath,err);
1217 ImVector<CharType> tmp;bufferOut.swap(tmp);
1223 fprintf(stderr,
"Error while unzipping: \"%s\": %d with zipfile in unzCloseCurrentFile\n",filePath,err);
1227bool UnZipFile::getFileContent(
const char* filePath,ImVector<unsigned char>& bufferOut,
const char* password)
const {
return UnZipFileGetFileContentBase<unsigned char>(im,filePath,bufferOut,password);}
1228bool UnZipFile::getFileContent(
const char* filePath,ImVector<char>& bufferOut,
const char* password)
const {
return UnZipFileGetFileContentBase<char>(im,filePath,bufferOut,password);}
1229bool UnZipFile::exists(
const char* pathInsideZip,
bool reportOnlyFiles,
bool reportOnlyDirectories)
const {
1230 if (!im->uf || !pathInsideZip)
return false;
1234 size_t dirNameLen = 0;
1235 if (pathInsideZip) {
1236 dirNameLen = strlen(pathInsideZip);
1237 if (dirNameLen>1 && pathInsideZip[0]==
'.' && (pathInsideZip[1]==
'/' || pathInsideZip[1]==
'\\')) {
1238 strcpy(path,&pathInsideZip[2]);
1240 else strcpy(path,pathInsideZip);
1242 else strcpy(path,pathInsideZip ? pathInsideZip :
"");
1244 dirNameLen = strlen(path);
1245 while (dirNameLen>0 && (path[dirNameLen-1]==
'/' || path[dirNameLen-1]==
'\\')) {path[dirNameLen-1]=
'\0';--dirNameLen;}
1247 bool onlyDirs =
false,onlyFiles=
false;
1248 if ((reportOnlyFiles || reportOnlyDirectories) && !(reportOnlyFiles && reportOnlyDirectories)) {
1249 onlyDirs = reportOnlyDirectories;
1250 onlyFiles = reportOnlyFiles;
1253 if (strlen(path)==0 && !onlyFiles)
return true;
1255 if (!onlyFiles) {path[dirNameLen++]=
'/';path[dirNameLen]=
'\0';}
1261 if (found && (onlyDirs || onlyFiles)) {
1263 char filename_inzip[2048];
1266 fprintf(stderr,
"Error while checking: \"%s\": %d in unzGetCurrentFileInfo\n",pathInsideZip,err);
1270 size_t filename_inzip_len = strlen(filename_inzip);
1272 const bool isDirectory = filename_inzip_len>0 && (filename_inzip[filename_inzip_len-1]==
'/' || filename_inzip[filename_inzip_len-1]==
'\\');
1273 found = onlyFiles ? (!isDirectory && !hasZeroSize) : onlyDirs ? (isDirectory && hasZeroSize) : false;
1281bool UnZipFile::fileExists(
const char* pathInsideZip)
const {
1282 return exists(pathInsideZip,
true,
false);
1284bool UnZipFile::directoryExists(
const char* pathInsideZip)
const {
1285 return exists(pathInsideZip,
false,
true);
1287UnZipFile::UnZipFile(
const char* zipFilePath) {
1288 im = (UnZipFileImpl*) ImGui::MemAlloc(
sizeof(UnZipFileImpl));
1289 im->uf = NULL;im->zipFilePath[0]=
'\0';
1292UnZipFile::~UnZipFile() {
1300bool PathSplitFirstZipFolder(
const char* path,
char* rv1,
char* rv2,
bool rv1IsAbsolutePath) {
1301 return UnZipFileImpl::PathSplitFirstZipFolder(path,rv1,rv2,rv1IsAbsolutePath);
1303bool PathExistsWithZipSupport(
const char* path,
bool reportOnlyFiles,
bool reportOnlyDirectories,
bool checkAbsolutePath,
bool* isInsideAZipFile) {
1304 return UnZipFileImpl::PathExistsWithZipSupport(path,reportOnlyFiles,reportOnlyDirectories,checkAbsolutePath,isInsideAZipFile);
1306bool PathIsInsideAZipFile(
const char* path) {
1307 bool isInsideAZipFile =
false;
1308 UnZipFileImpl::PathExistsWithZipSupport(path,
true,
true,
true,&isInsideAZipFile);
1309 return isInsideAZipFile;
1312 result.clear();
if (pOptionalNamesOut) pOptionalNamesOut->clear();
1315 if (PathSplitFirstZipFolder(directoryName,zipRoot,zipFolder)) {
1316 UnZipFile uzf(zipRoot);
1317 if (!uzf.isValid())
return false;
1318 return uzf.getDirectories(zipFolder,result,pOptionalNamesOut,sorting,prefixResultWithTheFullPathOfTheZipFile);
1324 result.clear();
if (pOptionalNamesOut) pOptionalNamesOut->clear();
1327 if (PathSplitFirstZipFolder(directoryName,zipRoot,zipFolder)) {
1328 UnZipFile uzf(zipRoot);
1329 if (!uzf.isValid())
return false;
1330 return uzf.getFiles(zipFolder,result,pOptionalNamesOut,sorting,prefixResultWithTheFullPathOfTheZipFile);
1335void PathGetDirectoryNameWithZipSupport(
const char* path,
char* rv,
bool prefixResultWithTheFullPathOfTheZipFile) {
1339 if (PathSplitFirstZipFolder(path,zipRoot,zipRelativePath)) {
1342 if (prefixResultWithTheFullPathOfTheZipFile) {
1344 if (strlen(tmp)>0 && tmp[0]!=
'/' && tmp[0]!=
'\\') strcat(rv,
"/");
1350void PathGetAbsoluteWithZipSupport(
const char* path,
char* rv) {
1354 if (PathSplitFirstZipFolder(path,zipRoot,zipRelativePath)) {
1358 if (strlen(zipRelativePath)>0 && zipRelativePath[0]!=
'/' && zipRelativePath[0]!=
'\\') strcat(rv,
"/");
1359 strcat(rv,zipRelativePath);
1365template <
typename CharType>
bool FileGetContentBase(
const char* path,ImVector<CharType>& bufferOut,
bool openInTextMode,
const char* password) {
1368# ifdef IMGUI_USE_MINIZIP
1370 PathSplitFirstZipFolder(path,mainPath,zipPath,
true);
1372 if (strlen(zipPath)>0) {
1373 UnZipFile unz(mainPath);
1374 return unz.getFileContent(zipPath,bufferOut,password);
1377 strcpy(mainPath,path);
1379 FILE* fin = ImFileOpen(mainPath,openInTextMode?
"rt":
"rb");
1380 if (!fin)
return false;
1382 const long szl = ftell(fin);
1383 const size_t sz = (size_t) szl;
1384 if ((
sizeof(
long)>
sizeof(
size_t) && szl!=(
long)sz) || (
sizeof(long)<
sizeof(
size_t) && (size_t)szl!=sz)) {
1385 fprintf(stderr,
"Error in: FileGetContent(\"%s\"): file too big.\n",mainPath);
1386 fclose(fin);fin=NULL;
1390 if (openInTextMode) {bufferOut.resize(sz+1);bufferOut[sz]=
'\0';}
1391 else bufferOut.resize(sz);
1393 if (bufferOut.size()>=(
int)sz) fread(&bufferOut[0],(
size_t)sz,1,fin);
1395 fprintf(stderr,
"Error in: FileGetContent(\"%s\"): file too big.\n",mainPath);
1397 fclose(fin);fin=NULL;
1401 fclose(fin);fin=NULL;
1404bool FileGetContent(
const char* path,ImVector<unsigned char>& bufferOut,
bool openInTextMode,
const char* password) {
return FileGetContentBase<unsigned char>(path,bufferOut,openInTextMode,password);}
1405bool FileGetContent(
const char* path,ImVector<char>& bufferOut,
bool openInTextMode,
const char* password) {
return FileGetContentBase<char>(path,bufferOut,openInTextMode,password);}
1419 static char tmp[512];
1422 char* token = strtok(tmp,
";");
1431 strcpy(&
v[vSz],token);
1433 token = strtok(NULL,
";");
1446 add(
"h;hpp;hh;hxx;inl");
1447 add(
"cpp;c;cxx;cc");
1448 add(
"jpg;jpeg;png;bmp;ico;gif;tif;tiff;tga");
1450 add(
"doc;docx;odt;ott;uot");
1451 add(
"txt;setting;settings;layout;ini;md;sh;bat");
1452 add(
"db;sql;sqlite");
1453 add(
"ods;ots;uos;xlsx;xls");
1454 add(
"odp;otp;uop;pptx;ppt");
1455 add(
"7z;zip;bz2;gz;lz;lzma;ar;rar");
1456 add(
"mp3;wav;ogg;spx;opus;mid;mod;flac");
1457 add(
"mp4;flv;avi;ogv;theora;mkv;webm;mpg");
1463 if (!ext)
return -1;
1464 if (ext[0]==
'.') ext+=1;
1465 const int extLen = strlen(ext);
1466 if (extLen==0)
return -1;
1467 typedef int (*strcmpdelegate) (
const char*,
const char*);
1468 const strcmpdelegate myStrCmp = caseSensitiveMatch ? &strcmp : &
strcasecmp;
1469 int start=0,startLen=0;
1470 for (
int si = 0,siSz=
vStarters.size();si<siSz;si++) {
1472 if (extLen!=startLen)
continue;
1479 fileExtensionTypes.resize(fileNames.size());
1480 for (
int i=0,isz=fileNames.size();i<isz;i++) fileExtensionTypes[i] =
getExtensionType(strrchr(fileNames[i],
'.'));
1483 inline bool drawIcon(
int extensionType,
const ImVec4* pOptionalColorOverride=NULL)
const {
1486 inline bool drawIcon(
const char* ext,
bool caseSensitiveMatch=
false,
const ImVec4* pOptionalColorOverride=NULL)
const {
1488 return drawIcon(extType,pOptionalColorOverride);
1495#ifndef IMGUIFS_NO_EXTRA_METHODS
1502#if (defined(__EMSCRIPTEN__) && defined(EMSCRIPTEN_SAVE_SHELL))
1503bool FileDownload(
const char* path,
const char* optionalSaveFileName) {
1504 if (!path || !
FileExists(path))
return false;
1505 ImGuiTextBuffer buffer;
1506 if (optionalSaveFileName) buffer.appendf(
"saveFileFromMemoryFSToDisk(\"%s\",\"%s\")",path,optionalSaveFileName);
1510 buffer.appendf(
"saveFileFromMemoryFSToDisk(\"%s\",\"%s\")",path,fileName);
1512 emscripten_run_script(&buffer.Buf[0]);
1547 if (!path || strlen(path)==0)
reset();
1558# ifdef IMGUI_USE_MINIZIP
1559 const char* lower =
".zip";
const char* upper =
".ZIP";
const int numCharsToMath = (int)strlen(lower);
int gc=0;
1560 for (
int j=0,jsz=(
int)
SplitPath.size();j<jsz;j++) {
1563 const int sz = (int) strlen(path);
1564 const int startCharToMatch = (j==jsz-1) ? numCharsToMath : (numCharsToMath+1);
1565 if (sz<=startCharToMatch)
continue;
1566 const int i = sz-startCharToMatch;
1570 while (c==lower[gc] || c==upper[gc]) {
1572 if (++gc==numCharsToMath) {
1591 if (!path || strncmp(path,
fullFolder,strlen(path))!=0)
return -1;
1596 for (
int i=0,sz=(
int)
SplitPath.size();i<sz;i++) {
1599 if (strcmp(tmp,path)==0) {spi=i;
break;}
1607 const int splitPathSize = (int)
SplitPath.size();
1608 if (_splitPathIndex<0 || _splitPathIndex>=splitPathSize)
return false;
1614 if (_splitPathIndex>=0 && _splitPathIndex<splitPathSize) {
1615 for (
int i=0;i<=_splitPathIndex;i++) {
1650 if (!currentFolder || strlen(currentFolder)==0)
return false;
1661 if (lastInfo.
isEqual(currentFolder))
return false;
1666 if (splitPathIndexInsideLastInfo==-1) {
1684 if (lastInfo.
isEqual(fi))
return false;
1722# ifdef IMGUI_USE_MINIZIP
1763# if FILENAME_MAX!=DIRENT_MAX_PATH
1814# ifdef IMGUI_USE_MINIZIP
1820 int approxNumEntriesPerColumn = 20;
1821 if (childWindowSize.y>0) {
1822 int numLinesThatFit = childWindowSize.y/ImGui::GetTextLineHeightWithSpacing();
1823 if (numLinesThatFit<=0) numLinesThatFit=1;
1824 approxNumEntriesPerColumn = numLinesThatFit;
1833 int maxNumBrowsingColumns = (childWindowSize.x>0) ? (childWindowSize.x/100) : 6;
1834 if (maxNumBrowsingColumns<1) maxNumBrowsingColumns=1;
1862 inline static void ColorCombine(ImVec4& c,
const ImVec4& r,
const ImVec4& factor) {
1863 const float rr = (r.x+r.y+r.z)*0.3334f;
1864 c.x = rr * factor.x;c.y = rr * factor.y;c.z = rr * factor.z;c.w = r.w;
1878Dialog::Dialog(
bool noKnownDirectoriesSection,
bool noCreateDirectorySection,
bool noFilteringSection,
bool detectKnownDirectoriesAtEachOpening,
bool addDisplayByOption,
bool dontFilterSaveFilePathsEnteredByTheUser) {
1908 va_start(args, fmt);
1909 int w = vsnprintf(buf, buf_size, fmt, args);
1911 buf[buf_size-1] = 0;
1912 return (w == -1) ? buf_size : (size_t)w;
1917const 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) {
1927 static const int* pNumberKnownUserDirectoriesExceptDrives=NULL;
1931 const ImGuiStyle& style = ImGui::GetStyle();
1932 ImVec4 dummyButtonColor(0.0f,0.0f,0.0f,0.5f);
1933 ImVec4 dummyZipButtonColor(0.0f,0.0f,0.0f,0.5f);
1937 static const ImVec4 df(0.9,0.9,0.3,0.65);
1938 static const ImVec4 ff(0.7,0.7,0.7,0.65);
1939 static const ImVec4 zdf(1.5,0.8,0.8,0.65);
1942 ImVec4& c = ColorSet[i];
1943 const ImVec4& r = style.Colors[i<sz ? ((int)ImGuiCol_Button + i) : ImGuiCol_Text];
1945 if (i<sz) c.w *= df.w;
1948 ImVec4& c = ColorSet[i];
1951 if (i<sz) c.w *= ff.w;
1954 ImVec4& c = ColorSet[i];
1955 const ImVec4& r = style.Colors[i<sz ? ((int)ImGuiCol_Button + i) : ImGuiCol_Text];
1957 if (c.x>1.f) c.x=1.f;
1958 if (c.y>1.f) c.y=1.f;
1959 if (c.z>1.f) c.z=1.f;
1960 if (c.w>1.f) c.w=1.f;
1961 if (i<sz) c.w *= zdf.w;
1963 if (dummyButtonColor.w>0) {
1964 const ImVec4& bbc = style.Colors[ImGuiCol_Button];
1965 dummyButtonColor.x = bbc.x;dummyButtonColor.y = bbc.y;dummyButtonColor.z = bbc.z;dummyButtonColor.w *= bbc.w;
1967 if (dummyZipButtonColor.w>0) {
1969 dummyZipButtonColor.x = bbc.x;dummyZipButtonColor.y = bbc.y;dummyZipButtonColor.z = bbc.z;dummyZipButtonColor.w *= bbc.w;
1975# ifndef IMGUI_USE_MINIZIP
1976 if (directory && strlen(directory)>0) {
1986 bool isInsideZipFile =
false;
1987 if (directory && strlen(directory)>0) isInsideZipFile = PathSplitFirstZipFolder(directory,basePath,zipPath);
1988 else isInsideZipFile = PathSplitFirstZipFolder(I.
currentFolder,basePath,zipPath);
1990 strcpy(validDirectory,basePath);
1991 if (zipPath[0]!=
'\0') {
2011 if (_saveFileName) {
2016 isSelectFolderDialog = _isFolderChooserDialog;
2017 isSaveFileDialog = _isSaveFileDialog;
2023 if (!windowTitle || strlen(windowTitle)==0) {
2024 if (isSelectFolderDialog) strcpy(I.
wndTitle,
"Please select a folder");
2025 else if (isSaveFileDialog) strcpy(I.
wndTitle,
"Please choose/create a file for saving");
2026 else strcpy(I.
wndTitle,
"Please choose a file");
2028 else strcpy(I.
wndTitle,windowTitle);
2030 char tmpWndTitleNumber[12];
2032 strcat(I.
wndTitle,tmpWndTitleNumber);
2037 const ImVec2 mousePos = ImGui::GetMousePos();
2038 ImGui::GetCursorPos();
2041 const ImVec2 screenSize = ImGui::GetIO().DisplaySize;
2060# ifndef IMGUI_USE_MINIZIP
2064 if (!isSelectFolderDialog) {
2074 const size_t currentFolderNameSize = strlen(currentFolderName);
2075 if (currentFolderNameSize==0 || currentFolderName[currentFolderNameSize-1]==
':') strcat(currentFolderName,
"/");
2081 const bool isInsideZipFile = PathSplitFirstZipFolder(I.
currentFolder,basePath,zipPath);
2084 if (I.unz.load(basePath,
false)) I.unz.getDirectories(zipPath,I.
dirs,&I.
dirNames,(
Sorting)sortingModeForDirectories,
true);
2088 if (!isSelectFolderDialog) {
2089 if (!isInsideZipFile) {
2094 else if (I.unz.isValid()) {
2104 const size_t currentFolderNameSize = strlen(currentFolderName);
2105 if (currentFolderNameSize==0 || currentFolderName[currentFolderNameSize-1]==
':') strcat(currentFolderName,
"/");
2116# ifdef DEBUG_HISTORY
2125 ImGui::SetNextWindowPos(I.
wndPos);ImGui::SetNextWindowSize(I.
wndSize);
2127 if (!popupOk)
return rv;
2132 ImGui::SetNextWindowPos(I.
wndPos);
2133 ImGui::SetNextWindowSize(I.
wndSize);
2136 if (!popupOk)
return rv;
2143 bool historyBackClicked =
false;
2144 bool historyForwardClicked =
false;
2147 ImGui::PushID(
"historyDirectoriesID");
2152 if (!historyCanGoBack) {
2153 ImGui::PushStyleColor(ImGuiCol_Button,dummyButtonColor);
2154 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,dummyButtonColor);
2155 ImGui::PushStyleColor(ImGuiCol_ButtonActive,dummyButtonColor);
2157 historyBackClicked = ImGui::Button(
"<")&historyCanGoBack;
2159 if (!historyCanGoBack) {
2160 ImGui::PopStyleColor();
2161 ImGui::PopStyleColor();
2162 ImGui::PopStyleColor();
2165 if (!historyCanGoForward) {
2166 ImGui::PushStyleColor(ImGuiCol_Button,dummyButtonColor);
2167 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,dummyButtonColor);
2168 ImGui::PushStyleColor(ImGuiCol_ButtonActive,dummyButtonColor);
2170 historyForwardClicked = ImGui::Button(
">")&historyCanGoForward;
2172 if (!historyCanGoForward) {
2173 ImGui::PopStyleColor();
2174 ImGui::PopStyleColor();
2175 ImGui::PopStyleColor();
2181 if (historyBackClicked || historyForwardClicked) {
2192# ifdef DEBUG_HISTORY
2193 if (historyBackClicked) fprintf(stderr,
"\nPressed BACK to\t");
2194 else fprintf(stderr,
"\nPressed FORWARD to\t");
2196# undef DEBUG_HISTOTY
2206 bool editLocationInputTextReturnPressed =
false;
2209 bool mustValidateInputPath =
false;
2212 if (ImGui::Button(
"L##EditLocationCheckButton")) {
2217 ImGui::SetKeyboardFocusHere();
2222 ImGui::PopStyleColor();
2226 editLocationInputTextReturnPressed = ImGui::InputText(
"##EditLocationInputText",I.
editLocationInputText,
MAX_PATH_BYTES,ImGuiInputTextFlags_AutoSelectAll|ImGuiInputTextFlags_EnterReturnsTrue);
2227 if (editLocationInputTextReturnPressed) mustValidateInputPath =
true;
2228 else ImGui::Separator();
2231 if (mustValidateInputPath) {
2235 size_t len = strlen(cleanEnteredPath);
2236 while (len>0 && (cleanEnteredPath[len-1]==
'/' || cleanEnteredPath[len-1]==
'\\')) {cleanEnteredPath[len-1]=
'\0';len = strlen(cleanEnteredPath);}
2239# ifndef IMGUI_USE_MINIZIP
2249 bool isInsideZipFile =
false;
2251 isInsideZipFile = PathSplitFirstZipFolder(cleanEnteredPath,basePath,zipPath,
false);
2252 if (!isInsideZipFile) {
2262 bool dirExists =
false;
2263 if (strcmp(I.unz.getZipFilePath(),basePath)==0) dirExists = I.unz.directoryExists(zipPath);
2265 UnZipFile unz(basePath);
2266 dirExists = unz.directoryExists(zipPath);
2280 else ImGui::SameLine();
2286 bool mustSwitchSplitPath =
false;
2289 ImVec2& framePadding = ImGui::GetStyle().FramePadding;
2290 const float originalFramePaddingX = framePadding.x;
2312 float windowWidth = -1;
float sumX = 0;
2314 sumX+=ImGui::GetCursorPosX();
2315 windowWidth=ImGui::GetWindowWidth()-ImGui::GetStyle().WindowPadding.x;
2317 for (
int t=0;t<numTabs;t++) {
2319 const ImVec4* pDummyButtonColor = &dummyButtonColor;
2320# ifdef IMGUI_USE_MINIZIP
2323 ImGui::PushStyleColor(ImGuiCol_Button,*pDummyButtonColor);
2324 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,*pDummyButtonColor);
2325 ImGui::PushStyleColor(ImGuiCol_ButtonActive,*pDummyButtonColor);
2327# ifdef IMGUI_USE_MINIZIP
2341 sumX+= 2.*ImGui::GetStyle().FramePadding.x;
2342 if (sumX >= windowWidth) sumX=0;
2343 if (t!=0 && sumX>0) ImGui::SameLine(0,0);
2345 else if (t>0) ImGui::SameLine(0,0);
2347 if (wrapMode && sumX==0) {sumX = ImGui::GetStyle().WindowPadding.x + ImGui::GetItemRectSize().x;}
2350 if (fi.
splitPathIndex!=t && !mustSwitchSplitPath) mustSwitchSplitPath =
true;
2354 ImGui::PopStyleColor();
2355 ImGui::PopStyleColor();
2356 ImGui::PopStyleColor();
2358# ifdef IMGUI_USE_MINIZIP
2360 ImGui::PopStyleColor();
2361 ImGui::PopStyleColor();
2362 ImGui::PopStyleColor();
2366 if (mustSwitchSplitPath) {
2378 framePadding.x = originalFramePaddingX;
2388 if (ImGui::CollapsingHeader(
"Known Directories##imguifs_UserKnownDirectories")) {
2398 for (
int i=0,sz=(
int)pUserKnownDirectories->size();i<sz;i++) {
2399 const char* userKnownFolder = (*pUserKnownDirectories)[i];
2400 const char* userKnownFolderDisplayName = (*pUserKnownDirectoryDisplayNames)[i];
2402 if (ImGui::SmallButton(userKnownFolderDisplayName) && strcmp(userKnownFolder,I.
currentFolder)!=0) {
2409 if (i!=sz-1 && (i>=*pNumberKnownUserDirectoriesExceptDrives || i%7!=6)) ImGui::SameLine();
2412 ImGui::PopStyleColor();
2413 ImGui::PopStyleColor();
2414 ImGui::PopStyleColor();
2415 ImGui::PopStyleColor();
2423 if (allowDirectoryCreation && !isBrowsingInsideZipFile) {
2425 bool mustCreate =
false;
2427 if (ImGui::CollapsingHeader(
"New Directory##imguifs_allowDirectoryCreation")) {
2433 mustCreate = ImGui::Button(
"CREATE");
2443# ifdef SIMULATING_ONLY
2444 fprintf(stderr,
"creating: \"%s\"\n",newDirPath);
2445# undef SIMULATING_ONLY
2448 if (!
Directory::Exists(newDirPath)) fprintf(stderr,
"Error creating new folder: \"%s\"\n",newDirPath);
2458 if (ImGui::CollapsingHeader(
"Filtering##imguifs_fileNameFiltering")) {
2474 ImGui::Text(
"Sorting by: ");ImGui::SameLine();
2483 int newSortingMode = oldSortingMode;
2484 static const char* names[numTabs] = {
"Name",
"Modified",
"Size",
"Type"};
2485 const int numUsedTabs = isSelectFolderDialog ? 2 : numTabs;
2486 for (
int t=0;t<numUsedTabs;t++) {
2487 if (t>0) ImGui::SameLine();
2488 if (t==oldSelectedTab) {
2489 ImGui::PushStyleColor(ImGuiCol_Button,dummyButtonColor);
2491 ImGui::PushID(&names[t]);
2492 const bool pressed = ImGui::SmallButton(names[t]);
2495 if (oldSelectedTab==t) {
2496 newSortingMode = oldSortingMode;
2497 if (newSortingMode%2==0) ++newSortingMode;
2498 else --newSortingMode;
2500 else newSortingMode = t*2;
2502 if (t==oldSelectedTab) {
2503 ImGui::PopStyleColor();
2507 if (newSortingMode!=oldSortingMode) {
2516 ImGui::Text(
" Display by:");
2518 ImGui::PushStyleColor(ImGuiCol_Button,dummyButtonColor);
2522 ImGui::PopStyleColor();
2534 if (ImGui::BeginChild(
"BrowsingFrame",ImVec2(0,(isSaveFileDialog || isSelectFolderDialog)?(ImGui::GetContentRegionAvail().y-1.2f*ImGui::GetTextLineHeightWithSpacing()-ImGui::GetStyle().WindowPadding.y):0))) {
2547 if (I.
dirs.size()>0) {
2554 for (
int i=0,sz=(
int)I.
dirs.size();i<sz;i++) {
2555 const char* dirName = &I.
dirNames[i][0];
2556 if (I.
filter.PassFilter(dirName)) {
2558 if (ImGui::SmallButton(dirName)) {
2569 ImGui::NextColumn();
2574 ImGui::PopStyleColor();
2575 ImGui::PopStyleColor();
2576 ImGui::PopStyleColor();
2577 ImGui::PopStyleColor();
2580 if (!isSelectFolderDialog && I.
files.size()>0) {
2587# ifdef IMGUI_USE_MINIZIP
2589 const bool acceptZipFilesForBrowsing = !isBrowsingInsideZipFile;
2590 bool isZipFile =
false;
bool hasZipExtension =
false;
2600 for (
int i=0,sz=(
int)I.
files.size();i<sz;i++) {
2601 const char* fileName = &I.
fileNames[i][0];
2602 if (I.
filter.PassFilter(fileName)) {
2603# ifdef IMGUI_USE_MINIZIP
2604 if (acceptZipFilesForBrowsing) {
2606 if (hasZipExtension && !isZipFile) {
2607 ImGui::PopStyleColor(4);
2614 else if (!hasZipExtension && isZipFile) {
2615 ImGui::PopStyleColor(4);
2622 isZipFile = hasZipExtension;
2626 if (ImGui::SmallButton(fileName)) {
2627 if (!isSaveFileDialog) {
2628 strcpy(rv,I.
files[i]);
2635# if (defined(__EMSCRIPTEN__) && defined(EMSCRIPTEN_SAVE_SHELL))
2637# ifndef IMGUI_USE_MINIZIP
2638 if (ImGui::IsItemHovered() && ImGui::GetIO().KeyCtrl) {
2639 ImGui::SetTooltip(
"%s",
"right click to download this file locally");
2640 if (ImGui::GetIO().MouseClicked[1]) {
2641 strcpy(tmpString,
"saveFileFromMemoryFSToDisk('");
2642 strcat(tmpString,I.
files[i]);strcat(tmpString,
"','");
2643 strcat(tmpString,fileName);strcat(tmpString,
"')");
2645 emscripten_run_script(tmpString);
2649 if (ImGui::IsItemHovered()) {
2650 if (!isBrowsingInsideZipFile && ImGui::GetIO().KeyCtrl) {
2651 ImGui::SetTooltip(
"%s",
"right click to download this file locally");
2652 if (ImGui::GetIO().MouseClicked[1]) {
2653 strcpy(tmpString,
"saveFileFromMemoryFSToDisk('");
2654 strcat(tmpString,I.
files[i]);strcat(tmpString,
"','");
2655 strcat(tmpString,fileName);strcat(tmpString,
"')");
2657 emscripten_run_script(tmpString);
2660 else if (isZipFile) {
2661 ImGui::SetTooltip(
"right click to browse it");
2662 if (ImGui::GetIO().MouseClicked[1]) {
2672# elif IMGUI_USE_MINIZIP
2674 if (ImGui::IsItemHovered()) ImGui::SetTooltip(
"right click to browse it");
2675 if (ImGui::GetIO().MouseClicked[1]) {
2688 ImGui::NextColumn();
2693 ImGui::PopStyleColor();
2694 ImGui::PopStyleColor();
2695 ImGui::PopStyleColor();
2696 ImGui::PopStyleColor();
2706 if (isSaveFileDialog || isSelectFolderDialog) {
2708 bool selectionButtonPressed =
false;
2711 float lastTwoButtonsWidth = 0;
2713 if (isSaveFileDialog) {
2714 ImGui::AlignTextToFramePadding();
2715 ImGui::Text(
"File:");ImGui::SameLine();
2716 lastTwoButtonsWidth = ImGui::CalcTextSize(
"Save Cancel").x+2.0f*(style.FramePadding.x+style.ItemSpacing.x)+style.WindowPadding.x;
2717 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x-lastTwoButtonsWidth);
2720 ImGui::PopItemWidth();
2724 ImGui::AlignTextToFramePadding();
2726 static const ImVec4 sf(1.0,0.8,0.5,1);
2728 const ImVec4& r = style.Colors[ImGuiCol_Text];
2735 lastTwoButtonsWidth = ImGui::CalcTextSize(
"Select Cancel").x+2.0f*(style.FramePadding.x+style.ItemSpacing.x)+style.WindowPadding.x;
2736 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x-lastTwoButtonsWidth);
2738 ImGui::PopItemWidth();
2742 bool mustCancel =
false;
2743 if (ImGui::Button(
"Cancel")) {mustCancel =
true;} ImGui::SameLine();
2745 if (isSelectFolderDialog) selectionButtonPressed = ImGui::Button(
"Select");
2746 else selectionButtonPressed = ImGui::Button(
"Save");
2751 if (selectionButtonPressed) {
2752 if (isSelectFolderDialog) {
2756 else if (isSaveFileDialog) {
2762 const bool saveFileNameHasExtension = strlen(saveFileNameExtension)>0;
2765 const size_t wExtsSize = wExts.size();
2766 if (!saveFileNameHasExtension) {
2767 if (wExtsSize==0) pathOk =
true;
2772 for (
size_t i = 0;i<wExtsSize;i++) {
2773 const char* ext = wExts[i];
2774 if (strcmp(ext,saveFileNameExtension)==0) {
2779 if (!pathOk && wExtsSize>0) strcat(I.
saveFileName,wExts[0]);
2785 strcpy(rv,savePath);
2791 else if (mustCancel && rv[0]==0) {
2792 ImGui::CloseCurrentPopup();
2793# ifdef IMGUI_USE_MINIZIP
2805 if (rv[0]!=0 || !I.
open) {
2806 ImGui::CloseCurrentPopup();
2807# ifdef IMGUI_USE_MINIZIP
2816const char*
Dialog::chooseFileDialog(
bool dialogTriggerButton,
const char* directory,
const char* fileFilterExtensionString,
const char* windowTitle,
const ImVec2& windowSize,
const ImVec2& windowPos,
const float windowAlpha) {
2819 const char* cp =
ChooseFileMainMethod(*
this,directory,
false,
false,
"",fileFilterExtensionString,windowTitle,windowSize,windowPos,windowAlpha);
2822# ifdef IMGUI_USE_MINIZIP
2831const char*
Dialog::chooseFolderDialog(
bool dialogTriggerButton,
const char* directory,
const char* windowTitle,
const ImVec2& windowSize,
const ImVec2& windowPos,
const float windowAlpha) {
2834 const char* cp =
ChooseFileMainMethod(*
this,directory,
true,
false,
"",
"",windowTitle,windowSize,windowPos,windowAlpha);
2837# ifdef IMGUI_USE_MINIZIP
2846const char*
Dialog::saveFileDialog(
bool dialogTriggerButton,
const char* directory,
const char* startingFileNameEntry,
const char* fileFilterExtensionString,
const char* windowTitle,
const ImVec2& windowSize,
const ImVec2& windowPos,
const float windowAlpha) {
2849 const char* cp =
ChooseFileMainMethod(*
this,directory,
false,
true,startingFileNameEntry,fileFilterExtensionString,windowTitle,windowSize,windowPos,windowAlpha);
2852# ifdef IMGUI_USE_MINIZIP
2864#ifndef IMGUIFS_NO_EXTRA_METHODS
2879 struct stat statbuf;
return (stat(path, &statbuf) != -1 && (S_ISDIR(statbuf.st_mode) || S_ISREG(statbuf.st_mode)));
2883 struct stat statbuf;
return (stat(path, &statbuf) != -1 && S_ISREG(statbuf.st_mode));
static void GetDirectoryName(const char *filePath, char *rv)
static bool HasZipExtension(const char *filePath)
static void GetAbsolutePath(const char *path, char *rv)
static void Split(const char *path, FilenameStringVector &rv, bool leaveIntermediateTrailingSlashes=true)
static void ChangeExtension(const char *filePath, const char *newExtension, char *rv)
static void GetFileName(const char *filePath, char *rv)
static void GetFileNameWithoutExtension(const char *filePath, char *rv)
static void GetExtension(const char *filePath, char *rv)
static void Combine(const char *directory, const char *fileName, char *rv, bool appendMode=true)
static void Append(const char *directory, char *rv)
static const SorterSignature Sorters[]
static int Lastmodsort(const struct dirent **e1, const struct dirent **e2)
static SorterSignature sorter
static int Sizesort(const struct dirent **e1, const struct dirent **e2)
static int Lastmodsortinverse(const struct dirent **e1, const struct dirent **e2)
static int Typesort(const struct dirent **e1, const struct dirent **e2)
static int Alphasortinverse(const struct dirent **e1, const struct dirent **e2)
static int Alphasort(const struct dirent **e1, const struct dirent **e2)
static int Typesortinverse(const struct dirent **e1, const struct dirent **e2)
static const SorterSignature & SetSorter(Sorting sorting)
int(* SorterSignature)(const struct dirent **e1, const struct dirent **e2)
static int Sizesortinverse(const struct dirent **e1, const struct dirent **e2)
static void Substr(const char *text, char *rv, int start, int count=-1)
static void PushBack(FilenameStringVector &rv, const char *s)
static void ReplaceInPlace(char *text, const char toReplace, const char replacement)
static void Split(const char *text, FilenameStringVector &rv, const char c=' ')
static void Replace(const char *baseText, const char textToReplace, const char replacement, char *rv)
static void ToLowerInPlace(char *text)
static int Find(const char *text, const char toFind, int beg=0)
static void ToLower(const char *text, char *rv)
static int FindLastOf(const char *text, const char toFind)
unsigned long long int ZPOS64_T
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)
void PathChangeExtension(const char *filePath, const char *newExtension, char *rv)
int FileGetExtensionType(const char *path)
@ SORT_ORDER_TYPE_INVERSE
@ 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)
bool FileGetContentBase(const char *path, ImVector< CharType > &bufferOut, bool openInTextMode, const char *password)
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)
static size_t ImFormatString(char *buf, size_t buf_size, const char *fmt,...)
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
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 Dialog(bool noKnownDirectoriesSection=false, bool noCreateDirectorySection=false, bool noFilteringSection=false, bool detectKnownDirectoriesAtEachOpening=false, bool addDisplayByOption=false, bool dontFilterSaveFilePathsEnteredByTheUser=false)
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
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)
static void GetFiles(const char *path, PathStringVector &files, const char *wantedExtensions, const char *unwantedExtensions=NULL, FilenameStringVector *pOptionalNamesOut=NULL, Sorting sorting=SORT_ORDER_ALPHABETIC)
static int DirentGetFiles(const struct dirent *de)
static int DirentGetDirectories(const struct dirent *de)
static const PathStringVector & GetUserKnownDirectories(const FilenameStringVector **pOptionalUserKnownDirectoryDisplayNamesOut, const int **pOptionalNumberKnownUserDirectoriesExceptDrives=NULL, bool forceUpdate=false)
static void GetFiles(const char *directoryName, PathStringVector &result, FilenameStringVector *pOptionalNamesOut=NULL, Sorting sorting=SORT_ORDER_ALPHABETIC)
static bool Exists(const char *path)
static void GetDirectories(const char *directoryName, PathStringVector &result, FilenameStringVector *pOptionalNamesOut=NULL, Sorting sorting=SORT_ORDER_ALPHABETIC)
static void Create(const char *directoryName)
bool getFolderInfoForSplitPathIndex(int _splitPathIndex, FolderInfo &rv) const
static FilenameStringVector SplitPath
static int GetSplitPathIndexOfZipFile(const FilenameStringVector &SplitPath)
void fromCurrentFolder(const char *path)
const FolderInfo & operator=(const FolderInfo &o)
char currentFolder[MAX_PATH_BYTES]
int getSplitPathIndexFor(const char *path) const
int splitPathIndexOfZipFile
bool isEqual(const FolderInfo &fi) const
char fullFolder[MAX_PATH_BYTES]
void getSplitPath(FilenameStringVector &splitPath) const
bool isEqual(const char *path) const
FolderInfo(const FolderInfo &o)
ImVector< FolderInfo > info
bool getCurrentSplitPath(FilenameStringVector &rv) const
bool switchTo(const char *currentFolder)
const char * getCurrentFolder() const
size_t getInfoSize() const
bool switchTo(const FolderInfo &fi)
const FolderInfo * getCurrentFolderInfo() const
const int * getCurrentSplitPathIndex() const
int getExtensionType(const char *ext, bool caseSensitiveMatch=false) const
ImVector< int > vStartersCounts
bool drawIcon(int extensionType, const ImVec4 *pOptionalColorOverride=NULL) const
bool drawIcon(const char *ext, bool caseSensitiveMatch=false, const ImVec4 *pOptionalColorOverride=NULL) const
ImVector< int > vStarters
void fillExtensionTypesFromFilenames(ImVector< int > &fileExtensionTypes, const FilenameStringVector &fileNames)
static ImGuiFsDrawIconStruct & Get()
ImVector< int > vStartersLengths
int add(const char *exts)
FilenameStringVector currentSplitPath
static bool BrowsingPerRow
bool allowKnownDirectoriesSection
bool detectKnownDirectoriesAtEveryOpening
char editLocationInputText[MAX_PATH_BYTES]
ImVector< int > fileExtensionTypes
bool forbidDirectoryCreation
static void FreeMemory(PathStringVector &v)
char newDirectoryName[MAX_FILENAME_BYTES]
char chosenPath[MAX_PATH_BYTES]
bool editLocationCheckButtonPressed
FilenameStringVector fileNames
int numBrowsingEntriesPerColumn
void calculateBrowsingDataTableSizes(const ImVec2 &childWindowSize=ImVec2(-1,-1))
bool allowDirectoryCreation
@ ImGuiCol_Dialog_File_Hover
@ ImGuiCol_Dialog_Directory_Pressed
@ ImGuiCol_Dialog_Directory_Text
@ ImGuiCol_Dialog_File_Background
@ ImGuiCol_Dialog_ZipDirectory_Pressed
@ ImGuiCol_Dialog_ZipDirectory_Text
@ ImGuiCol_Dialog_File_Pressed
@ ImGuiCol_Dialog_File_Text
@ ImGuiCol_Dialog_Directory_Hover
@ ImGuiCol_Dialog_SelectedFolder_Text
@ ImGuiCol_Dialog_ZipDirectory_Hover
@ ImGuiCol_Dialog_ZipDirectory_Background
@ ImGuiCol_Dialog_Directory_Background
char wndTitle[MAX_PATH_BYTES]
static void ColorCombine(ImVec4 &c, const ImVec4 &r, const ImVec4 &factor)
bool isSelectFolderDialog
char currentFolder[MAX_PATH_BYTES]
bool forceSetWindowPositionAndSize
bool allowDisplayByOption
bool userHasJustCancelledDialog
FilenameStringVector dirNames
bool mustFilterSaveFilePathWithFileFilterExtensionString
int totalNumBrowsingEntries
char saveFileName[MAX_FILENAME_BYTES]
ZPOS64_T uncompressed_size
int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password)
int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity)
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
int ZEXPORT unzGoToFirstFile(unzFile file)
int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len)
int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info)
unzFile ZEXPORT unzOpen64(const void *path)
int ZEXPORT unzCloseCurrentFile(unzFile file)
int ZEXPORT unzGoToNextFile(unzFile file)
int ZEXPORT unzClose(unzFile file)