Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace local footer in existing sheared overlays (e.g. mod select & first-run setup) with ScreenFooter #28683

Merged
merged 17 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#nullable disable

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
Expand All @@ -16,6 +17,7 @@
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Footer;
using osu.Game.Screens.OnlinePlay;
using osu.Game.Utils;
using osuTK.Input;
Expand All @@ -26,6 +28,7 @@ public partial class TestSceneFreeModSelectOverlay : MultiplayerTestScene
{
private FreeModSelectOverlay freeModSelectOverlay;
private FooterButtonFreeMods footerButtonFreeMods;
private ScreenFooter footer;
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();

[BackgroundDependencyLoader]
Expand Down Expand Up @@ -127,7 +130,7 @@ public void TestSelectAllViaFooterButtonThenDeselectFromOverlay()
{
createFreeModSelect();

AddAssert("overlay select all button enabled", () => freeModSelectOverlay.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
AddAssert("overlay select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
AddAssert("footer button displays off", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "off"));

AddStep("click footer select all button", () =>
Expand All @@ -150,19 +153,27 @@ public void TestSelectAllViaFooterButtonThenDeselectFromOverlay()

private void createFreeModSelect()
{
AddStep("create free mod select screen", () => Children = new Drawable[]
AddStep("create free mod select screen", () => Child = new DependencyProvidingContainer
{
freeModSelectOverlay = new FreeModSelectOverlay
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
State = { Value = Visibility.Visible }
},
footerButtonFreeMods = new FooterButtonFreeMods(freeModSelectOverlay)
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Current = { BindTarget = freeModSelectOverlay.SelectedMods },
freeModSelectOverlay = new FreeModSelectOverlay
{
State = { Value = Visibility.Visible }
},
footerButtonFreeMods = new FooterButtonFreeMods(freeModSelectOverlay)
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Y = -ScreenFooter.HEIGHT,
Current = { BindTarget = freeModSelectOverlay.SelectedMods },
},
footer = new ScreenFooter(),
},
CachedDependencies = new (Type, object)[] { (typeof(ScreenFooter), footer) },
});

AddUntilStep("all column content loaded",
() => freeModSelectOverlay.ChildrenOfType<ModColumn>().Any()
&& freeModSelectOverlay.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,14 +312,14 @@ public void TestModSelectOverlay()
AddUntilStep("wait for join", () => RoomJoined);

ClickButtonWhenEnabled<UserModSelectButton>();
AddAssert("mod select shows unranked", () => screen.UserModsSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().Ranked.Value == false);
AddAssert("score multiplier = 1.20", () => screen.UserModsSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(1.2).Within(0.01));
AddAssert("mod select shows unranked", () => this.ChildrenOfType<RankingInformationDisplay>().Single().Ranked.Value == false);
AddAssert("score multiplier = 1.20", () => this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(1.2).Within(0.01));

AddStep("select flashlight", () => screen.UserModsSelectOverlay.ChildrenOfType<ModPanel>().Single(m => m.Mod is ModFlashlight).TriggerClick());
AddAssert("score multiplier = 1.35", () => screen.UserModsSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(1.35).Within(0.01));
AddAssert("score multiplier = 1.35", () => this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(1.35).Within(0.01));

AddStep("change flashlight setting", () => ((OsuModFlashlight)screen.UserModsSelectOverlay.SelectedMods.Value.Single()).FollowDelay.Value = 1200);
AddAssert("score multiplier = 1.20", () => screen.UserModsSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(1.2).Within(0.01));
AddAssert("score multiplier = 1.20", () => this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(1.2).Within(0.01));
}

private partial class TestMultiplayerMatchSubScreen : MultiplayerMatchSubScreen
Expand Down
6 changes: 0 additions & 6 deletions osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,6 @@ public void TestOverlayPresent()

#endregion

protected override void Update()
{
base.Update();
Stack.Padding = new MarginPadding { Bottom = screenScreenFooter.DrawHeight - screenScreenFooter.Y };
}

private void updateFooter(IScreen? _, IScreen? newScreen)
{
if (newScreen is IOsuScreen osuScreen && osuScreen.ShowFooter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
Expand All @@ -20,6 +22,7 @@
using osu.Game.Overlays.FirstRunSetup;
using osu.Game.Overlays.Notifications;
using osu.Game.Screens;
using osu.Game.Screens.Footer;
using osuTK;
using osuTK.Input;

Expand All @@ -28,6 +31,7 @@ namespace osu.Game.Tests.Visual.UserInterface
public partial class TestSceneFirstRunSetupOverlay : OsuManualInputManagerTestScene
{
private FirstRunSetupOverlay overlay;
private ScreenFooter footer;

private readonly Mock<TestPerformerFromScreenRunner> performer = new Mock<TestPerformerFromScreenRunner>();

Expand Down Expand Up @@ -60,19 +64,16 @@ public void SetUpSteps()
.Callback((Notification n) => lastNotification = n);
});

AddStep("add overlay", () =>
{
Child = overlay = new FirstRunSetupOverlay
{
State = { Value = Visibility.Visible }
};
});
createOverlay();

AddStep("show overlay", () => overlay.Show());
}

[Test]
public void TestBasic()
{
AddAssert("overlay visible", () => overlay.State.Value == Visibility.Visible);
AddAssert("footer visible", () => footer.State.Value == Visibility.Visible);
}

[Test]
Expand All @@ -82,16 +83,13 @@ public void TestDoesntOpenOnSecondRun()

AddUntilStep("step through", () =>
{
if (overlay.CurrentScreen?.IsLoaded != false) overlay.NextButton.TriggerClick();
if (overlay.CurrentScreen?.IsLoaded != false) overlay.NextButton.AsNonNull().TriggerClick();
return overlay.State.Value == Visibility.Hidden;
});

AddAssert("first run false", () => !LocalConfig.Get<bool>(OsuSetting.ShowFirstRunSetup));

AddStep("add overlay", () =>
{
Child = overlay = new FirstRunSetupOverlay();
});
createOverlay();

AddWaitStep("wait some", 5);

Expand All @@ -109,7 +107,7 @@ public void TestOverlayRunsToFinish(bool keyboard)
if (keyboard)
InputManager.Key(Key.Enter);
else
overlay.NextButton.TriggerClick();
overlay.NextButton.AsNonNull().TriggerClick();
}

return overlay.State.Value == Visibility.Hidden;
Expand All @@ -128,11 +126,9 @@ public void TestOverlayRunsToFinish(bool keyboard)
[TestCase(true)]
public void TestBackButton(bool keyboard)
{
AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value);

AddUntilStep("step to last", () =>
{
var nextButton = overlay.NextButton;
var nextButton = overlay.NextButton.AsNonNull();

if (overlay.CurrentScreen?.IsLoaded != false)
nextButton.TriggerClick();
Expand All @@ -142,24 +138,29 @@ public void TestBackButton(bool keyboard)

AddUntilStep("step back to start", () =>
{
if (overlay.CurrentScreen?.IsLoaded != false)
if (overlay.CurrentScreen?.IsLoaded != false && !(overlay.CurrentScreen is ScreenWelcome))
{
if (keyboard)
InputManager.Key(Key.Escape);
else
overlay.BackButton.TriggerClick();
footer.BackButton.TriggerClick();
}

return overlay.CurrentScreen is ScreenWelcome;
});

AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value);
AddAssert("overlay not dismissed", () => overlay.State.Value == Visibility.Visible);

if (keyboard)
{
AddStep("exit via keyboard", () => InputManager.Key(Key.Escape));
AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden);
}
else
{
AddStep("press back button", () => footer.BackButton.TriggerClick());
AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden);
}
}

[Test]
Expand All @@ -185,7 +186,7 @@ public void TestClickAwayToExit()
[Test]
public void TestResumeViaNotification()
{
AddStep("step to next", () => overlay.NextButton.TriggerClick());
AddStep("step to next", () => overlay.NextButton.AsNonNull().TriggerClick());

AddAssert("is at known screen", () => overlay.CurrentScreen is ScreenUIScale);

Expand All @@ -200,6 +201,27 @@ public void TestResumeViaNotification()
AddAssert("is resumed", () => overlay.CurrentScreen is ScreenUIScale);
}

private void createOverlay()
{
AddStep("add overlay", () =>
{
var receptor = new ScreenFooter.BackReceptor();
footer = new ScreenFooter(receptor);

Child = new DependencyProvidingContainer
{
RelativeSizeAxes = Axes.Both,
CachedDependencies = new[] { (typeof(ScreenFooter), (object)footer) },
Children = new Drawable[]
{
receptor,
overlay = new FirstRunSetupOverlay(),
footer,
}
};
});
}

// interface mocks break hot reload, mocking this stub implementation instead works around it.
// see: https://github.com/moq/moq4/issues/1252
[UsedImplicitly]
Expand Down
39 changes: 27 additions & 12 deletions osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Taiko.Mods;
using osu.Game.Screens.Footer;
using osu.Game.Tests.Mods;
using osuTK;
using osuTK.Input;
Expand Down Expand Up @@ -94,12 +95,28 @@ public void SetUpSteps()

private void createScreen()
{
AddStep("create screen", () => Child = modSelectOverlay = new TestModSelectOverlay
AddStep("create screen", () =>
{
RelativeSizeAxes = Axes.Both,
State = { Value = Visibility.Visible },
Beatmap = Beatmap.Value,
SelectedMods = { BindTarget = SelectedMods }
var receptor = new ScreenFooter.BackReceptor();
var footer = new ScreenFooter(receptor);

Child = new DependencyProvidingContainer
{
RelativeSizeAxes = Axes.Both,
CachedDependencies = new[] { (typeof(ScreenFooter), (object)footer) },
Children = new Drawable[]
{
receptor,
modSelectOverlay = new TestModSelectOverlay
{
RelativeSizeAxes = Axes.Both,
State = { Value = Visibility.Visible },
Beatmap = { Value = Beatmap.Value },
SelectedMods = { BindTarget = SelectedMods },
},
footer,
}
};
});
waitForColumnLoad();
}
Expand All @@ -120,7 +137,7 @@ public void TestPreexistingSelection()
AddAssert("mod multiplier correct", () =>
{
double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier);
return Precision.AlmostEquals(multiplier, modSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value);
return Precision.AlmostEquals(multiplier, this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value);
});
assertCustomisationToggleState(disabled: false, active: false);
AddAssert("setting items created", () => modSelectOverlay.ChildrenOfType<ISettingsItem>().Any());
Expand All @@ -135,7 +152,7 @@ public void TestExternalSelection()
AddAssert("mod multiplier correct", () =>
{
double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier);
return Precision.AlmostEquals(multiplier, modSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value);
return Precision.AlmostEquals(multiplier, this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value);
});
assertCustomisationToggleState(disabled: false, active: false);
AddAssert("setting items created", () => modSelectOverlay.ChildrenOfType<ISettingsItem>().Any());
Expand Down Expand Up @@ -757,7 +774,7 @@ public void TestCloseViaBackButton()

AddStep("click back button", () =>
{
InputManager.MoveMouseTo(modSelectOverlay.BackButton);
InputManager.MoveMouseTo(this.ChildrenOfType<ScreenBackButton>().Single());
InputManager.Click(MouseButton.Left);
});
AddAssert("mod select hidden", () => modSelectOverlay.State.Value == Visibility.Hidden);
Expand Down Expand Up @@ -885,7 +902,7 @@ public void TestModMultiplierUpdates()
InputManager.Click(MouseButton.Left);
});
AddAssert("difficulty multiplier display shows correct value",
() => modSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(0.1).Within(Precision.DOUBLE_EPSILON));
() => this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(0.1).Within(Precision.DOUBLE_EPSILON));

// this is highly unorthodox in a test, but because the `ModSettingChangeTracker` machinery heavily leans on events and object disposal and re-creation,
// it is instrumental in the reproduction of the failure scenario that this test is supposed to cover.
Expand All @@ -895,7 +912,7 @@ public void TestModMultiplierUpdates()
AddStep("reset half time speed to default", () => modSelectOverlay.ChildrenOfType<ModCustomisationPanel>().Single()
.ChildrenOfType<RevertToDefaultButton<double>>().Single().TriggerClick());
AddUntilStep("difficulty multiplier display shows correct value",
() => modSelectOverlay.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(0.3).Within(Precision.DOUBLE_EPSILON));
() => this.ChildrenOfType<RankingInformationDisplay>().Single().ModMultiplier.Value, () => Is.EqualTo(0.3).Within(Precision.DOUBLE_EPSILON));
}

[Test]
Expand Down Expand Up @@ -1015,8 +1032,6 @@ private ModPanel getPanelForMod(Type modType)
private partial class TestModSelectOverlay : UserModSelectOverlay
{
protected override bool ShowPresets => true;

public new ShearedButton BackButton => base.BackButton;
}

private class TestUnimplementedMod : Mod
Expand Down
Loading
Loading