mirror of https://github.com/PCSX2/pcsx2.git
RetroAchievements/Qt: Add configurable achievement notification duration
This commit is contained in:
parent
2ef1589e76
commit
f2c032ba07
|
@ -1078,7 +1078,10 @@ namespace SettingWidgetBinder
|
|||
static inline void BindSliderToIntSetting(SettingsInterface* sif, QSlider* slider, QLabel* label, const QString& label_suffix,
|
||||
std::string section, std::string key, s32 default_value)
|
||||
{
|
||||
const s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
|
||||
//Clamp in case setting was updated manually using INI
|
||||
global_value = std::clamp(global_value, slider->minimum(), slider->maximum());
|
||||
|
||||
if (sif)
|
||||
{
|
||||
|
@ -1086,7 +1089,9 @@ namespace SettingWidgetBinder
|
|||
QFont bold_font(orig_font);
|
||||
bold_font.setBold(true);
|
||||
|
||||
const s32 current_value = sif->GetOptionalIntValue(section.c_str(), key.c_str()).value_or(global_value);
|
||||
s32 current_value = sif->GetOptionalIntValue(section.c_str(), key.c_str()).value_or(global_value);
|
||||
current_value = std::clamp(current_value, slider->minimum(), slider->maximum());
|
||||
|
||||
slider->setValue(current_value);
|
||||
|
||||
label->setText(QStringLiteral("%1%2").arg(current_value).arg(label_suffix));
|
||||
|
@ -1100,8 +1105,10 @@ namespace SettingWidgetBinder
|
|||
[sif, slider, label, label_suffix, orig_font = std::move(orig_font), section, key, default_value](const QPoint& pt) {
|
||||
QMenu menu(slider);
|
||||
slider->connect(menu.addAction(qApp->translate("SettingWidgetBinder", "Reset")), &QAction::triggered, slider,
|
||||
[sif, label, label_suffix, orig_font, section, key, default_value]() {
|
||||
const s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
[sif, slider, label, label_suffix, orig_font, section, key, default_value]() {
|
||||
s32 global_value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
global_value = std::clamp(global_value, slider->minimum(), slider->maximum());
|
||||
|
||||
label->setText(QStringLiteral("%1%2").arg(global_value).arg(label_suffix));
|
||||
label->setFont(orig_font);
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <QtCore/QDateTime>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
static constexpr s32 DEFAULT_NOTIFICATIONS_DURATION = 5;
|
||||
|
||||
AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_dialog(dialog)
|
||||
|
@ -48,6 +50,9 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi
|
|||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.soundEffects, "Achievements", "SoundEffects", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.primedIndicators, "Achievements", "PrimedIndicators", true);
|
||||
|
||||
SettingWidgetBinder::BindSliderToIntSetting(sif, m_ui.notifications_duration, m_ui.notifications_duration_seconds,
|
||||
tr(" seconds"), "Achievements", "NotificationsDuration", DEFAULT_NOTIFICATIONS_DURATION);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.enable, tr("Enable Achievements"), tr("Unchecked"),
|
||||
tr("When enabled and logged in, PCSX2 will scan for achievements on game load."));
|
||||
dialog->registerWidgetHelp(m_ui.testMode, tr("Enable Test Mode"), tr("Unchecked"),
|
||||
|
@ -70,10 +75,18 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsDialog* dialog, QWi
|
|||
dialog->registerWidgetHelp(m_ui.primedIndicators, tr("Show Challenge Indicators"), tr("Checked"),
|
||||
tr("Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.notifications_duration, tr("Notification Duration"),
|
||||
tr("5 seconds"), tr("The duration, in seconds, an achievement popup notification will remain on screen."));
|
||||
dialog->registerWidgetHelp(m_ui.notifications_duration_label, tr("Notification Duration"),
|
||||
tr("5 seconds"), tr("The duration, in seconds, an achievement popup notification will remain on screen."));
|
||||
dialog->registerWidgetHelp(m_ui.notifications_duration_seconds, tr("Notification Duration"),
|
||||
tr("5 seconds"), tr("The duration, in seconds, an achievement popup notification will remain on screen."));
|
||||
|
||||
connect(m_ui.enable, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
|
||||
connect(m_ui.notifications, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
|
||||
connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
|
||||
connect(m_ui.challengeMode, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::onChallengeModeStateChanged);
|
||||
connect(m_ui.notifications_duration, &QSlider::valueChanged, this, &AchievementSettingsWidget::onNotificationsDurationChanged);
|
||||
|
||||
if (!m_dialog->isPerGameSettings())
|
||||
{
|
||||
|
@ -105,6 +118,8 @@ void AchievementSettingsWidget::updateEnableState()
|
|||
{
|
||||
const bool enabled = m_dialog->getEffectiveBoolValue("Achievements", "Enabled", false);
|
||||
const bool challenge = m_dialog->getEffectiveBoolValue("Achievements", "ChallengeMode", false);
|
||||
const bool notifications = m_dialog->getEffectiveBoolValue("Achievements", "Notifications", true);
|
||||
|
||||
m_ui.testMode->setEnabled(enabled);
|
||||
m_ui.unofficialTestMode->setEnabled(enabled);
|
||||
m_ui.richPresence->setEnabled(enabled);
|
||||
|
@ -113,6 +128,10 @@ void AchievementSettingsWidget::updateEnableState()
|
|||
m_ui.notifications->setEnabled(enabled);
|
||||
m_ui.soundEffects->setEnabled(enabled);
|
||||
m_ui.primedIndicators->setEnabled(enabled);
|
||||
|
||||
m_ui.notifications_duration->setEnabled(enabled && notifications);
|
||||
m_ui.notifications_duration_label->setEnabled(enabled && notifications);
|
||||
m_ui.notifications_duration_seconds->setEnabled(enabled && notifications);
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::onChallengeModeStateChanged()
|
||||
|
@ -196,3 +215,9 @@ void AchievementSettingsWidget::onAchievementsRefreshed(quint32 id, const QStrin
|
|||
{
|
||||
m_ui.gameInfo->setText(game_info_string);
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::onNotificationsDurationChanged()
|
||||
{
|
||||
m_ui.notifications_duration_seconds->setText(tr("%1 seconds")
|
||||
.arg(m_ui.notifications_duration->value()));
|
||||
}
|
|
@ -33,6 +33,7 @@ private Q_SLOTS:
|
|||
void onLoginLogoutPressed();
|
||||
void onViewProfilePressed();
|
||||
void onAchievementsRefreshed(quint32 id, const QString& game_info_string, quint32 total, quint32 points);
|
||||
void onNotificationsDurationChanged();
|
||||
|
||||
private:
|
||||
void updateLoginState();
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>658</width>
|
||||
<height>496</height>
|
||||
<width>829</width>
|
||||
<height>641</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -39,13 +39,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="primedIndicators">
|
||||
<property name="text">
|
||||
<string>Show Challenge Indicators</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="richPresence">
|
||||
<property name="text">
|
||||
|
@ -74,13 +67,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="testMode">
|
||||
<property name="text">
|
||||
<string>Enable Test Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="soundEffects">
|
||||
<property name="text">
|
||||
|
@ -89,12 +75,93 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="primedIndicators">
|
||||
<property name="text">
|
||||
<string>Show Challenge Indicators</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="testMode">
|
||||
<property name="text">
|
||||
<string>Enable Test Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="notificationBox">
|
||||
<property name="title">
|
||||
<string>Notifications</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="notifications_box_layout" stretch="0,0">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifications">
|
||||
<property name="text">
|
||||
<string>Show Notifications</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="notifications_duration_layout" stretch="0,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="notifications_duration_label">
|
||||
<property name="text">
|
||||
<string>Duration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="notifications_duration">
|
||||
<property name="minimum">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="notifications_duration_seconds">
|
||||
<property name="text">
|
||||
<string>5 seconds</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -132,6 +132,8 @@ namespace Achievements
|
|||
static void UnlockAchievementCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data);
|
||||
static void SubmitLeaderboardCallback(s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data, u32 lboard_id);
|
||||
|
||||
static s32 GetNotificationsDuration();
|
||||
|
||||
static bool s_active = false;
|
||||
static bool s_logged_in = false;
|
||||
static bool s_challenge_mode = false;
|
||||
|
@ -1117,9 +1119,9 @@ void Achievements::DisplayAchievementSummary()
|
|||
summary.append(TRANSLATE_SV("Achievements", "Leaderboard submission is enabled."));
|
||||
}
|
||||
|
||||
MTGS::RunOnGSThread([title = std::move(title), summary = std::move(summary), icon = s_game_icon]() {
|
||||
MTGS::RunOnGSThread([duration = GetNotificationsDuration(), title = std::move(title), summary = std::move(summary), icon = s_game_icon]() {
|
||||
if (FullscreenUI::IsInitialized())
|
||||
ImGuiFullscreen::AddNotification(10.0f, std::move(title), std::move(summary), std::move(icon));
|
||||
ImGuiFullscreen::AddNotification(duration, std::move(title), std::move(summary), std::move(icon));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1137,9 +1139,9 @@ void Achievements::DisplayMasteredNotification()
|
|||
std::string message(fmt::format(
|
||||
"{} achievements, {} points{}", GetAchievementCount(), GetCurrentPointsForGame(), s_challenge_mode ? " (Hardcore Mode)" : ""));
|
||||
|
||||
MTGS::RunOnGSThread([title = std::move(title), message = std::move(message), icon = s_game_icon]() {
|
||||
MTGS::RunOnGSThread([duration = GetNotificationsDuration(), title = std::move(title), message = std::move(message), icon = s_game_icon]() {
|
||||
if (FullscreenUI::IsInitialized())
|
||||
ImGuiFullscreen::AddNotification(20.0f, std::move(title), std::move(message), std::move(icon));
|
||||
ImGuiFullscreen::AddNotification(duration, std::move(title), std::move(message), std::move(icon));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1850,9 +1852,9 @@ void Achievements::SubmitLeaderboardCallback(s32 status_code, const std::string&
|
|||
std::string summary = fmt::format(
|
||||
"Your Score: {} (Best: {})\nLeaderboard Position: {} of {}", submitted_score, best_score, response.new_rank, response.num_entries);
|
||||
|
||||
MTGS::RunOnGSThread([title = lb->title, summary = std::move(summary), icon = s_game_icon]() {
|
||||
MTGS::RunOnGSThread([duration = GetNotificationsDuration(), title = lb->title, summary = std::move(summary), icon = s_game_icon]() {
|
||||
if (FullscreenUI::IsInitialized())
|
||||
ImGuiFullscreen::AddNotification(10.0f, std::move(title), std::move(summary), std::move(icon));
|
||||
ImGuiFullscreen::AddNotification(duration, std::move(title), std::move(summary), std::move(icon));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1894,8 +1896,8 @@ void Achievements::UnlockAchievement(u32 achievement_id, bool add_notification /
|
|||
}
|
||||
|
||||
MTGS::RunOnGSThread(
|
||||
[title = std::move(title), description = achievement->description, icon = GetAchievementBadgePath(*achievement)]() {
|
||||
ImGuiFullscreen::AddNotification(15.0f, std::move(title), std::move(description), std::move(icon));
|
||||
[duration = GetNotificationsDuration(), title = std::move(title), description = achievement->description, icon = GetAchievementBadgePath(*achievement)]() {
|
||||
ImGuiFullscreen::AddNotification(duration, std::move(title), std::move(description), std::move(icon));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2153,6 +2155,12 @@ void Achievements::PokeMemory(unsigned address, unsigned num_bytes, void* ud, un
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
s32 Achievements::GetNotificationsDuration()
|
||||
{
|
||||
return EmuConfig.Achievements.NotificationsDuration;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RAINTEGRATION
|
||||
|
||||
#include "RA_Consoles.h"
|
||||
|
|
|
@ -1262,12 +1262,14 @@ struct Pcsx2Config
|
|||
PrimedIndicators : 1;
|
||||
BITFIELD_END
|
||||
|
||||
s32 NotificationsDuration = 5;
|
||||
|
||||
AchievementsOptions();
|
||||
void LoadSave(SettingsWrapper& wrap);
|
||||
|
||||
bool operator==(const AchievementsOptions& right) const
|
||||
{
|
||||
return OpEqu(bitset);
|
||||
return OpEqu(bitset) && OpEqu(NotificationsDuration);
|
||||
}
|
||||
|
||||
bool operator!=(const AchievementsOptions& right) const
|
||||
|
|
|
@ -1429,6 +1429,7 @@ Pcsx2Config::AchievementsOptions::AchievementsOptions()
|
|||
Notifications = true;
|
||||
SoundEffects = true;
|
||||
PrimedIndicators = true;
|
||||
NotificationsDuration = 5;
|
||||
}
|
||||
|
||||
void Pcsx2Config::AchievementsOptions::LoadSave(SettingsWrapper& wrap)
|
||||
|
@ -1444,6 +1445,13 @@ void Pcsx2Config::AchievementsOptions::LoadSave(SettingsWrapper& wrap)
|
|||
SettingsWrapBitBool(Notifications);
|
||||
SettingsWrapBitBool(SoundEffects);
|
||||
SettingsWrapBitBool(PrimedIndicators);
|
||||
SettingsWrapBitfield(NotificationsDuration);
|
||||
|
||||
if (wrap.IsLoading())
|
||||
{
|
||||
//Clamp in case setting was updated manually using the INI
|
||||
NotificationsDuration = std::clamp(NotificationsDuration, 3, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue