diff --git a/filepicker.hpp b/filepicker.hpp index 45e5353..2e5f8a4 100644 --- a/filepicker.hpp +++ b/filepicker.hpp @@ -1,11 +1,23 @@ //DEBUG MACRO +#ifdef DEBUG #define log_debugc(str, ...) do { if (debug) fprintf(stdout, "[DEBUG] (%s:%d): " (str) "\n", __FILE__, __LINE__, ##__VA_ARGS__); } while (0) #define log_debugcpp(str) do { \ if (debug) std::cout << "[DEBUG]" << "(" << __FILE__ << ":" << __LINE__ << "): " << str << std::endl; \ - } while (0) + } while (0) +#define log_wdebugcpp(str) do { \ + if (debug) std::wcout << "[DEBUG]" << "(" << __FILE__ << ":" << __LINE__ << "): " << str << std::endl; \ + } while (0) #define log_directory(str) if(debugVerbosity & DEBUG_DIRECTORY) log_debugcpp((str)) #define log_volume(str) if(debugVerbosity & DEBUG_VOLUME) log_debugcpp((str)) -#define log_extension(str) if(debugVerbosity & DEBUG_EXTENSION) log_debugcpp((str)) +#define log_extension(str) if(debugVerbosity & DEBUG_EXTENSION) log_debugcpp((str)) +#else +#define log_debugc(str, ...) +#define log_debugcpp(str) +#define log_wdebugcpp(str) +#define log_directory(str) +#define log_volume(str) +#define log_extension(str) +#endif //PATH MACRO #define MAX_LISTDIR_PATH_LENGTH (MAX_PATH - 3) @@ -23,14 +35,13 @@ #pragma once - - namespace fp { typedef struct { long long size; //TODO yel spacsio NELLA MEMoria - TCHAR name[MAX_LISTDIR_PATH_LENGTH]; + WCHAR name[MAX_LISTDIR_PATH_LENGTH]; + char nameUTF8[MAX_LISTDIR_PATH_LENGTH * 4]; SYSTEMTIME createTime; SYSTEMTIME lastAccessTime; SYSTEMTIME lastWriteTime; @@ -40,16 +51,34 @@ typedef struct { } directoriesInfo; -struct History{ - std::vector previousPaths; +struct History { + std::vector previousPaths; + std::vector previousPathsUTF8; //warnings e 1 cosa //int historyDepth = -1; //TODO Limitar historial //const int maxHistoryDepth = 10000; + //int currentStart = 0; int historyDepth; int historyTraversalPos; bool isAdditionTime; + // wchar* operator[](int idx){ + // if (idx > previousPaths.size()) + // int newPos = idx + currentStart; + + // if (newPos < 0) return previousPaths[maxHistoryDepth - (newPos % maxHistoryDepth)]; + // else return previousPaths[newPos % maxHistoryDepth]; + + // } + + // void push_back(wchar* path){ + // if (previousPaths.size() < maxHistoryDepth) previousPaths.push_back(path); + // else { + // previousPaths[currentStart++] = path; + // } + // } + History(){ historyTraversalPos = historyDepth = -1; isAdditionTime = true; @@ -66,7 +95,7 @@ enum ListDirectoryError { DIRECTORY_ERROR_ACCESSING_CONTENT = -2 }; -enum agnosticDirError { +enum AgnosticDirError { AGDIR_ERROR_ACCESS_DENIED = 1 }; @@ -78,51 +107,81 @@ namespace ErrorMessages { char moveUpError[] = "Failed to move up: reached volume root?"; }; -enum listFlags { +namespace Label { + wchar_t saveFileLabel[] = L"Save file: "; + wchar_t loadFileLabel[] = L"Select a file: "; + wchar_t selectDirectoryLabel[] = L"Select a directory: "; +}; + +enum ListFlags { LIST_DIRECTORY = (1<<0), LIST_VOLUME = (1<<1) }; +enum WindowFlags { + FP_FULLSCREEN = (1<<0), + FP_MODAL = (1<<1), + FP_FILE_LOAD = (1<<2), + FP_FILE_SAVE = (1<<3), + FP_DIRECTORY_SELECT = (1<<4) +}; + +enum exitFlags { + EXIT_CONTINUE = (1<<0), + EXIT_SELECTED = (1<<1), + EXIT_CLOSED = (1<<2), + EXIT_ERROR = (1<<3) +}; + //VARS - +#ifdef DEBUG bool debug = true; +#else +bool debug = false; +#endif -History* history = new History(); - +// Window open bool +bool windowOpen = true; +bool windowConfigured = false; + //Flags used to determine: // window format -int windowFlags = 0; +//int windowFlags = 0; // if it's time to load new data int listFlags = LIST_DIRECTORY | LIST_VOLUME; //Array used to display current error char error[MAX_ERRORSTR_LEN]; +//wchar_t errorUTF8[MAX_ERRORSTR_LEN * 4]; bool showError = false; //Stores found volumes -//TODO onPresentPaths???? wtf is dis naem bru -std::vector onPresentPaths; +//TODO onPresentPaths might not be the best name +std::vector onPresentPaths; +std::vector onPresentPathsUTF8; int numVolumes; -//currentPath is the one used to retrieve data, then copied to addrBalVar for display. -//addrBalVar is also used as a bacukp in case new currentPath is invalid +//currentPath is the one used to retrieve data, then copied to addrBarVal for display. +//addrBarVal is also used as a bacukp in case new currentPath is invalid +//chosenFile stores absolute file path to return //TODO: hay historial. Coalescer en una sola? -//TODO: david wtf -//cursed C momento: necesario ptr en otra var para mandar a char** de firma -char currentPath[MAX_PATH]; -char* currentPathPtr = ¤tPath[0]; -char addrBarVal[MAX_LISTDIR_PATH_LENGTH]; -char* addrBarValPtr = &addrBarVal[0]; - +//cursed C momento: necesario ptr en otra var para mandar a wchar_t** de firma +wchar_t currentPath[MAX_PATH]; +//wchar_t* currentPathPtr = ¤tPath[0]; +wchar_t addrBarVal[MAX_LISTDIR_PATH_LENGTH]; +char addrBarValUTF8[MAX_LISTDIR_PATH_LENGTH * 4]; +//wchar_t* addrBarValPtr = &addrBarVal[0]; +wchar_t chosenPath[MAX_PATH]; +char chosenPathUTF8[MAX_PATH * 4]; + //Stores entires found within a given directory //static int currentItemIdx = -1; std::vector directoryContents; int numFiles = 0; -//Going one level up needs to be hardcoded like this due to function inputMove needing a char** +//Going one level up needs to be hardcoded like this due to function inputMove needing a wchar_t** //c pervirtio con unicode std::wstring s(L"←→↑↓"); -char moveUp[] = ".."; -char* moveUpPtr = &moveUp[0]; +wchar_t moveUp[] = L".."; bool isListVolumesAdequate = true; bool isListDirectoriesAdequate = true; @@ -130,8 +189,9 @@ bool isListDirectoriesAdequate = true; //RenderTime vars for filtering bool showHidden = false; bool filterByExtension = false; -std::vector extensions; +std::vector extensions; +History* history; // int debugVerbosity = 0; // enum enumDebugVerbosity { @@ -150,29 +210,29 @@ std::vector extensions; /* DIRECTORIES */ -bool retrieveCurrentDirectory(char* currentPath){ +bool retrieveCurrentDirectory(wchar_t* currentPath){ if(GetCurrentDirectory(MAX_PATH, currentPath)) return true; return false; } -bool moveDirectory(char* currentPath){ +bool moveDirectory(wchar_t* currentPath){ log_debugcpp(currentPath); if(SetCurrentDirectory(currentPath)) return true; return false; } -int listDirectory(std::string path, std::vector *directoryContents){ +int listDirectory(std::wstring path, std::vector *directoryContents){ HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA ffd; LARGE_INTEGER filesize; int numFiles = 0; if (path.length() > (MAX_LISTDIR_PATH_LENGTH)) return DIRECTORY_ERROR_PATH_TOO_LONG; - path = path + "\\*"; + path = path + L"\\*"; hFind = FindFirstFile(path.c_str(), &ffd); if (INVALID_HANDLE_VALUE == hFind) return DIRECTORY_ERROR_ACCESSING_CONTENT; do { - if(!strcmp(ffd.cFileName, ".") || !strcmp(ffd.cFileName, "..")) continue; + if(!wcscmp(ffd.cFileName, L".") || !wcscmp(ffd.cFileName, L"..")) continue; log_debugcpp("BUCLE listDirectory iteracion " + std::to_string(numFiles)); directoriesInfo* itemInfo; @@ -198,9 +258,11 @@ int listDirectory(std::string path, std::vector *directoryCont uint64_t idx = 0; do { itemInfo->name[idx] = ffd.cFileName[idx]; + itemInfo->nameUTF8[idx] = ffd.cFileName[idx]; idx++; } while (ffd.cFileName[idx]); itemInfo->name[idx] = '\0'; + itemInfo->nameUTF8[idx] = '\0'; log_debugcpp("INFORMACION ALMACENADA iteracion " + std::to_string(numFiles)); numFiles++; @@ -209,35 +271,37 @@ int listDirectory(std::string path, std::vector *directoryCont return numFiles; } -long getLastDirectorySystemError(){ - long winLastError = GetLastError(); +long getLastSystemError(){ + DWORD winLastError = GetLastError(); switch(winLastError){ case ERROR_ACCESS_DENIED: return AGDIR_ERROR_ACCESS_DENIED; break; default: - return -1; + return winLastError; break; } } /* VOLUMES */ -//new char*[CharCount * sizeof(WCHAR) +//new wchar_t*[Wchar_TCount * sizeof(WWCHAR_T) /*idea, si quisiera que empezase en punto X del string coger el param opcional y crear un puntero a la posicion X del array para empezar desde ahi - int explodePaths(TCHAR* volumePaths, int volumePathLength, int volumePathBufferSize, - char separator, std::vector *dest, , int startingFrom = 0); + int explodePaths(TWCHAR_T* volumePaths, int volumePathLength, int volumePathBufferSize, + wchar_t separator, std::vector *dest, , int startingFrom = 0); if (nextOcurrence == NULL) return 0; */ -int explodePaths(TCHAR* volumePaths, int volumePathsBufferSize, char separator, std::vector *dest, int depth = 1){ - //Por alguna razon esta puta mierda que dice acabar con 2 NULL acaba con 3; de locos. +int explodePaths(wchar_t* volumePaths, int volumePathsBufferSize, wchar_t separator, std::vector *dest, std::vector *destUTF8, int depth = 1){ + //Por alguna razón, esto que dice acabar con 2 NULL acaba con 3; de locos. //https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumepathnamesforvolumenamew - char* nextOcurrence = strchr(volumePaths, separator); + wchar_t* nextOcurrence = wcschr(volumePaths, separator); - char* itemPath; - itemPath = (char*)calloc(1, volumePathsBufferSize); + wchar_t* itemPath; + char* itemPathUTF8; + itemPath = (wchar_t*)calloc(2, volumePathsBufferSize); + itemPathUTF8 = (char*)calloc(4, volumePathsBufferSize); int pathLengthIdx = 0; for (; volumePaths[pathLengthIdx] != nextOcurrence[0]; pathLengthIdx++) { @@ -246,27 +310,32 @@ int explodePaths(TCHAR* volumePaths, int volumePathsBufferSize, char separator, } itemPath[pathLengthIdx + 1] = '\0'; dest->push_back(itemPath); + WideCharToMultiByte(CP_UTF8, NULL, itemPath, -1, itemPathUTF8, + 4 * volumePathsBufferSize, NULL, NULL); + destUTF8->push_back(itemPathUTF8); + - log_debugcpp(dest->at(dest->size() - 1) << " EXPLODEPATH"); + log_wdebugcpp(dest->at(dest->size() - 1) << L" EXPLODEPATH"); + log_debugcpp(dest->at(destUTF8->size() - 1) << " EXPLODEPATH"); if (nextOcurrence[0] == nextOcurrence[1]) return depth; depth++; - return explodePaths(nextOcurrence + sizeof(TCHAR), (volumePathsBufferSize - pathLengthIdx), separator, dest, depth); + return explodePaths(nextOcurrence + sizeof(wchar_t), (volumePathsBufferSize - pathLengthIdx), separator, dest, destUTF8, depth); } -int listVolumes(std::vector *onPresentPaths){ +int listVolumes(std::vector *onPresentPaths, std::vector *onPresentPathsUTF8){ HANDLE hFind = INVALID_HANDLE_VALUE; - const char separator = '\0'; + const wchar_t separator = '\0'; int numVolumes = 0; //Volume name - TCHAR volumeName[MAX_PATH]; + wchar_t volumeName[MAX_PATH]; int volumeNameSize = sizeof volumeName / sizeof volumeName[0]; //Paths - int volumePathsBufferSize = (MAX_PATH + 1) * sizeof(TCHAR); + int volumePathsBufferSize = (MAX_PATH + 1) * sizeof(wchar_t); unsigned long volumePathLength; - TCHAR volumePaths[volumePathsBufferSize]; + wchar_t volumePaths[volumePathsBufferSize]; std::fill(volumePaths, volumePaths + volumePathsBufferSize, '\0'); hFind = FindFirstVolume(volumeName, volumeNameSize); @@ -294,7 +363,7 @@ int listVolumes(std::vector *onPresentPaths){ // exit(1); // } if (debug) { - if(numVolumes += explodePaths(volumePaths, volumePathsBufferSize, separator, onPresentPaths)){ + if(numVolumes += explodePaths(volumePaths, volumePathsBufferSize, separator, onPresentPaths, onPresentPathsUTF8)){ for (int i = 0; i < onPresentPaths->size(); i++){ log_debugcpp(onPresentPaths->at(i)); } @@ -305,7 +374,7 @@ int listVolumes(std::vector *onPresentPaths){ log_debugcpp(std::to_string(volumePathLength) + "<- VOLUME PATH LENGTH"); log_debugcpp("THE END"); } else { - log_debugcpp("no volumes found wtf"); + log_debugcpp("no volumes found"); } //TODO benchimarqui std::fill(volumePaths, volumePaths + volumePathsBufferSize, '\0'); @@ -319,17 +388,17 @@ int listVolumes(std::vector *onPresentPaths){ /* DISPLAY */ -bool compareLastChar(std::vector *lastCharCandidates, char* string){ +bool compareLastWchar(std::vector *lastCharCandidates, wchar_t* string){ bool matchingExtension = false; for (int i = 0; i < lastCharCandidates->size(); i++){ - log_debugcpp(lastCharCandidates->at(i) + " <- FILTERING EXTENSION"); + log_wdebugcpp(lastCharCandidates->at(i) + L" <- FILTERING EXTENSION"); - if(strlen(string) < lastCharCandidates->at(i).length()) continue; - char* potentialExtension = &string[strlen(string) - lastCharCandidates->at(i).length()]; + if(wcslen(string) < lastCharCandidates->at(i).length()) continue; + wchar_t* potentialExtension = &string[wcslen(string) - lastCharCandidates->at(i).length()]; - log_debugcpp(potentialExtension << " LEN " + std::to_string(strlen(potentialExtension)) + " <- VS -> " + lastCharCandidates->at(i) + " LEN " + std::to_string(lastCharCandidates->at(i).length())); + log_wdebugcpp(potentialExtension << L" LEN " + std::to_wstring(wcslen(potentialExtension)) + L" <- VS -> " + lastCharCandidates->at(i) + L" LEN " + std::to_wstring(lastCharCandidates->at(i).length())); //+ strlen(potentialExtension) + std::to_string(lastCharCandidates->at(i).length()) - if(!strcmp(potentialExtension, lastCharCandidates->at(i).c_str())) { + if(!wcscmp(potentialExtension, lastCharCandidates->at(i).c_str())) { log_debugcpp("VALID EXTENSION"); matchingExtension = true; } @@ -338,19 +407,19 @@ bool compareLastChar(std::vector *lastCharCandidates, char* string) } //TODO huh -// int handleFolderAccessResult(int listFlags, char* nextPath, bool* error, char* errorDest, \ - // const char* errorContent, History* history, char* currentPath = NULL, char* addrBarVal = NULL){ +// int handleFolderAccessResult(int listFlags, wchar_t* nextPath, bool* error, wchar_t* errorDest, \ + // const wchar_t* errorContent, History* history, wchar_t* currentPath = NULL, wchar_t* addrBarVal = NULL){ // *error = false; // if(!moveDirectory(nextPath)) { // *error = true; // if(currentPath && addrBarVal) { - // strcpy(errorDest, errorContent); - // strcpy(addrBarVal, currentPath); + // wcscpy(errorDest, errorContent); + // wcscpy(addrBarVal, currentPath); // } // return listFlags; // } // if(currentPath && addrBarVal) { - // strcpy(currentPath, addrBarVal); + // wcscpy(currentPath, addrBarVal); // history->isAdditionTime = true; // } // return (listFlags |= LIST_DIRECTORY); @@ -358,21 +427,21 @@ bool compareLastChar(std::vector *lastCharCandidates, char* string) //TODO huh, vale, no pasa por listdirectory por la flag, pero esto se podria hacer mejor manteniendo el no tirar de disco tb? -int handleFolderAccessResult(int listFlags, char* nextPath, bool* error, char* errorDest, \ - const char* errorContent, History* history, char* currentPath , char* addrBarVal){ +int handleFolderAccessResult(int listFlags, wchar_t* nextPath, bool* error, char* errorDest, \ + const char* errorContent, History* history, wchar_t* currentPath , wchar_t* addrBarVal){ *error = false; if(!moveDirectory(nextPath)) { *error = true; strcpy(errorDest, errorContent); - strcpy(addrBarVal, currentPath); + wcscpy(addrBarVal, currentPath); return listFlags; } - //strcpy(currentPath, addrBarVal); + //wcscpy(currentPath, addrBarVal); history->isAdditionTime = true; return (listFlags |= LIST_DIRECTORY); } -int handleFolderAccessResult(int listFlags, char* nextPath, bool* error, char* errorDest, \ +int handleFolderAccessResult(int listFlags, wchar_t* nextPath, bool* error, char* errorDest, \ const char* errorContent, History* history, bool isAdditionTime){ *error = false; if(!moveDirectory(nextPath)) { @@ -386,21 +455,27 @@ int handleFolderAccessResult(int listFlags, char* nextPath, bool* error, char* e /* HISTORIAL */ -void addPathToHistory(History *history, char* pathToAdd){ - char* path; +void addPathToHistory(History *history, wchar_t* pathToAdd){ + wchar_t* path; + char* pathUTF8; if (history->historyTraversalPos + 1 >= history->previousPaths.size()){ - path = (char*)calloc(1, MAX_PATH); + path = (wchar_t*)calloc(2, MAX_PATH); history->previousPaths.push_back(path); + pathUTF8 = (char*)calloc(4, MAX_PATH); + WideCharToMultiByte(CP_UTF8, NULL, path, -1, pathUTF8, + 4 * MAX_PATH, NULL, NULL); + history->previousPathsUTF8.push_back(pathUTF8); } else { path = history->previousPaths.at(history->historyTraversalPos + 1); + pathUTF8 = history->previousPathsUTF8.at(history->historyTraversalPos + 1); } - strncpy(path, pathToAdd, MAX_PATH); + wcsncpy(path, pathToAdd, MAX_PATH); history->historyTraversalPos++; history->historyDepth = history->historyTraversalPos; history->isAdditionTime = false; } -char* moveThroughHistory(History *history, HistoryMovement movement) { +wchar_t* moveThroughHistory(History *history, HistoryMovement movement) { int sign = (movement == HISTORY_BACKWARD ? -1 : 1); switch(movement){ case HISTORY_BACKWARD: @@ -418,25 +493,60 @@ char* moveThroughHistory(History *history, HistoryMovement movement) { return history->previousPaths.at(history->historyTraversalPos); } +/* RENDERING */ -/* FIN FILE PICKER MOMENTO */ - - -void filePickerMomento(bool isFullViewport = false){ - if (isFullViewport){ +int windowRendering(wchar_t*, bool*, int); +int renderFilePicker(wchar_t* userPath, bool* windowOpen, int windowFlags = 0) { + //TODO filesystem watcher + //TODO let user handle memory management + //TODO use local val to create actual windowFlags when expanding functionality + if (!windowConfigured) { + listFlags = LIST_DIRECTORY | LIST_VOLUME; + history = new History(); + if (windowFlags & FP_FULLSCREEN){ ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f)); ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize; + } else { + ImGui::SetNextWindowPos(ImVec2(50.0f, 50.0f)); + ImGui::SetNextWindowSize(ImVec2(500.0f, 500.0f)); + windowFlags = ImGuiWindowFlags_None; + //const ImGuiViewport* viewport = ImGui::GetMainViewport(); } + windowConfigured = true; + } else windowFlags = 0; + return windowRendering(userPath, windowOpen, windowFlags); +} - ImGui::Begin("File Picker in 4K", NULL, windowFlags); - if (isFullViewport) ImGui::PopStyleVar(1); - +int exitWindow(wchar_t* userPath, bool* windowOpen, int exitFlag){ + if(exitFlag & EXIT_SELECTED) { + if (chosenPath[0] == '\0') return EXIT_CONTINUE; + wcscpy(userPath, chosenPath); + *windowOpen = false; + } + //Memory cleanup + windowConfigured = false; + for (int i = 0; i < history->previousPaths.size(); i++){ + free(history->previousPaths.at(i)); + } + for (int i = 0; i < onPresentPaths.size(); i++){ + free(onPresentPaths.at(i)); + } + onPresentPaths.resize(0); + std::vector previousPaths; + delete history; + return exitFlag; + } + +int windowRendering(wchar_t* userPath, bool* windowOpen, int windowFlags = 0){ + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::Begin("File picker", windowOpen, windowFlags); + ImGui::PopStyleVar(1); + //log_debugcpp(*windowOpen); //Listar UNA VEZ volumenes if (listFlags & LIST_VOLUME) { listFlags &= ~LIST_VOLUME; - numVolumes = listVolumes(&onPresentPaths); + numVolumes = listVolumes(&onPresentPaths, &onPresentPathsUTF8); log_debugcpp(std::to_string(numVolumes) + "<- depth MAIN size() ->" + std::to_string(onPresentPaths.size())); } @@ -444,68 +554,52 @@ void filePickerMomento(bool isFullViewport = false){ //ImGui::Text("%s PRE DIRECTORY TREATMENTO", currentPath); if (listFlags & LIST_DIRECTORY) { listFlags &= ~LIST_DIRECTORY; + chosenPath[0] = '\0'; log_debugcpp("ADECUADO LISTAR DIRECTORIOS"); if(!retrieveCurrentDirectory(currentPath)) { log_debugcpp("NO HABIA DIRECTORIO GetCurrentPath()"); exit(EXIT_FAILURE); } // - //TODO ELIMINAR RESTRICCION EXE; PRUEBITA DEL SIGNIORE + //TODO Expand extension filter - numFiles = listDirectory(std::string(currentPath), &directoryContents); + numFiles = listDirectory(std::wstring(currentPath), &directoryContents); //std::cout << numFiles; if (numFiles < 0) { - //TODO quitar GetLastError() de aqui long directoryErrorCode; log_debugcpp("FALLO LA FUNCION, VALOR NEGATIVO " + std::to_string(numFiles)); - if (numFiles == DIRECTORY_ERROR_ACCESSING_CONTENT) directoryErrorCode = getLastDirectorySystemError(); + if (numFiles == DIRECTORY_ERROR_ACCESSING_CONTENT) directoryErrorCode = getLastSystemError(); showError = true; switch(directoryErrorCode) { case AGDIR_ERROR_ACCESS_DENIED: - strcpy(error, ErrorMessages::accessDeniedError); - strcpy(addrBarVal, history->previousPaths.at(history->historyTraversalPos)); - strcpy(currentPath, history->previousPaths.at(history->historyTraversalPos)); - numFiles = listDirectory(history->previousPaths.at(history->historyTraversalPos), &directoryContents); - break; + strcpy(error, ErrorMessages::accessDeniedError); + wcscpy(addrBarVal, history->previousPaths.at(history->historyTraversalPos)); + wcscpy(currentPath, history->previousPaths.at(history->historyTraversalPos)); + numFiles = listDirectory(history->previousPaths.at(history->historyTraversalPos), &directoryContents); + break; default: - strcpy(error, ErrorMessages::listDirectoryError); - strcpy(currentPath, addrBarVal); - numFiles = listDirectory(std::string(currentPath), &directoryContents); + strcpy(error, ErrorMessages::listDirectoryError); + wcscpy(currentPath, addrBarVal); + numFiles = listDirectory(std::wstring(currentPath), &directoryContents); break; } history->isAdditionTime = false; } else { showError = false; - strcpy(addrBarVal, currentPath); + wcscpy(addrBarVal, currentPath); if(history->isAdditionTime) addPathToHistory(history, addrBarVal); } } - /* + /* It's renderin' time */ - - - - - It's renderin' time - - - - - - */ - - if(showError){ - ImGui::Text(error); - } - + if(showError) ImGui::Text(error); ImGui::Text("Select a file:"); - //Permanentes e increiblemente utilitarios botones en Cuatro K: BACK + //BACK ImGui::BeginDisabled(MIN_HISTORY_POS); if(ImGui::Button("Back")) { - char* interfaceMovementButtonsPath = moveThroughHistory(history, HISTORY_BACKWARD); - //TODO: ERROR + wchar_t* interfaceMovementButtonsPath = moveThroughHistory(history, HISTORY_BACKWARD); listFlags = handleFolderAccessResult(listFlags, interfaceMovementButtonsPath, &showError, error, ErrorMessages::moveUpError, history, false); } @@ -514,8 +608,7 @@ void filePickerMomento(bool isFullViewport = false){ ImGui::SameLine(); ImGui::BeginDisabled(MAX_HISTORY_POS); if(ImGui::Button("Forward")) { - //TODO david???????????????????????????????????? - char* interfaceMovementButtonsPath = moveThroughHistory(history, HISTORY_FORWARD); + wchar_t* interfaceMovementButtonsPath = moveThroughHistory(history, HISTORY_FORWARD); listFlags = handleFolderAccessResult(listFlags, interfaceMovementButtonsPath, &showError, error, ErrorMessages::moveUpError, history, false); } @@ -531,11 +624,13 @@ void filePickerMomento(bool isFullViewport = false){ ImGui::SameLine(); //BARRA DE DIRECCIONES ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize("Enter").x + ImGui::GetStyle().ItemSpacing.x * 2) ); - if(ImGui::InputText("##addrbar", addrBarVal, IM_ARRAYSIZE(addrBarVal), ImGuiInputTextFlags_EnterReturnsTrue )){ + WideCharToMultiByte(CP_UTF8, NULL, addrBarVal, -1, addrBarValUTF8, + 4 * MAX_PATH, NULL, NULL); + if(ImGui::InputText("##addrbar", addrBarValUTF8, IM_ARRAYSIZE(addrBarValUTF8), ImGuiInputTextFlags_EnterReturnsTrue )){ log_debugcpp(currentPath <<" ADDRBAR INTENTO"); - listFlags = handleFolderAccessResult(listFlags, addrBarVal, &showError, error, ErrorMessages::addrBarError, - history, currentPath, addrBarVal); - }; + MultiByteToWideChar(CP_UTF8, NULL, addrBarValUTF8, -1, addrBarVal, 2 * MAX_PATH); + listFlags = handleFolderAccessResult(listFlags, addrBarVal, &showError, error, ErrorMessages::addrBarError, history, currentPath, addrBarVal); + } ImGui::PopItemWidth(); ImGui::SameLine(); if(ImGui::Button("Enter")){ @@ -567,8 +662,7 @@ void filePickerMomento(bool isFullViewport = false){ ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.6f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.7f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.8f, 0.8f)); - if(ImGui::Button(onPresentPaths.at(i))){ - //TODO xdddddddd + if(ImGui::Button(onPresentPathsUTF8.at(i))){ listFlags = handleFolderAccessResult(listFlags, onPresentPaths.at(i), &showError, error, ErrorMessages::moveUpError, history, true); } @@ -582,7 +676,7 @@ void filePickerMomento(bool isFullViewport = false){ ImGui::TableNextColumn(); - //DIRECTORIOS ENCONTRADOS bien pinta2 + //DRAW DIRECTORIOS ENCONTRADOS static ImGuiTableFlags directoriesFlags = ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable |ImGuiTableFlags_ScrollY ; if (ImGui::BeginTable("##directoriesTable", 3, directoriesFlags, ImVec2(-FLT_MIN, 20 * ImGui::GetTextLineHeightWithSpacing()))){ ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide); @@ -596,10 +690,10 @@ void filePickerMomento(bool isFullViewport = false){ for (; idx < numFiles; idx++) { if(directoryContents.at(idx)->isHidden && !showHidden) continue; if(filterByExtension && !directoryContents.at(idx)->isFile) { - //TODO XAPUSITA + //TODO Expand extensions filter extensions.clear(); - extensions.push_back("exe"); - if (!compareLastChar(&extensions, directoryContents.at(idx)->name)) continue; + extensions.push_back(L"exe"); + if (!compareLastWchar(&extensions, directoryContents.at(idx)->name)) continue; } ImGui::TableNextRow(); @@ -607,11 +701,21 @@ void filePickerMomento(bool isFullViewport = false){ //NAME bool isSelected = false; - if (ImGui::Selectable(directoryContents.at(idx)->name, &isSelected)){ - strcat(addrBarVal, "\\"); - strcat(addrBarVal, directoryContents.at(idx)->name); - listFlags = handleFolderAccessResult(listFlags, addrBarVal, &showError, error, + WideCharToMultiByte(CP_UTF8, NULL, addrBarVal, -1, addrBarValUTF8, + 4 * MAX_PATH, NULL, NULL); + if (ImGui::Selectable(directoryContents.at(idx)->nameUTF8, &isSelected)){ + if(!directoryContents.at(idx)->isFile) { + wcscpy(chosenPath, addrBarVal); + wcscat(chosenPath, L"\\"); + wcscat(chosenPath, directoryContents.at(idx)->name); + log_wdebugcpp(chosenPath << L" selected"); + } else { + wcscat(addrBarVal, L"\\"); + wcscat(addrBarVal, directoryContents.at(idx)->name); + log_debugcpp("directo selected"); + listFlags = handleFolderAccessResult(listFlags, addrBarVal, &showError, error, ErrorMessages::tableElementError, history, currentPath, addrBarVal); + } //currentItemIdx = -1; } ImGui::TableNextColumn(); @@ -639,14 +743,37 @@ void filePickerMomento(bool isFullViewport = false){ //ImGui::TreePop(); - + //BOTTOM ROW ImGui::Checkbox("Show hidden", &showHidden); ImGui::SameLine(); ImGui::Checkbox("Filter by .exe", &filterByExtension); ImGui::SameLine(); - ImGui::Button("Select"); + ImGui::SameLine(); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize("Select").x + ImGui::GetStyle().ItemSpacing.x * 2) ); + + ImGui::BeginDisabled(); + WideCharToMultiByte(CP_UTF8, NULL, chosenPath, -1, chosenPathUTF8, + 4 * MAX_PATH, NULL, NULL); + ImGui::InputText("##chosenbar", chosenPathUTF8, IM_ARRAYSIZE(chosenPathUTF8), ImGuiInputTextFlags_EnterReturnsTrue ); + ImGui::EndDisabled(); + + ImGui::SameLine(); + if(ImGui::Button("Select")) { + log_wdebugcpp(chosenPath << " TRIED TO RETURN"); + ImGui::End(); + return exitWindow(userPath, windowOpen, exitFlags::EXIT_SELECTED); + } + //listFlags = handleFolderAccessResult(listFlags, addrBarVal, &showError, error, ErrorMessages::addrBarError, history, currentPath, addrBarVal); + ImGui::End(); + + if(windowOpen) return EXIT_CONTINUE; + else return exitWindow(userPath, windowOpen, exitFlags::EXIT_CLOSED); + +} + + } -} \ No newline at end of file + diff --git a/glfw3.dll b/glfw3.dll new file mode 100644 index 0000000..f355ace Binary files /dev/null and b/glfw3.dll differ diff --git a/main.cpp b/main.cpp index 0a40c4e..0b229e9 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,7 @@ #define IMGUI_IMPLEMENTATION #define GL_SILENCE_DEPRECATION -#include "imgui/misc/single_file/imgui_single_file.h" +#include "unityBuild.h" #include "filepicker.hpp" // [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. @@ -60,7 +60,7 @@ int main(int, char**) { // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; + ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls @@ -80,18 +80,18 @@ int main(int, char**) { // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. // - Read 'docs/FONTS.md' for more instructions and details. // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); - //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - //IM_ASSERT(font != NULL); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); // Our state bool show_demo_window = true; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - + // Main loop while (!glfwWindowShouldClose(window)) { // Poll and handle events (inputs, window resize, etc.) @@ -107,10 +107,14 @@ int main(int, char**) { ImGui::NewFrame(); // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). - if (show_demo_window) + static wchar_t path[MAX_PATH];// = malloc(MAX_PATH * sizeof(char)); + static bool windowOpen = true; + if(windowOpen) + fp::renderFilePicker(&path[0], &windowOpen, 0); + + if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); - fp::filePickerMomento(true); // Rendering ImGui::Render(); @@ -120,7 +124,7 @@ int main(int, char**) { glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - + ImGui::EndFrame(); glfwSwapBuffers(window); } @@ -130,10 +134,10 @@ int main(int, char**) { - - + + // Cleanup diff --git a/unityBuild.h b/unityBuild.h new file mode 100644 index 0000000..502c54c --- /dev/null +++ b/unityBuild.h @@ -0,0 +1,25 @@ +// dear imgui: single-file wrapper include +// We use this to validate compiling all *.cpp files in a same compilation unit. +// Users of that technique (also called "Unity builds") can generally provide this themselves, +// so we don't really recommend you use this in your projects. + +// Do this: +// #define IMGUI_IMPLEMENTATION +// Before you include this file in *one* C++ file to create the implementation. +// Using this in your project will leak the contents of imgui_internal.h and ImVec2 operators in this compilation unit. +#define WIN32_LEAN_AND_MEAN +#define UNICODE +#define _UNICODE +#include "imgui/imgui.h" + +#ifdef IMGUI_IMPLEMENTATION +#include "imgui/imgui.cpp" +#include "imgui/imgui_demo.cpp" +#include "imgui/imgui_draw.cpp" +#include "imgui/imgui_tables.cpp" +#include "imgui/imgui_widgets.cpp" +#include "imgui/backends/imgui_impl_glfw.h" +#include "imgui/backends/imgui_impl_opengl3.h" +#include "imgui/backends/imgui_impl_opengl3.cpp" +#include "imgui/backends/imgui_impl_glfw.cpp" +#endif