mirror of
				https://github.com/dolphin-emu/dolphin.git
				synced 2025-10-27 02:19:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			142 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright 2024 Dolphin Emulator Project
 | |
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |
| 
 | |
| #ifdef USE_RETRO_ACHIEVEMENTS
 | |
| #include "DolphinQt/Achievements/AchievementBox.h"
 | |
| 
 | |
| #include <QByteArray>
 | |
| #include <QDateTime>
 | |
| #include <QHBoxLayout>
 | |
| #include <QLabel>
 | |
| #include <QProgressBar>
 | |
| #include <QSizePolicy>
 | |
| #include <QVBoxLayout>
 | |
| #include <QWidget>
 | |
| 
 | |
| #include <rcheevos/include/rc_api_runtime.h>
 | |
| 
 | |
| #include "Core/AchievementManager.h"
 | |
| #include "Core/Config/AchievementSettings.h"
 | |
| 
 | |
| #include "DolphinQt/QtUtils/FromStdString.h"
 | |
| 
 | |
| static constexpr size_t PROGRESS_LENGTH = 24;
 | |
| 
 | |
| AchievementBox::AchievementBox(QWidget* parent, const rc_client_achievement_t* achievement)
 | |
|     : QGroupBox(parent), m_achievement(achievement)
 | |
| {
 | |
|   const auto& instance = AchievementManager::GetInstance();
 | |
|   if (!instance.IsGameLoaded())
 | |
|     return;
 | |
| 
 | |
|   m_badge = new QLabel();
 | |
|   QLabel* title = new QLabel(QString::fromUtf8(achievement->title, strlen(achievement->title)));
 | |
|   title->setWordWrap(true);
 | |
|   title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
 | |
|   QLabel* description =
 | |
|       new QLabel(QString::fromUtf8(achievement->description, strlen(achievement->description)));
 | |
|   description->setWordWrap(true);
 | |
|   description->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
 | |
|   QLabel* points = new QLabel(tr("%1 points").arg(achievement->points));
 | |
|   m_status = new QLabel();
 | |
|   m_progress_bar = new QProgressBar();
 | |
|   QSizePolicy sp_retain = m_progress_bar->sizePolicy();
 | |
|   sp_retain.setRetainSizeWhenHidden(true);
 | |
|   m_progress_bar->setSizePolicy(sp_retain);
 | |
|   m_progress_label = new QLabel();
 | |
|   m_progress_label->setStyleSheet(QStringLiteral("background-color:transparent;"));
 | |
|   m_progress_label->setAlignment(Qt::AlignCenter);
 | |
| 
 | |
|   QVBoxLayout* a_col_left = new QVBoxLayout();
 | |
|   a_col_left->addSpacerItem(new QSpacerItem(0, 0));
 | |
|   a_col_left->addWidget(m_badge);
 | |
|   a_col_left->addSpacerItem(new QSpacerItem(0, 0));
 | |
|   a_col_left->setSizeConstraint(QLayout::SetFixedSize);
 | |
|   a_col_left->setAlignment(Qt::AlignCenter);
 | |
|   QVBoxLayout* a_col_right = new QVBoxLayout();
 | |
|   a_col_right->addWidget(title);
 | |
|   a_col_right->addWidget(description);
 | |
|   a_col_right->addWidget(points);
 | |
|   a_col_right->addWidget(m_status);
 | |
|   a_col_right->addWidget(m_progress_bar);
 | |
|   QVBoxLayout* a_prog_layout = new QVBoxLayout(m_progress_bar);
 | |
|   a_prog_layout->setContentsMargins(0, 0, 0, 0);
 | |
|   a_prog_layout->addWidget(m_progress_label);
 | |
|   QHBoxLayout* a_total = new QHBoxLayout();
 | |
|   a_total->addLayout(a_col_left);
 | |
|   a_total->addLayout(a_col_right);
 | |
|   setLayout(a_total);
 | |
| 
 | |
|   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->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->unlocked)
 | |
|     {
 | |
|       if (m_achievement->unlock_time != 0)
 | |
|       {
 | |
|         m_status->setText(
 | |
|             // i18n: %1 is a date/time.
 | |
|             tr("Unlocked at %1")
 | |
|                 .arg(QDateTime::fromSecsSinceEpoch(m_achievement->unlock_time).toString()));
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         m_status->setText(tr("Unlocked"));
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       m_status->setText(tr("Locked"));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   UpdateProgress();
 | |
| }
 | |
| 
 | |
| void AchievementBox::UpdateProgress()
 | |
| {
 | |
|   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;
 | |
| 
 | |
|   if (m_achievement->measured_percent > 0.000)
 | |
|   {
 | |
|     m_progress_bar->setRange(0, 100);
 | |
|     m_progress_bar->setValue(m_achievement->unlocked ? 100 : m_achievement->measured_percent);
 | |
|     m_progress_bar->setTextVisible(false);
 | |
|     m_progress_label->setText(
 | |
|         QString::fromUtf8(m_achievement->measured_progress,
 | |
|                           qstrnlen(m_achievement->measured_progress, PROGRESS_LENGTH)));
 | |
|     m_progress_label->setVisible(!m_achievement->unlocked);
 | |
|     m_progress_bar->setVisible(true);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     m_progress_bar->setVisible(false);
 | |
|   }
 | |
| }
 | |
| 
 | |
| #endif  // USE_RETRO_ACHIEVEMENTS
 |