// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. // Read online: https://github.com/ocornut/imgui/tree/master/docs #define IMGUI_IMPLEMENTATION #define GL_SILENCE_DEPRECATION #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) #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)) #include "imgui/misc/single_file/imgui_single_file.h" #include #include #include #include #include // [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. // To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. // Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio. #if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) #pragma comment(lib, "legacy_stdio_definitions") #endif static void glfw_error_callback(int error, const char* description) { fprintf(stderr, "Glfw Error %d: %s\n", error, description); } bool debug = true; // int debugVerbosity = 0; // enum enumDebugVerbosity { // DEBUG_DIRECTORY = (1<<0), // DEBUG_VOLUME = (1<<1), // DEBUG_EXTENSION = (1<<2) // }; // debugVerbosity = DEBUG_DIRECTORY | DEBUG_EXTENSION; // debugVerbosity &= ~DEBUG_DIRECTORY; // if (debugVerbosity & (DEBUG_DIRECTORY | DEBUG_EXTENSION)); typedef struct { std::vector size; std::vector name; } directoriesInfo, volumesInfo; //TODO UNICORDEO /* FILE PICKER MOMENTO */ /* DIRECTORIES */ bool retrieveCurrentDirectory(char** currentPath){ if(GetCurrentDirectory(MAX_PATH, *currentPath)) return true; return false; } bool moveDirectory(char** currentPath){ if (debug) std::cout << *currentPath << std::endl; if(SetCurrentDirectory(*currentPath)) return true; return false; } int listDirectory(std::string path, std::vector *directoryContents, std::vector *desiredExtensions = nullptr){ HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA ffd; LARGE_INTEGER filesize; bool skipDueToExtension = false; int numFiles = 0; if (path.length() > (MAX_PATH - 3)) return -1; path = path + "\\*"; hFind = FindFirstFile(path.c_str(), &ffd); if (INVALID_HANDLE_VALUE == hFind) return -2; do { //TODO laberga k momento educativo if(!strcmp(ffd.cFileName, ".") || !strcmp(ffd.cFileName, "..")) continue; //Codigo pa saltarse arxibus k no estiendan /*if(desiredExtensions != nullptr){ TCHAR* fileExtension = strrchr(ffd.cFileName, '.'); if (debug && fileExtension != NULL) { std::cout << fileExtension; std::cout << " <- FILTERING EXTENSION" << std::endl; } std::cout << ffd.cFileName << std::endl; //TODO tabien no??? if (fileExtension == NULL) continue; for (int i = 0; i < desiredExtensions->size(); i++) { if (debug) { std::cout << std::to_string(strcmp(desiredExtensions->at(i).c_str(), fileExtension)) << std::endl; } if (strcmp(desiredExtensions->at(i).c_str(), fileExtension)){ skipDueToExtension = true; } } }*/ if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && skipDueToExtension) continue; //TODO multi info Struct if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { //strcat(itemPath, " "); } else { // filesize.QuadPart = ((ffd.nFileSizeHigh * (MAXDWORD+1)) + ffd.nFileSizeLow); // char buf[16]; buf[0] = ' '; // itoa(filesize.QuadPart, buf + 1 , 10 ); // strcat(itemPath, buf); } char* itemPath; if (directoryContents->size() <= numFiles){ itemPath = (char*)calloc(1, MAX_PATH * sizeof(WCHAR)); directoryContents->push_back(itemPath); } else { itemPath = directoryContents->at(numFiles); } uint64_t idx = 0; do { itemPath[idx] = ffd.cFileName[idx]; idx++; } while (ffd.cFileName[idx]); numFiles++; } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); return numFiles; } /* VOLUMES */ //new char*[CharCount * sizeof(WCHAR) /*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); 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. //https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumepathnamesforvolumenamew char* nextOcurrence = strchr(volumePaths, separator); char* itemPath; itemPath = (char*)calloc(1, volumePathsBufferSize); int pathLengthIdx = 0; for (; volumePaths[pathLengthIdx] != nextOcurrence[0]; pathLengthIdx++) { if (debug) { std::cout << volumePaths[0]; std::cout << " ENTERS " + std::to_string(pathLengthIdx) << std::endl; } itemPath[pathLengthIdx] = volumePaths[pathLengthIdx]; } itemPath[pathLengthIdx + 1] = '\0'; dest->push_back(itemPath); if (debug) { std::cout << dest->at(dest->size() - 1); std::cout << " EXPLODEPATH" << std::endl; } if (nextOcurrence[0] == nextOcurrence[1]) return depth; depth++; return explodePaths(nextOcurrence + sizeof(TCHAR), (volumePathsBufferSize - pathLengthIdx), separator, dest, depth); } int listVolumes(std::vector *onPresentPaths){ //int listVolumes(){ HANDLE hFind = INVALID_HANDLE_VALUE; const char separator = '\0'; int numVolumes = 0; //Volume name TCHAR volumeName[MAX_PATH]; int volumeNameSize = sizeof volumeName / sizeof volumeName[0]; //Paths int volumePathsBufferSize = (MAX_PATH + 1) * sizeof(TCHAR); unsigned long volumePathLength; TCHAR volumePaths[volumePathsBufferSize]; std::fill(volumePaths, volumePaths + volumePathsBufferSize, '\0'); hFind = FindFirstVolume(volumeName, volumeNameSize); //if (debug) std::cout << volumeNameSize << std::endl; if (INVALID_HANDLE_VALUE == hFind) return -2; do { //if (debug) std::cout << volumeName << std::endl; if(GetVolumePathNamesForVolumeName(volumeName, volumePaths, volumePathsBufferSize, &volumePathLength)){ if (volumePathLength == 1) { if (debug) std::cout << "Skill Issue" << std::endl; continue; } if (debug) std::cout << volumeName; //pathSchecker // if (debug && volumePaths[0] == 'E') { // std::cout << volumePathLength << std::endl; // /*exit(1);*/ // for (int i = 0; i < volumePathsBufferSize; i++){ // std::cout << std::to_string(i) + ": "; // std::cout << volumePaths[i]; // std::cout << " | "; // } // std::cout << std::endl << "I IA" << std::endl; // exit(1); // } if(numVolumes += explodePaths(volumePaths, volumePathsBufferSize, separator, onPresentPaths)){ for (int i = 0; i < onPresentPaths->size(); i++){ std::cout << onPresentPaths->at(i) << std::endl; } } //std::cout << volumePaths << std::endl; if (debug) std::cout << std::to_string(volumePathLength) + " " ; if (debug) std::cout << "THE END" << std::endl; }else{ if (debug) std::cout << "no volumes found wtf" << std::endl; } std::fill(volumePaths, volumePaths + volumePathsBufferSize, '\0'); } while (FindNextVolume(hFind, volumeName, volumeNameSize) != 0); if (debug) std::cout << std::to_string(onPresentPaths->size()) + " JUST BEFORE MAIN" << std::endl; FindVolumeClose(hFind); return numVolumes; } /* FIN FILE PICKER MOMENTO */ int main(int, char**) { // Setup window glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) return 1; // Decide GL+GLSL versions #if defined(IMGUI_IMPL_OPENGL_ES2) // GL ES 2.0 + GLSL 100 const char* glsl_version = "#version 100"; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); #elif defined(__APPLE__) // GL 3.2 + GLSL 150 const char* glsl_version = "#version 150"; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac #else // GL 3.0 + GLSL 130 const char* glsl_version = "#version 130"; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only #endif // Create window with graphics context GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", NULL, NULL); if (window == NULL) return 1; glfwMakeContextCurrent(window); glfwSwapInterval(1); // Enable vsync // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // Setup Dear ImGui style ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); // Setup Platform/Renderer backends ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. // - 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); // Our state bool show_demo_window = true; bool show_another_window = false; 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.) // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); // Start the Dear ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); 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) ImGui::ShowDemoWindow(&show_demo_window); // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window. { static float f = 0.0f; static int counter = 0; ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state ImGui::Checkbox("Another Window", &show_another_window); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) counter++; ImGui::SameLine(); ImGui::Text("counter = %d", counter); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::End(); } { ImGui::Begin("File Picker in 4K"); static bool isListVolumesAdequate = true; static bool isListDirectoriesAdequate = true; //Listar UNA VEZ volumenes static int numVolumes; static std::vector onPresentPaths; if (isListVolumesAdequate) { isListVolumesAdequate = false; //std::cout << isListVolumesAdequate << std::endl; numVolumes = listVolumes(&onPresentPaths); if (debug) std::cout << std::to_string(numVolumes) + "<- depth MAIN size() ->" + std::to_string(onPresentPaths.size()) << std::endl; } //Listar UNA VEZ directorios //cursed C momento: necesario ptr en otra var para mandar a char** de firma static char currentPath[MAX_PATH]; static char* currentPathPtr = ¤tPath[0]; static int currentItemIdx = -1; //TODO David momento static std::vector displayContents; std::vector directoryContents; static int numFiles = 0; if (debug) ImGui::Text("%s primir", currentPath); if(isListDirectoriesAdequate) { log_debugcpp("renderiso"); isListDirectoriesAdequate = false; if(!retrieveCurrentDirectory(¤tPathPtr)) { if (debug) std::cout << "pencaste"; goto filepickerFailure; } // //TODO ELIMINAR RESTRICCION EXE; PRUEBITA DEL SIGNIORE static std::vector restrictToExe{"exe", "DSDFD"}; numFiles = (listDirectory(std::string(currentPath), &directoryContents));//, &restrictToExe)); //std::cout << numFiles; if (numFiles < 0) { ImGui::Text("Path not valid"); if (debug) std::cout << "pencaste 2 el repencazo"; goto filepickerFailure; } if (numFiles == 0) { if (debug) std::cout << std::to_string (numFiles) << "<- NUM FILES" << std::endl; char empty[] = "Empty"; numFiles++; directoryContents.push_back(empty); } displayContents = std::move(directoryContents); directoryContents.clear(); } //It's renderin' time if(numFiles > 0){ ImGui::Text("Select a file:"); if (debug) ImGui::Text("%s %d", currentPath, currentItemIdx); //Y a que los VOLUMENES pinta2 pa100pre //if (debug) std::cout << std::to_string(onPresentPaths.size()) + "<- numvols" << std::endl; if (numVolumes > 0) { for (int i = 0; i < onPresentPaths.size(); i++) { if (i > 0) ImGui::SameLine(); // if (debug) std::cout << std::to_string(i) + "<- WE IN" << std::endl; // ImGui::PushID(i); 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))){ moveDirectory(&onPresentPaths.at(i)); isListDirectoriesAdequate = true; } ImGui::PopStyleColor(3); // ImGui::PopID(); } } //Permanentes e increiblemente utilitarios botones en Cuatro K //c pervirtio con unicode std::wstring s(L"←→↑↓"); static char moveUp[] = ".."; static char* moveUpPtr = &moveUp[0]; if(ImGui::Button("Move Up")){ moveDirectory(&moveUpPtr); isListDirectoriesAdequate = true; } //DIRECTORIOS ENCONTRADOS bien pinta2 if (ImGui::BeginListBox("fpLb", ImVec2(-FLT_MIN, 25 * ImGui::GetTextLineHeightWithSpacing()))){ for (int i = 0; i < numFiles; i++) { const bool isSelected = (currentItemIdx == i); if (ImGui::Selectable(displayContents.at(i), isSelected)) currentItemIdx = i; if (isSelected) { strcat(currentPath, "\\"); strcat(currentPath, displayContents.at(i)); moveDirectory(¤tPathPtr); currentItemIdx = -1; isListDirectoriesAdequate = true; } //ImGui::SetItemDefaultFocus(); } ImGui::EndListBox(); } } else { ImGui::Text("cagaste"); } //ImGui::TreePop(); filepickerFailure: ImGui::End(); } // 3. Show another simple window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) ImGui::Text("Hello from another window!"); if (ImGui::Button("Close Me")) show_another_window = false; ImGui::End(); } // Rendering ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); 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()); glfwSwapBuffers(window); } // Cleanup ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(window); glfwTerminate(); return 0; }