-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request ppy#31801 from peppy/carousel-v2-artist-grouping
Add support for grouping by artist to beatmap carousel v2
- Loading branch information
Showing
12 changed files
with
496 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System; | ||
using System.Linq; | ||
using NUnit.Framework; | ||
using osu.Framework.Allocation; | ||
|
@@ -16,7 +17,6 @@ | |
using osu.Game.Graphics; | ||
using osu.Game.Graphics.Containers; | ||
using osu.Game.Screens.Select; | ||
using osu.Game.Screens.Select.Filter; | ||
using osu.Game.Screens.SelectV2; | ||
using osu.Game.Tests.Beatmaps; | ||
using osu.Game.Tests.Resources; | ||
|
@@ -53,16 +53,6 @@ protected BeatmapCarouselV2TestScene() | |
Scheduler.AddDelayed(updateStats, 100, true); | ||
} | ||
|
||
[SetUpSteps] | ||
public virtual void SetUpSteps() | ||
{ | ||
RemoveAllBeatmaps(); | ||
|
||
CreateCarousel(); | ||
|
||
SortBy(new FilterCriteria { Sort = SortMode.Title }); | ||
} | ||
|
||
protected void CreateCarousel() | ||
{ | ||
AddStep("create components", () => | ||
|
@@ -146,6 +136,9 @@ protected void CreateCarousel() | |
protected void CheckNoSelection() => AddAssert("has no selection", () => Carousel.CurrentSelection, () => Is.Null); | ||
protected void CheckHasSelection() => AddAssert("has selection", () => Carousel.CurrentSelection, () => Is.Not.Null); | ||
|
||
protected BeatmapPanel? GetSelectedPanel() => Carousel.ChildrenOfType<BeatmapPanel>().SingleOrDefault(p => p.Selected.Value); | ||
protected GroupPanel? GetKeyboardSelectedPanel() => Carousel.ChildrenOfType<GroupPanel>().SingleOrDefault(p => p.KeyboardSelected.Value); | ||
|
||
protected void WaitForGroupSelection(int group, int panel) | ||
{ | ||
AddUntilStep($"selected is group{group} panel{panel}", () => | ||
|
@@ -190,12 +183,41 @@ protected void ClickVisiblePanel<T>(int index) | |
/// </summary> | ||
/// <param name="count">The count of beatmap sets to add.</param> | ||
/// <param name="fixedDifficultiesPerSet">If not null, the number of difficulties per set. If null, randomised difficulty count will be used.</param> | ||
protected void AddBeatmaps(int count, int? fixedDifficultiesPerSet = null) => AddStep($"add {count} beatmaps", () => | ||
/// <param name="randomMetadata">Whether to randomise the metadata to make groupings more uniform.</param> | ||
protected void AddBeatmaps(int count, int? fixedDifficultiesPerSet = null, bool randomMetadata = false) => AddStep($"add {count} beatmaps{(randomMetadata ? " with random data" : "")}", () => | ||
{ | ||
for (int i = 0; i < count; i++) | ||
BeatmapSets.Add(TestResources.CreateTestBeatmapSetInfo(fixedDifficultiesPerSet ?? RNG.Next(1, 4))); | ||
{ | ||
var beatmapSetInfo = TestResources.CreateTestBeatmapSetInfo(fixedDifficultiesPerSet ?? RNG.Next(1, 4)); | ||
|
||
if (randomMetadata) | ||
{ | ||
char randomCharacter = getRandomCharacter(); | ||
|
||
var metadata = new BeatmapMetadata | ||
{ | ||
// Create random metadata, then we can check if sorting works based on these | ||
Artist = $"{randomCharacter}ome Artist " + RNG.Next(0, 9), | ||
Title = $"{randomCharacter}ome Song (set id {beatmapSetInfo.OnlineID:000}) {Guid.NewGuid()}", | ||
Author = { Username = $"{randomCharacter}ome Guy " + RNG.Next(0, 9) }, | ||
}; | ||
|
||
foreach (var beatmap in beatmapSetInfo.Beatmaps) | ||
beatmap.Metadata = metadata.DeepClone(); | ||
} | ||
|
||
BeatmapSets.Add(beatmapSetInfo); | ||
} | ||
}); | ||
|
||
private static long randomCharPointer; | ||
|
||
private static char getRandomCharacter() | ||
{ | ||
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz*"; | ||
return chars[(int)((randomCharPointer++ / 2) % chars.Length)]; | ||
} | ||
|
||
protected void RemoveAllBeatmaps() => AddStep("clear all beatmaps", () => BeatmapSets.Clear()); | ||
|
||
protected void RemoveFirstBeatmap() => | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
177 changes: 177 additions & 0 deletions
177
osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarouselV2ArtistGrouping.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System.Linq; | ||
using NUnit.Framework; | ||
using osu.Framework.Testing; | ||
using osu.Game.Beatmaps; | ||
using osu.Game.Screens.Select; | ||
using osu.Game.Screens.Select.Filter; | ||
using osu.Game.Screens.SelectV2; | ||
|
||
namespace osu.Game.Tests.Visual.SongSelect | ||
{ | ||
[TestFixture] | ||
public partial class TestSceneBeatmapCarouselV2ArtistGrouping : BeatmapCarouselV2TestScene | ||
{ | ||
[SetUpSteps] | ||
public void SetUpSteps() | ||
{ | ||
RemoveAllBeatmaps(); | ||
CreateCarousel(); | ||
SortBy(new FilterCriteria { Group = GroupMode.Artist, Sort = SortMode.Artist }); | ||
|
||
AddBeatmaps(10, 3, true); | ||
WaitForDrawablePanels(); | ||
} | ||
|
||
[Test] | ||
public void TestOpenCloseGroupWithNoSelectionMouse() | ||
{ | ||
AddAssert("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
AddUntilStep("no sets visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
CheckNoSelection(); | ||
|
||
ClickVisiblePanel<GroupPanel>(0); | ||
|
||
AddUntilStep("some sets visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.GreaterThan(0)); | ||
AddUntilStep("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
CheckNoSelection(); | ||
|
||
ClickVisiblePanel<GroupPanel>(0); | ||
|
||
AddUntilStep("no sets visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
AddUntilStep("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
CheckNoSelection(); | ||
} | ||
|
||
[Test] | ||
public void TestOpenCloseGroupWithNoSelectionKeyboard() | ||
{ | ||
AddAssert("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
AddUntilStep("no sets visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
CheckNoSelection(); | ||
|
||
SelectNextPanel(); | ||
Select(); | ||
|
||
AddUntilStep("some sets visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.GreaterThan(0)); | ||
AddUntilStep("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
AddAssert("keyboard selected is expanded", () => GetKeyboardSelectedPanel()?.Expanded.Value, () => Is.True); | ||
CheckNoSelection(); | ||
|
||
Select(); | ||
|
||
AddUntilStep("no sets visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
AddUntilStep("no beatmaps visible", () => Carousel.ChildrenOfType<BeatmapPanel>().Count(p => p.Alpha > 0), () => Is.Zero); | ||
AddAssert("keyboard selected is collapsed", () => GetKeyboardSelectedPanel()?.Expanded.Value, () => Is.False); | ||
CheckNoSelection(); | ||
} | ||
|
||
[Test] | ||
public void TestCarouselRemembersSelection() | ||
{ | ||
SelectNextGroup(); | ||
|
||
object? selection = null; | ||
|
||
AddStep("store drawable selection", () => selection = GetSelectedPanel()?.Item?.Model); | ||
|
||
CheckHasSelection(); | ||
AddAssert("drawable selection non-null", () => selection, () => Is.Not.Null); | ||
AddAssert("drawable selection matches carousel selection", () => selection, () => Is.EqualTo(Carousel.CurrentSelection)); | ||
|
||
RemoveAllBeatmaps(); | ||
AddUntilStep("no drawable selection", GetSelectedPanel, () => Is.Null); | ||
|
||
AddBeatmaps(10); | ||
WaitForDrawablePanels(); | ||
|
||
CheckHasSelection(); | ||
AddAssert("no drawable selection", GetSelectedPanel, () => Is.Null); | ||
|
||
AddStep("add previous selection", () => BeatmapSets.Add(((BeatmapInfo)selection!).BeatmapSet!)); | ||
|
||
AddAssert("selection matches original carousel selection", () => selection, () => Is.EqualTo(Carousel.CurrentSelection)); | ||
AddUntilStep("drawable selection restored", () => GetSelectedPanel()?.Item?.Model, () => Is.EqualTo(selection)); | ||
AddAssert("carousel item is visible", () => GetSelectedPanel()?.Item?.IsVisible, () => Is.True); | ||
|
||
ClickVisiblePanel<GroupPanel>(0); | ||
AddUntilStep("carousel item not visible", GetSelectedPanel, () => Is.Null); | ||
|
||
ClickVisiblePanel<GroupPanel>(0); | ||
AddUntilStep("carousel item is visible", () => GetSelectedPanel()?.Item?.IsVisible, () => Is.True); | ||
} | ||
|
||
[Test] | ||
public void TestGroupSelectionOnHeader() | ||
{ | ||
SelectNextGroup(); | ||
WaitForGroupSelection(0, 1); | ||
|
||
SelectPrevPanel(); | ||
SelectPrevPanel(); | ||
|
||
AddAssert("keyboard selected panel is expanded", () => GetKeyboardSelectedPanel()?.Expanded.Value, () => Is.True); | ||
|
||
SelectPrevGroup(); | ||
|
||
WaitForGroupSelection(0, 1); | ||
AddAssert("keyboard selected panel is contracted", () => GetKeyboardSelectedPanel()?.Expanded.Value, () => Is.False); | ||
|
||
SelectPrevGroup(); | ||
|
||
WaitForGroupSelection(0, 1); | ||
AddAssert("keyboard selected panel is expanded", () => GetKeyboardSelectedPanel()?.Expanded.Value, () => Is.True); | ||
} | ||
|
||
[Test] | ||
public void TestKeyboardSelection() | ||
{ | ||
SelectNextPanel(); | ||
SelectNextPanel(); | ||
SelectNextPanel(); | ||
SelectNextPanel(); | ||
CheckNoSelection(); | ||
|
||
// open first group | ||
Select(); | ||
CheckNoSelection(); | ||
AddUntilStep("some beatmaps visible", () => Carousel.ChildrenOfType<BeatmapSetPanel>().Count(p => p.Alpha > 0), () => Is.GreaterThan(0)); | ||
|
||
SelectNextPanel(); | ||
Select(); | ||
WaitForGroupSelection(3, 1); | ||
|
||
SelectNextGroup(); | ||
WaitForGroupSelection(3, 5); | ||
|
||
SelectNextGroup(); | ||
WaitForGroupSelection(4, 1); | ||
|
||
SelectPrevGroup(); | ||
WaitForGroupSelection(3, 5); | ||
|
||
SelectNextGroup(); | ||
WaitForGroupSelection(4, 1); | ||
|
||
SelectNextGroup(); | ||
WaitForGroupSelection(4, 5); | ||
|
||
SelectNextGroup(); | ||
WaitForGroupSelection(0, 1); | ||
|
||
SelectNextPanel(); | ||
SelectNextPanel(); | ||
SelectNextPanel(); | ||
SelectNextPanel(); | ||
|
||
SelectNextGroup(); | ||
WaitForGroupSelection(0, 1); | ||
|
||
SelectNextPanel(); | ||
SelectNextGroup(); | ||
WaitForGroupSelection(1, 1); | ||
} | ||
} | ||
} |
Oops, something went wrong.