// 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 #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; 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(SetCurrentDirectory(*currentPath)) return true; return false; } int listDirectory(std::string path, std::vector *directoryContents){ HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA ffd; LARGE_INTEGER filesize; 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 { 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]); 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); } 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 = 0){ //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 static int lmao = 0; char* nextOcurrence = strchr(volumePaths, separator); //TODO Test de cadena original; // if (debug && lmao) { // std::cout << std::to_string(lmao) + ":lmao " << std::endl; // 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 (debug && volumePaths[0] == 'E') lmao = 1; char* itemPath; itemPath = (char*)calloc(1, volumePathsBufferSize); //for (int i = 0; &volumePaths[i] == nextOcurrence; i++) { 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]; } dest->push_back(itemPath); if (debug) { std::cout << dest->at(dest->size() - 1); std::cout << " EXPLODEPATH" << std::endl; } //TODO Test de recursividad //if (debug) { std::cout << dest->at(0) << std::endl; exit(1); } //if (debug && lmao == 3) { std::cout << volumePaths << std::endl; exit(1); } //lmao++; depth++; if (nextOcurrence[0] == nextOcurrence[1]) return depth; return explodePaths(nextOcurrence + sizeof(TCHAR), (volumePathsBufferSize - pathLengthIdx), separator, dest); } 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]; //TODO necesario? di 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; if (debug) { // 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(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 << "cagaste" << std::endl; } numVolumes++; //TODO necesario? di CAMBIAR 4 A NUL std::fill(volumePaths, volumePaths + volumePathsBufferSize, '4'); } while (FindNextVolume(hFind, volumeName, volumeNameSize) != 0); 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"); //TODO test listar volumenes static bool isListVolumesAdequate = true; if (debug && isListVolumesAdequate) { isListVolumesAdequate = false; //std::cout << isListVolumesAdequate << std::endl; std::vector onPresentPaths; listVolumes(&onPresentPaths); } // static bool renderListbox = true; //cursed C momento: necesario ptr en otra var para mandar a char** de firma static char currentPath[MAX_PATH]; static char* ptr = ¤tPath[0]; static int currentItemIdx = -1; static std::vector displayContents; std::vector directoryContents; static int numFiles = 0; if (debug) ImGui::Text("%s primir", currentPath); if(renderListbox) { if (debug) std::cout << "renderiso" << std::endl; renderListbox = false; if(!retrieveCurrentDirectory(&ptr)) { if (debug) std::cout << "pencaste"; goto filepickerFailure; } // numFiles = (listDirectory(std::string(currentPath), &directoryContents)); //std::cout << numFiles; if (numFiles < 0) { if (debug) std::cout << "pencaste 2 el repencazo"; goto filepickerFailure; } displayContents = std::move(directoryContents); } if(numFiles > 0){ ImGui::Text("Select a file:"); if (debug) ImGui::Text("%s %d", currentPath, currentItemIdx); 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(&ptr); currentItemIdx = -1; renderListbox = 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; }