template struct complete { bool good = true, done = false; T value; complete() {} complete(const T& t, bool g = true, bool d = false) : value(t), good(g), done(d) {} complete(T&& t, bool g = true, bool d = false) : value(t), good(g), done(d) {} }; void windowOpenPath(complete& dir, bool file = true) { if (ImGui::Begin("Open File", &dir.good)) { bool hasParent = dir.value.has_parent_path(); bool isDir = fs::is_directory(dir.value); fs::path p = (isDir ? dir.value : (hasParent ? dir.value.parent_path() : fs::current_path())); const float footer = ImGui::GetStyle().ItemSpacing.y + (ImGui::GetFrameHeightWithSpacing() * 2); ImGui::BeginChild("Viewer", ImVec2(0, -footer)); if ((hasParent && isDir) || (hasParent && dir.value.parent_path().has_parent_path())) { if (ImGui::Button("<- Back")) dir.value = isDir ? dir.value.parent_path() : dir.value.parent_path().parent_path(); ImGui::Separator(); } for(auto& d : fs::directory_iterator(p)) { bool selected = dir.value == d.path(); if (ImGui::Selectable(d.path().filename().u8string().c_str(), &selected)) dir.value = d.path(); } ImGui::EndChild(); ImGui::Separator(); ImGui::Text(dir.value.u8string().c_str()); if (file ? fs::is_regular_file(dir.value) : fs::is_directory(dir.value)) { dir.done |= ImGui::Button("Open"); ImGui::SameLine(); } else if (!file && hasParent) { if (ImGui::Button("Open")) { dir.value = dir.value.parent_path(); dir.done = true; } ImGui::SameLine(); } dir.good ^= ImGui::Button("Cancel"); } ImGui::End(); }