mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-05-09 04:13:28 -05:00
Yellow squiggly lines begone! Done automatically on .cpp files through `run-clang-tidy`, with manual corrections to the mistakes. If an import is directly used, but is technically unnecessary since it's recursively imported by something else, it is *not* removed. The tool doesn't touch .h files, so I did some of them by hand while fixing errors due to old recursive imports. Not everything is removed, but the cleanup should be substantial enough. Because this done on Linux, code that isn't used on it is mostly untouched. (Hopefully no open PR is depending on these imports...)
157 lines
5.9 KiB
C++
157 lines
5.9 KiB
C++
// Copyright 2023 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#ifdef USE_RETRO_ACHIEVEMENTS
|
|
#include "DolphinQt/Achievements/AchievementLeaderboardWidget.h"
|
|
|
|
#include <QGroupBox>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QString>
|
|
#include <QVBoxLayout>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Core/AchievementManager.h"
|
|
|
|
#include "DolphinQt/QtUtils/ClearLayoutRecursively.h"
|
|
|
|
AchievementLeaderboardWidget::AchievementLeaderboardWidget(QWidget* parent) : QWidget(parent)
|
|
{
|
|
m_common_box = new QGroupBox();
|
|
m_common_layout = new QGridLayout();
|
|
|
|
m_common_box->setLayout(m_common_layout);
|
|
|
|
auto* layout = new QVBoxLayout;
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->setAlignment(Qt::AlignTop);
|
|
layout->addWidget(m_common_box);
|
|
layout->setSizeConstraint(QLayout::SetFixedSize);
|
|
setLayout(layout);
|
|
}
|
|
|
|
void AchievementLeaderboardWidget::UpdateData(bool clean_all)
|
|
{
|
|
if (clean_all)
|
|
{
|
|
ClearLayoutRecursively(m_common_layout);
|
|
|
|
auto& instance = AchievementManager::GetInstance();
|
|
if (!instance.IsGameLoaded())
|
|
return;
|
|
auto* client = instance.GetClient();
|
|
auto* leaderboard_list =
|
|
rc_client_create_leaderboard_list(client, RC_CLIENT_LEADERBOARD_LIST_GROUPING_TRACKING);
|
|
|
|
u32 row = 0;
|
|
for (u32 bucket = 0; bucket < leaderboard_list->num_buckets; bucket++)
|
|
{
|
|
const auto& leaderboard_bucket = leaderboard_list->buckets[bucket];
|
|
m_common_layout->addWidget(new QLabel(tr(leaderboard_bucket.label)), row, 0);
|
|
row += 2;
|
|
for (u32 board = 0; board < leaderboard_bucket.num_leaderboards; board++)
|
|
{
|
|
const auto* leaderboard = leaderboard_bucket.leaderboards[board];
|
|
m_leaderboard_order[leaderboard->id] = row;
|
|
QLabel* a_title = new QLabel(QString::fromUtf8(leaderboard->title));
|
|
a_title->setWordWrap(true);
|
|
a_title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
QLabel* a_description = new QLabel(QString::fromUtf8(leaderboard->description));
|
|
a_description->setWordWrap(true);
|
|
a_description->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
QVBoxLayout* a_col_left = new QVBoxLayout();
|
|
a_col_left->addWidget(a_title);
|
|
a_col_left->addWidget(a_description);
|
|
QFrame* a_divider = new QFrame();
|
|
a_divider->setFrameShape(QFrame::HLine);
|
|
m_common_layout->addWidget(a_divider, row - 1, 0);
|
|
m_common_layout->addLayout(a_col_left, row, 0);
|
|
for (size_t ix = 0; ix < 4; ix++)
|
|
{
|
|
QVBoxLayout* a_col = new QVBoxLayout();
|
|
for (size_t jx = 0; jx < 3; jx++)
|
|
a_col->addWidget(new QLabel(QStringLiteral("---")));
|
|
QFrame* a_divider_2 = new QFrame();
|
|
a_divider_2->setFrameShape(QFrame::HLine);
|
|
m_common_layout->addWidget(a_divider_2, row - 1, static_cast<int>(ix) + 1);
|
|
m_common_layout->addLayout(a_col, row, static_cast<int>(ix) + 1);
|
|
}
|
|
row += 2;
|
|
}
|
|
}
|
|
rc_client_destroy_leaderboard_list(leaderboard_list);
|
|
}
|
|
for (auto row : m_leaderboard_order)
|
|
{
|
|
UpdateRow(row.first);
|
|
}
|
|
}
|
|
|
|
void AchievementLeaderboardWidget::UpdateData(
|
|
const std::set<AchievementManager::AchievementId>& update_ids)
|
|
{
|
|
for (auto row : m_leaderboard_order)
|
|
{
|
|
if (update_ids.contains(row.first))
|
|
{
|
|
UpdateRow(row.first);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AchievementLeaderboardWidget::UpdateRow(AchievementManager::AchievementId leaderboard_id)
|
|
{
|
|
const auto leaderboard_itr = m_leaderboard_order.find(leaderboard_id);
|
|
if (leaderboard_itr == m_leaderboard_order.end())
|
|
return;
|
|
const int row = leaderboard_itr->second;
|
|
|
|
const AchievementManager::LeaderboardStatus* board;
|
|
{
|
|
std::lock_guard lg{AchievementManager::GetInstance().GetLock()};
|
|
board = AchievementManager::GetInstance().GetLeaderboardInfo(leaderboard_id);
|
|
}
|
|
if (!board)
|
|
return;
|
|
|
|
// Each leaderboard entry is displayed with four values. These are *generally* intended to be,
|
|
// in order, the first place entry, the entry one above the player, the player's entry, and
|
|
// the entry one below the player.
|
|
// Edge cases:
|
|
// * If there are fewer than four entries in the leaderboard, all entries will be shown in
|
|
// order and the remainder of the list will be padded with empty values.
|
|
// * If the player does not currently have a score in the leaderboard, or is in the top 3,
|
|
// the four slots will be the top four players in order.
|
|
// * If the player is last place, the player will be in the fourth slot, and the second and
|
|
// third slots will be the two players above them. The first slot will always be first place.
|
|
std::array<u32, 4> to_display{1, 2, 3, 4};
|
|
if (board->player_index > to_display.size() - 1)
|
|
{
|
|
// If the rank one below than the player is found, offset = 1.
|
|
u32 offset = static_cast<u32>(board->entries.count(board->player_index + 1));
|
|
// Example: player is 10th place but not last
|
|
// to_display = {1, 10-3+1+1, 10-3+1+2, 10-3+1+3} = {1, 9, 10, 11}
|
|
// Example: player is 15th place and is last
|
|
// to_display = {1, 15-3+0+1, 15-3+0+2, 15-3+0+3} = {1, 13, 14, 15}
|
|
for (size_t ix = 1; ix < to_display.size(); ++ix)
|
|
to_display[ix] = board->player_index - 3 + offset + static_cast<u32>(ix);
|
|
}
|
|
for (size_t ix = 0; ix < to_display.size(); ++ix)
|
|
{
|
|
const auto it = board->entries.find(to_display[ix]);
|
|
if (it != board->entries.end())
|
|
{
|
|
QVBoxLayout* a_col = new QVBoxLayout();
|
|
a_col->addWidget(new QLabel(tr("Rank %1").arg(it->second.rank)));
|
|
a_col->addWidget(new QLabel(QString::fromStdString(it->second.username)));
|
|
a_col->addWidget(new QLabel(QString::fromUtf8(it->second.score.data())));
|
|
auto old_item = m_common_layout->itemAtPosition(row, static_cast<int>(ix) + 1);
|
|
m_common_layout->removeItem(old_item);
|
|
ClearLayoutRecursively(static_cast<QLayout*>(old_item));
|
|
m_common_layout->addLayout(a_col, row, static_cast<int>(ix) + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // USE_RETRO_ACHIEVEMENTS
|