mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-04 05:04:33 +00:00
FullscreenUI: Add achievement subset selection
This commit is contained in:
@@ -1394,16 +1394,7 @@ void Achievements::HandleSubsetCompleteEvent(const rc_client_event_t* event)
|
||||
if (g_settings.achievements_notifications && event->subset->badge_name[0] != '\0')
|
||||
{
|
||||
// Need to grab the icon for the subset.
|
||||
std::string badge_path = GetLocalImagePath(event->subset->badge_name, RC_IMAGE_TYPE_GAME);
|
||||
if (!FileSystem::FileExists(badge_path.c_str()))
|
||||
{
|
||||
std::string url;
|
||||
if (IsUsingRAIntegration() || !event->subset->badge_url)
|
||||
url = GetImageURL(event->subset->badge_name, RC_IMAGE_TYPE_GAME);
|
||||
else
|
||||
url = event->subset->badge_url;
|
||||
DownloadImage(std::move(url), badge_path);
|
||||
}
|
||||
std::string badge_path = GetSubsetBadgePath(event->subset);
|
||||
|
||||
std::string message = fmt::format(
|
||||
TRANSLATE_FS("Achievements", "Subset complete.\n{0}, {1}."),
|
||||
@@ -1873,6 +1864,22 @@ std::string Achievements::GetLeaderboardUserBadgePath(const rc_client_leaderboar
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string Achievements::GetSubsetBadgePath(const rc_client_subset_t* subset)
|
||||
{
|
||||
std::string badge_path = GetLocalImagePath(subset->badge_name, RC_IMAGE_TYPE_GAME);
|
||||
if (!FileSystem::FileExists(badge_path.c_str()))
|
||||
{
|
||||
std::string url;
|
||||
if (IsUsingRAIntegration() || !subset->badge_url)
|
||||
url = GetImageURL(subset->badge_name, RC_IMAGE_TYPE_GAME);
|
||||
else
|
||||
url = subset->badge_url;
|
||||
DownloadImage(std::move(url), badge_path);
|
||||
}
|
||||
|
||||
return badge_path;
|
||||
}
|
||||
|
||||
bool Achievements::IsLoggedIn()
|
||||
{
|
||||
return (rc_client_get_user_info(s_state.client) != nullptr);
|
||||
|
||||
@@ -32,6 +32,8 @@ std::string GetAchievementBadgePath(const rc_client_achievement_t* achievement,
|
||||
bool download_if_missing = true);
|
||||
std::string GetLeaderboardUserBadgePath(const rc_client_leaderboard_entry_t* entry);
|
||||
|
||||
std::string GetSubsetBadgePath(const rc_client_subset_t* subset);
|
||||
|
||||
} // namespace Achievements
|
||||
|
||||
#ifndef __ANDROID__
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
#include "IconsEmoji.h"
|
||||
@@ -62,6 +63,15 @@ struct PauseMenuTimedMeasuredAchievementInfo : PauseMenuMeasuredAchievementInfo
|
||||
|
||||
} // namespace
|
||||
|
||||
static void AddSubsetInfo(const rc_client_subset_t* subset);
|
||||
static bool IsCoreSubsetOpen();
|
||||
static void SetCurrentSubsetID(u32 subset_id);
|
||||
static void DrawSubsetSelector();
|
||||
template<typename T>
|
||||
static void CollectSubsetsFromList(const T* list);
|
||||
template<typename T>
|
||||
static bool IsBucketVisibleInCurrentSubset(const T& bucket);
|
||||
|
||||
static const std::string& GetCachedAchievementBadgePath(const rc_client_achievement_t* achievement, bool locked);
|
||||
|
||||
template<typename T>
|
||||
@@ -85,8 +95,22 @@ static void DrawLeaderboardEntry(const rc_client_leaderboard_entry_t& entry, u32
|
||||
|
||||
namespace {
|
||||
|
||||
struct SubsetInfo
|
||||
{
|
||||
std::string full_name;
|
||||
std::string short_name;
|
||||
std::string badge_path;
|
||||
u32 subset_id;
|
||||
u32 num_leaderboards;
|
||||
rc_client_user_game_summary_t summary;
|
||||
};
|
||||
|
||||
struct AchievementsLocals
|
||||
{
|
||||
// Shared by both achievements and leaderboards, TODO: add all filter
|
||||
std::vector<SubsetInfo> subset_info_list;
|
||||
const SubsetInfo* open_subset = nullptr;
|
||||
|
||||
rc_client_achievement_list_t* achievement_list = nullptr;
|
||||
std::vector<std::tuple<const void*, std::string, bool>> achievement_badge_paths;
|
||||
|
||||
@@ -135,6 +159,9 @@ void FullscreenUI::ClearAchievementsState()
|
||||
s_achievements_locals.achievement_list = nullptr;
|
||||
}
|
||||
|
||||
s_achievements_locals.open_subset = nullptr;
|
||||
s_achievements_locals.subset_info_list.clear();
|
||||
|
||||
s_achievements_locals.most_recent_unlock.reset();
|
||||
s_achievements_locals.achievement_nearest_completion.reset();
|
||||
}
|
||||
@@ -581,6 +608,159 @@ void FullscreenUI::OpenAchievementsWindow()
|
||||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::AddSubsetInfo(const rc_client_subset_t* subset)
|
||||
{
|
||||
const std::string_view game_title = Achievements::GetGameTitle();
|
||||
|
||||
SubsetInfo info;
|
||||
info.subset_id = subset->id;
|
||||
|
||||
// is this the core subset?
|
||||
std::string_view subset_title = subset->title;
|
||||
if (game_title == subset_title)
|
||||
{
|
||||
info.full_name = subset_title;
|
||||
info.short_name = TRANSLATE_STR("Achievements", "Core");
|
||||
}
|
||||
else if (subset_title.starts_with(game_title))
|
||||
{
|
||||
info.full_name = subset_title;
|
||||
info.short_name = StringUtil::StripWhitespace(subset_title.substr(game_title.size()));
|
||||
if (info.short_name.starts_with("-"))
|
||||
info.short_name = StringUtil::StripWhitespace(info.short_name.substr(1));
|
||||
if (info.short_name.empty())
|
||||
info.short_name = StringUtil::ToChars(subset->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.full_name = fmt::format(TRANSLATE_FS("Achievements", "{0} - {1}"), game_title, subset_title);
|
||||
info.short_name = subset_title;
|
||||
}
|
||||
|
||||
info.badge_path = Achievements::GetSubsetBadgePath(subset);
|
||||
info.num_leaderboards = subset->num_leaderboards;
|
||||
|
||||
info.summary = {};
|
||||
rc_client_get_user_subset_summary(Achievements::GetClient(), subset->id, &info.summary);
|
||||
|
||||
s_achievements_locals.subset_info_list.push_back(std::move(info));
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawSubsetSelector()
|
||||
{
|
||||
DebugAssert(s_achievements_locals.open_subset);
|
||||
|
||||
const float& font_size = UIStyle.MediumFontSize;
|
||||
constexpr float font_weight = UIStyle.BoldFontWeight;
|
||||
constexpr float nav_x_padding = 12.0f;
|
||||
constexpr float nav_y_padding = 8.0f;
|
||||
|
||||
float nav_width = 0.0f;
|
||||
for (const SubsetInfo& subset : s_achievements_locals.subset_info_list)
|
||||
nav_width += CalcFloatingNavBarButtonWidth(subset.short_name, font_size, font_size, font_weight, nav_x_padding);
|
||||
|
||||
BeginFloatingNavBar(30.0f, 10.0f, nav_width, font_size, 1.0f, 0.0f, nav_x_padding, nav_y_padding);
|
||||
|
||||
std::optional<u32> new_subset_id;
|
||||
|
||||
for (size_t i = 0; i < s_achievements_locals.subset_info_list.size(); i++)
|
||||
{
|
||||
const SubsetInfo& subset = s_achievements_locals.subset_info_list[i];
|
||||
GPUTexture* badge = GetCachedTextureAsync(subset.badge_path);
|
||||
|
||||
if (FloatingNavBarIcon(subset.short_name, badge, (&subset == s_achievements_locals.open_subset), font_size,
|
||||
font_size, font_weight))
|
||||
{
|
||||
new_subset_id = subset.subset_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_subset_id.has_value())
|
||||
{
|
||||
const size_t i = s_achievements_locals.open_subset - &s_achievements_locals.subset_info_list[0];
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadLeft, true) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakSlow, true) || ImGui::IsKeyPressed(ImGuiKey_LeftArrow, true))
|
||||
{
|
||||
new_subset_id = (i == 0) ? s_achievements_locals.subset_info_list.back().subset_id :
|
||||
s_achievements_locals.subset_info_list[i - 1].subset_id;
|
||||
}
|
||||
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadRight, true) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakFast, true) || ImGui::IsKeyPressed(ImGuiKey_RightArrow, true))
|
||||
{
|
||||
new_subset_id = ((i + 1) == s_achievements_locals.subset_info_list.size()) ?
|
||||
s_achievements_locals.subset_info_list.front().subset_id :
|
||||
s_achievements_locals.subset_info_list[i + 1].subset_id;
|
||||
}
|
||||
}
|
||||
|
||||
EndFloatingNavBar();
|
||||
|
||||
if (new_subset_id.has_value())
|
||||
{
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME,
|
||||
[new_subset_id = new_subset_id.value()]() { SetCurrentSubsetID(new_subset_id); });
|
||||
}
|
||||
}
|
||||
|
||||
bool FullscreenUI::IsCoreSubsetOpen()
|
||||
{
|
||||
return (!s_achievements_locals.open_subset ||
|
||||
s_achievements_locals.open_subset == &s_achievements_locals.subset_info_list[0]);
|
||||
}
|
||||
|
||||
void FullscreenUI::SetCurrentSubsetID(u32 subset_id)
|
||||
{
|
||||
for (const SubsetInfo& info : s_achievements_locals.subset_info_list)
|
||||
{
|
||||
if (info.subset_id == subset_id)
|
||||
{
|
||||
s_achievements_locals.open_subset = &info;
|
||||
QueueResetFocus(FocusResetType::ViewChanged);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void FullscreenUI::CollectSubsetsFromList(const T* list)
|
||||
{
|
||||
s_achievements_locals.open_subset = nullptr;
|
||||
s_achievements_locals.subset_info_list.clear();
|
||||
if (std::any_of(list->buckets, list->buckets + list->num_buckets,
|
||||
[&list](const auto& it) { return it.subset_id != list->buckets[0].subset_id; }))
|
||||
{
|
||||
for (u32 bucket_idx = 0; bucket_idx < list->num_buckets; bucket_idx++)
|
||||
{
|
||||
const auto& bucket = list->buckets[bucket_idx];
|
||||
if (std::ranges::none_of(s_achievements_locals.subset_info_list,
|
||||
[&bucket](const SubsetInfo& info) { return info.subset_id == bucket.subset_id; }))
|
||||
{
|
||||
const rc_client_subset_t* subset = rc_client_get_subset_info(Achievements::GetClient(), bucket.subset_id);
|
||||
if (subset)
|
||||
AddSubsetInfo(subset);
|
||||
}
|
||||
}
|
||||
|
||||
// hopefully the first will be core...
|
||||
Assert(s_achievements_locals.subset_info_list.size() > 1);
|
||||
s_achievements_locals.open_subset = &s_achievements_locals.subset_info_list[0];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool FullscreenUI::IsBucketVisibleInCurrentSubset(const T& bucket)
|
||||
{
|
||||
// Show e.g. active challenges/leaderboards in all subsets.
|
||||
if (bucket.subset_id == 0)
|
||||
return true;
|
||||
|
||||
if (s_achievements_locals.open_subset && bucket.subset_id != s_achievements_locals.open_subset->subset_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FullscreenUI::SwitchToAchievements()
|
||||
{
|
||||
const auto lock = Achievements::GetLock();
|
||||
@@ -617,6 +797,7 @@ void FullscreenUI::SwitchToAchievements()
|
||||
}
|
||||
}
|
||||
|
||||
CollectSubsetsFromList(s_achievements_locals.achievement_list);
|
||||
SwitchToMainWindow(MainWindowType::Achievements);
|
||||
}
|
||||
|
||||
@@ -631,7 +812,9 @@ void FullscreenUI::DrawAchievementsWindow()
|
||||
return;
|
||||
}
|
||||
|
||||
const rc_client_user_game_summary_t& summary = Achievements::GetGameSummary();
|
||||
const rc_client_user_game_summary_t& summary =
|
||||
s_achievements_locals.open_subset ? s_achievements_locals.open_subset->summary : Achievements::GetGameSummary();
|
||||
const bool is_core_subset = IsCoreSubsetOpen();
|
||||
const float heading_height_unscaled = ((summary.beaten_time > 0 || summary.completed_time) ? 122.0f : 102.0f) +
|
||||
((summary.num_unsupported_achievements > 0) ? 20.0f : 0.0f);
|
||||
|
||||
@@ -667,10 +850,16 @@ void FullscreenUI::DrawAchievementsWindow()
|
||||
SmallString text;
|
||||
ImVec2 text_size;
|
||||
|
||||
if (s_achievements_locals.open_subset)
|
||||
DrawSubsetSelector();
|
||||
|
||||
close_window = (FloatingButton(ICON_FA_XMARK, 10.0f, 10.0f, 1.0f, 0.0f, true) || WantsToCloseMenu());
|
||||
|
||||
const ImRect title_bb(ImVec2(left, top), ImVec2(right, top + UIStyle.LargeFontSize));
|
||||
text.assign(Achievements::GetGameTitle());
|
||||
if (s_achievements_locals.open_subset)
|
||||
text.assign(s_achievements_locals.open_subset->full_name);
|
||||
else
|
||||
text.assign(Achievements::GetGameTitle());
|
||||
|
||||
if (rc_client_get_hardcore_enabled(Achievements::GetClient()))
|
||||
text.append(TRANSLATE_SV("Achievements", " (Hardcore Mode)"));
|
||||
@@ -700,7 +889,8 @@ void FullscreenUI::DrawAchievementsWindow()
|
||||
}
|
||||
else
|
||||
{
|
||||
text.format(ICON_FA_BAN " {}", TRANSLATE_SV("Achievements", "This game has no achievements."));
|
||||
text.format(ICON_FA_BAN " {}", is_core_subset ? TRANSLATE_SV("Achievements", "This game has no achievements.") :
|
||||
TRANSLATE_SV("Achievements", "This subset has no achievements."));
|
||||
}
|
||||
|
||||
top += UIStyle.MediumFontSize + spacing;
|
||||
@@ -737,19 +927,33 @@ void FullscreenUI::DrawAchievementsWindow()
|
||||
{
|
||||
const std::string completion_time =
|
||||
Host::FormatNumber(Host::NumberFormatType::ShortDate, static_cast<s64>(summary.completed_time));
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Game was beaten on {0}, and completed on {1}."), beaten_time,
|
||||
completion_time);
|
||||
if (is_core_subset)
|
||||
{
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Game was beaten on {0}, and completed on {1}."),
|
||||
beaten_time, completion_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Subset was beaten on {0}, and completed on {1}."),
|
||||
beaten_time, completion_time);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Game was beaten on {0}."), beaten_time);
|
||||
if (is_core_subset)
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Game was beaten on {0}."), beaten_time);
|
||||
else
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Subset was beaten on {0}."), beaten_time);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string completion_time =
|
||||
Host::FormatNumber(Host::NumberFormatType::ShortDate, static_cast<s64>(summary.completed_time));
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Game was completed on {0}."), completion_time);
|
||||
if (is_core_subset)
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Game was completed on {0}."), completion_time);
|
||||
else
|
||||
text.append_format(TRANSLATE_FS("Achievements", "Subset was completed on {0}."), completion_time);
|
||||
}
|
||||
|
||||
const ImRect beaten_bb(ImVec2(left, top), ImVec2(right, top + UIStyle.MediumFontSize));
|
||||
@@ -821,12 +1025,11 @@ void FullscreenUI::DrawAchievementsWindow()
|
||||
for (u32 bucket_idx = 0; bucket_idx < s_achievements_locals.achievement_list->num_buckets; bucket_idx++)
|
||||
{
|
||||
const rc_client_achievement_bucket_t& bucket = s_achievements_locals.achievement_list->buckets[bucket_idx];
|
||||
if (bucket.bucket_type != bucket_type)
|
||||
if (bucket.bucket_type != bucket_type || !IsBucketVisibleInCurrentSubset(bucket))
|
||||
continue;
|
||||
|
||||
DebugAssert(bucket.bucket_type < NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS);
|
||||
|
||||
// TODO: Once subsets are supported, this will need to change.
|
||||
bool& bucket_collapsed = buckets_collapsed[bucket.bucket_type];
|
||||
bucket_collapsed ^= MenuHeadingButton(
|
||||
TinyString::from_format("{} {}", bucket_names[bucket.bucket_type].first,
|
||||
@@ -854,17 +1057,39 @@ void FullscreenUI::DrawAchievementsWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_A, TRANSLATE_SV("Achievements", "View Details")),
|
||||
std::make_pair(ICON_PF_BUTTON_B, TRANSLATE_SV("Achievements", "Back"))});
|
||||
if (s_achievements_locals.open_subset)
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_XBOX_DPAD_LEFT_RIGHT, TRANSLATE_SV("Achievements", "Change Subset")),
|
||||
std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_A, TRANSLATE_SV("Achievements", "View Details")),
|
||||
std::make_pair(ICON_PF_BUTTON_B, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_A, TRANSLATE_SV("Achievements", "View Details")),
|
||||
std::make_pair(ICON_PF_BUTTON_B, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "View Details")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back"))});
|
||||
if (s_achievements_locals.open_subset)
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, TRANSLATE_SV("Achievements", "Change Subset")),
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "View Details")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "View Details")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
}
|
||||
|
||||
if (close_window)
|
||||
@@ -1079,6 +1304,7 @@ void FullscreenUI::SwitchToLeaderboards()
|
||||
return;
|
||||
}
|
||||
|
||||
CollectSubsetsFromList(s_achievements_locals.leaderboard_list);
|
||||
SwitchToMainWindow(MainWindowType::Leaderboards);
|
||||
}
|
||||
|
||||
@@ -1129,7 +1355,10 @@ void FullscreenUI::DrawLeaderboardsWindow()
|
||||
float top = heading_pos.y;
|
||||
|
||||
const ImRect title_bb(ImVec2(left, top), ImVec2(right, top + UIStyle.LargeFontSize));
|
||||
text.assign(Achievements::GetGameTitle());
|
||||
if (s_achievements_locals.open_subset)
|
||||
text.assign(s_achievements_locals.open_subset->full_name);
|
||||
else
|
||||
text.assign(Achievements::GetGameTitle());
|
||||
|
||||
top += UIStyle.LargeFontSize + spacing_small;
|
||||
|
||||
@@ -1156,8 +1385,17 @@ void FullscreenUI::DrawLeaderboardsWindow()
|
||||
{
|
||||
u32 count = 0;
|
||||
for (u32 i = 0; i < s_achievements_locals.leaderboard_list->num_buckets; i++)
|
||||
count += s_achievements_locals.leaderboard_list->buckets[i].num_leaderboards;
|
||||
text = TRANSLATE_PLURAL_SSTR("Achievements", "This game has %n leaderboards.", "Leaderboard count", count);
|
||||
{
|
||||
const rc_client_leaderboard_bucket_t& bucket = s_achievements_locals.leaderboard_list->buckets[i];
|
||||
if (IsBucketVisibleInCurrentSubset(bucket))
|
||||
count += bucket.num_leaderboards;
|
||||
}
|
||||
|
||||
if (IsCoreSubsetOpen())
|
||||
text = TRANSLATE_PLURAL_SSTR("Achievements", "This game has %n leaderboards.", "Leaderboard count", count);
|
||||
else
|
||||
text = TRANSLATE_PLURAL_SSTR("Achievements", "This subset has %n leaderboards.", "Leaderboard count", count);
|
||||
|
||||
summary_color = ImGui::GetColorU32(DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_Text]));
|
||||
}
|
||||
|
||||
@@ -1185,6 +1423,9 @@ void FullscreenUI::DrawLeaderboardsWindow()
|
||||
|
||||
if (!is_leaderboard_open)
|
||||
{
|
||||
if (s_achievements_locals.open_subset)
|
||||
DrawSubsetSelector();
|
||||
|
||||
if (FloatingButton(ICON_FA_XMARK, 10.0f, 10.0f, 1.0f, 0.0f, true) || WantsToCloseMenu())
|
||||
ReturnToPreviousWindow();
|
||||
}
|
||||
@@ -1254,6 +1495,9 @@ void FullscreenUI::DrawLeaderboardsWindow()
|
||||
for (u32 bucket_index = 0; bucket_index < s_achievements_locals.leaderboard_list->num_buckets; bucket_index++)
|
||||
{
|
||||
const rc_client_leaderboard_bucket_t& bucket = s_achievements_locals.leaderboard_list->buckets[bucket_index];
|
||||
if (!IsBucketVisibleInCurrentSubset(bucket))
|
||||
continue;
|
||||
|
||||
for (u32 i = 0; i < bucket.num_leaderboards; i++)
|
||||
DrawLeaderboardListEntry(bucket.leaderboards[i]);
|
||||
}
|
||||
@@ -1264,19 +1508,40 @@ void FullscreenUI::DrawLeaderboardsWindow()
|
||||
|
||||
if (IsGamepadInputSource())
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_A, TRANSLATE_SV("Achievements", "Open Leaderboard")),
|
||||
std::make_pair(ICON_PF_BUTTON_B, TRANSLATE_SV("Achievements", "Back"))});
|
||||
if (s_achievements_locals.open_subset)
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_XBOX_DPAD_LEFT_RIGHT, TRANSLATE_SV("Achievements", "Change Subset")),
|
||||
std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_A, TRANSLATE_SV("Achievements", "Open Leaderboard")),
|
||||
std::make_pair(ICON_PF_BUTTON_B, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_BUTTON_A, TRANSLATE_SV("Achievements", "Open Leaderboard")),
|
||||
std::make_pair(ICON_PF_BUTTON_B, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_achievements_locals.open_subset)
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, TRANSLATE_SV("Achievements", "Change Subset")),
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "Open Leaderboard")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "Open Leaderboard")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
}
|
||||
|
||||
SetFullscreenFooterText(
|
||||
std::array{std::make_pair(ICON_PF_ARROW_UP ICON_PF_ARROW_DOWN, TRANSLATE_SV("Achievements", "Change Selection")),
|
||||
std::make_pair(ICON_PF_ENTER, TRANSLATE_SV("Achievements", "Open Leaderboard")),
|
||||
std::make_pair(ICON_PF_ESC, TRANSLATE_SV("Achievements", "Back"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user