From 9bfdfa149efb5a70867845b59423ec2d66587d20 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 23 Feb 2024 17:52:42 +0100 Subject: [PATCH] feat: Added search bar to file chooser popup, allow for custom naming functions --- .../ui/include/popups/popup_file_chooser.hpp | 72 +++++++++++++------ 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/plugins/ui/include/popups/popup_file_chooser.hpp b/plugins/ui/include/popups/popup_file_chooser.hpp index 99084281e..90966b6fd 100644 --- a/plugins/ui/include/popups/popup_file_chooser.hpp +++ b/plugins/ui/include/popups/popup_file_chooser.hpp @@ -5,19 +5,23 @@ #include #include +#include #include #include namespace hex::ui { - class PopupFileChooser : public Popup { + template + class PopupNamedFileChooserBase : public Popup { public: - PopupFileChooser(const std::vector &basePaths, const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &callback) - : hex::Popup("hex.ui.common.choose_file"), - m_indices({ }), + PopupNamedFileChooserBase(const std::vector &basePaths, const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &nameCallback, const std::function &callback) + : hex::Popup("hex.ui.common.choose_file"), + m_selectedFiles({ }), + m_nameCallback(nameCallback), m_openCallback(callback), - m_validExtensions(validExtensions), m_multiple(multiple) { + m_validExtensions(validExtensions), + m_multiple(multiple) { for (const auto &path : files) { std::fs::path adjustedPath; @@ -42,21 +46,30 @@ namespace hex::ui { void drawContent() override { bool doubleClicked = false; - if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) { - u32 index = 0; - for (auto &[path, pathName] : m_files) { - ImGui::PushID(index); + ImGui::PushItemWidth(-1); + ImGuiExt::InputTextIcon("##search", ICON_VS_FILTER, m_filter); + ImGui::PopItemWidth(); - bool selected = m_indices.contains(index); - if (ImGui::Selectable(wolv::util::toUTF8String(pathName).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) { + if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) { + for (auto fileIt = m_files.begin(); fileIt != m_files.end(); ++fileIt) { + const auto &[path, pathName] = *fileIt; + + const auto &pathNameString = m_nameCallback(pathName); + if (!m_filter.empty() && !pathNameString.contains(m_filter)) + continue; + + ImGui::PushID(&*fileIt); + + bool selected = m_selectedFiles.contains(fileIt); + if (ImGui::Selectable(pathNameString.c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) { if (!m_multiple) { - m_indices.clear(); - m_indices.insert(index); + m_selectedFiles.clear(); + m_selectedFiles.insert(fileIt); } else { if (selected) { - m_indices.erase(index); + m_selectedFiles.erase(fileIt); } else { - m_indices.insert(index); + m_selectedFiles.insert(fileIt); } } } @@ -67,16 +80,15 @@ namespace hex::ui { ImGuiExt::InfoTooltip(wolv::util::toUTF8String(path).c_str()); ImGui::PopID(); - index++; } ImGui::EndListBox(); } if (ImGui::Button("hex.ui.common.open"_lang) || doubleClicked) { - for (const auto &index : m_indices) - m_openCallback(m_files[index].first); - Popup::close(); + for (const auto &it : m_selectedFiles) + m_openCallback(it->first); + Popup::close(); } ImGui::SameLine(); @@ -84,7 +96,7 @@ namespace hex::ui { if (ImGui::Button("hex.ui.common.browse"_lang)) { fs::openFileBrowser(fs::DialogMode::Open, m_validExtensions, [this](const auto &path) { m_openCallback(path); - Popup::close(); + Popup::close(); }, {}, m_multiple); } @@ -104,11 +116,29 @@ namespace hex::ui { } private: - std::set m_indices; + std::string m_filter; std::vector> m_files; + std::set>::const_iterator> m_selectedFiles; + std::function m_nameCallback; std::function m_openCallback; std::vector m_validExtensions; bool m_multiple = false; }; + class PopupNamedFileChooser : public PopupNamedFileChooserBase { + public: + PopupNamedFileChooser(const std::vector &basePaths, const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &nameCallback, const std::function &callback) + : PopupNamedFileChooserBase(basePaths, files, validExtensions, multiple, nameCallback, callback) { } + }; + + class PopupFileChooser : public PopupNamedFileChooserBase { + public: + PopupFileChooser(const std::vector &basePaths, const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &callback) + : PopupNamedFileChooserBase(basePaths, files, validExtensions, multiple, nameCallback, callback) { } + + static std::string nameCallback(const std::fs::path &path) { + return wolv::util::toUTF8String(path); + } + }; + } \ No newline at end of file