1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:57:36 +08:00

Merge pull request #20389 from peppy/fix-gameplay-leaderboard-layout

Fix gameplay leaderboard sometimes not showing up
This commit is contained in:
Dan Balasescu 2022-09-22 20:51:54 +09:00 committed by GitHub
commit 445e026a32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 14 deletions

View File

@ -6,7 +6,9 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Extensions.PolygonExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Online.API.Requests.Responses;
@ -18,37 +20,52 @@ namespace osu.Game.Tests.Visual.Gameplay
[TestFixture]
public class TestSceneGameplayLeaderboard : OsuTestScene
{
private readonly TestGameplayLeaderboard leaderboard;
private TestGameplayLeaderboard leaderboard;
private readonly BindableDouble playerScore = new BindableDouble();
public TestSceneGameplayLeaderboard()
{
Add(leaderboard = new TestGameplayLeaderboard
AddStep("toggle expanded", () =>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(2),
if (leaderboard != null)
leaderboard.Expanded.Value = !leaderboard.Expanded.Value;
});
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
}
[SetUpSteps]
public void SetUpSteps()
[Test]
public void TestLayoutWithManyScores()
{
AddStep("reset leaderboard", () =>
createLeaderboard();
AddStep("add many scores in one go", () =>
{
leaderboard.Clear();
playerScore.Value = 1222333;
for (int i = 0; i < 32; i++)
createRandomScore(new APIUser { Username = $"Player {i + 1}" });
// Add player at end to force an animation down the whole list.
playerScore.Value = 0;
createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true);
});
AddStep("add local player", () => createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true));
AddStep("toggle expanded", () => leaderboard.Expanded.Value = !leaderboard.Expanded.Value);
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
// Gameplay leaderboard has custom scroll logic, which when coupled with LayoutDuration
// has caused layout to not work in the past.
AddUntilStep("wait for fill flow layout",
() => leaderboard.ChildrenOfType<FillFlowContainer<GameplayLeaderboardScore>>().First().ScreenSpaceDrawQuad.Intersects(leaderboard.ScreenSpaceDrawQuad));
AddUntilStep("wait for some scores not masked away",
() => leaderboard.ChildrenOfType<GameplayLeaderboardScore>().Any(s => leaderboard.ScreenSpaceDrawQuad.Contains(s.ScreenSpaceDrawQuad.Centre)));
}
[Test]
public void TestPlayerScore()
{
createLeaderboard();
addLocalPlayer();
var player2Score = new BindableDouble(1234567);
var player3Score = new BindableDouble(1111111);
@ -73,6 +90,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestRandomScores()
{
createLeaderboard();
addLocalPlayer();
int playerNumber = 1;
AddRepeatStep("add player with random score", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 10);
}
@ -80,6 +100,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestExistingUsers()
{
createLeaderboard();
addLocalPlayer();
AddStep("add peppy", () => createRandomScore(new APIUser { Username = "peppy", Id = 2 }));
AddStep("add smoogipoo", () => createRandomScore(new APIUser { Username = "smoogipoo", Id = 1040328 }));
AddStep("add flyte", () => createRandomScore(new APIUser { Username = "flyte", Id = 3103765 }));
@ -89,6 +112,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestMaxHeight()
{
createLeaderboard();
addLocalPlayer();
int playerNumber = 1;
AddRepeatStep("add 3 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 3);
checkHeight(4);
@ -103,6 +129,28 @@ namespace osu.Game.Tests.Visual.Gameplay
=> AddAssert($"leaderboard height is {panelCount} panels high", () => leaderboard.DrawHeight == (GameplayLeaderboardScore.PANEL_HEIGHT + leaderboard.Spacing) * panelCount);
}
private void addLocalPlayer()
{
AddStep("add local player", () =>
{
playerScore.Value = 1222333;
createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true);
});
}
private void createLeaderboard()
{
AddStep("create leaderboard", () =>
{
Child = leaderboard = new TestGameplayLeaderboard
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(2),
};
});
}
private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user);
private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false)

View File

@ -96,6 +96,14 @@ namespace osu.Game.Screens.Play.HUD
int displayCount = Math.Min(Flow.Count, maxPanels);
Height = displayCount * (GameplayLeaderboardScore.PANEL_HEIGHT + Flow.Spacing.Y);
// Add extra margin space to flow equal to height of leaderboard.
// This ensures the content is always on screen, but also accounts for the fact that scroll operations
// without animation were actually forcing the local score to a location it can't usually reside at.
//
// Basically, the local score was in the scroll extension region (due to always trying to scroll the
// local player to the middle of the display, but there being no other content below the local player
// to scroll up by).
Flow.Margin = new MarginPadding { Bottom = Height };
requiresScroll = displayCount != Flow.Count;
return drawable;
@ -118,7 +126,7 @@ namespace osu.Game.Screens.Play.HUD
if (requiresScroll && trackedScore != null)
{
float scrollTarget = scroll.GetChildPosInContent(trackedScore) + trackedScore.DrawHeight / 2 - scroll.DrawHeight / 2;
scroll.ScrollTo(scrollTarget, false);
scroll.ScrollTo(scrollTarget);
}
const float panel_height = GameplayLeaderboardScore.PANEL_HEIGHT;