2023-01-05 09:30:15 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <hex.hpp>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <atomic>
|
|
|
|
|
2023-11-18 14:50:43 +01:00
|
|
|
#include <hex/api/task_manager.hpp>
|
2023-01-05 09:30:15 +01:00
|
|
|
|
|
|
|
#include <imgui.h>
|
|
|
|
#include <hex/ui/imgui_imhex_extensions.h>
|
|
|
|
|
|
|
|
namespace hex::ui {
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
class SearchableWidget {
|
|
|
|
public:
|
|
|
|
SearchableWidget(const std::function<bool(const std::string&, const T&)> &comparator) : m_comparator(comparator) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<const T*> &draw(const auto &entries) {
|
2023-12-19 13:10:25 +01:00
|
|
|
if (m_filteredEntries.empty() && m_searchBuffer.empty()) {
|
2023-01-05 09:30:15 +01:00
|
|
|
for (auto &entry : entries)
|
2023-12-19 13:10:25 +01:00
|
|
|
m_filteredEntries.push_back(&entry);
|
2023-01-05 09:30:15 +01:00
|
|
|
}
|
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
if (ImGui::InputText("##search", m_searchBuffer)) {
|
|
|
|
m_pendingUpdate = true;
|
2023-01-05 09:30:15 +01:00
|
|
|
}
|
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
if (m_pendingUpdate && !m_updateTask.isRunning()) {
|
|
|
|
m_pendingUpdate = false;
|
|
|
|
m_filteredEntries.clear();
|
|
|
|
m_filteredEntries.reserve(entries.size());
|
2023-01-05 09:30:15 +01:00
|
|
|
|
2024-07-27 16:29:06 +02:00
|
|
|
m_updateTask = TaskManager::createBackgroundTask(Lang("Searching"), [this, &entries, searchBuffer = m_searchBuffer](Task&) {
|
2023-01-05 09:30:15 +01:00
|
|
|
for (auto &entry : entries) {
|
2023-12-19 13:10:25 +01:00
|
|
|
if (searchBuffer.empty() || m_comparator(searchBuffer, entry))
|
|
|
|
m_filteredEntries.push_back(&entry);
|
2023-01-05 09:30:15 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
return m_filteredEntries;
|
2023-01-05 09:30:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void reset() {
|
2023-12-19 13:10:25 +01:00
|
|
|
m_filteredEntries.clear();
|
2023-01-05 09:30:15 +01:00
|
|
|
}
|
|
|
|
private:
|
|
|
|
std::atomic<bool> m_pendingUpdate = false;
|
|
|
|
TaskHolder m_updateTask;
|
|
|
|
|
|
|
|
std::string m_searchBuffer;
|
|
|
|
std::vector<const T*> m_filteredEntries;
|
|
|
|
std::function<bool(const std::string&, const T&)> m_comparator;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|