From f47f99b62d0f3316d4b0a15209fba78a92bd9374 Mon Sep 17 00:00:00 2001
From: Connor McLaughlin <stenzek@gmail.com>
Date: Wed, 3 Mar 2021 02:25:58 +1000
Subject: [PATCH] FullscreenUI: Make achievement list collapsable

---
 src/frontend-common/fullscreen_ui.cpp    | 34 ++++++++++++-------
 src/frontend-common/imgui_fullscreen.cpp | 42 +++++++++++++++++++++++-
 src/frontend-common/imgui_fullscreen.h   |  1 +
 3 files changed, 65 insertions(+), 12 deletions(-)

diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp
index d28dab318..3953a5c10 100644
--- a/src/frontend-common/fullscreen_ui.cpp
+++ b/src/frontend-common/fullscreen_ui.cpp
@@ -67,6 +67,7 @@ using ImGuiFullscreen::MenuButton;
 using ImGuiFullscreen::MenuButtonFrame;
 using ImGuiFullscreen::MenuButtonWithValue;
 using ImGuiFullscreen::MenuHeading;
+using ImGuiFullscreen::MenuHeadingButton;
 using ImGuiFullscreen::MenuImageButton;
 using ImGuiFullscreen::OpenChoiceDialog;
 using ImGuiFullscreen::OpenFileSelector;
@@ -3888,28 +3889,39 @@ void DrawAchievementWindow()
   if (BeginFullscreenWindow(ImVec2(0.0f, heading_height), ImVec2(display_size.x, display_size.y - heading_height),
                             "achievements", background, 0.0f, 0.0f, 0))
   {
-
     BeginMenuButtons();
 
-    MenuHeading("Unlocked Achievements");
-    Cheevos::EnumerateAchievements([](const Cheevos::Achievement& cheevo) -> bool {
-      if (!cheevo.locked)
-        DrawAchievement(cheevo);
+    static bool unlocked_achievements_collapsed = false;
 
-      return true;
-    });
-
-    if (Cheevos::GetUnlockedAchiementCount() != Cheevos::GetAchievementCount())
+    unlocked_achievements_collapsed ^=
+      MenuHeadingButton("Unlocked Achievements",
+                        unlocked_achievements_collapsed ? ICON_FA_CHEVRON_DOWN : ICON_FA_CHEVRON_UP);
+    if (!unlocked_achievements_collapsed)
     {
-      MenuHeading("Locked Achievements");
       Cheevos::EnumerateAchievements([](const Cheevos::Achievement& cheevo) -> bool {
-        if (cheevo.locked)
+        if (!cheevo.locked)
           DrawAchievement(cheevo);
 
         return true;
       });
     }
 
+    if (Cheevos::GetUnlockedAchiementCount() != Cheevos::GetAchievementCount())
+    {
+      static bool locked_achievements_collapsed = false;
+      locked_achievements_collapsed ^= MenuHeadingButton(
+        "Locked Achievements", locked_achievements_collapsed ? ICON_FA_CHEVRON_DOWN : ICON_FA_CHEVRON_UP);
+      if (!locked_achievements_collapsed)
+      {
+        Cheevos::EnumerateAchievements([](const Cheevos::Achievement& cheevo) -> bool {
+          if (cheevo.locked)
+            DrawAchievement(cheevo);
+
+          return true;
+        });
+      }
+    }
+
     EndMenuButtons();
   }
   EndFullscreenWindow();
diff --git a/src/frontend-common/imgui_fullscreen.cpp b/src/frontend-common/imgui_fullscreen.cpp
index 917c11498..35e8eea45 100644
--- a/src/frontend-common/imgui_fullscreen.cpp
+++ b/src/frontend-common/imgui_fullscreen.cpp
@@ -454,7 +454,7 @@ void MenuHeading(const char* title, bool draw_line /*= true*/)
 
   bool visible, hovered;
   ImRect bb;
-  MenuButtonFrame("menu_heading", false, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, &visible, &hovered, &bb);
+  MenuButtonFrame(title, false, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, &visible, &hovered, &bb);
   if (!visible)
     return;
 
@@ -473,6 +473,46 @@ void MenuHeading(const char* title, bool draw_line /*= true*/)
   }
 }
 
+bool MenuHeadingButton(const char* title, const char* value /*= nullptr*/, bool enabled /*= true*/,
+                       bool draw_line /*= true*/)
+{
+  const float line_thickness = draw_line ? LayoutScale(1.0f) : 0.0f;
+  const float line_padding = draw_line ? LayoutScale(5.0f) : 0.0f;
+
+  ImRect bb;
+  bool visible, hovered;
+  bool pressed = MenuButtonFrame(title, enabled, LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, &visible, &hovered, &bb);
+  if (!visible)
+    return false;
+
+  if (!enabled)
+    ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled));
+  ImGui::PushFont(g_large_font);
+  ImGui::RenderTextClipped(bb.Min, bb.Max, title, nullptr, nullptr, ImVec2(0.0f, 0.0f), &bb);
+
+  if (value)
+  {
+    const ImVec2 value_size(
+      g_large_font->CalcTextSizeA(g_large_font->FontSize, std::numeric_limits<float>::max(), 0.0f, value));
+    const ImRect value_bb(ImVec2(bb.Max.x - value_size.x, bb.Min.y), ImVec2(bb.Max.x, bb.Max.y));
+    ImGui::RenderTextClipped(value_bb.Min, value_bb.Max, value, nullptr, nullptr, ImVec2(0.0f, 0.0f), &value_bb);
+  }
+
+  ImGui::PopFont();
+  if (!enabled)
+    ImGui::PopStyleColor();
+
+  if (draw_line)
+  {
+    const ImVec2 line_start(bb.Min.x, bb.Min.y + g_large_font->FontSize + line_padding);
+    const ImVec2 line_end(bb.Max.x, line_start.y);
+    ImGui::GetWindowDrawList()->AddLine(line_start, line_end, ImGui::GetColorU32(ImGuiCol_TextDisabled),
+                                        line_thickness);
+  }
+
+  return pressed;
+}
+
 bool ActiveButton(const char* title, bool is_active, bool enabled, float height, ImFont* font)
 {
   if (is_active)
diff --git a/src/frontend-common/imgui_fullscreen.h b/src/frontend-common/imgui_fullscreen.h
index 8a6665ca5..628b263c6 100644
--- a/src/frontend-common/imgui_fullscreen.h
+++ b/src/frontend-common/imgui_fullscreen.h
@@ -177,6 +177,7 @@ void EndMenuButtons();
 bool MenuButtonFrame(const char* str_id, bool enabled, float height, bool* visible, bool* hovered, ImVec2* min,
                      ImVec2* max, ImGuiButtonFlags flags = 0, float hover_alpha = 1.0f);
 void MenuHeading(const char* title, bool draw_line = true);
+bool MenuHeadingButton(const char* title, const char* value = nullptr, bool enabled = true, bool draw_line = true);
 bool ActiveButton(const char* title, bool is_active, bool enabled = true,
                   float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImFont* font = g_large_font);
 bool MenuButton(const char* title, const char* summary, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,