From 120446e4a72ddef607693884800d07b01547dfc1 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Wed, 20 Sep 2017 14:31:17 +0900
Subject: [PATCH] Ensure only one dialog is being displayed by the SongSelect
 footer at a time

Fixes #1208
---
 osu.Game/Screens/Select/Footer.cs         | 26 +++++++++++++++++++++++
 osu.Game/Screens/Select/PlaySongSelect.cs |  2 +-
 osu.Game/Screens/Select/SongSelect.cs     |  2 +-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs
index bb6d16da0f..6636dbde76 100644
--- a/osu.Game/Screens/Select/Footer.cs
+++ b/osu.Game/Screens/Select/Footer.cs
@@ -2,6 +2,7 @@
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using OpenTK;
 using OpenTK.Graphics;
@@ -58,6 +59,31 @@ namespace osu.Game.Screens.Select
             Action = action,
         });
 
+        private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
+
+        /// <param name="text">Text on the button.</param>
+        /// <param name="colour">Colour of the button.</param>
+        /// <param name="hotkey">Hotkey of the button.</param>
+        /// <param name="overlay">The <see cref="OverlayContainer"/> to be toggled by this button.</param>
+        /// <param name="depth">
+        /// <para>Higher depth to be put on the left, and lower to be put on the right.</para>
+        /// <para>Notice this is different to <see cref="Options.BeatmapOptionsOverlay"/>!</para>
+        /// </param>
+        public void AddButton(string text, Color4 colour, OverlayContainer overlay, Key? hotkey = null, float depth = 0)
+        {
+            overlays.Add(overlay);
+            AddButton(text, colour, () =>
+            {
+                foreach (var o in overlays)
+                {
+                    if (o == overlay)
+                        overlay.ToggleVisibility();
+                    else
+                        overlay.Hide();
+                }
+            }, hotkey, depth);
+        }
+
         private void updateModeLight() => modeLight.FadeColour(buttons.FirstOrDefault(b => b.IsHovered)?.SelectedColour ?? Color4.Transparent, TRANSITION_LENGTH, Easing.OutQuint);
 
         public Footer()
diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs
index 7e03707d18..e0a3693371 100644
--- a/osu.Game/Screens/Select/PlaySongSelect.cs
+++ b/osu.Game/Screens/Select/PlaySongSelect.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Screens.Select
         [BackgroundDependencyLoader]
         private void load(OsuColour colours)
         {
-            Footer.AddButton(@"mods", colours.Yellow, modSelect.ToggleVisibility, Key.F1, float.MaxValue);
+            Footer.AddButton(@"mods", colours.Yellow, modSelect, Key.F1, float.MaxValue);
 
             BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
             BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, null, Key.Number2);
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index 84457b77a7..836ed465c3 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -164,7 +164,7 @@ namespace osu.Game.Screens.Select
             if (Footer != null)
             {
                 Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
-                Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3);
+                Footer.AddButton(@"options", colours.Blue, BeatmapOptions, Key.F3);
 
                 BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue);
             }