From 4cdaebb42bf681a04e2e4043fd18f204c928fa6e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 02:58:10 +0300 Subject: [PATCH] Implement ProfileScore component --- .../Online/TestSceneUserProfileScores.cs | 82 ++++++ osu.Game/Graphics/DrawableDate.cs | 4 +- .../Profile/Sections/Ranks/ProfileScore.cs | 242 ++++++++++++++++++ 3 files changed, 326 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs new file mode 100644 index 0000000000..f8e3da5241 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -0,0 +1,82 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Game.Overlays.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Ranks; +using osu.Framework.Graphics; +using osu.Game.Scoring; +using osu.Framework.Graphics.Containers; +using osuTK; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneUserProfileScores : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ProfileScore), + typeof(ProfileItemBackground), + }; + + public TestSceneUserProfileScores() + { + var score = new ScoreInfo + { + PP = 134.32, + Rank = ScoreRank.A, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "Triumph & Regret", + Artist = "typeMARS" + }, + Version = "[4K] Regret" + }, + Date = DateTimeOffset.Now, + Mods = new Mod[] + { + new OsuModHardRock(), + new OsuModDoubleTime(), + }, + Accuracy = 0.998546 + }; + + var noPPScore = new ScoreInfo + { + Rank = ScoreRank.B, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "C18H27NO3(extend)", + Artist = "Team Grimoire" + }, + Version = "[4K] Cataclysmic Hypernova" + }, + Date = DateTimeOffset.Now, + Accuracy = 0.55879 + }; + + Add(new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new[] + { + new ProfileScore(score), + new ProfileScore(noPPScore), + } + }); + } + } +} diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 533f02af7b..925c7981e0 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -29,9 +29,9 @@ namespace osu.Game.Graphics } } - public DrawableDate(DateTimeOffset date) + public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE) { - Font = OsuFont.GetFont(weight: FontWeight.Regular, italics: true); + Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: true); Date = date; } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs new file mode 100644 index 0000000000..c30c13d52e --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs @@ -0,0 +1,242 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Sections.Ranks +{ + public class ProfileScore : CompositeDrawable + { + private const int performance_width = 80; + private const int content_padding = 10; + + protected readonly ScoreInfo Score; + + [Resolved] + private OsuColour colours { get; set; } + + public ProfileScore(ScoreInfo score) + { + Score = score; + + RelativeSizeAxes = Axes.X; + Height = 40; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(new ProfileItemBackground + { + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding }, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(8, 0), + Children = new Drawable[] + { + new UpdateableRank(Score.Rank) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(50, 20), + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Children = new Drawable[] + { + new ScoreBeatmapMetadataContainer(Score.Beatmap), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new OsuSpriteText + { + Text = $"{Score.Beatmap.Version}", + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), + Colour = colours.Yellow + }, + new DrawableDate(Score.Date, 12) + { + Colour = colours.GreySeafoamLighter + } + } + } + } + } + } + }, + new FillFlowContainer + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10), + Children = new Drawable[] + { + CreateRightContent().With(c => + { + c.Anchor = Anchor.CentreRight; + c.Origin = Anchor.CentreRight; + }), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(2), + Children = Score.Mods.Select(mod => new ModIcon(mod) + { + Scale = new Vector2(0.35f) + }).ToList(), + } + } + } + } + }, + new Container + { + RelativeSizeAxes = Axes.Y, + Width = performance_width, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1, 0.5f), + Colour = Color4.Black.Opacity(0.5f), + Shear = new Vector2(-0.45f, 0), + EdgeSmoothness = new Vector2(2, 0), + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Y, + Size = new Vector2(1, -0.5f), + Position = new Vector2(0, 1), + Colour = Color4.Black.Opacity(0.5f), + Shear = new Vector2(0.45f, 0), + EdgeSmoothness = new Vector2(2, 0), + }, + createDrawablePerformance().With(d => + { + d.Anchor = Anchor.Centre; + d.Origin = Anchor.Centre; + }) + } + } + } + }); + } + + protected virtual Drawable CreateRightContent() => CreateDrawableAccuracy(); + + protected OsuSpriteText CreateDrawableAccuracy(float textSize = 16) => new OsuSpriteText + { + Text = $"{Score.Accuracy:P2}", + Font = OsuFont.GetFont(size: textSize, weight: FontWeight.Bold, italics: true), + Colour = colours.Yellow, + }; + + private Drawable createDrawablePerformance() + { + if (Score.PP.HasValue) + { + return new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Children = new[] + { + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Text = $"{Score.PP:0}", + Colour = colours.GreenLight + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Text = "pp", + Colour = colours.Green + } + } + }; + } + + return new OsuSpriteText + { + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Text = "-", + Colour = colours.GreenLight + }; + } + + private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer + { + public ScoreBeatmapMetadataContainer(BeatmapInfo beatmap) + : base(beatmap) + { + } + + protected override Drawable[] CreateText(BeatmapInfo beatmap) => new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = new LocalisedString(( + $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ", + $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} ")), + Font = OsuFont.GetFont(weight: FontWeight.SemiBold, italics: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = "by " + new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)), + Font = OsuFont.GetFont(size: 14, italics: true) + }, + }; + } + } +}