From dea441899a6aee7c63a29e0c196ed4e7cb3158b1 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 20 Jul 2025 02:44:09 +0200 Subject: [PATCH] searchbox color --- client/adventureMap/AdventureMapShortcuts.cpp | 47 +++++++++++++------ client/render/Colors.cpp | 11 +++++ client/render/Colors.h | 2 + client/windows/GUIClasses.cpp | 9 +++- lib/Color.h | 8 ++++ 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/client/adventureMap/AdventureMapShortcuts.cpp b/client/adventureMap/AdventureMapShortcuts.cpp index b8b99c571..c301bfe2f 100644 --- a/client/adventureMap/AdventureMapShortcuts.cpp +++ b/client/adventureMap/AdventureMapShortcuts.cpp @@ -463,42 +463,61 @@ void AdventureMapShortcuts::search(bool next) // get all relevant objects std::vector visitableObjInstances; for(auto & obj : GAME->interface()->cb->getAllVisitableObjs()) - if(obj->ID != MapObjectID::MONSTER && obj->ID != MapObjectID::HERO && obj->ID != MapObjectID::TOWN) - visitableObjInstances.push_back(obj->id); + visitableObjInstances.push_back(obj->id); + + auto getColor = [](MapObjectID id ){ + switch (id) + { + case MapObjectID::HERO: + return ColorRGBA{ 0, 192, 0}; + case MapObjectID::MONSTER: + return ColorRGBA{ 255, 0, 0}; + case MapObjectID::TOWN: + return ColorRGBA{ 100, 100, 255}; + case MapObjectID::MINE: + return ColorRGBA{ 255, 153, 204}; + case MapObjectID::RESOURCE: + return ColorRGBA{ 255, 51, 255}; + case MapObjectID::ARTIFACT: + return ColorRGBA{ 192, 255, 0}; + default: + return Colors::WHITE; + } + }; // count of elements for each group (map is already sorted) - std::map mapObjCount; - for(auto & obj : visitableObjInstances) - mapObjCount[{ GAME->interface()->cb->getObjInstance(obj)->getObjectName() }]++; + std::map, int> mapObjCount; + for(auto & obj : GAME->interface()->cb->getAllVisitableObjs()) + mapObjCount[{GAME->interface()->cb->getObjInstance(obj->id)->getObjectName(), getColor(obj->ID)}]++; // convert to vector for indexed access - std::vector> textCountList; + std::vector, int>> textCountList; for (auto itr = mapObjCount.begin(); itr != mapObjCount.end(); ++itr) - textCountList.push_back(*itr); + textCountList.push_back({(*itr).first, (*itr).second}); // get pos of last selection int lastSel = 0; for(int i = 0; i < textCountList.size(); i++) - if(textCountList[i].first == searchLast) + if(textCountList[i].first.first == searchLast) lastSel = i; // create texts std::vector texts; for(auto & obj : textCountList) - texts.push_back(obj.first + " (" + std::to_string(obj.second) + ")"); + texts.push_back("{" + Colors::colorToHexString(obj.first.second) + "|" + obj.first.first + "}" + " (" + std::to_string(obj.second) + ")"); // function to center element from list on map - auto selectObjOnMap = [this, textCountList, visitableObjInstances](int index) + auto selectObjOnMap = [this, textCountList](int index) { auto selObj = textCountList[index].first; // filter for matching objects std::vector selVisitableObjInstances; - for(auto & obj : visitableObjInstances) - if(selObj == GAME->interface()->cb->getObjInstance(obj)->getObjectName()) - selVisitableObjInstances.push_back(obj); + for(auto & obj : GAME->interface()->cb->getAllVisitableObjs()) + if(selObj.first == GAME->interface()->cb->getObjInstance(obj->id)->getObjectName()) + selVisitableObjInstances.push_back(obj->id); - if(searchPos + 1 < selVisitableObjInstances.size() && searchLast == selObj) + if(searchPos + 1 < selVisitableObjInstances.size() && searchLast == selObj.first) searchPos++; else searchPos = 0; diff --git a/client/render/Colors.cpp b/client/render/Colors.cpp index 974c063cd..cf56537fc 100644 --- a/client/render/Colors.cpp +++ b/client/render/Colors.cpp @@ -53,3 +53,14 @@ std::optional Colors::parseColor(std::string text) return std::nullopt; } + +std::string Colors::colorToHexString(const ColorRGBA& color) +{ + std::ostringstream oss; + oss << "#" + << std::hex << std::uppercase + << std::setw(2) << std::setfill('0') << static_cast(color.r) + << std::setw(2) << std::setfill('0') << static_cast(color.g) + << std::setw(2) << std::setfill('0') << static_cast(color.b); + return oss.str(); +} diff --git a/client/render/Colors.h b/client/render/Colors.h index cd643381b..4cb774cb3 100644 --- a/client/render/Colors.h +++ b/client/render/Colors.h @@ -55,4 +55,6 @@ public: /// parse color static std::optional parseColor(std::string text); + + static std::string colorToHexString(const ColorRGBA& color); }; diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 362ee283d..dd7e9bd9f 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -1641,7 +1641,14 @@ void CObjectListWindow::itemsSearchCallback(const std::string & text) for(const auto & item : items) { - if(auto score = TextOperations::textSearchSimilarityScore(text, item.second)) // Keep only relevant items + // remove color information + std::vector parts; + boost::split(parts, item.second, boost::is_any_of("|")); + std::string name = parts.back(); + boost::erase_all(name, "{"); + boost::erase_all(name, "}"); + + if(auto score = TextOperations::textSearchSimilarityScore(text, name)) // Keep only relevant items rankedItems.emplace_back(score.value(), item); } diff --git a/lib/Color.h b/lib/Color.h index a983df691..a1f1ac83c 100644 --- a/lib/Color.h +++ b/lib/Color.h @@ -62,6 +62,14 @@ public: { return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a; } + + bool operator<(const ColorRGBA& rhs) const + { + auto mean_lhs = (r + g + b + a) / 4.0; + auto mean_rhs = (rhs.r + rhs.g + rhs.b + rhs.a) / 4.0; + return mean_lhs < mean_rhs; + } + }; namespace vstd