// 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.Diagnostics; using System.Linq; using NUnit.Framework; using osu.Framework.Input; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; using osu.Game.Screens.Edit.Timing; using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual; using osuTK; using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { public class TestSceneSliderVelocityAdjust : OsuGameTestScene { private Screens.Edit.Editor editor => Game.ScreenStack.CurrentScreen as Screens.Edit.Editor; private EditorBeatmap editorBeatmap => editor.ChildrenOfType().FirstOrDefault(); private EditorClock editorClock => editor.ChildrenOfType().FirstOrDefault(); private Slider slider => editorBeatmap.HitObjects.OfType().FirstOrDefault(); private TimelineHitObjectBlueprint blueprint => editor.ChildrenOfType().FirstOrDefault(); private DifficultyPointPiece difficultyPointPiece => blueprint.ChildrenOfType().First(); private IndeterminateSliderWithTextBoxInput velocityTextBox => Game.ChildrenOfType().First().ChildrenOfType>().First(); protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false); private bool editorComponentsReady => editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true && editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true && editor?.ChildrenOfType().FirstOrDefault()?.IsLoaded == true; [TestCase(true)] [TestCase(false)] public void TestVelocityChangeSavesCorrectly(bool adjustVelocity) { double? velocity = null; AddStep("enter editor", () => Game.ScreenStack.Push(new EditorLoader())); AddUntilStep("wait for editor load", () => editorComponentsReady); AddStep("seek to first control point", () => editorClock.Seek(editorBeatmap.ControlPointInfo.TimingPoints.First().Time)); AddStep("enter slider placement mode", () => InputManager.Key(Key.Number3)); AddStep("move mouse to centre", () => InputManager.MoveMouseTo(editor.ChildrenOfType().First().ScreenSpaceDrawQuad.Centre)); AddStep("start placement", () => InputManager.Click(MouseButton.Left)); AddStep("move mouse to bottom right", () => InputManager.MoveMouseTo(editor.ChildrenOfType().First().ScreenSpaceDrawQuad.BottomRight - new Vector2(10))); AddStep("end placement", () => InputManager.Click(MouseButton.Right)); AddStep("exit placement mode", () => InputManager.Key(Key.Number1)); AddAssert("slider placed", () => slider != null); AddStep("select slider", () => editorBeatmap.SelectedHitObjects.Add(slider)); AddAssert("ensure one slider placed", () => slider != null); AddStep("store velocity", () => velocity = slider.Velocity); if (adjustVelocity) { AddStep("open velocity adjust panel", () => difficultyPointPiece.TriggerClick()); AddStep("change velocity", () => velocityTextBox.Current.Value = 2); AddAssert("velocity adjusted", () => { Debug.Assert(velocity != null); return Precision.AlmostEquals(velocity.Value * 2, slider.Velocity); }); AddStep("store velocity", () => velocity = slider.Velocity); } AddStep("save", () => InputManager.Keys(PlatformAction.Save)); AddStep("exit", () => InputManager.Key(Key.Escape)); AddStep("enter editor (again)", () => Game.ScreenStack.Push(new EditorLoader())); AddUntilStep("wait for editor load", () => editorComponentsReady); AddStep("seek to slider", () => editorClock.Seek(slider.StartTime)); AddAssert("slider has correct velocity", () => slider.Velocity == velocity); } } }