Achievement sorting (#3533)

The comparison for goals and progress still has to be changed from alphanumerical to a progress status.
This commit is contained in:
Ryan 2018-11-21 08:33:26 -06:00 committed by Alayan-stk-2
parent e2337d3d9c
commit 271b032ef3
2 changed files with 131 additions and 36 deletions

View File

@ -48,6 +48,9 @@ BaseOnlineProfileAchievements::BaseOnlineProfileAchievements(const std::string &
: OnlineProfileBase(name)
{
m_selected_achievement_index = -1;
m_sort_column = 0;
m_sort_desc = false;
m_sort_default = true;
} // BaseOnlineProfileAchievements
// -----------------------------------------------------------------------------
@ -58,6 +61,7 @@ void BaseOnlineProfileAchievements::loadedFromFile()
OnlineProfileBase::loadedFromFile();
m_achievements_list_widget = getWidget<ListWidget>("achievements_list");
assert(m_achievements_list_widget != NULL);
m_achievements_list_widget->setColumnListener(this);
} // loadedFromFile
@ -98,30 +102,7 @@ void BaseOnlineProfileAchievements::init()
// m_visiting_profile is NULL if the user is not logged in.
if(!m_visiting_profile || m_visiting_profile->isCurrentUser())
{
// No need to wait for results, since they are local anyway
m_waiting_for_achievements = false;
m_achievements_list_widget->clear();
std::map<uint32_t, Achievement *> & all_achievements =
PlayerManager::getCurrentPlayer()->getAchievementsStatus()
->getAllAchievements();
std::map<uint32_t, Achievement *>::const_iterator it;
for (it = all_achievements.begin(); it != all_achievements.end(); ++it)
{
std::vector<ListWidget::ListCell> row;
Achievement *a = it->second;
if(a->getInfo()->isSecret() && !a->isAchieved())
continue;
ListWidget::ListCell title(translations->fribidize(a->getInfo()->getName()), -1, 2);
ListWidget::ListCell goals(a->getGoalProgressAsString(), -1, 1);
ListWidget::ListCell progress(a->getProgressAsString(), -1, 1);
row.push_back(title);
row.push_back(goals);
row.push_back(progress);
const std::string id = StringUtils::toString(a->getInfo()->getID());
m_achievements_list_widget->addItem(id, row);
if (a->isAchieved())
m_achievements_list_widget->emphasisItem(id);
}
displayResults();
}
else
{
@ -177,6 +158,119 @@ void BaseOnlineProfileAchievements::eventCallback(Widget* widget,
}
} // eventCallback
// ----------------------------------------------------------------------------
void BaseOnlineProfileAchievements::onColumnClicked(int column_id, bool sort_desc, bool sort_default)
{
m_sort_column = column_id;
m_sort_desc = sort_desc;
m_sort_default = sort_default;
if (!m_waiting_for_achievements)
{
displayResults();
}
} // onColumnClicked
// ----------------------------------------------------------------------------
/** Displays the achievements from a given profile.
*/
void BaseOnlineProfileAchievements::displayResults()
{
m_achievements_list_widget->clear();
m_waiting_for_achievements = false;
if (!m_visiting_profile || m_visiting_profile->isCurrentUser())
{
// No need to wait for results, since they are local anyway
std::map<uint32_t, Achievement *> & all_achievements =
PlayerManager::getCurrentPlayer()->getAchievementsStatus()
->getAllAchievements();
// We need to get a vector instead because we need to sort
std::vector<Achievement *> all_achievements_list;
std::map<uint32_t, Achievement *>::const_iterator it;
for (it = all_achievements.begin(); it != all_achievements.end(); ++it)
{
all_achievements_list.push_back(it->second);
}
auto compAchievement = [=](Achievement *a, Achievement *b) {
if (m_sort_column == 0)
{
// Sort by name
return a->getInfo()->getName().lower_ignore_case(b->getInfo()->getName());
}
else if (m_sort_column == 1)
{
// Sort by goals
return a->getInfo()->goalString().lower_ignore_case(b->getInfo()->goalString());
}
else if (m_sort_column == 2)
{
// Sort by progress
return a->getProgressAsString().lower_ignore_case(b->getProgressAsString());
}
};
if (m_sort_desc && !m_sort_default)
{
std::sort(all_achievements_list.rbegin(), all_achievements_list.rend(), compAchievement);
}
else if (!m_sort_default)
{
std::sort(all_achievements_list.begin(), all_achievements_list.end(), compAchievement);
}
std::vector<Achievement *>::iterator vit;
for (vit = all_achievements_list.begin(); vit != all_achievements_list.end(); ++vit)
{
std::vector<ListWidget::ListCell> row;
Achievement *a = *vit;
if (a->getInfo()->isSecret() && !a->isAchieved())
continue;
ListWidget::ListCell title(translations->fribidize(a->getInfo()->getName()), -1, 2);
ListWidget::ListCell goals(a->getGoalProgressAsString(), -1, 1);
ListWidget::ListCell progress(a->getProgressAsString(), -1, 1);
row.push_back(title);
row.push_back(goals);
row.push_back(progress);
const std::string id = StringUtils::toString(a->getInfo()->getID());
m_achievements_list_widget->addItem(id, row);
if (a->isAchieved())
m_achievements_list_widget->emphasisItem(id);
}
}
else
{
OnlineProfile::IDList a = m_visiting_profile->getAchievements();
auto compAchievementInfo = [](int a, int b) {
AchievementInfo *a1 = AchievementsManager::get()->getAchievementInfo(a);
AchievementInfo *a2 = AchievementsManager::get()->getAchievementInfo(b);
return a1->getName().lower_ignore_case(a2->getName());
};
// Because only the name column is visible when viewing other player's achievements, col does not matter
if (m_sort_desc && !m_sort_default)
{
std::sort(a.rbegin(), a.rend(), compAchievementInfo);
}
else if (!m_sort_default)
{
std::sort(a.begin(), a.end(), compAchievementInfo);
}
for (unsigned int i = 0; i < a.size(); i++)
{
AchievementInfo *info =
AchievementsManager::get()->getAchievementInfo(a[i]);
m_achievements_list_widget->addItem(StringUtils::toString(info->getID()),
info->getName());
}
}
} // displayResults
// ----------------------------------------------------------------------------
/** Called every frame. It will check if results from an achievement request
* have been received, and if so, display them.
@ -194,15 +288,5 @@ void BaseOnlineProfileAchievements::onUpdate(float delta)
}
// Now reesults are available, display them.
m_achievements_list_widget->clear();
const OnlineProfile::IDList &a = m_visiting_profile->getAchievements();
for (unsigned int i = 0; i < a.size(); i++)
{
AchievementInfo *info =
AchievementsManager::get()->getAchievementInfo(a[i]);
m_achievements_list_widget->addItem(StringUtils::toString(info->getID()),
info->getName() );
}
m_waiting_for_achievements = false;
displayResults();
} // onUpdate

View File

@ -35,7 +35,8 @@ namespace GUIEngine { class Widget; }
* \brief Online profiel overview screen
* \ingroup states_screens
*/
class BaseOnlineProfileAchievements : public OnlineProfileBase
class BaseOnlineProfileAchievements : public OnlineProfileBase,
public GUIEngine::IListWidgetHeaderListener
{
private:
@ -44,6 +45,15 @@ private:
int m_selected_achievement_index;
bool m_waiting_for_achievements;
/** Which column to use for sorting. */
int m_sort_column;
bool m_sort_desc;
bool m_sort_default;
void displayResults();
protected:
BaseOnlineProfileAchievements(const std::string &filename);
@ -62,6 +72,7 @@ public:
virtual void onUpdate(float delta) OVERRIDE;
virtual void beforeAddingWidget() OVERRIDE;
virtual void onColumnClicked(int column_id, bool sort_desc, bool sort_default) OVERRIDE;
// ------------------------------------------------------------------------
virtual void refreshAchievementsList()