2019-10-09 15:06:16 +08:00
// 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.
2022-06-17 15:37:17 +08:00
#nullable disable
2022-11-20 20:20:35 +08:00
using System ;
2024-01-17 13:10:02 +08:00
using System.Diagnostics ;
2022-05-31 14:00:30 +08:00
using System.Linq ;
2019-10-09 15:06:16 +08:00
using NUnit.Framework ;
using osu.Framework.Allocation ;
2022-11-20 20:20:35 +08:00
using osu.Framework.Graphics ;
2021-08-29 01:09:35 +08:00
using osu.Framework.Graphics.Containers ;
2024-01-17 13:10:02 +08:00
using osu.Framework.Graphics.UserInterface ;
2022-05-31 14:00:30 +08:00
using osu.Framework.Testing ;
2022-11-27 10:48:15 +08:00
using osu.Game.Beatmaps.ControlPoints ;
using osu.Game.Graphics.Containers ;
2021-11-12 03:42:33 +08:00
using osu.Game.Overlays ;
2020-07-17 13:38:28 +08:00
using osu.Game.Rulesets.Edit ;
2020-01-02 00:23:21 +08:00
using osu.Game.Screens.Edit ;
2019-10-09 15:06:16 +08:00
using osu.Game.Screens.Edit.Timing ;
2022-05-31 14:00:30 +08:00
using osu.Game.Screens.Edit.Timing.RowAttributes ;
2023-12-26 20:20:18 +08:00
using osuTK ;
2022-05-31 14:00:30 +08:00
using osuTK.Input ;
2019-10-09 15:06:16 +08:00
2020-04-23 16:07:55 +08:00
namespace osu.Game.Tests.Visual.Editing
2019-10-09 15:06:16 +08:00
{
[TestFixture]
2022-11-24 13:32:20 +08:00
public partial class TestSceneTimingScreen : EditorClockTestScene
2019-10-09 15:06:16 +08:00
{
2021-11-12 03:42:33 +08:00
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider ( OverlayColourScheme . Blue ) ;
2022-05-31 14:00:30 +08:00
private TimingScreen timingScreen ;
2022-11-27 10:48:15 +08:00
private EditorBeatmap editorBeatmap ;
2022-05-31 14:00:30 +08:00
2020-09-30 15:39:02 +08:00
protected override bool ScrollUsingMouseWheel = > false ;
2022-01-18 12:22:55 +08:00
protected override void LoadComplete ( )
2019-10-09 15:06:16 +08:00
{
2022-01-18 12:22:55 +08:00
base . LoadComplete ( ) ;
2022-11-20 20:20:35 +08:00
Beatmap . Value = CreateWorkingBeatmap ( Ruleset . Value ) ;
2020-09-30 15:16:14 +08:00
Beatmap . Disabled = true ;
2022-11-27 10:48:15 +08:00
}
2020-09-30 15:16:14 +08:00
2022-11-27 10:48:15 +08:00
private void reloadEditorBeatmap ( )
{
editorBeatmap = new EditorBeatmap ( Beatmap . Value . GetPlayableBeatmap ( Ruleset . Value ) ) ;
2022-11-20 20:20:35 +08:00
Child = new DependencyProvidingContainer
2021-08-29 01:09:35 +08:00
{
2022-11-20 20:20:35 +08:00
RelativeSizeAxes = Axes . Both ,
CachedDependencies = new ( Type , object ) [ ]
{
( typeof ( EditorBeatmap ) , editorBeatmap ) ,
( typeof ( IBeatSnapProvider ) , editorBeatmap )
} ,
Child = timingScreen = new TimingScreen
{
State = { Value = Visibility . Visible } ,
} ,
2021-08-29 01:09:35 +08:00
} ;
2019-10-09 15:06:16 +08:00
}
2020-09-30 15:16:14 +08:00
2022-05-31 14:00:30 +08:00
[SetUpSteps]
public void SetUpSteps ( )
{
2022-08-17 14:40:01 +08:00
AddStep ( "Stop clock" , ( ) = > EditorClock . Stop ( ) ) ;
2022-05-31 14:54:07 +08:00
2022-11-27 10:48:15 +08:00
AddStep ( "Reload Editor Beatmap" , reloadEditorBeatmap ) ;
AddUntilStep ( "Wait for rows to load" , ( ) = > Child . ChildrenOfType < EffectRowAttribute > ( ) . Any ( ) ) ;
2022-05-31 14:00:30 +08:00
}
2023-12-26 20:20:18 +08:00
[Test]
public void TestSelectedRetainedOverUndo ( )
{
AddStep ( "Select first timing point" , ( ) = >
{
InputManager . MoveMouseTo ( Child . ChildrenOfType < TimingRowAttribute > ( ) . First ( ) ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
AddUntilStep ( "Selection changed" , ( ) = > timingScreen . SelectedGroup . Value . Time = = 2170 ) ;
AddUntilStep ( "Ensure seeked to correct time" , ( ) = > EditorClock . CurrentTimeAccurate = = 2170 ) ;
AddStep ( "Adjust offset" , ( ) = >
{
InputManager . MoveMouseTo ( timingScreen . ChildrenOfType < TimingAdjustButton > ( ) . First ( ) . ScreenSpaceDrawQuad . Centre + new Vector2 ( 20 , 0 ) ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
AddUntilStep ( "wait for offset changed" , ( ) = >
{
return timingScreen . SelectedGroup . Value . ControlPoints . Any ( c = > c is TimingControlPoint ) & & timingScreen . SelectedGroup . Value . Time > 2170 ;
} ) ;
AddStep ( "simulate undo" , ( ) = >
{
var clone = editorBeatmap . ControlPointInfo . DeepClone ( ) ;
editorBeatmap . ControlPointInfo . Clear ( ) ;
foreach ( var group in clone . Groups )
{
foreach ( var cp in group . ControlPoints )
editorBeatmap . ControlPointInfo . Add ( group . Time , cp ) ;
}
} ) ;
AddUntilStep ( "selection retained" , ( ) = >
{
return timingScreen . SelectedGroup . Value . ControlPoints . Any ( c = > c is TimingControlPoint ) & & timingScreen . SelectedGroup . Value . Time > 2170 ;
} ) ;
}
2022-11-27 10:48:15 +08:00
[Test]
public void TestScrollControlGroupIntoView ( )
{
AddStep ( "Add many control points" , ( ) = >
{
editorBeatmap . ControlPointInfo . Clear ( ) ;
editorBeatmap . ControlPointInfo . Add ( 0 , new TimingControlPoint ( ) ) ;
for ( int i = 0 ; i < 100 ; i + + )
{
editorBeatmap . ControlPointInfo . Add ( ( i + 1 ) * 1000 , new EffectControlPoint
{
KiaiMode = Convert . ToBoolean ( i % 2 ) ,
} ) ;
}
} ) ;
AddStep ( "Select first effect point" , ( ) = >
{
InputManager . MoveMouseTo ( Child . ChildrenOfType < EffectRowAttribute > ( ) . First ( ) ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
AddStep ( "Seek to beginning" , ( ) = > EditorClock . Seek ( 0 ) ) ;
AddStep ( "Seek to last point" , ( ) = > EditorClock . Seek ( 101 * 1000 ) ) ;
AddUntilStep ( "Scrolled to end" , ( ) = > timingScreen . ChildrenOfType < OsuScrollContainer > ( ) . First ( ) . IsScrolledToEnd ( ) ) ;
}
2024-01-17 13:10:02 +08:00
[Test]
2024-01-17 18:53:23 +08:00
public void TestEditThenClickAwayAppliesChanges ( )
2024-01-17 13:10:02 +08:00
{
AddStep ( "Add two control points" , ( ) = >
{
editorBeatmap . ControlPointInfo . Clear ( ) ;
editorBeatmap . ControlPointInfo . Add ( 1000 , new TimingControlPoint ( ) ) ;
editorBeatmap . ControlPointInfo . Add ( 2000 , new TimingControlPoint ( ) ) ;
} ) ;
AddStep ( "Select second timing point" , ( ) = >
{
InputManager . MoveMouseTo ( Child . ChildrenOfType < TimingRowAttribute > ( ) . Last ( ) ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
AddStep ( "Scroll to end" , ( ) = > timingScreen . ChildrenOfType < ControlPointSettings > ( ) . Single ( ) . ChildrenOfType < OsuScrollContainer > ( ) . Single ( ) . ScrollToEnd ( false ) ) ;
AddStep ( "Modify time signature" , ( ) = >
{
var timeSignatureTextBox = Child . ChildrenOfType < LabelledTimeSignature . TimeSignatureBox > ( ) . Single ( ) . ChildrenOfType < TextBox > ( ) . Single ( ) ;
InputManager . MoveMouseTo ( timeSignatureTextBox ) ;
InputManager . Click ( MouseButton . Left ) ;
2024-01-17 13:53:24 +08:00
Debug . Assert ( ! timeSignatureTextBox . Current . Value . Equals ( "1" , StringComparison . Ordinal ) ) ;
2024-01-17 13:10:02 +08:00
timeSignatureTextBox . Current . Value = "1" ;
} ) ;
AddStep ( "Select first timing point" , ( ) = >
{
InputManager . MoveMouseTo ( Child . ChildrenOfType < TimingRowAttribute > ( ) . First ( ) ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
AddAssert ( "Second timing point changed time signature" , ( ) = > editorBeatmap . ControlPointInfo . TimingPoints . Last ( ) . TimeSignature . Numerator = = 1 ) ;
AddAssert ( "First timing point preserved time signature" , ( ) = > editorBeatmap . ControlPointInfo . TimingPoints . First ( ) . TimeSignature . Numerator = = 4 ) ;
}
2020-09-30 15:16:14 +08:00
protected override void Dispose ( bool isDisposing )
{
Beatmap . Disabled = false ;
base . Dispose ( isDisposing ) ;
}
2019-10-09 15:06:16 +08:00
}
}