Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mods;
Expand Down Expand Up @@ -67,16 +68,16 @@ public void TestSheared()

foreach (var scoreInfo in getTestScores())
{
BeatmapLeaderboardScore.HighlightType? highlightType = null;
LeaderboardRankDisplay.HighlightType? highlightType = null;

switch (scoreInfo.User.Id)
{
case 2:
highlightType = BeatmapLeaderboardScore.HighlightType.Own;
highlightType = LeaderboardRankDisplay.HighlightType.Own;
break;

case 1541390:
highlightType = BeatmapLeaderboardScore.HighlightType.Friend;
highlightType = LeaderboardRankDisplay.HighlightType.Friend;
break;
}

Expand Down Expand Up @@ -118,16 +119,16 @@ public void TestNonSheared()

foreach (var scoreInfo in getTestScores())
{
BeatmapLeaderboardScore.HighlightType? highlightType = null;
LeaderboardRankDisplay.HighlightType? highlightType = null;

switch (scoreInfo.User.Id)
{
case 2:
highlightType = BeatmapLeaderboardScore.HighlightType.Own;
highlightType = LeaderboardRankDisplay.HighlightType.Own;
break;

case 1541390:
highlightType = BeatmapLeaderboardScore.HighlightType.Friend;
highlightType = LeaderboardRankDisplay.HighlightType.Friend;
break;
}

Expand Down
180 changes: 180 additions & 0 deletions osu.Game/Online/Leaderboards/LeaderboardCommonDisplay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// 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;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation;
using osu.Game.Extensions;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Screens.Select;
using osu.Game.Users.Drawables;
using osuTK;

namespace osu.Game.Online.Leaderboards
{
public partial class LeaderboardCommonDisplay : Container
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dunno about naming here.

How about LeaderboardScoreUserInfo?

All these components may work better as partial classes inside LeaderboardScore given how they are all just pieces of that component (i think?)

See something like BeatmapTitleWedge and adjacent files as an example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it look awkward if I then reuse them on a potential PlaylistsLeaderboardScore and it'll have a bunch of references to BeatmapLeaderboardScore.<something>? I don't think it's that big of a deal but it would be at least a little eyebrow raising.

But then on the other hand I am already pulling in constants from it in some places so I guess it's fine?

{
public readonly APIUser User;
public readonly DateTimeOffset? Date;
public readonly int? Rank;

private const int corner_radius = BeatmapLeaderboardScore.CORNER_RADIUS;

private FillFlowContainer fillFlowContainer = null!;
private ClickableAvatar innerAvatar = null!;
private Container rankOverlay = null!;

private readonly bool sheared;

public LeaderboardCommonDisplay(APIUser user, DateTimeOffset? date, int? rank = null, bool sheared = false)
{
User = user;
Date = date;
Rank = rank;

this.sheared = sheared;
}

[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
RelativeSizeAxes = Axes.Both;

Child = new GridContainer
{
RelativeSizeAxes = Axes.Both,
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
},
Content = new[]
{
new Drawable[]
{
new Container
{
AutoSizeAxes = Axes.Both,
CornerRadius = corner_radius,
Masking = true,
Children = new Drawable[]
{
new DelayedLoadWrapper(innerAvatar = new ClickableAvatar(User)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.1f),
Shear = sheared ? -OsuGame.SHEAR : Vector2.Zero,
RelativeSizeAxes = Axes.Both,
})
{
RelativeSizeAxes = Axes.None,
Size = new Vector2(BeatmapLeaderboardScore.HEIGHT)
},
rankOverlay = new Container
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Colour4.Black.Opacity(0.5f),
},
new LeaderboardRankLabel(Rank, sheared, false)
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
}
}
},
},
new FillFlowContainer
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Horizontal = corner_radius },
Children = new Drawable[]
{
fillFlowContainer = new FillFlowContainer
{
Shear = sheared ? -OsuGame.SHEAR : Vector2.Zero,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
AutoSizeAxes = Axes.Both,
Masking = true,
Children = new Drawable[]
{
new UpdateableFlag(User.CountryCode)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(20, 14),
},
new UpdateableTeamFlag(User.Team)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(30, 15),
},
},
},
new TruncatingSpriteText
{
RelativeSizeAxes = Axes.X,
Shear = sheared ? -OsuGame.SHEAR : Vector2.Zero,
Text = User.Username,
Font = OsuFont.Style.Heading2,
}
}
},
},
}
};

innerAvatar.OnLoadComplete += d => d.FadeInFromZero(200);

if (Date != null)
{
fillFlowContainer.Add(new DateLabel(Date.Value)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Colour = colourProvider.Content2,
UseFullGlyphHeight = false,
});
}
}

public void UpdateRankOverlayState(bool shouldBeVisible, double duration)
{
if (shouldBeVisible)
rankOverlay.FadeIn(duration, Easing.OutQuint);
else
rankOverlay.FadeOut(duration, Easing.OutQuint);
}

private partial class DateLabel : DrawableDate
{
public DateLabel(DateTimeOffset date)
: base(date)
{
Font = OsuFont.Style.Caption1.With(weight: FontWeight.SemiBold);
}

protected override LocalisableString Format() => Date.ToShortRelativeTime(TimeSpan.FromSeconds(30));
}
}
}
98 changes: 98 additions & 0 deletions osu.Game/Online/Leaderboards/LeaderboardRankDisplay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osuTK.Graphics;

namespace osu.Game.Online.Leaderboards
{
public partial class LeaderboardRankDisplay : Container
{
public const int WIDTH = 40;

public readonly int? Rank;
public readonly HighlightType? Highlight;

[Resolved]
private OsuColour colours { get; set; } = null!;

private static readonly Color4 personal_best_gradient_left = Color4Extensions.FromHex("#66FFCC");
private static readonly Color4 personal_best_gradient_right = Color4Extensions.FromHex("#51A388");

private Container highlightGradient = null!;

private readonly bool sheared;

public LeaderboardRankDisplay(int? rank, bool sheared = false, HighlightType? highlight = null)
{
Rank = rank;
Highlight = highlight;

this.sheared = sheared;
}

[BackgroundDependencyLoader]
private void load()
{
Width = WIDTH;
RelativeSizeAxes = Axes.Y;
Children = new Drawable[]
{
highlightGradient = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = -10f },
Alpha = Highlight != null ? 1 : 0,
Colour = getHighlightColour(Highlight),
Child = new Box { RelativeSizeAxes = Axes.Both },
},
new LeaderboardRankLabel(Rank, sheared, darkText: Highlight == HighlightType.Own)
{
RelativeSizeAxes = Axes.Both,
},
};
}

private ColourInfo getHighlightColour(HighlightType? highlightType, float lightenAmount = 0)
{
switch (highlightType)
{
case HighlightType.Own:
return ColourInfo.GradientHorizontal(personal_best_gradient_left.Lighten(lightenAmount), personal_best_gradient_right.Lighten(lightenAmount));

case HighlightType.Friend:
return ColourInfo.GradientHorizontal(colours.Pink1.Lighten(lightenAmount), colours.Pink3.Lighten(lightenAmount));

default:
return Colour4.White;
}
}

public void UpdateHighlightState(bool isHovered, double duration)
{
highlightGradient.FadeColour(getHighlightColour(Highlight, isHovered ? 0.2f : 0), duration, Easing.OutQuint);
}

public void Appear(double duration)
{
this.FadeIn(duration, Easing.OutQuint).ResizeWidthTo(WIDTH, duration, Easing.OutQuint);
}

public void Disappear(double duration)
{
this.FadeOut(duration, Easing.OutQuint).ResizeWidthTo(0, duration, Easing.OutQuint);
}

public enum HighlightType
{
Own,
Friend,
}
}
}
47 changes: 47 additions & 0 deletions osu.Game/Online/Leaderboards/LeaderboardRankLabel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Utils;
using osuTK;

namespace osu.Game.Online.Leaderboards
{
public partial class LeaderboardRankLabel : Container, IHasTooltip
{
private readonly bool darkText;
private readonly OsuSpriteText text;

public LeaderboardRankLabel(int? rank, bool sheared, bool darkText)
{
this.darkText = darkText;
if (rank >= 1000)
TooltipText = $"#{rank:N0}";

Child = text = new OsuSpriteText
{
Shear = sheared ? -OsuGame.SHEAR : Vector2.Zero,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Style.Heading2,
Text = rank?.FormatRank().Insert(0, "#") ?? "-",
Shadow = !darkText,
};
}

[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
text.Colour = darkText ? colourProvider.Background3 : colourProvider.Content1;
}

public LocalisableString TooltipText { get; }
}
}
Loading
Loading