#pragma once #include #include #include #include #include #include #include namespace hex::ui { template class SearchableWidget { public: SearchableWidget(const std::function &comparator) : m_comparator(comparator) { } const std::vector &draw(const auto &entries) { if (this->m_filteredEntries.empty() && this->m_searchBuffer.empty()) { for (auto &entry : entries) this->m_filteredEntries.push_back(&entry); } if (ImGui::InputText("##search", this->m_searchBuffer)) { this->m_pendingUpdate = true; } if (this->m_pendingUpdate && !this->m_updateTask.isRunning()) { this->m_pendingUpdate = false; this->m_filteredEntries.clear(); this->m_filteredEntries.reserve(entries.size()); this->m_updateTask = TaskManager::createBackgroundTask("Searching", [this, &entries, searchBuffer = this->m_searchBuffer](Task&) { for (auto &entry : entries) { if (searchBuffer.empty() || this->m_comparator(searchBuffer, entry)) this->m_filteredEntries.push_back(&entry); } }); } return this->m_filteredEntries; } void reset() { this->m_filteredEntries.clear(); } private: std::atomic m_pendingUpdate = false; TaskHolder m_updateTask; std::string m_searchBuffer; std::vector m_filteredEntries; std::function m_comparator; }; }