Achievements: Add progress indicator mode option

Show the title by default.
pull/3732/head
Stenzek 2 months ago
parent 122bd30ba0
commit 6513e47784
No known key found for this signature in database

@ -796,7 +796,8 @@ void Achievements::UpdateSettings(const Settings& old_config)
if (!g_settings.achievements_leaderboard_trackers)
s_state.active_leaderboard_trackers.clear();
if (!g_settings.achievements_progress_indicators)
// remove progress indicator because it won't remove normally
if (g_settings.achievements_progress_indicator_mode == AchievementProgressIndicatorMode::Disabled)
s_state.active_progress_indicator.reset();
}
@ -1793,9 +1794,6 @@ void Achievements::HandleAchievementProgressIndicatorShowEvent(const rc_client_e
DEV_LOG("Showing progress indicator: {} ({}): {}", event->achievement->id, event->achievement->title,
event->achievement->measured_progress);
if (!g_settings.achievements_progress_indicators)
return;
// Don't show pinned achievements.
if (IsAchievementPinned(event->achievement->id))
{
@ -1820,12 +1818,6 @@ void Achievements::HandleAchievementProgressIndicatorHideEvent(const rc_client_e
DEV_LOG("Hiding progress indicator");
if (!g_settings.achievements_progress_indicators)
{
s_state.active_progress_indicator.reset();
return;
}
s_state.active_progress_indicator->active = false;
s_state.active_progress_indicator->time = std::min(s_state.active_progress_indicator->time, INDICATOR_FADE_OUT_TIME);
}

@ -624,16 +624,28 @@ void FullscreenUI::DrawIndicators(NotificationLayout& layout)
}
if (std::optional<Achievements::AchievementProgressIndicator>& indicator = Achievements::GetActiveProgressIndicator();
indicator.has_value())
indicator.has_value() &&
g_gpu_settings.achievements_progress_indicator_mode != AchievementProgressIndicatorMode::Disabled)
{
indicator->time += indicator->active ? io.DeltaTime : -io.DeltaTime;
const bool show_title =
(g_gpu_settings.achievements_progress_indicator_mode == AchievementProgressIndicatorMode::IconAndTitle);
const ImVec4 left_background_color = DarkerColor(UIStyle.ToastBackgroundColor, 1.3f);
const ImVec4 right_background_color = DarkerColor(UIStyle.ToastBackgroundColor, 0.8f);
const float progress_image_size = ImCeil(32.0f * scale);
const std::string_view text = indicator->achievement->measured_progress;
const ImVec2 text_size = UIStyle.Font->CalcTextSizeA(font_size, font_weight, FLT_MAX, 0.0f, IMSTR_START_END(text));
const float box_width = progress_image_size + text_size.x + spacing + padding.x * 2.0f;
const std::string_view progress_text = indicator->achievement->measured_progress;
const float& progress_text_weight = show_title ? UIStyle.NormalFontWeight : font_weight;
const ImVec2 progress_text_size =
UIStyle.Font->CalcTextSizeA(font_size, progress_text_weight, FLT_MAX, 0.0f, IMSTR_START_END(progress_text));
const std::string_view title_text =
show_title ? std::string_view(indicator->achievement->title) : std::string_view();
const ImVec2 title_text_size =
show_title ? UIStyle.Font->CalcTextSizeA(font_size, font_weight, FLT_MAX, 0.0f, indicator->achievement->title) :
ImVec2();
const float box_width =
progress_image_size + std::max(progress_text_size.x, title_text_size.x) + spacing + padding.x * 2.0f;
const float box_height = progress_image_size + padding.y * 2.0f;
const auto& [box_min, opacity] = layout.GetNextPosition(
@ -661,12 +673,40 @@ void FullscreenUI::DrawIndicators(NotificationLayout& layout)
ImVec2(1.0f, 1.0f), ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, opacity)));
}
const ImVec2 text_pos = box_min + ImVec2(padding.x + progress_image_size + spacing,
ImFloor((box_max.y - box_min.y - text_size.y) * 0.5f));
const ImRect text_clip_rect(text_pos, box_max);
RenderShadowedTextClipped(dl, UIStyle.Font, font_size, font_weight, text_pos, box_max,
ImGui::GetColorU32(ModAlpha(UIStyle.ToastTextColor, opacity)), text, &text_size,
ImVec2(0.0f, 0.0f), 0.0f, &text_clip_rect);
// Show:
// [ badge ] [ title ]
// [ badge ] [ progress text ]
// Or:
// [ badge ] [ progress text centered vertically ]
if (show_title)
{
const float space = box_width - (padding.x * 2.0f) - progress_image_size - spacing;
const ImRect title_clip_rect(ImVec2(box_min.x + padding.x + progress_image_size + spacing +
std::max(ImFloor((space - title_text_size.x) * 0.5f), 0.0f),
box_min.y + padding.y),
box_max);
RenderShadowedTextClipped(dl, UIStyle.Font, font_size, font_weight, title_clip_rect.Min, title_clip_rect.Max,
ImGui::GetColorU32(ModAlpha(UIStyle.ToastTextColor, opacity)), title_text,
&title_text_size, ImVec2(0.0f, 0.0f), 0.0f, &title_clip_rect);
const ImRect text_clip_rect(ImVec2(box_min.x + padding.x + progress_image_size + spacing +
std::max(ImFloor((space - progress_text_size.x) * 0.5f), 0.0f),
box_min.y + padding.y + title_text_size.y),
box_max);
RenderShadowedTextClipped(dl, UIStyle.Font, font_size, progress_text_weight, text_clip_rect.Min,
text_clip_rect.Max,
ImGui::GetColorU32(ModAlpha(DarkerColor(UIStyle.ToastTextColor), opacity)),
progress_text, &progress_text_size, ImVec2(0.0f, 0.0f), 0.0f, &text_clip_rect);
}
else
{
const ImRect text_clip_rect(box_min + ImVec2(padding.x + progress_image_size + spacing,
ImFloor((box_max.y - box_min.y - progress_text_size.y) * 0.5f)),
box_max);
RenderShadowedTextClipped(dl, UIStyle.Font, font_size, progress_text_weight, text_clip_rect.Min,
text_clip_rect.Max, ImGui::GetColorU32(ModAlpha(UIStyle.ToastTextColor, opacity)),
progress_text, &progress_text_size, ImVec2(0.0f, 0.0f), 0.0f, &text_clip_rect);
}
if (!indicator->active && opacity <= 0.01f)
{

@ -5217,6 +5217,12 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
"Cheevos", "ChallengeIndicatorMode", Settings::DEFAULT_ACHIEVEMENT_CHALLENGE_INDICATOR_MODE,
&Settings::ParseAchievementChallengeIndicatorMode, &Settings::GetAchievementChallengeIndicatorModeName,
&Settings::GetAchievementChallengeIndicatorModeDisplayName, AchievementChallengeIndicatorMode::MaxCount, enabled);
DrawEnumSetting(
bsi, FSUI_ICONVSTR(ICON_FA_BARS_PROGRESS, "Progress Indicators"),
FSUI_VSTR("Shows a popup in the selected location when progress towards a measured achievement changes."),
"Cheevos", "ProgressIndicatorMode", Settings::DEFAULT_ACHIEVEMENT_PROGRESS_INDICATOR_MODE,
&Settings::ParseAchievementProgressIndicatorMode, &Settings::GetAchievementProgressIndicatorModeName,
&Settings::GetAchievementProgressIndicatorModeDisplayName, AchievementProgressIndicatorMode::MaxCount, enabled);
DrawEnumSetting(bsi, FSUI_ICONVSTR(ICON_FA_LOCATION_DOT, "Indicator Location"),
FSUI_VSTR("Selects the screen location for challenge/progress indicators, and leaderboard trackers."),
@ -5228,11 +5234,6 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
FSUI_ICONVSTR(ICON_FA_EXPAND, "Custom Indicator Scale"),
FSUI_VSTR("Sets the custom scale percentage for challenge/progress indicators."));
DrawToggleSetting(
bsi, FSUI_ICONVSTR(ICON_FA_BARS_PROGRESS, "Progress Indicators"),
FSUI_VSTR("Shows a popup in the selected location when progress towards a measured achievement changes."),
"Cheevos", "ProgressIndicators", true, enabled);
if (!IsEditingGameSettings(bsi))
{
MenuHeading(FSUI_VSTR("Operations"));

@ -544,7 +544,6 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
achievements_leaderboard_notifications = si.GetBoolValue("Cheevos", "LeaderboardNotifications", true);
achievements_leaderboard_trackers = si.GetBoolValue("Cheevos", "LeaderboardTrackers", true);
achievements_sound_effects = si.GetBoolValue("Cheevos", "SoundEffects", true);
achievements_progress_indicators = si.GetBoolValue("Cheevos", "ProgressIndicators", true);
achievements_prefetch_badges = si.GetBoolValue("Cheevos", "PrefetchBadges", true);
achievements_notification_location =
ParseNotificationLocation(si.GetStringViewValue("Cheevos", "NotificationLocation"))
@ -554,6 +553,9 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
achievements_challenge_indicator_mode =
ParseAchievementChallengeIndicatorMode(si.GetStringViewValue("Cheevos", "ChallengeIndicatorMode"))
.value_or(DEFAULT_ACHIEVEMENT_CHALLENGE_INDICATOR_MODE);
achievements_progress_indicator_mode =
ParseAchievementProgressIndicatorMode(si.GetStringViewValue("Cheevos", "ProgressIndicatorMode"))
.value_or(DEFAULT_ACHIEVEMENT_PROGRESS_INDICATOR_MODE);
achievements_notification_duration =
si.GetSaturatedIntValue<u8>("Cheevos", "NotificationsDuration", DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME);
achievements_leaderboard_duration =
@ -883,12 +885,13 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
si.SetBoolValue("Cheevos", "LeaderboardNotifications", achievements_leaderboard_notifications);
si.SetBoolValue("Cheevos", "LeaderboardTrackers", achievements_leaderboard_trackers);
si.SetBoolValue("Cheevos", "SoundEffects", achievements_sound_effects);
si.SetBoolValue("Cheevos", "ProgressIndicators", achievements_progress_indicators);
si.SetBoolValue("Cheevos", "PrefetchBadges", achievements_prefetch_badges);
si.SetStringValue("Cheevos", "NotificationLocation", GetNotificationLocationName(achievements_notification_location));
si.SetStringValue("Cheevos", "IndicatorLocation", GetNotificationLocationName(achievements_indicator_location));
si.SetStringValue("Cheevos", "ChallengeIndicatorMode",
GetAchievementChallengeIndicatorModeName(achievements_challenge_indicator_mode));
si.SetStringValue("Cheevos", "ProgressIndicatorMode",
GetAchievementProgressIndicatorModeName(achievements_progress_indicator_mode));
si.SetUIntValue("Cheevos", "NotificationsDuration", achievements_notification_duration);
si.SetUIntValue("Cheevos", "LeaderboardsDuration", achievements_leaderboard_duration);
si.SetIntValue("Cheevos", "NotificationScale", achievements_notification_scale);
@ -2497,6 +2500,47 @@ const char* Settings::GetAchievementChallengeIndicatorModeDisplayName(Achievemen
"AchievementChallengeIndicatorMode");
}
static constexpr const std::array s_achievement_progress_indicator_mode_names = {
"Disabled",
"Icon",
"IconAndTitle",
};
static_assert(s_achievement_progress_indicator_mode_names.size() ==
static_cast<size_t>(AchievementProgressIndicatorMode::MaxCount));
static constexpr const std::array s_achievement_progress_indicator_mode_display_names = {
TRANSLATE_DISAMBIG_NOOP("Settings", "Disabled", "AchievementProgressIndicatorMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Show Icon", "AchievementProgressIndicatorMode"),
TRANSLATE_DISAMBIG_NOOP("Settings", "Show Icon and Title", "AchievementProgressIndicatorMode"),
};
static_assert(s_achievement_progress_indicator_mode_display_names.size() ==
static_cast<size_t>(AchievementProgressIndicatorMode::MaxCount));
std::optional<AchievementProgressIndicatorMode> Settings::ParseAchievementProgressIndicatorMode(std::string_view str)
{
int index = 0;
for (const char* name : s_achievement_progress_indicator_mode_names)
{
if (str == name)
return static_cast<AchievementProgressIndicatorMode>(index);
index++;
}
return std::nullopt;
}
const char* Settings::GetAchievementProgressIndicatorModeName(AchievementProgressIndicatorMode mode)
{
return s_achievement_progress_indicator_mode_names[static_cast<size_t>(mode)];
}
const char* Settings::GetAchievementProgressIndicatorModeDisplayName(AchievementProgressIndicatorMode mode)
{
return Host::TranslateToCString("Settings",
s_achievement_progress_indicator_mode_display_names[static_cast<size_t>(mode)],
"AchievementProgressIndicatorMode");
}
static constexpr const std::array s_memory_card_type_names = {
"None", "Shared", "PerGame", "PerGameTitle", "PerGameFileTitle", "NonPersistent",
};

@ -119,15 +119,6 @@ struct GPUSettings
bool display_show_enhancements : 1 = false;
bool display_auto_resize_window : 1 = false;
float gpu_pgxp_tolerance = -1.0f;
float gpu_pgxp_depth_clear_threshold = 0.0f;
std::array<s16, 4> display_fine_crop_amount = {};
float display_osd_scale = DEFAULT_OSD_SCALE;
float display_osd_margin = 0.0f;
std::array<float, 4> display_osd_message_duration = DEFAULT_DISPLAY_OSD_MESSAGE_DURATIONS;
NotificationLocation display_osd_message_location = DEFAULT_OSD_MESSAGE_LOCATION;
// achievements
@ -135,9 +126,20 @@ struct GPUSettings
NotificationLocation achievements_indicator_location = DEFAULT_ACHIEVEMENT_INDICATOR_LOCATION;
AchievementChallengeIndicatorMode achievements_challenge_indicator_mode =
DEFAULT_ACHIEVEMENT_CHALLENGE_INDICATOR_MODE;
AchievementProgressIndicatorMode achievements_progress_indicator_mode = DEFAULT_ACHIEVEMENT_PROGRESS_INDICATOR_MODE;
s16 achievements_notification_scale = ACHIEVEMENT_NOTIFICATION_SCALE_AUTO;
s16 achievements_indicator_scale = ACHIEVEMENT_NOTIFICATION_SCALE_AUTO;
std::array<s16, 4> display_fine_crop_amount = {};
float display_osd_scale = DEFAULT_OSD_SCALE;
float display_osd_margin = 0.0f;
std::array<float, 4> display_osd_message_duration = DEFAULT_DISPLAY_OSD_MESSAGE_DURATIONS;
float gpu_pgxp_tolerance = -1.0f;
float gpu_pgxp_depth_clear_threshold = 0.0f;
// texture replacements
struct TextureReplacementSettings
{
@ -247,6 +249,8 @@ struct GPUSettings
static constexpr AchievementChallengeIndicatorMode DEFAULT_ACHIEVEMENT_CHALLENGE_INDICATOR_MODE =
AchievementChallengeIndicatorMode::Notification;
static constexpr AchievementProgressIndicatorMode DEFAULT_ACHIEVEMENT_PROGRESS_INDICATOR_MODE =
AchievementProgressIndicatorMode::IconAndTitle;
static constexpr NotificationLocation DEFAULT_ACHIEVEMENT_NOTIFICATION_LOCATION = NotificationLocation::TopLeft;
static constexpr NotificationLocation DEFAULT_ACHIEVEMENT_INDICATOR_LOCATION = NotificationLocation::BottomRight;
static constexpr s16 ACHIEVEMENT_NOTIFICATION_SCALE_OSD_SCALE = -1;
@ -370,7 +374,6 @@ struct Settings : public GPUSettings
bool achievements_leaderboard_notifications : 1 = true;
bool achievements_leaderboard_trackers : 1 = true;
bool achievements_sound_effects : 1 = true;
bool achievements_progress_indicators : 1 = true;
bool achievements_prefetch_badges : 1 = DEFAULT_ACHIEVEMENT_BADGE_PREFETCH;
u8 achievements_notification_duration = DEFAULT_ACHIEVEMENT_NOTIFICATION_TIME;
u8 achievements_leaderboard_duration = DEFAULT_LEADERBOARD_NOTIFICATION_TIME;
@ -579,6 +582,10 @@ struct Settings : public GPUSettings
static const char* GetAchievementChallengeIndicatorModeName(AchievementChallengeIndicatorMode mode);
static const char* GetAchievementChallengeIndicatorModeDisplayName(AchievementChallengeIndicatorMode mode);
static std::optional<AchievementProgressIndicatorMode> ParseAchievementProgressIndicatorMode(std::string_view str);
static const char* GetAchievementProgressIndicatorModeName(AchievementProgressIndicatorMode mode);
static const char* GetAchievementProgressIndicatorModeDisplayName(AchievementProgressIndicatorMode mode);
static std::optional<DisplayScreenshotFormat> ParseDisplayScreenshotFormat(std::string_view str);
static const char* GetDisplayScreenshotFormatName(DisplayScreenshotFormat mode);
static const char* GetDisplayScreenshotFormatDisplayName(DisplayScreenshotFormat mode);

@ -4570,6 +4570,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
g_settings.achievements_notification_location != old_settings.achievements_notification_location ||
g_settings.achievements_indicator_location != old_settings.achievements_indicator_location ||
g_settings.achievements_challenge_indicator_mode != old_settings.achievements_challenge_indicator_mode ||
g_settings.achievements_progress_indicator_mode != old_settings.achievements_progress_indicator_mode ||
g_settings.achievements_notification_scale != old_settings.achievements_notification_scale ||
g_settings.achievements_indicator_scale != old_settings.achievements_indicator_scale)
{

@ -263,6 +263,15 @@ enum class AchievementChallengeIndicatorMode : u8
MaxCount
};
enum class AchievementProgressIndicatorMode : u8
{
Disabled,
Icon,
IconAndTitle,
MaxCount
};
enum class ControllerType : u8
{
None,

@ -57,7 +57,11 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
&Settings::ParseAchievementChallengeIndicatorMode, &Settings::GetAchievementChallengeIndicatorModeName,
&Settings::GetAchievementChallengeIndicatorModeDisplayName, Settings::DEFAULT_ACHIEVEMENT_CHALLENGE_INDICATOR_MODE,
AchievementChallengeIndicatorMode::MaxCount);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.progressIndicators, "Cheevos", "ProgressIndicators", true);
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.progressIndicatorMode, "Cheevos", "ProgressIndicatorMode",
&Settings::ParseAchievementProgressIndicatorMode, &Settings::GetAchievementProgressIndicatorModeName,
&Settings::GetAchievementProgressIndicatorModeDisplayName, Settings::DEFAULT_ACHIEVEMENT_PROGRESS_INDICATOR_MODE,
AchievementProgressIndicatorMode::MaxCount);
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.indicatorLocation, "Cheevos", "IndicatorLocation", &Settings::ParseNotificationLocation,
&Settings::GetNotificationLocationName, &Settings::GetNotificationLocationDisplayName,
@ -114,7 +118,7 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
dialog->registerWidgetHelp(m_ui.indicatorScaleCustom, tr("Custom Indicator Scale"), tr("100%"),
tr("Sets the custom scale percentage for challenge/progress indicators."));
dialog->registerWidgetHelp(
m_ui.progressIndicators, tr("Show Progress Indicators"), tr("Checked"),
m_ui.progressIndicatorMode, tr("Progress Indicators"), tr("Checked"),
tr("Shows a popup in the selected location when progress towards a measured achievement changes."));
connect(m_ui.enable, &QCheckBox::checkStateChanged, this, &AchievementSettingsWidget::updateEnableState);

@ -311,27 +311,23 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="progressIndicatorMode"/>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="indicatorLocation"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="challengeIndicatorMode"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="indicatorLocationLabel">
<property name="text">
<string>Indicator Location:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="indicatorLocation"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="indicatorScaleLabel">
<widget class="QLabel" name="progressIndicatorModeLabel">
<property name="text">
<string>Indicator Size:</string>
<string>Progress Indicators:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<layout class="QHBoxLayout" name="indicatorScaleLayout">
<item>
<widget class="QComboBox" name="indicatorScale"/>
@ -351,10 +347,17 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="indicatorLocationLabel">
<property name="text">
<string>Indicator Location:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="progressIndicators">
<widget class="QLabel" name="indicatorScaleLabel">
<property name="text">
<string>Show Progress Indicators</string>
<string>Indicator Size:</string>
</property>
</widget>
</item>

Loading…
Cancel
Save