diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 9cf8b95ddf..81edcd8db8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -153,6 +153,18 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("nightcore still visible", () => modSelect.ChildrenOfType().Any(b => b.Mods.Any(m => m is OsuModNightcore))); } + [Test] + public void TestChangeIsValidPreservesSelection() + { + changeRuleset(0); + + AddStep("select DT + HD", () => SelectedMods.Value = new Mod[] { new OsuModDoubleTime(), new OsuModHidden() }); + AddAssert("DT + HD selected", () => modSelect.ChildrenOfType().Count(b => b.Selected) == 2); + + AddStep("make NF invalid", () => modSelect.IsValidMod = m => !(m is ModNoFail)); + AddAssert("DT + HD still selected", () => modSelect.ChildrenOfType().Count(b => b.Selected) == 2); + } + private void testSingleMod(Mod mod) { selectNext(mod); diff --git a/osu.Game/Overlays/Mods/ModSection.cs b/osu.Game/Overlays/Mods/ModSection.cs index 573d1e5355..4c629aef54 100644 --- a/osu.Game/Overlays/Mods/ModSection.cs +++ b/osu.Game/Overlays/Mods/ModSection.cs @@ -130,13 +130,13 @@ namespace osu.Game.Overlays.Mods /// Updates all buttons with the given list of selected mods. /// /// The new list of selected mods to select. - public void UpdateSelectedMods(IReadOnlyList newSelectedMods) + public void UpdateSelectedButtons(IReadOnlyList newSelectedMods) { foreach (var button in buttons) - updateButtonMods(button, newSelectedMods); + updateButtonSelection(button, newSelectedMods); } - private void updateButtonMods(ModButton button, IReadOnlyList newSelectedMods) + private void updateButtonSelection(ModButton button, IReadOnlyList newSelectedMods) { foreach (var mod in newSelectedMods) { diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 61e4b45495..fcec6f3926 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -367,7 +367,7 @@ namespace osu.Game.Overlays.Mods base.LoadComplete(); availableMods.BindValueChanged(_ => updateAvailableMods(), true); - SelectedMods.BindValueChanged(selectedModsChanged, true); + SelectedMods.BindValueChanged(_ => updateSelectedButtons(), true); } protected override void PopOut() @@ -435,6 +435,8 @@ namespace osu.Game.Overlays.Mods section.Mods = modEnumeration.Select(getValidModOrNull).Where(m => m != null); } + + updateSelectedButtons(); } /// @@ -459,10 +461,13 @@ namespace osu.Game.Overlays.Mods return validSubset.Length == 1 ? validSubset[0] : new MultiMod(validSubset); } - private void selectedModsChanged(ValueChangedEvent> mods) + private void updateSelectedButtons() { + // Enumeration below may update the bindable list. + var selectedMods = SelectedMods.Value.ToList(); + foreach (var section in ModSectionsContainer.Children) - section.UpdateSelectedMods(mods.NewValue); + section.UpdateSelectedButtons(selectedMods); updateMods(); }