2021-11-13 23:58:24 +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.
using System.Linq ;
2023-04-26 23:34:02 +08:00
using System.Collections.Generic ;
2021-11-13 23:58:24 +08:00
using Humanizer ;
using NUnit.Framework ;
2024-05-22 21:55:53 +08:00
using osu.Framework.Input ;
2021-11-13 23:58:24 +08:00
using osu.Framework.Testing ;
2024-07-04 21:25:43 +08:00
using osu.Framework.Utils ;
2022-10-19 19:34:41 +08:00
using osu.Game.Audio ;
2021-11-13 23:58:24 +08:00
using osu.Game.Beatmaps ;
2021-11-14 00:43:33 +08:00
using osu.Game.Graphics.UserInterface ;
2021-11-13 23:58:24 +08:00
using osu.Game.Graphics.UserInterfaceV2 ;
using osu.Game.Rulesets ;
2023-05-24 16:33:48 +08:00
using osu.Game.Rulesets.Edit ;
2023-06-02 06:40:00 +08:00
using osu.Game.Rulesets.Objects ;
using osu.Game.Rulesets.Objects.Types ;
2021-11-13 23:58:24 +08:00
using osu.Game.Rulesets.Osu ;
using osu.Game.Rulesets.Osu.Objects ;
using osu.Game.Rulesets.Osu.UI ;
2023-06-02 06:40:00 +08:00
using osu.Game.Screens.Edit.Components.TernaryButtons ;
2021-11-13 23:58:24 +08:00
using osu.Game.Screens.Edit.Compose.Components.Timeline ;
using osu.Game.Screens.Edit.Timing ;
using osu.Game.Tests.Beatmaps ;
using osuTK ;
using osuTK.Input ;
namespace osu.Game.Tests.Visual.Editing
{
2023-05-16 17:31:10 +08:00
public partial class TestSceneHitObjectSampleAdjustments : EditorTestScene
2021-11-13 23:58:24 +08:00
{
protected override Ruleset CreateEditorRuleset ( ) = > new OsuRuleset ( ) ;
protected override IBeatmap CreateBeatmap ( RulesetInfo ruleset ) = > new TestBeatmap ( ruleset , false ) ;
public override void SetUpSteps ( )
{
base . SetUpSteps ( ) ;
AddStep ( "add test objects" , ( ) = >
{
EditorBeatmap . Add ( new HitCircle
{
StartTime = 0 ,
Position = ( OsuPlayfield . BASE_SIZE - new Vector2 ( 100 , 0 ) ) / 2 ,
2023-04-26 20:21:52 +08:00
Samples = new List < HitSampleInfo >
2021-11-13 23:58:24 +08:00
{
2023-05-16 15:29:24 +08:00
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL , volume : 80 )
2021-11-13 23:58:24 +08:00
}
} ) ;
2021-11-14 00:43:33 +08:00
EditorBeatmap . Add ( new HitCircle
2021-11-13 23:58:24 +08:00
{
StartTime = 500 ,
Position = ( OsuPlayfield . BASE_SIZE + new Vector2 ( 100 , 0 ) ) / 2 ,
2023-04-26 20:21:52 +08:00
Samples = new List < HitSampleInfo >
2021-11-13 23:58:24 +08:00
{
2023-05-24 13:04:10 +08:00
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL , HitSampleInfo . BANK_SOFT , volume : 60 )
2021-11-13 23:58:24 +08:00
}
} ) ;
} ) ;
}
2023-05-16 17:52:35 +08:00
[Test]
public void TestAddSampleAddition ( )
{
AddStep ( "select both objects" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
AddStep ( "add clap addition" , ( ) = > InputManager . Key ( Key . R ) ) ;
hitObjectHasSampleBank ( 0 , "normal" ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_CLAP ) ;
2023-05-24 13:04:10 +08:00
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
2023-05-16 17:52:35 +08:00
hitObjectHasSamples ( 1 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_CLAP ) ;
AddStep ( "remove clap addition" , ( ) = > InputManager . Key ( Key . R ) ) ;
hitObjectHasSampleBank ( 0 , "normal" ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL ) ;
2023-05-24 13:04:10 +08:00
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
2023-05-16 17:52:35 +08:00
hitObjectHasSamples ( 1 , HitSampleInfo . HIT_NORMAL ) ;
}
2022-05-11 14:51:59 +08:00
[Test]
2023-08-17 05:16:57 +08:00
public void TestPopoverHasNoFocus ( )
2022-05-11 14:51:59 +08:00
{
clickSamplePiece ( 0 ) ;
2023-08-17 05:16:57 +08:00
samplePopoverHasNoFocus ( ) ;
2022-05-11 14:51:59 +08:00
}
2021-11-13 23:58:24 +08:00
[Test]
public void TestSingleSelection ( )
{
clickSamplePiece ( 0 ) ;
2022-10-19 19:34:41 +08:00
samplePopoverHasSingleBank ( HitSampleInfo . BANK_NORMAL ) ;
2021-11-13 23:58:24 +08:00
samplePopoverHasSingleVolume ( 80 ) ;
dismissPopover ( ) ;
// select first object to ensure that sample pieces for unselected objects
// work independently from selection state.
AddStep ( "select first object" , ( ) = > EditorBeatmap . SelectedHitObjects . Add ( EditorBeatmap . HitObjects . First ( ) ) ) ;
clickSamplePiece ( 1 ) ;
2022-10-19 19:34:41 +08:00
samplePopoverHasSingleBank ( HitSampleInfo . BANK_SOFT ) ;
2021-11-13 23:58:24 +08:00
samplePopoverHasSingleVolume ( 60 ) ;
setVolumeViaPopover ( 90 ) ;
hitObjectHasSampleVolume ( 1 , 90 ) ;
2022-10-19 19:34:41 +08:00
setBankViaPopover ( HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_DRUM ) ;
2021-11-13 23:58:24 +08:00
}
2023-05-23 04:23:05 +08:00
[Test]
public void TestUndo ( )
{
clickSamplePiece ( 1 ) ;
2023-05-24 13:04:10 +08:00
samplePopoverHasSingleBank ( HitSampleInfo . BANK_SOFT ) ;
2023-05-23 04:23:05 +08:00
samplePopoverHasSingleVolume ( 60 ) ;
setVolumeViaPopover ( 90 ) ;
hitObjectHasSampleVolume ( 1 , 90 ) ;
dismissPopover ( ) ;
AddStep ( "undo" , ( ) = > Editor . Undo ( ) ) ;
hitObjectHasSampleVolume ( 1 , 60 ) ;
}
2021-11-14 00:02:55 +08:00
[Test]
public void TestMultipleSelectionWithSameSampleVolume ( )
{
AddStep ( "unify sample volume" , ( ) = >
{
foreach ( var h in EditorBeatmap . HitObjects )
2023-04-26 20:21:52 +08:00
{
for ( int i = 0 ; i < h . Samples . Count ; i + + )
{
h . Samples [ i ] = h . Samples [ i ] . With ( newVolume : 50 ) ;
}
}
2021-11-14 00:02:55 +08:00
} ) ;
AddStep ( "select both objects" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
clickSamplePiece ( 0 ) ;
samplePopoverHasSingleVolume ( 50 ) ;
dismissPopover ( ) ;
clickSamplePiece ( 1 ) ;
samplePopoverHasSingleVolume ( 50 ) ;
setVolumeViaPopover ( 75 ) ;
hitObjectHasSampleVolume ( 0 , 75 ) ;
hitObjectHasSampleVolume ( 1 , 75 ) ;
}
[Test]
public void TestMultipleSelectionWithDifferentSampleVolume ( )
{
AddStep ( "select both objects" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
clickSamplePiece ( 0 ) ;
samplePopoverHasIndeterminateVolume ( ) ;
dismissPopover ( ) ;
clickSamplePiece ( 1 ) ;
samplePopoverHasIndeterminateVolume ( ) ;
setVolumeViaPopover ( 30 ) ;
hitObjectHasSampleVolume ( 0 , 30 ) ;
hitObjectHasSampleVolume ( 1 , 30 ) ;
}
2021-11-14 00:07:19 +08:00
[Test]
2023-05-24 16:33:48 +08:00
public void TestPopoverMultipleSelectionWithSameSampleBank ( )
2021-11-14 00:07:19 +08:00
{
AddStep ( "unify sample bank" , ( ) = >
{
foreach ( var h in EditorBeatmap . HitObjects )
2023-04-26 20:21:52 +08:00
{
for ( int i = 0 ; i < h . Samples . Count ; i + + )
{
2023-05-24 13:04:10 +08:00
h . Samples [ i ] = h . Samples [ i ] . With ( newBank : HitSampleInfo . BANK_SOFT ) ;
2023-04-26 20:21:52 +08:00
}
}
2021-11-14 00:07:19 +08:00
} ) ;
AddStep ( "select both objects" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
clickSamplePiece ( 0 ) ;
2022-10-19 19:34:41 +08:00
samplePopoverHasSingleBank ( HitSampleInfo . BANK_SOFT ) ;
2021-11-14 00:07:19 +08:00
dismissPopover ( ) ;
clickSamplePiece ( 1 ) ;
2022-10-19 19:34:41 +08:00
samplePopoverHasSingleBank ( HitSampleInfo . BANK_SOFT ) ;
2021-11-14 00:07:19 +08:00
2021-11-14 00:43:33 +08:00
setBankViaPopover ( string . Empty ) ;
2022-10-19 19:34:41 +08:00
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
samplePopoverHasSingleBank ( HitSampleInfo . BANK_SOFT ) ;
setBankViaPopover ( HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_DRUM ) ;
samplePopoverHasSingleBank ( HitSampleInfo . BANK_DRUM ) ;
2021-11-14 00:07:19 +08:00
}
[Test]
2023-05-24 16:33:48 +08:00
public void TestPopoverMultipleSelectionWithDifferentSampleBank ( )
2021-11-14 00:07:19 +08:00
{
AddStep ( "select both objects" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
clickSamplePiece ( 0 ) ;
samplePopoverHasIndeterminateBank ( ) ;
dismissPopover ( ) ;
clickSamplePiece ( 1 ) ;
samplePopoverHasIndeterminateBank ( ) ;
2021-11-14 00:43:33 +08:00
setBankViaPopover ( string . Empty ) ;
2022-10-19 19:34:41 +08:00
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
2021-11-14 00:43:33 +08:00
samplePopoverHasIndeterminateBank ( ) ;
2022-10-19 19:34:41 +08:00
setBankViaPopover ( HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_NORMAL ) ;
samplePopoverHasSingleBank ( HitSampleInfo . BANK_NORMAL ) ;
2021-11-14 00:07:19 +08:00
}
2023-06-02 06:40:00 +08:00
[Test]
public void TestPopoverAddSampleAddition ( )
{
clickSamplePiece ( 0 ) ;
setBankViaPopover ( HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_SOFT ) ;
toggleAdditionViaPopover ( 0 ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_WHISTLE ) ;
setAdditionBankViaPopover ( HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSampleNormalBank ( 0 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSampleAdditionBank ( 0 , HitSampleInfo . BANK_DRUM ) ;
toggleAdditionViaPopover ( 0 ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL ) ;
}
[Test]
public void TestNodeSamplePopover ( )
{
AddStep ( "add slider" , ( ) = >
{
EditorBeatmap . Clear ( ) ;
EditorBeatmap . Add ( new Slider
{
Position = new Vector2 ( 256 , 256 ) ,
StartTime = 0 ,
Path = new SliderPath ( new [ ] { new PathControlPoint ( Vector2 . Zero ) , new PathControlPoint ( new Vector2 ( 250 , 0 ) ) } ) ,
Samples =
{
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL )
} ,
NodeSamples =
{
new List < HitSampleInfo > { new HitSampleInfo ( HitSampleInfo . HIT_NORMAL ) } ,
new List < HitSampleInfo > { new HitSampleInfo ( HitSampleInfo . HIT_NORMAL ) } ,
}
} ) ;
} ) ;
clickNodeSamplePiece ( 0 , 1 ) ;
setBankViaPopover ( HitSampleInfo . BANK_SOFT ) ;
hitObjectNodeHasSampleBank ( 0 , 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectNodeHasSampleBank ( 0 , 1 , HitSampleInfo . BANK_SOFT ) ;
toggleAdditionViaPopover ( 0 ) ;
hitObjectNodeHasSampleBank ( 0 , 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectNodeHasSampleBank ( 0 , 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectNodeHasSamples ( 0 , 0 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectNodeHasSamples ( 0 , 1 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_WHISTLE ) ;
setAdditionBankViaPopover ( HitSampleInfo . BANK_DRUM ) ;
hitObjectNodeHasSampleBank ( 0 , 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectNodeHasSampleNormalBank ( 0 , 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectNodeHasSampleAdditionBank ( 0 , 1 , HitSampleInfo . BANK_DRUM ) ;
toggleAdditionViaPopover ( 0 ) ;
hitObjectNodeHasSampleBank ( 0 , 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectNodeHasSamples ( 0 , 0 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectNodeHasSamples ( 0 , 1 , HitSampleInfo . HIT_NORMAL ) ;
setVolumeViaPopover ( 10 ) ;
hitObjectNodeHasSampleVolume ( 0 , 0 , 100 ) ;
hitObjectNodeHasSampleVolume ( 0 , 1 , 10 ) ;
}
2024-07-04 21:25:43 +08:00
[Test]
public void TestSamplePointSeek ( )
{
AddStep ( "add slider" , ( ) = >
{
EditorBeatmap . Clear ( ) ;
EditorBeatmap . Add ( new Slider
{
Position = new Vector2 ( 256 , 256 ) ,
StartTime = 0 ,
Path = new SliderPath ( new [ ] { new PathControlPoint ( Vector2 . Zero ) , new PathControlPoint ( new Vector2 ( 250 , 0 ) ) } ) ,
Samples =
{
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL )
} ,
NodeSamples =
{
new List < HitSampleInfo > { new HitSampleInfo ( HitSampleInfo . HIT_NORMAL ) } ,
new List < HitSampleInfo > { new HitSampleInfo ( HitSampleInfo . HIT_NORMAL ) } ,
} ,
RepeatCount = 1
} ) ;
} ) ;
doubleClickNodeSamplePiece ( 0 , 0 ) ;
editorTimeIs ( 0 ) ;
doubleClickNodeSamplePiece ( 0 , 1 ) ;
editorTimeIs ( 813 ) ;
doubleClickNodeSamplePiece ( 0 , 2 ) ;
editorTimeIs ( 1627 ) ;
doubleClickSamplePiece ( 0 ) ;
editorTimeIs ( 0 ) ;
}
2023-05-24 16:33:48 +08:00
[Test]
public void TestHotkeysMultipleSelectionWithSameSampleBank ( )
{
AddStep ( "unify sample bank" , ( ) = >
{
foreach ( var h in EditorBeatmap . HitObjects )
{
for ( int i = 0 ; i < h . Samples . Count ; i + + )
{
h . Samples [ i ] = h . Samples [ i ] . With ( newBank : HitSampleInfo . BANK_SOFT ) ;
}
}
} ) ;
AddStep ( "select both objects" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
AddStep ( "Press normal bank shortcut" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . W ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_NORMAL ) ;
AddStep ( "Press drum bank shortcut" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . R ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_DRUM ) ;
AddStep ( "Press auto bank shortcut" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . Q ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
// Should be a noop.
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_DRUM ) ;
}
[Test]
public void TestHotkeysDuringPlacement ( )
{
AddStep ( "Enter placement mode" , ( ) = > InputManager . Key ( Key . Number2 ) ) ;
AddStep ( "Move mouse to centre" , ( ) = > InputManager . MoveMouseTo ( Editor . ChildrenOfType < HitObjectComposer > ( ) . First ( ) . ScreenSpaceDrawQuad . Centre ) ) ;
AddStep ( "Move between two objects" , ( ) = > EditorClock . Seek ( 250 ) ) ;
AddStep ( "Press normal bank shortcut" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . W ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
checkPlacementSample ( HitSampleInfo . BANK_NORMAL ) ;
AddStep ( "Press drum bank shortcut" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . R ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
checkPlacementSample ( HitSampleInfo . BANK_DRUM ) ;
AddStep ( "Press auto bank shortcut" , ( ) = >
{
InputManager . PressKey ( Key . ShiftLeft ) ;
InputManager . Key ( Key . Q ) ;
InputManager . ReleaseKey ( Key . ShiftLeft ) ;
} ) ;
checkPlacementSample ( HitSampleInfo . BANK_NORMAL ) ;
AddStep ( "Move after second object" , ( ) = > EditorClock . Seek ( 750 ) ) ;
checkPlacementSample ( HitSampleInfo . BANK_SOFT ) ;
AddStep ( "Move to first object" , ( ) = > EditorClock . Seek ( 0 ) ) ;
checkPlacementSample ( HitSampleInfo . BANK_NORMAL ) ;
void checkPlacementSample ( string expected ) = > AddAssert ( $"Placement sample is {expected}" , ( ) = > EditorBeatmap . PlacementObject . Value . Samples . First ( ) . Bank , ( ) = > Is . EqualTo ( expected ) ) ;
}
2024-07-02 22:21:56 +08:00
[Test]
public void TestHotkeysAffectNodeSamples ( )
{
AddStep ( "add slider" , ( ) = >
{
EditorBeatmap . Add ( new Slider
{
Position = new Vector2 ( 256 , 256 ) ,
StartTime = 1000 ,
Path = new SliderPath ( new [ ] { new PathControlPoint ( Vector2 . Zero ) , new PathControlPoint ( new Vector2 ( 250 , 0 ) ) } ) ,
Samples =
{
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL )
} ,
NodeSamples = new List < IList < HitSampleInfo > >
{
new List < HitSampleInfo >
{
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL , bank : HitSampleInfo . BANK_DRUM ) ,
new HitSampleInfo ( HitSampleInfo . HIT_CLAP , bank : HitSampleInfo . BANK_DRUM ) ,
} ,
new List < HitSampleInfo >
{
new HitSampleInfo ( HitSampleInfo . HIT_NORMAL , bank : HitSampleInfo . BANK_SOFT ) ,
new HitSampleInfo ( HitSampleInfo . HIT_WHISTLE , bank : HitSampleInfo . BANK_SOFT ) ,
} ,
}
} ) ;
} ) ;
AddStep ( "select everything" , ( ) = > EditorBeatmap . SelectedHitObjects . AddRange ( EditorBeatmap . HitObjects ) ) ;
AddStep ( "add clap addition" , ( ) = > InputManager . Key ( Key . R ) ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_CLAP ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSamples ( 1 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_CLAP ) ;
hitObjectHasSampleBank ( 2 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSamples ( 2 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_CLAP ) ;
hitObjectNodeHasSampleBank ( 2 , 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectNodeHasSamples ( 2 , 0 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_CLAP ) ;
hitObjectNodeHasSampleBank ( 2 , 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectNodeHasSamples ( 2 , 1 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_WHISTLE , HitSampleInfo . HIT_CLAP ) ;
AddStep ( "remove clap addition" , ( ) = > InputManager . Key ( Key . R ) ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectHasSamples ( 1 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectHasSampleBank ( 2 , HitSampleInfo . BANK_NORMAL ) ;
hitObjectHasSamples ( 2 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectNodeHasSampleBank ( 2 , 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectNodeHasSamples ( 2 , 0 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectNodeHasSampleBank ( 2 , 1 , HitSampleInfo . BANK_SOFT ) ;
hitObjectNodeHasSamples ( 2 , 1 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_WHISTLE ) ;
AddStep ( "set drum bank" , ( ) = >
{
InputManager . PressKey ( Key . LShift ) ;
InputManager . Key ( Key . R ) ;
InputManager . ReleaseKey ( Key . LShift ) ;
} ) ;
hitObjectHasSampleBank ( 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSamples ( 0 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectHasSampleBank ( 1 , HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSamples ( 1 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectHasSampleBank ( 2 , HitSampleInfo . BANK_DRUM ) ;
hitObjectHasSamples ( 2 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectNodeHasSampleBank ( 2 , 0 , HitSampleInfo . BANK_DRUM ) ;
hitObjectNodeHasSamples ( 2 , 0 , HitSampleInfo . HIT_NORMAL ) ;
hitObjectNodeHasSampleBank ( 2 , 1 , HitSampleInfo . BANK_DRUM ) ;
hitObjectNodeHasSamples ( 2 , 1 , HitSampleInfo . HIT_NORMAL , HitSampleInfo . HIT_WHISTLE ) ;
}
2022-05-11 14:51:00 +08:00
private void clickSamplePiece ( int objectIndex ) = > AddStep ( $"click {objectIndex.ToOrdinalWords()} sample piece" , ( ) = >
2021-11-13 23:58:24 +08:00
{
2022-05-11 14:51:00 +08:00
var samplePiece = this . ChildrenOfType < SamplePointPiece > ( ) . Single ( piece = > piece . HitObject = = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ) ;
2021-11-13 23:58:24 +08:00
2022-05-11 14:51:00 +08:00
InputManager . MoveMouseTo ( samplePiece ) ;
2021-11-13 23:58:24 +08:00
InputManager . Click ( MouseButton . Left ) ;
} ) ;
2023-06-02 06:40:00 +08:00
private void clickNodeSamplePiece ( int objectIndex , int nodeIndex ) = > AddStep ( $"click {objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node sample piece" , ( ) = >
{
var samplePiece = this . ChildrenOfType < NodeSamplePointPiece > ( ) . Where ( piece = > piece . HitObject = = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ) . ToArray ( ) [ nodeIndex ] ;
InputManager . MoveMouseTo ( samplePiece ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
2024-07-04 21:25:43 +08:00
private void doubleClickSamplePiece ( int objectIndex ) = > AddStep ( $"double-click {objectIndex.ToOrdinalWords()} sample piece" , ( ) = >
{
var samplePiece = this . ChildrenOfType < SamplePointPiece > ( ) . Single ( piece = > piece is not NodeSamplePointPiece & & piece . HitObject = = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ) ;
InputManager . MoveMouseTo ( samplePiece ) ;
InputManager . Click ( MouseButton . Left ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
private void doubleClickNodeSamplePiece ( int objectIndex , int nodeIndex ) = > AddStep ( $"double-click {objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node sample piece" , ( ) = >
{
var samplePiece = this . ChildrenOfType < NodeSamplePointPiece > ( ) . Where ( piece = > piece . HitObject = = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ) . ToArray ( ) [ nodeIndex ] ;
InputManager . MoveMouseTo ( samplePiece ) ;
InputManager . Click ( MouseButton . Left ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
2023-08-17 05:16:57 +08:00
private void samplePopoverHasNoFocus ( ) = > AddUntilStep ( "sample popover textbox not focused" , ( ) = >
2022-05-11 14:51:59 +08:00
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . SingleOrDefault ( ) ;
var slider = popover ? . ChildrenOfType < IndeterminateSliderWithTextBoxInput < int > > ( ) . Single ( ) ;
var textbox = slider ? . ChildrenOfType < OsuTextBox > ( ) . Single ( ) ;
2023-08-17 05:16:57 +08:00
return textbox ? . HasFocus = = false ;
2022-05-11 14:51:59 +08:00
} ) ;
2021-11-13 23:58:24 +08:00
private void samplePopoverHasSingleVolume ( int volume ) = > AddUntilStep ( $"sample popover has volume {volume}" , ( ) = >
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . SingleOrDefault ( ) ;
2021-11-14 00:21:48 +08:00
var slider = popover ? . ChildrenOfType < IndeterminateSliderWithTextBoxInput < int > > ( ) . Single ( ) ;
2021-11-13 23:58:24 +08:00
return slider ? . Current . Value = = volume ;
} ) ;
2021-11-14 00:21:48 +08:00
private void samplePopoverHasIndeterminateVolume ( ) = > AddUntilStep ( "sample popover has indeterminate volume" , ( ) = >
2021-11-14 00:02:55 +08:00
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . SingleOrDefault ( ) ;
2021-11-14 00:21:48 +08:00
var slider = popover ? . ChildrenOfType < IndeterminateSliderWithTextBoxInput < int > > ( ) . Single ( ) ;
2021-11-14 00:02:55 +08:00
return slider ! = null & & slider . Current . Value = = null ;
} ) ;
2021-11-13 23:58:24 +08:00
private void samplePopoverHasSingleBank ( string bank ) = > AddUntilStep ( $"sample popover has bank {bank}" , ( ) = >
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . SingleOrDefault ( ) ;
2021-11-14 00:43:33 +08:00
var textBox = popover ? . ChildrenOfType < OsuTextBox > ( ) . First ( ) ;
2021-11-13 23:58:24 +08:00
2023-06-23 23:59:36 +08:00
return textBox ? . Current . Value = = bank & & string . IsNullOrEmpty ( textBox . PlaceholderText . ToString ( ) ) ;
2021-11-13 23:58:24 +08:00
} ) ;
2021-11-14 00:43:33 +08:00
private void samplePopoverHasIndeterminateBank ( ) = > AddUntilStep ( "sample popover has indeterminate bank" , ( ) = >
2021-11-14 00:07:19 +08:00
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . SingleOrDefault ( ) ;
2021-11-14 00:43:33 +08:00
var textBox = popover ? . ChildrenOfType < OsuTextBox > ( ) . First ( ) ;
2021-11-14 00:07:19 +08:00
2021-11-14 00:43:33 +08:00
return textBox ! = null & & string . IsNullOrEmpty ( textBox . Current . Value ) & & ! string . IsNullOrEmpty ( textBox . PlaceholderText . ToString ( ) ) ;
2021-11-14 00:07:19 +08:00
} ) ;
2021-11-13 23:58:24 +08:00
private void dismissPopover ( )
{
AddStep ( "dismiss popover" , ( ) = > InputManager . Key ( Key . Escape ) ) ;
2022-05-11 14:51:00 +08:00
AddUntilStep ( "wait for dismiss" , ( ) = > ! this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . Any ( popover = > popover . IsPresent ) ) ;
2021-11-13 23:58:24 +08:00
}
private void setVolumeViaPopover ( int volume ) = > AddStep ( $"set volume {volume} via popover" , ( ) = >
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . Single ( ) ;
2021-11-14 00:21:48 +08:00
var slider = popover . ChildrenOfType < IndeterminateSliderWithTextBoxInput < int > > ( ) . Single ( ) ;
2021-11-13 23:58:24 +08:00
slider . Current . Value = volume ;
} ) ;
private void hitObjectHasSampleVolume ( int objectIndex , int volume ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} has volume {volume}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ;
2023-04-26 20:21:52 +08:00
return h . Samples . All ( o = > o . Volume = = volume ) ;
2021-11-13 23:58:24 +08:00
} ) ;
2023-06-02 06:40:00 +08:00
private void hitObjectNodeHasSampleVolume ( int objectIndex , int nodeIndex , int volume ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node has volume {volume}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) as IHasRepeats ;
return h is not null & & h . NodeSamples [ nodeIndex ] . All ( o = > o . Volume = = volume ) ;
} ) ;
2021-11-13 23:58:24 +08:00
private void setBankViaPopover ( string bank ) = > AddStep ( $"set bank {bank} via popover" , ( ) = >
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . Single ( ) ;
var textBox = popover . ChildrenOfType < LabelledTextBox > ( ) . First ( ) ;
textBox . Current . Value = bank ;
2021-11-14 01:06:32 +08:00
// force a commit via keyboard.
// this is needed when testing attempting to set empty bank - which should revert to the previous value, but only on commit.
2024-05-22 21:55:53 +08:00
( ( IFocusManager ) InputManager ) . ChangeFocus ( textBox ) ;
2021-11-14 01:06:32 +08:00
InputManager . Key ( Key . Enter ) ;
2021-11-13 23:58:24 +08:00
} ) ;
2023-06-02 06:40:00 +08:00
private void setAdditionBankViaPopover ( string bank ) = > AddStep ( $"set addition bank {bank} via popover" , ( ) = >
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . Single ( ) ;
var textBox = popover . ChildrenOfType < LabelledTextBox > ( ) . ToArray ( ) [ 1 ] ;
textBox . Current . Value = bank ;
// force a commit via keyboard.
// this is needed when testing attempting to set empty bank - which should revert to the previous value, but only on commit.
2024-06-06 19:50:31 +08:00
( ( IFocusManager ) InputManager ) . ChangeFocus ( textBox ) ;
2023-06-02 06:40:00 +08:00
InputManager . Key ( Key . Enter ) ;
} ) ;
private void toggleAdditionViaPopover ( int index ) = > AddStep ( $"toggle addition {index} via popover" , ( ) = >
{
var popover = this . ChildrenOfType < SamplePointPiece . SampleEditPopover > ( ) . First ( ) ;
var ternaryButton = popover . ChildrenOfType < DrawableTernaryButton > ( ) . ToArray ( ) [ index ] ;
InputManager . MoveMouseTo ( ternaryButton ) ;
InputManager . PressButton ( MouseButton . Left ) ;
InputManager . ReleaseButton ( MouseButton . Left ) ;
} ) ;
2023-05-16 17:52:35 +08:00
private void hitObjectHasSamples ( int objectIndex , params string [ ] samples ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} has samples {string.Join(',', samples)}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ;
return h . Samples . Select ( s = > s . Name ) . SequenceEqual ( samples ) ;
} ) ;
2021-11-13 23:58:24 +08:00
private void hitObjectHasSampleBank ( int objectIndex , string bank ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} has bank {bank}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ;
2023-04-26 20:21:52 +08:00
return h . Samples . All ( o = > o . Bank = = bank ) ;
2021-11-13 23:58:24 +08:00
} ) ;
2023-06-02 06:40:00 +08:00
private void hitObjectHasSampleNormalBank ( int objectIndex , string bank ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} has normal bank {bank}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ;
return h . Samples . Where ( o = > o . Name = = HitSampleInfo . HIT_NORMAL ) . All ( o = > o . Bank = = bank ) ;
} ) ;
private void hitObjectHasSampleAdditionBank ( int objectIndex , string bank ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} has addition bank {bank}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) ;
return h . Samples . Where ( o = > o . Name ! = HitSampleInfo . HIT_NORMAL ) . All ( o = > o . Bank = = bank ) ;
} ) ;
private void hitObjectNodeHasSamples ( int objectIndex , int nodeIndex , params string [ ] samples ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node has samples {string.Join(',', samples)}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) as IHasRepeats ;
return h is not null & & h . NodeSamples [ nodeIndex ] . Select ( s = > s . Name ) . SequenceEqual ( samples ) ;
} ) ;
private void hitObjectNodeHasSampleBank ( int objectIndex , int nodeIndex , string bank ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node has bank {bank}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) as IHasRepeats ;
return h is not null & & h . NodeSamples [ nodeIndex ] . All ( o = > o . Bank = = bank ) ;
} ) ;
private void hitObjectNodeHasSampleNormalBank ( int objectIndex , int nodeIndex , string bank ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node has normal bank {bank}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) as IHasRepeats ;
return h is not null & & h . NodeSamples [ nodeIndex ] . Where ( o = > o . Name = = HitSampleInfo . HIT_NORMAL ) . All ( o = > o . Bank = = bank ) ;
} ) ;
private void hitObjectNodeHasSampleAdditionBank ( int objectIndex , int nodeIndex , string bank ) = > AddAssert ( $"{objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node has addition bank {bank}" , ( ) = >
{
var h = EditorBeatmap . HitObjects . ElementAt ( objectIndex ) as IHasRepeats ;
return h is not null & & h . NodeSamples [ nodeIndex ] . Where ( o = > o . Name ! = HitSampleInfo . HIT_NORMAL ) . All ( o = > o . Bank = = bank ) ;
} ) ;
2024-07-04 21:25:43 +08:00
private void editorTimeIs ( double time ) = > AddAssert ( $"editor time is {time}" , ( ) = > Precision . AlmostEquals ( EditorClock . CurrentTimeAccurate , time , 1 ) ) ;
2021-11-13 23:58:24 +08:00
}
}