// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable disable using System.Linq; using NUnit.Framework; using osu.Framework.Extensions; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD.HitErrorMeters; using osu.Game.Skinning.Editor; using osu.Game.Tests.Beatmaps.IO; using osuTK.Input; using static osu.Game.Tests.Visual.Navigation.TestSceneScreenNavigation; namespace osu.Game.Tests.Visual.Navigation { public class TestSceneSkinEditorNavigation : OsuGameTestScene { private TestPlaySongSelect songSelect; private SkinEditor skinEditor => Game.ChildrenOfType().FirstOrDefault(); private void advanceToSongSelect() { PushAndConfirm(() => songSelect = new TestPlaySongSelect()); AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely()); AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); } private void openSkinEditor() { AddStep("open skin editor", () => { InputManager.PressKey(Key.ControlLeft); InputManager.PressKey(Key.ShiftLeft); InputManager.Key(Key.S); InputManager.ReleaseKey(Key.ControlLeft); InputManager.ReleaseKey(Key.ShiftLeft); }); AddUntilStep("skin editor loaded", () => skinEditor != null); } [Test] public void TestEditComponentDuringGameplay() { advanceToSongSelect(); openSkinEditor(); switchToGameplayScene(); BarHitErrorMeter hitErrorMeter = null; AddUntilStep("select bar hit error blueprint", () => { var blueprint = skinEditor.ChildrenOfType().FirstOrDefault(b => b.Item is BarHitErrorMeter); if (blueprint == null) return false; hitErrorMeter = (BarHitErrorMeter)blueprint.Item; skinEditor.SelectedComponents.Clear(); skinEditor.SelectedComponents.Add(blueprint.Item); return true; }); AddAssert("value is default", () => hitErrorMeter.JudgementLineThickness.IsDefault); AddStep("hover first slider", () => { InputManager.MoveMouseTo( skinEditor.ChildrenOfType().First() .ChildrenOfType>().First() .ChildrenOfType>().First() ); }); AddStep("adjust slider via keyboard", () => InputManager.Key(Key.Left)); AddAssert("value is less than default", () => hitErrorMeter.JudgementLineThickness.Value < hitErrorMeter.JudgementLineThickness.Default); } [Test] public void TestComponentsDeselectedOnSkinEditorHide() { advanceToSongSelect(); openSkinEditor(); switchToGameplayScene(); AddStep("select all components", () => { InputManager.PressKey(Key.ControlLeft); InputManager.Key(Key.A); InputManager.ReleaseKey(Key.ControlLeft); }); AddStep("toggle skin editor", () => { InputManager.PressKey(Key.ControlLeft); InputManager.PressKey(Key.ShiftLeft); InputManager.Key(Key.S); InputManager.ReleaseKey(Key.ControlLeft); InputManager.ReleaseKey(Key.ShiftLeft); }); AddUntilStep("no components selected", () => skinEditor.SelectedComponents.Count == 0); } [Test] public void TestAutoplayCompatibleModsRetainedOnEnteringGameplay() { advanceToSongSelect(); openSkinEditor(); AddStep("select DT", () => Game.SelectedMods.Value = new Mod[] { new OsuModDoubleTime() }); switchToGameplayScene(); AddAssert("DT still selected", () => ((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Single() is OsuModDoubleTime); } [Test] public void TestAutoplayIncompatibleModsRemovedOnEnteringGameplay() { advanceToSongSelect(); openSkinEditor(); AddStep("select no fail and spun out", () => Game.SelectedMods.Value = new Mod[] { new OsuModNoFail(), new OsuModSpunOut() }); switchToGameplayScene(); AddAssert("no mod selected", () => !((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Any()); } [Test] public void TestDuplicateAutoplayModRemovedOnEnteringGameplay() { advanceToSongSelect(); openSkinEditor(); AddStep("select autoplay", () => Game.SelectedMods.Value = new Mod[] { new OsuModAutoplay() }); switchToGameplayScene(); AddAssert("no mod selected", () => !((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Any()); } [Test] public void TestCinemaModRemovedOnEnteringGameplay() { advanceToSongSelect(); openSkinEditor(); AddStep("select cinema", () => Game.SelectedMods.Value = new Mod[] { new OsuModCinema() }); switchToGameplayScene(); AddAssert("no mod selected", () => !((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Any()); } [Test] public void TestModOverlayClosesOnOpeningSkinEditor() { advanceToSongSelect(); AddStep("open mod overlay", () => songSelect.ModSelectOverlay.Show()); openSkinEditor(); AddUntilStep("mod overlay closed", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); } private void switchToGameplayScene() { AddStep("Click gameplay scene button", () => skinEditor.ChildrenOfType().First(b => b.Text == "Gameplay").TriggerClick()); AddUntilStep("wait for player", () => { DismissAnyNotifications(); return Game.ScreenStack.CurrentScreen is Player; }); } } }