Prioritise favourited elements in element search

Also prevent favourited tools from showing up twice there.
This commit is contained in:
Tamás Bálint Misius 2020-09-25 20:47:39 +02:00
parent 88fd676cd2
commit c73dfe8ca0
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
2 changed files with 36 additions and 21 deletions

View File

@ -1,5 +1,6 @@
#include "ElementSearchActivity.h" #include "ElementSearchActivity.h"
#include <set>
#include <map> #include <map>
#include <algorithm> #include <algorithm>
@ -12,6 +13,7 @@
#include "gui/game/Favorite.h" #include "gui/game/Favorite.h"
#include "gui/game/GameController.h" #include "gui/game/GameController.h"
#include "gui/game/ToolButton.h" #include "gui/game/ToolButton.h"
#include "gui/game/Favorite.h"
#include "graphics/Graphics.h" #include "graphics/Graphics.h"
@ -69,22 +71,29 @@ void ElementSearchActivity::searchTools(String query)
struct Match struct Match
{ {
int tool_index; // relevance by position of tool in tools vector int favouritePriority; // relevant by whether the tool is favourited
int hs_org; // relevance by origin of haystack int toolIndex; // relevance by position of tool in tools vector
int nd_pos; // relevance by position of needle in haystack int haystackOrigin; // relevance by origin of haystack
int needlePosition; // relevance by position of needle in haystack
bool operator <(Match const &other) const bool operator <(Match const &other) const
{ {
return std::tie(hs_org, nd_pos, tool_index) < std::tie(other.hs_org, other.nd_pos, other.tool_index); return std::tie(favouritePriority, haystackOrigin, needlePosition, toolIndex) < std::tie(other.favouritePriority, other.haystackOrigin, other.needlePosition, other.toolIndex);
} }
}; };
std::map<int, Match> index_to_match; std::set<ByteString> favs;
auto push = [ &index_to_match ](Match match) { for (auto fav : Favorite::Ref().GetFavoritesList())
auto it = index_to_match.find(match.tool_index);
if (it == index_to_match.end())
{ {
index_to_match.insert(std::make_pair(match.tool_index, match)); favs.insert(fav);
}
std::map<int, Match> indexToMatch;
auto push = [ &indexToMatch ](Match match) {
auto it = indexToMatch.find(match.toolIndex);
if (it == indexToMatch.end())
{
indexToMatch.insert(std::make_pair(match.toolIndex, match));
} }
else if (match < it->second) else if (match < it->second)
{ {
@ -92,18 +101,18 @@ void ElementSearchActivity::searchTools(String query)
} }
}; };
auto push_if_matches = [ &queryLower, &push ](String infoLower, int tool_index, int haystack_relevance) { auto pushIfMatches = [ &queryLower, &push ](String infoLower, int toolIndex, int favouritePriority, int haystackRelevance) {
if (infoLower == queryLower) if (infoLower == queryLower)
{ {
push(Match{ tool_index, haystack_relevance, 0 }); push(Match{ favouritePriority, toolIndex, haystackRelevance, 0 });
} }
if (infoLower.BeginsWith(queryLower)) if (infoLower.BeginsWith(queryLower))
{ {
push(Match{ tool_index, haystack_relevance, 1 }); push(Match{ favouritePriority, toolIndex, haystackRelevance, 1 });
} }
if (infoLower.Contains(queryLower)) if (infoLower.Contains(queryLower))
{ {
push(Match{ tool_index, haystack_relevance, 2 }); push(Match{ favouritePriority, toolIndex, haystackRelevance, 2 });
} }
}; };
@ -116,25 +125,26 @@ void ElementSearchActivity::searchTools(String query)
} }
} }
for (int tool_index = 0; tool_index < (int)tools.size(); ++tool_index) for (int toolIndex = 0; toolIndex < (int)tools.size(); ++toolIndex)
{ {
push_if_matches(tools[tool_index]->GetName().ToLower(), tool_index, 0); int favouritePriority = favs.find(tools[toolIndex]->GetIdentifier()) != favs.end() ? 0 : 1;
push_if_matches(tools[tool_index]->GetDescription().ToLower(), tool_index, 1); pushIfMatches(tools[toolIndex]->GetName().ToLower(), toolIndex, favouritePriority, 0);
auto it = menudescriptionLower.find(tools[tool_index]); pushIfMatches(tools[toolIndex]->GetDescription().ToLower(), toolIndex, favouritePriority, 1);
auto it = menudescriptionLower.find(tools[toolIndex]);
if (it != menudescriptionLower.end()) if (it != menudescriptionLower.end())
{ {
push_if_matches(it->second, tool_index, 2); pushIfMatches(it->second, toolIndex, favouritePriority, 2);
} }
} }
std::vector<Match> matches; std::vector<Match> matches;
std::transform(index_to_match.begin(), index_to_match.end(), std::back_inserter(matches), [](decltype(index_to_match)::value_type const &pair) { std::transform(indexToMatch.begin(), indexToMatch.end(), std::back_inserter(matches), [](decltype(indexToMatch)::value_type const &pair) {
return pair.second; return pair.second;
}); });
std::sort(matches.begin(), matches.end()); std::sort(matches.begin(), matches.end());
for (auto &match : matches) for (auto &match : matches)
{ {
Tool *tool = tools[match.tool_index]; Tool *tool = tools[match.toolIndex];
if(!firstResult) if(!firstResult)
firstResult = tool; firstResult = tool;

View File

@ -1300,8 +1300,13 @@ void GameController::OpenElementSearch()
{ {
std::vector<Tool*> toolList; std::vector<Tool*> toolList;
std::vector<Menu*> menuList = gameModel->GetMenuList(); std::vector<Menu*> menuList = gameModel->GetMenuList();
for(auto *mm : menuList) for (auto i = 0U; i < menuList.size(); ++i)
{ {
if (i == SC_FAVORITES)
{
continue;
}
auto *mm = menuList[i];
if(!mm) if(!mm)
continue; continue;
std::vector<Tool*> menuToolList = mm->GetToolList(); std::vector<Tool*> menuToolList = mm->GetToolList();