Skip to content

Commit

Permalink
Merge pull request ppy#18230 from bdach/mod-overlay/data-flow-refactor
Browse files Browse the repository at this point in the history
Restructure data flow in mod select overlay
  • Loading branch information
smoogipoo authored May 12, 2022
2 parents 4a4f6ab + 981ead6 commit 678cde3
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 230 deletions.
59 changes: 36 additions & 23 deletions osu.Game.Tests/Visual/UserInterface/TestSceneModColumn.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable enable

using System;
using System.Linq;
using NUnit.Framework;
Expand All @@ -12,11 +14,9 @@
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko;
using osu.Game.Utils;
using osuTK.Input;

namespace osu.Game.Tests.Visual.UserInterface
Expand All @@ -41,28 +41,25 @@ public void TestBasic(ModType modType)
Child = new ModColumn(modType, false)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
Origin = Anchor.Centre,
AvailableMods = getExampleModsFor(modType)
}
});

AddStep("change ruleset to osu!", () => Ruleset.Value = new OsuRuleset().RulesetInfo);
AddStep("change ruleset to taiko", () => Ruleset.Value = new TaikoRuleset().RulesetInfo);
AddStep("change ruleset to catch", () => Ruleset.Value = new CatchRuleset().RulesetInfo);
AddStep("change ruleset to mania", () => Ruleset.Value = new ManiaRuleset().RulesetInfo);
}

[Test]
public void TestMultiSelection()
{
ModColumn column = null;
ModColumn column = null!;
AddStep("create content", () => Child = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(30),
Child = column = new ModColumn(ModType.DifficultyIncrease, true)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
Origin = Anchor.Centre,
AvailableMods = getExampleModsFor(ModType.DifficultyIncrease)
}
});

Expand Down Expand Up @@ -91,7 +88,7 @@ void clickToggle() => AddStep("click toggle", () =>
[Test]
public void TestFiltering()
{
TestModColumn column = null;
TestModColumn column = null!;

AddStep("create content", () => Child = new Container
{
Expand All @@ -100,30 +97,31 @@ public void TestFiltering()
Child = column = new TestModColumn(ModType.Fun, true)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
Origin = Anchor.Centre,
AvailableMods = getExampleModsFor(ModType.Fun)
}
});

AddStep("set filter", () => column.Filter = mod => mod.Name.Contains("Wind", StringComparison.CurrentCultureIgnoreCase));
AddStep("set filter", () => setFilter(mod => mod.Name.Contains("Wind", StringComparison.CurrentCultureIgnoreCase)));
AddUntilStep("two panels visible", () => column.ChildrenOfType<ModPanel>().Count(panel => !panel.Filtered.Value) == 2);

clickToggle();
AddUntilStep("wait for animation", () => !column.SelectionAnimationRunning);
AddAssert("only visible items selected", () => column.ChildrenOfType<ModPanel>().Where(panel => panel.Active.Value).All(panel => !panel.Filtered.Value));

AddStep("unset filter", () => column.Filter = null);
AddStep("unset filter", () => setFilter(null));
AddUntilStep("all panels visible", () => column.ChildrenOfType<ModPanel>().All(panel => !panel.Filtered.Value));
AddAssert("checkbox not selected", () => !column.ChildrenOfType<OsuCheckbox>().Single().Current.Value);

AddStep("set filter", () => column.Filter = mod => mod.Name.Contains("Wind", StringComparison.CurrentCultureIgnoreCase));
AddStep("set filter", () => setFilter(mod => mod.Name.Contains("Wind", StringComparison.CurrentCultureIgnoreCase)));
AddUntilStep("two panels visible", () => column.ChildrenOfType<ModPanel>().Count(panel => !panel.Filtered.Value) == 2);
AddAssert("checkbox selected", () => column.ChildrenOfType<OsuCheckbox>().Single().Current.Value);

AddStep("filter out everything", () => column.Filter = _ => false);
AddStep("filter out everything", () => setFilter(_ => false));
AddUntilStep("no panels visible", () => column.ChildrenOfType<ModPanel>().All(panel => panel.Filtered.Value));
AddUntilStep("checkbox hidden", () => !column.ChildrenOfType<OsuCheckbox>().Single().IsPresent);

AddStep("inset filter", () => column.Filter = null);
AddStep("inset filter", () => setFilter(null));
AddUntilStep("all panels visible", () => column.ChildrenOfType<ModPanel>().All(panel => !panel.Filtered.Value));
AddUntilStep("checkbox visible", () => column.ChildrenOfType<OsuCheckbox>().Single().IsPresent);

Expand All @@ -138,15 +136,16 @@ void clickToggle() => AddStep("click toggle", () =>
[Test]
public void TestKeyboardSelection()
{
ModColumn column = null;
ModColumn column = null!;
AddStep("create content", () => Child = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(30),
Child = column = new ModColumn(ModType.DifficultyReduction, true, new[] { Key.Q, Key.W, Key.E, Key.R, Key.T, Key.Y, Key.U, Key.I, Key.O, Key.P })
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
Origin = Anchor.Centre,
AvailableMods = getExampleModsFor(ModType.DifficultyReduction)
}
});

Expand All @@ -158,20 +157,26 @@ public void TestKeyboardSelection()
AddStep("press W again", () => InputManager.Key(Key.W));
AddAssert("NF panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);

AddStep("set filter to NF", () => column.Filter = mod => mod.Acronym == "NF");
AddStep("set filter to NF", () => setFilter(mod => mod.Acronym == "NF"));

AddStep("press W", () => InputManager.Key(Key.W));
AddAssert("NF panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);

AddStep("press W again", () => InputManager.Key(Key.W));
AddAssert("NF panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);

AddStep("filter out everything", () => column.Filter = _ => false);
AddStep("filter out everything", () => setFilter(_ => false));

AddStep("press W", () => InputManager.Key(Key.W));
AddAssert("NF panel not selected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);

AddStep("clear filter", () => column.Filter = null);
AddStep("clear filter", () => setFilter(null));
}

private void setFilter(Func<Mod, bool>? filter)
{
foreach (var modState in this.ChildrenOfType<ModColumn>().Single().AvailableMods)
modState.Filtered.Value = filter?.Invoke(modState.Mod) == false;
}

private class TestModColumn : ModColumn
Expand All @@ -183,5 +188,13 @@ public TestModColumn(ModType modType, bool allowBulkSelection)
{
}
}

private static ModState[] getExampleModsFor(ModType modType)
{
return new OsuRuleset().GetModsFor(modType)
.SelectMany(ModUtils.FlattenMod)
.Select(mod => new ModState(mod))
.ToArray();
}
}
}
16 changes: 16 additions & 0 deletions osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Tests.Mods;
using osuTK;
using osuTK.Input;

Expand Down Expand Up @@ -481,6 +482,21 @@ public void TestColumnHiding()
AddUntilStep("3 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 3);
}

[Test]
public void TestColumnHidingOnRulesetChange()
{
createScreen();

changeRuleset(0);
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);

AddStep("change to ruleset without all mod types", () => Ruleset.Value = TestCustomisableModRuleset.CreateTestRulesetInfo());
AddUntilStep("1 column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);

changeRuleset(0);
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
}

private void waitForColumnLoad() => AddUntilStep("all column content loaded",
() => modSelectOverlay.ChildrenOfType<ModColumn>().Any() && modSelectOverlay.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));

Expand Down
5 changes: 5 additions & 0 deletions osu.Game/Overlays/Mods/IncompatibilityDisplayingModPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public class IncompatibilityDisplayingModPanel : ModPanel, IHasCustomTooltip<Mod
[Resolved]
private Bindable<IReadOnlyList<Mod>> selectedMods { get; set; }

public IncompatibilityDisplayingModPanel(ModState modState)
: base(modState)
{
}

public IncompatibilityDisplayingModPanel(Mod mod)
: base(mod)
{
Expand Down
Loading

0 comments on commit 678cde3

Please sign in to comment.