Merge pull request #12877 from LillyJadeKatrin/retroachievements-auto-update
Update Achievement List when Rich Presence Updates
This commit is contained in:
commit
233ea58446
|
@ -65,32 +65,48 @@ AchievementBox::AchievementBox(QWidget* parent, rc_client_achievement_t* achieve
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementBox::UpdateData()
|
void AchievementBox::UpdateData()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard lg{AchievementManager::GetInstance().GetLock()};
|
||||||
|
// rc_client guarantees m_achievement will be valid as long as the game is loaded
|
||||||
|
if (!AchievementManager::GetInstance().IsGameLoaded())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& badge = AchievementManager::GetInstance().GetAchievementBadge(
|
||||||
|
m_achievement->id, m_achievement->state != RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED);
|
||||||
|
std::string_view color = AchievementManager::GRAY;
|
||||||
|
if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE)
|
||||||
|
color = AchievementManager::GOLD;
|
||||||
|
else if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE)
|
||||||
|
color = AchievementManager::BLUE;
|
||||||
|
QImage i_badge(&badge.data.front(), badge.width, badge.height, QImage::Format_RGBA8888);
|
||||||
|
m_badge->setPixmap(
|
||||||
|
QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||||
|
m_badge->adjustSize();
|
||||||
|
m_badge->setStyleSheet(
|
||||||
|
QStringLiteral("border: 4px solid %1").arg(QtUtils::FromStdString(color)));
|
||||||
|
|
||||||
|
if (m_achievement->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED)
|
||||||
|
{
|
||||||
|
m_status->setText(
|
||||||
|
tr("Unlocked at %1")
|
||||||
|
.arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_status->setText(tr("Locked"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AchievementBox::UpdateProgress()
|
||||||
{
|
{
|
||||||
std::lock_guard lg{AchievementManager::GetInstance().GetLock()};
|
std::lock_guard lg{AchievementManager::GetInstance().GetLock()};
|
||||||
|
// rc_client guarantees m_achievement will be valid as long as the game is loaded
|
||||||
const auto& badge = AchievementManager::GetInstance().GetAchievementBadge(
|
if (!AchievementManager::GetInstance().IsGameLoaded())
|
||||||
m_achievement->id, m_achievement->state != RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED);
|
return;
|
||||||
std::string_view color = AchievementManager::GRAY;
|
|
||||||
if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE)
|
|
||||||
color = AchievementManager::GOLD;
|
|
||||||
else if (m_achievement->unlocked & RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE)
|
|
||||||
color = AchievementManager::BLUE;
|
|
||||||
QImage i_badge(&badge.data.front(), badge.width, badge.height, QImage::Format_RGBA8888);
|
|
||||||
m_badge->setPixmap(
|
|
||||||
QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
|
||||||
m_badge->adjustSize();
|
|
||||||
m_badge->setStyleSheet(QStringLiteral("border: 4px solid %1").arg(QtUtils::FromStdString(color)));
|
|
||||||
|
|
||||||
if (m_achievement->state == RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED)
|
|
||||||
{
|
|
||||||
m_status->setText(
|
|
||||||
tr("Unlocked at %1")
|
|
||||||
.arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_status->setText(tr("Locked"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_achievement->measured_percent > 0.000)
|
if (m_achievement->measured_percent > 0.000)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,7 @@ class AchievementBox final : public QGroupBox
|
||||||
public:
|
public:
|
||||||
explicit AchievementBox(QWidget* parent, rc_client_achievement_t* achievement);
|
explicit AchievementBox(QWidget* parent, rc_client_achievement_t* achievement);
|
||||||
void UpdateData();
|
void UpdateData();
|
||||||
|
void UpdateProgress();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel* m_badge;
|
QLabel* m_badge;
|
||||||
|
|
|
@ -42,33 +42,51 @@ void AchievementProgressWidget::UpdateData(bool clean_all)
|
||||||
{
|
{
|
||||||
m_achievement_boxes.clear();
|
m_achievement_boxes.clear();
|
||||||
ClearLayoutRecursively(m_common_layout);
|
ClearLayoutRecursively(m_common_layout);
|
||||||
|
|
||||||
auto& instance = AchievementManager::GetInstance();
|
|
||||||
if (!instance.IsGameLoaded())
|
|
||||||
return;
|
|
||||||
auto* client = instance.GetClient();
|
|
||||||
auto* achievement_list = rc_client_create_achievement_list(
|
|
||||||
client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL,
|
|
||||||
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS);
|
|
||||||
for (u32 ix = 0; ix < achievement_list->num_buckets; ix++)
|
|
||||||
{
|
|
||||||
m_common_layout->addWidget(new QLabel(tr(achievement_list->buckets[ix].label)));
|
|
||||||
for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++)
|
|
||||||
{
|
|
||||||
auto* achievement = achievement_list->buckets[ix].achievements[jx];
|
|
||||||
m_achievement_boxes[achievement->id] = std::make_shared<AchievementBox>(this, achievement);
|
|
||||||
m_common_layout->addWidget(m_achievement_boxes[achievement->id].get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc_client_destroy_achievement_list(achievement_list);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto box : m_achievement_boxes)
|
while (auto* item = m_common_layout->takeAt(0))
|
||||||
{
|
{
|
||||||
box.second->UpdateData();
|
auto* widget = item->widget();
|
||||||
|
m_common_layout->removeWidget(widget);
|
||||||
|
if (std::strcmp(widget->metaObject()->className(), "QLabel") == 0)
|
||||||
|
{
|
||||||
|
widget->deleteLater();
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& instance = AchievementManager::GetInstance();
|
||||||
|
if (!instance.IsGameLoaded())
|
||||||
|
return;
|
||||||
|
auto* client = instance.GetClient();
|
||||||
|
auto* achievement_list =
|
||||||
|
rc_client_create_achievement_list(client, RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL,
|
||||||
|
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS);
|
||||||
|
if (!achievement_list)
|
||||||
|
return;
|
||||||
|
for (u32 ix = 0; ix < achievement_list->num_buckets; ix++)
|
||||||
|
{
|
||||||
|
m_common_layout->addWidget(new QLabel(tr(achievement_list->buckets[ix].label)));
|
||||||
|
for (u32 jx = 0; jx < achievement_list->buckets[ix].num_achievements; jx++)
|
||||||
|
{
|
||||||
|
auto* achievement = achievement_list->buckets[ix].achievements[jx];
|
||||||
|
auto box_itr = m_achievement_boxes.lower_bound(achievement->id);
|
||||||
|
if (box_itr != m_achievement_boxes.end() && box_itr->first == achievement->id)
|
||||||
|
{
|
||||||
|
box_itr->second->UpdateProgress();
|
||||||
|
m_common_layout->addWidget(box_itr->second.get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto new_box_itr = m_achievement_boxes.try_emplace(
|
||||||
|
box_itr, achievement->id, std::make_shared<AchievementBox>(this, achievement));
|
||||||
|
m_common_layout->addWidget(new_box_itr->second.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc_client_destroy_achievement_list(achievement_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementProgressWidget::UpdateData(
|
void AchievementProgressWidget::UpdateData(
|
||||||
|
|
|
@ -91,7 +91,7 @@ void AchievementsWindow::UpdateData(AchievementManager::UpdatedItems updated_ite
|
||||||
{
|
{
|
||||||
m_header_widget->UpdateData();
|
m_header_widget->UpdateData();
|
||||||
}
|
}
|
||||||
if (updated_items.all_achievements)
|
if (updated_items.all_achievements || updated_items.rich_presence)
|
||||||
m_progress_widget->UpdateData(false);
|
m_progress_widget->UpdateData(false);
|
||||||
else if (updated_items.achievements.size() > 0)
|
else if (updated_items.achievements.size() > 0)
|
||||||
m_progress_widget->UpdateData(updated_items.achievements);
|
m_progress_widget->UpdateData(updated_items.achievements);
|
||||||
|
|
Loading…
Reference in New Issue