mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
launcher: vehicle picker filtering
This commit is contained in:
@@ -182,6 +182,10 @@ std::shared_ptr<ui::skin_meta> ui::vehicles_bank::parse_meta(const std::string &
|
|||||||
stream >> meta->rev_year;
|
stream >> meta->rev_year;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta->search_lowered +=
|
||||||
|
ToLower(meta->name + meta->short_id + meta->location +
|
||||||
|
meta->rev_date + meta->rev_company + meta->texture_author + meta->photo_author);
|
||||||
|
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ struct skin_meta {
|
|||||||
std::string rev_company;
|
std::string rev_company;
|
||||||
std::string texture_author;
|
std::string texture_author;
|
||||||
std::string photo_author;
|
std::string photo_author;
|
||||||
|
|
||||||
|
std::string search_lowered;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct skin_set {
|
struct skin_set {
|
||||||
|
|||||||
@@ -156,13 +156,11 @@ void ui::vehiclepicker_panel::render()
|
|||||||
|
|
||||||
ImGui::SetNextItemWidth(-1);
|
ImGui::SetNextItemWidth(-1);
|
||||||
ImGui::InputText("##search", search_query.data(), search_query.size());
|
ImGui::InputText("##search", search_query.data(), search_query.size());
|
||||||
skinset_list.erase(std::remove_if(skinset_list.begin(), skinset_list.end(), [this](const skin_set* skin)
|
auto query_info = parse_search_query(search_query.data());
|
||||||
{
|
if (!query_info.empty())
|
||||||
std::string query_str(search_query.data());
|
skinset_list.erase(std::remove_if(skinset_list.begin(), skinset_list.end(),
|
||||||
if (query_str.empty())
|
std::bind(&vehiclepicker_panel::skin_filter, this, std::placeholders::_1, query_info)),
|
||||||
return false;
|
skinset_list.end());
|
||||||
return skin->skin.find(query_str) == -1;
|
|
||||||
}), skinset_list.end());
|
|
||||||
|
|
||||||
if (ImGui::BeginChild("box3")) {
|
if (ImGui::BeginChild("box3")) {
|
||||||
ImGuiListClipper clipper(skinset_list.size());
|
ImGuiListClipper clipper(skinset_list.size());
|
||||||
@@ -201,6 +199,88 @@ void ui::vehiclepicker_panel::render()
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ui::vehiclepicker_panel::search_info> ui::vehiclepicker_panel::parse_search_query(const std::string &str)
|
||||||
|
{
|
||||||
|
std::vector<search_info> info_list;
|
||||||
|
std::istringstream query_stream(ToLower(str));
|
||||||
|
|
||||||
|
std::string term;
|
||||||
|
while (std::getline(query_stream, term, ' ')) {
|
||||||
|
size_t offset = 0;
|
||||||
|
search_info info;
|
||||||
|
if (offset < term.size() && term[offset] == '|') {
|
||||||
|
info.alternative = true;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
if (offset < term.size() && term[offset] == '!') {
|
||||||
|
info.negation = true;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
if (offset < term.size() && term[offset] == '<') {
|
||||||
|
info.mode = search_info::YEAR_MAX;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
if (offset < term.size() && term[offset] == '>') {
|
||||||
|
info.mode = search_info::YEAR_MIN;
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
term = term.substr(offset);
|
||||||
|
if (term.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (info.mode == search_info::TEXT) {
|
||||||
|
info.text = term;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::istringstream num_parser(term);
|
||||||
|
num_parser >> info.number;
|
||||||
|
}
|
||||||
|
|
||||||
|
info_list.push_back(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ui::vehiclepicker_panel::skin_filter(const skin_set *skin, std::vector<search_info> &info_list)
|
||||||
|
{
|
||||||
|
bool any = false;
|
||||||
|
bool alternative_present = false;
|
||||||
|
|
||||||
|
for (auto const &term : info_list) {
|
||||||
|
alternative_present |= term.alternative;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (term.mode == search_info::TEXT) {
|
||||||
|
if (skin->skin.find(term.text) != -1)
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (skin->meta && skin->meta->search_lowered.find(term.text) != -1)
|
||||||
|
found = true;
|
||||||
|
} else if (skin->meta && skin->meta->rev_year != -1) {
|
||||||
|
if (term.mode == search_info::YEAR_MIN) {
|
||||||
|
if (skin->meta->rev_year >= term.number)
|
||||||
|
found = true;
|
||||||
|
} else if (term.mode == search_info::YEAR_MAX) {
|
||||||
|
if (skin->meta->rev_year <= term.number)
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (term.negation)
|
||||||
|
found = !found;
|
||||||
|
|
||||||
|
if (found && term.alternative)
|
||||||
|
any = true;
|
||||||
|
|
||||||
|
if (!found && !term.alternative)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return alternative_present ? (!any) : false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, const deferred_image* image, const skin_set *pickable)
|
bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, const deferred_image* image, const skin_set *pickable)
|
||||||
{
|
{
|
||||||
ImGui::PushID(pickable);
|
ImGui::PushID(pickable);
|
||||||
|
|||||||
@@ -24,5 +24,23 @@ private:
|
|||||||
std::array<char, 128> search_query = { 0 };
|
std::array<char, 128> search_query = { 0 };
|
||||||
|
|
||||||
vehicles_bank bank;
|
vehicles_bank bank;
|
||||||
|
|
||||||
|
struct search_info
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TEXT,
|
||||||
|
YEAR_MIN,
|
||||||
|
YEAR_MAX
|
||||||
|
} mode = TEXT;
|
||||||
|
bool alternative = false;
|
||||||
|
bool negation = false;
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
int number;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<search_info> parse_search_query(const std::string &str);
|
||||||
|
bool skin_filter(const skin_set *skin, std::vector<search_info> &info_list);
|
||||||
};
|
};
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
|||||||
Reference in New Issue
Block a user