From f3c93c894b273d1373e5e44c302522b46e41becb Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 21 Nov 2017 10:15:16 +0300 Subject: [PATCH 01/11] Rank graph improvements --- osu.Game/Overlays/Profile/ProfileHeader.cs | 13 ++- osu.Game/Overlays/Profile/RankChart.cs | 125 +++++++++++++-------- 2 files changed, 88 insertions(+), 50 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4ddd6c498e..f0b441affb 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays.Profile private readonly OsuTextFlowContainer infoTextLeft; private readonly LinkFlowContainer infoTextRight; private readonly FillFlowContainer scoreText, scoreNumberText; + protected readonly RankChart rankGraph; private readonly Container coverContainer, chartContainer, supporterTag; private readonly Sprite levelBadge; @@ -285,6 +286,10 @@ namespace osu.Game.Overlays.Profile { Colour = Color4.Black.Opacity(0.25f), RelativeSizeAxes = Axes.Both + }, + rankGraph = new RankChart + { + RelativeSizeAxes = Axes.Both } } } @@ -303,11 +308,7 @@ namespace osu.Game.Overlays.Profile public User User { - get - { - return user; - } - + get { return user; } set { user = value; @@ -420,7 +421,7 @@ namespace osu.Game.Overlays.Profile gradeSPlus.DisplayCount = 0; gradeSSPlus.DisplayCount = 0; - chartContainer.Add(new RankChart(user) { RelativeSizeAxes = Axes.Both }); + rankGraph.Redraw(user); } } diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index 8190ef3c62..3981939bf8 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -14,30 +14,40 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Users; +using System.Collections.Generic; namespace osu.Game.Overlays.Profile { public class RankChart : Container { + private const float primary_textsize = 25; + private const float secondary_textsize = 13; + private const float padding = 10; + private const float fade_duration = 150; + private const int rankedDays = 88; + private readonly SpriteText rankText, performanceText, relativeText; private readonly RankChartLineGraph graph; + private readonly OsuSpriteText placeholder; - private readonly int[] ranks; + private KeyValuePair[] ranks; + private User user; - private const float primary_textsize = 25, secondary_textsize = 13, padding = 10; - - private readonly User user; - - public RankChart(User user) + public RankChart() { - this.user = user; - - int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; - ranks = userRanks.SkipWhile(x => x == 0).ToArray(); - Padding = new MarginPadding { Vertical = padding }; Children = new Drawable[] { + placeholder = new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Text = "No recent plays", + TextSize = 14, + Font = @"Exo2.0-RegularItalic", + Alpha = 0, + Padding = new MarginPadding { Bottom = padding } + }, rankText = new OsuSpriteText { Anchor = Anchor.TopCentre, @@ -60,50 +70,73 @@ namespace osu.Game.Overlays.Profile Font = @"Exo2.0-RegularItalic", TextSize = secondary_textsize }, - }; - - if (ranks.Length > 0) - { - Add(graph = new RankChartLineGraph + graph = new RankChartLineGraph { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.X, Y = -secondary_textsize, - DefaultValueCount = ranks.Length, - }); + Alpha = 0, + } + }; - graph.OnBallMove += showHistoryRankTexts; + graph.OnBallMove += showHistoryRankTexts; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + graph.Colour = colours.Yellow; + } + + public void Redraw(User user) + { + if (this.user == null && user != null) + placeholder.FadeOut(fade_duration, Easing.Out); + + this.user = user; + + if (user == null) + { + rankText.Text = string.Empty; + performanceText.Text = string.Empty; + relativeText.Text = string.Empty; + graph.FadeOut(fade_duration, Easing.Out); + placeholder.FadeIn(fade_duration, Easing.Out); + ranks = null; + return; } + + int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; + var tempRanks = userRanks.Select((x, index) => new KeyValuePair(index, x)).SkipWhile(x => x.Value == 0).ToArray(); + ranks = tempRanks.Where(x => x.Value != 0).ToArray(); + + if (ranks.Length > 1) + { + graph.DefaultValueCount = ranks.Length; + graph.Values = ranks.Select(x => -(float)Math.Log(x.Value)); + graph.SetStaticBallPosition(); + graph.FadeIn(fade_duration, Easing.Out); + } + else + { + graph.FadeOut(fade_duration, Easing.Out); + } + + updateRankTexts(); } private void updateRankTexts() { rankText.Text = user.Statistics.Rank > 0 ? $"#{user.Statistics.Rank:#,0}" : "no rank"; performanceText.Text = user.Statistics.PP != null ? $"{user.Statistics.PP:#,0}pp" : string.Empty; - relativeText.Text = user.CountryRank > 0 ? $"{user.Country?.FullName} #{user.CountryRank:#,0}" : $"{user.Country?.FullName}"; + relativeText.Text = $"{user.Country?.FullName} #{user.CountryRank:#,0}"; } private void showHistoryRankTexts(int dayIndex) { - rankText.Text = ranks[dayIndex] > 0 ? $"#{ranks[dayIndex]:#,0}" : "no rank"; - dayIndex++; - relativeText.Text = dayIndex == ranks.Length ? "Now" : $"{ranks.Length - dayIndex} days ago"; - //plural should be handled in a general way - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - if (graph != null) - { - graph.Colour = colours.Yellow; - // use logarithmic coordinates - graph.Values = ranks.Select(x => x == 0 ? float.MinValue : -(float)Math.Log(x)); - graph.SetStaticBallPosition(); - } - - updateRankTexts(); + rankText.Text = $"#{ranks[dayIndex].Value:#,0}"; + relativeText.Text = dayIndex + 1 == ranks.Length ? "Now" : $"{rankedDays - ranks[dayIndex].Key} days ago"; } public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) @@ -118,31 +151,35 @@ namespace osu.Game.Overlays.Profile protected override bool OnHover(InputState state) { - graph?.UpdateBallPosition(state.Mouse.Position.X); - graph?.ShowBall(); + if (ranks != null && ranks.Length > 1) + { + graph.UpdateBallPosition(state.Mouse.Position.X); + graph.ShowBall(); + } return base.OnHover(state); } protected override bool OnMouseMove(InputState state) { - graph?.UpdateBallPosition(state.Mouse.Position.X); + if (ranks != null && ranks.Length > 1) + graph.UpdateBallPosition(state.Mouse.Position.X); + return base.OnMouseMove(state); } protected override void OnHoverLost(InputState state) { - if (graph != null) + if (ranks != null && ranks.Length > 1) { graph.HideBall(); updateRankTexts(); } + base.OnHoverLost(state); } private class RankChartLineGraph : LineGraph { - private const double fade_duration = 200; - private readonly CircularContainer staticBall; private readonly CircularContainer movingBall; From 5ffdaf711e59f1dd909f4ed1cf758fa54e4877ce Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 21 Nov 2017 10:30:12 +0300 Subject: [PATCH 02/11] Remove useless array --- osu.Game/Overlays/Profile/RankChart.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index 3981939bf8..6547b0aa07 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -108,8 +108,7 @@ namespace osu.Game.Overlays.Profile } int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; - var tempRanks = userRanks.Select((x, index) => new KeyValuePair(index, x)).SkipWhile(x => x.Value == 0).ToArray(); - ranks = tempRanks.Where(x => x.Value != 0).ToArray(); + ranks = userRanks.Select((x, index) => new KeyValuePair(index, x)).Where(x => x.Value != 0).ToArray(); if (ranks.Length > 1) { From e48c515d5291ac8d045fa8433834a8731fee63aa Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 21 Nov 2017 10:36:53 +0300 Subject: [PATCH 03/11] CI fixes --- osu.Game/Overlays/Profile/ProfileHeader.cs | 6 +++--- osu.Game/Overlays/Profile/RankChart.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index f0b441affb..40843e5b98 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -27,9 +27,9 @@ namespace osu.Game.Overlays.Profile private readonly OsuTextFlowContainer infoTextLeft; private readonly LinkFlowContainer infoTextRight; private readonly FillFlowContainer scoreText, scoreNumberText; - protected readonly RankChart rankGraph; + private readonly RankChart rankGraph; - private readonly Container coverContainer, chartContainer, supporterTag; + private readonly Container coverContainer, supporterTag; private readonly Sprite levelBadge; private readonly SpriteText levelText; private readonly GradeBadge gradeSSPlus, gradeSS, gradeSPlus, gradeS, gradeA; @@ -274,7 +274,7 @@ namespace osu.Game.Overlays.Profile } } }, - chartContainer = new Container + new Container { RelativeSizeAxes = Axes.X, Anchor = Anchor.BottomCentre, diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index 6547b0aa07..c7a1c88818 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Profile private const float secondary_textsize = 13; private const float padding = 10; private const float fade_duration = 150; - private const int rankedDays = 88; + private const int ranked_days = 88; private readonly SpriteText rankText, performanceText, relativeText; private readonly RankChartLineGraph graph; @@ -135,7 +135,7 @@ namespace osu.Game.Overlays.Profile private void showHistoryRankTexts(int dayIndex) { rankText.Text = $"#{ranks[dayIndex].Value:#,0}"; - relativeText.Text = dayIndex + 1 == ranks.Length ? "Now" : $"{rankedDays - ranks[dayIndex].Key} days ago"; + relativeText.Text = dayIndex + 1 == ranks.Length ? "Now" : $"{ranked_days - ranks[dayIndex].Key} days ago"; } public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) From 94a974a397973d26569372aaa7be95f0f4eb760d Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 21 Nov 2017 13:33:34 +0300 Subject: [PATCH 04/11] Use bindable for a user --- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- osu.Game/Overlays/Profile/RankChart.cs | 30 ++++++++++------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 40843e5b98..509e05329b 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -421,7 +421,7 @@ namespace osu.Game.Overlays.Profile gradeSPlus.DisplayCount = 0; gradeSSPlus.DisplayCount = 0; - rankGraph.Redraw(user); + rankGraph.User.Value = user; } } diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index c7a1c88818..0ff7914fa9 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -15,6 +15,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Users; using System.Collections.Generic; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Profile { @@ -31,7 +32,7 @@ namespace osu.Game.Overlays.Profile private readonly OsuSpriteText placeholder; private KeyValuePair[] ranks; - private User user; + public Bindable User = new Bindable(); public RankChart() { @@ -81,6 +82,8 @@ namespace osu.Game.Overlays.Profile }; graph.OnBallMove += showHistoryRankTexts; + + User.ValueChanged += userChanged; } [BackgroundDependencyLoader] @@ -89,25 +92,21 @@ namespace osu.Game.Overlays.Profile graph.Colour = colours.Yellow; } - public void Redraw(User user) + private void userChanged(User newUser) { - if (this.user == null && user != null) - placeholder.FadeOut(fade_duration, Easing.Out); + placeholder.FadeTo(newUser == null ? 1 : 0, fade_duration, Easing.Out); - this.user = user; - - if (user == null) + if (newUser == null) { rankText.Text = string.Empty; performanceText.Text = string.Empty; relativeText.Text = string.Empty; graph.FadeOut(fade_duration, Easing.Out); - placeholder.FadeIn(fade_duration, Easing.Out); ranks = null; return; } - int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; + int[] userRanks = newUser.RankHistory?.Data ?? new[] { newUser.Statistics.Rank }; ranks = userRanks.Select((x, index) => new KeyValuePair(index, x)).Where(x => x.Value != 0).ToArray(); if (ranks.Length > 1) @@ -115,21 +114,18 @@ namespace osu.Game.Overlays.Profile graph.DefaultValueCount = ranks.Length; graph.Values = ranks.Select(x => -(float)Math.Log(x.Value)); graph.SetStaticBallPosition(); - graph.FadeIn(fade_duration, Easing.Out); - } - else - { - graph.FadeOut(fade_duration, Easing.Out); } + graph.FadeTo(ranks.Length > 1 ? 1 : 0, fade_duration, Easing.Out); + updateRankTexts(); } private void updateRankTexts() { - rankText.Text = user.Statistics.Rank > 0 ? $"#{user.Statistics.Rank:#,0}" : "no rank"; - performanceText.Text = user.Statistics.PP != null ? $"{user.Statistics.PP:#,0}pp" : string.Empty; - relativeText.Text = $"{user.Country?.FullName} #{user.CountryRank:#,0}"; + rankText.Text = User.Value.Statistics.Rank > 0 ? $"#{User.Value.Statistics.Rank:#,0}" : "no rank"; + performanceText.Text = User.Value.Statistics.PP != null ? $"{User.Value.Statistics.PP:#,0}pp" : string.Empty; + relativeText.Text = $"{User.Value.Country?.FullName} #{User.Value.CountryRank:#,0}"; } private void showHistoryRankTexts(int dayIndex) From 938c5feea4fddc4eae862cb3d9171b1fabdbe1d8 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 21 Nov 2017 13:42:42 +0300 Subject: [PATCH 05/11] Simplify interaction condition --- osu.Game/Overlays/Profile/RankChart.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index 0ff7914fa9..92655f2993 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -146,7 +146,7 @@ namespace osu.Game.Overlays.Profile protected override bool OnHover(InputState state) { - if (ranks != null && ranks.Length > 1) + if (ranks?.Length > 1) { graph.UpdateBallPosition(state.Mouse.Position.X); graph.ShowBall(); @@ -156,7 +156,7 @@ namespace osu.Game.Overlays.Profile protected override bool OnMouseMove(InputState state) { - if (ranks != null && ranks.Length > 1) + if (ranks?.Length > 1) graph.UpdateBallPosition(state.Mouse.Position.X); return base.OnMouseMove(state); @@ -164,7 +164,7 @@ namespace osu.Game.Overlays.Profile protected override void OnHoverLost(InputState state) { - if (ranks != null && ranks.Length > 1) + if (ranks?.Length > 1) { graph.HideBall(); updateRankTexts(); From 8c50fa0b84d31ac19f05a90e6c1a71a3a7e13047 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 22 Nov 2017 07:04:54 +0300 Subject: [PATCH 06/11] Add testcase --- osu.Game.Tests/Visual/TestCaseRankGraph.cs | 118 +++++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + osu.Game/Overlays/Profile/RankChart.cs | 1 - 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/TestCaseRankGraph.cs diff --git a/osu.Game.Tests/Visual/TestCaseRankGraph.cs b/osu.Game.Tests/Visual/TestCaseRankGraph.cs new file mode 100644 index 0000000000..5cdb6269f7 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseRankGraph.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Overlays.Profile; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using OpenTK; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using System.Collections.Generic; +using System; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseRankGraph : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(RankChart) }; + + public TestCaseRankGraph() + { + RankChart graph; + + var data = new int[89]; + var dataWithZeros = new int[89]; + var smallData = new int[89]; + + for(int i = 0; i < 89; i++) + data[i] = dataWithZeros[i] = (i + 1) * 1000; + + for (int i = 20; i < 60; i++) + dataWithZeros[i] = 0; + + for (int i = 79; i < 89; i++) + smallData[i] = 100000 - i * 1000; + + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(300, 150), + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }, + graph = new RankChart + { + RelativeSizeAxes = Axes.Both, + } + } + }); + + AddStep("null user", () => graph.User.Value = null); + AddStep("rank only", () => + { + graph.User.Value = new User + { + Statistics = new UserStatistics + { + Rank = 123456, + PP = 12345, + } + }; + }); + + AddStep("with rank history", () => + { + graph.User.Value = new User + { + Statistics = new UserStatistics + { + Rank = 89000, + PP = 12345, + }, + RankHistory = new User.RankHistoryData + { + Data = data, + } + }; + }); + + AddStep("with zero values", () => + { + graph.User.Value = new User + { + Statistics = new UserStatistics + { + Rank = 89000, + PP = 12345, + }, + RankHistory = new User.RankHistoryData + { + Data = dataWithZeros, + } + }; + }); + + AddStep("small amount of data", () => + { + graph.User.Value = new User + { + Statistics = new UserStatistics + { + Rank = 12000, + PP = 12345, + }, + RankHistory = new User.RankHistoryData + { + Data = smallData, + } + }; + }); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index e78b9d5c0e..31915b44cc 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -130,6 +130,7 @@ + diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index 92655f2993..73030acadd 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -46,7 +46,6 @@ namespace osu.Game.Overlays.Profile Text = "No recent plays", TextSize = 14, Font = @"Exo2.0-RegularItalic", - Alpha = 0, Padding = new MarginPadding { Bottom = padding } }, rankText = new OsuSpriteText From 1a318c5c2b87f4fa4161552ac717c5846fe54999 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Dec 2017 18:58:35 +0900 Subject: [PATCH 07/11] Improve LineGraph invalidation logic --- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 11 ++++++ osu.Game/Graphics/UserInterface/LineGraph.cs | 38 ++++++++++++++------ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index 697b84941c..7f2e7779d9 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -2,14 +2,25 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; +using osu.Game.Overlays.Profile; using osu.Game.Users; namespace osu.Game.Tests.Visual { public class TestCaseUserProfile : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ProfileHeader), + typeof(UserProfileOverlay), + typeof(RankChart), + typeof(LineGraph), + }; + public TestCaseUserProfile() { var profile = new UserProfileOverlay(); diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index aa9256e576..ea74c67f6c 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Caching; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -47,7 +48,16 @@ namespace osu.Game.Graphics.UserInterface set { values = value.ToArray(); - applyPath(); + + float max = values.Max(), min = values.Min(); + if (MaxValue > max) max = MaxValue.Value; + if (MinValue < min) min = MinValue.Value; + + ActualMaxValue = max; + ActualMinValue = min; + + pathCached.Invalidate(); + maskingContainer.Width = 0; maskingContainer.ResizeWidthTo(1, transform_duration, Easing.OutQuint); } @@ -63,13 +73,28 @@ namespace osu.Game.Graphics.UserInterface }); } + private bool pending; + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { - if ((invalidation & Invalidation.DrawSize) != 0) - applyPath(); + if ((invalidation & Invalidation.DrawSize) > 0) + pathCached.Invalidate(); + return base.Invalidate(invalidation, source, shallPropagate); } + private Cached pathCached = new Cached(); + + protected override void Update() + { + base.Update(); + if (!pathCached.IsValid) + { + applyPath(); + pathCached.Validate(); + } + } + private void applyPath() { path.ClearVertices(); @@ -77,13 +102,6 @@ namespace osu.Game.Graphics.UserInterface int count = Math.Max(values.Length, DefaultValueCount); - float max = values.Max(), min = values.Min(); - if (MaxValue > max) max = MaxValue.Value; - if (MinValue < min) min = MinValue.Value; - - ActualMaxValue = max; - ActualMinValue = min; - for (int i = 0; i < values.Length; i++) { float x = (i + count - values.Length) / (float)(count - 1) * DrawWidth - 1; From 728d1cb7f65110cb3f49459e776eff311f647dfd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Dec 2017 19:24:54 +0900 Subject: [PATCH 08/11] Formatting and more dynamically testable references --- osu.Game.Tests/Visual/TestCaseRankGraph.cs | 13 +++++++++---- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseRankGraph.cs b/osu.Game.Tests/Visual/TestCaseRankGraph.cs index 5cdb6269f7..489fba6501 100644 --- a/osu.Game.Tests/Visual/TestCaseRankGraph.cs +++ b/osu.Game.Tests/Visual/TestCaseRankGraph.cs @@ -9,23 +9,28 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using System.Collections.Generic; using System; +using osu.Game.Graphics.UserInterface; using osu.Game.Users; namespace osu.Game.Tests.Visual { public class TestCaseRankGraph : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(RankChart) }; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RankGraph), + typeof(LineGraph) + }; public TestCaseRankGraph() { - RankChart graph; + RankGraph graph; var data = new int[89]; var dataWithZeros = new int[89]; var smallData = new int[89]; - for(int i = 0; i < 89; i++) + for (int i = 0; i < 89; i++) data[i] = dataWithZeros[i] = (i + 1) * 1000; for (int i = 20; i < 60; i++) @@ -46,7 +51,7 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(0.2f) }, - graph = new RankChart + graph = new RankGraph { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index 7f2e7779d9..38d59f03b5 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual { typeof(ProfileHeader), typeof(UserProfileOverlay), - typeof(RankChart), + typeof(RankGraph), typeof(LineGraph), }; From 82909f6585eb372a91e37d3479d448300e7f217d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Dec 2017 19:25:18 +0900 Subject: [PATCH 09/11] RankChart -> RankGraph --- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- .../Profile/{RankChart.cs => RankGraph.cs} | 24 +++++++------------ osu.Game/osu.Game.csproj | 2 +- 3 files changed, 11 insertions(+), 19 deletions(-) rename osu.Game/Overlays/Profile/{RankChart.cs => RankGraph.cs} (88%) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 509e05329b..a706799664 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Profile private readonly OsuTextFlowContainer infoTextLeft; private readonly LinkFlowContainer infoTextRight; private readonly FillFlowContainer scoreText, scoreNumberText; - private readonly RankChart rankGraph; + private readonly RankGraph rankGraph; private readonly Container coverContainer, supporterTag; private readonly Sprite levelBadge; @@ -287,7 +287,7 @@ namespace osu.Game.Overlays.Profile Colour = Color4.Black.Opacity(0.25f), RelativeSizeAxes = Axes.Both }, - rankGraph = new RankChart + rankGraph = new RankGraph { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankGraph.cs similarity index 88% rename from osu.Game/Overlays/Profile/RankChart.cs rename to osu.Game/Overlays/Profile/RankGraph.cs index 73030acadd..b5933d6fec 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankGraph.cs @@ -19,7 +19,7 @@ using osu.Framework.Configuration; namespace osu.Game.Overlays.Profile { - public class RankChart : Container + public class RankGraph : Container { private const float primary_textsize = 25; private const float secondary_textsize = 13; @@ -34,19 +34,18 @@ namespace osu.Game.Overlays.Profile private KeyValuePair[] ranks; public Bindable User = new Bindable(); - public RankChart() + public RankGraph() { Padding = new MarginPadding { Vertical = padding }; Children = new Drawable[] { placeholder = new OsuSpriteText { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Text = "No recent plays", TextSize = 14, Font = @"Exo2.0-RegularItalic", - Padding = new MarginPadding { Bottom = padding } }, rankText = new OsuSpriteText { @@ -75,6 +74,7 @@ namespace osu.Game.Overlays.Profile Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.X, + Height = 75, Y = -secondary_textsize, Alpha = 0, } @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.Profile private void userChanged(User newUser) { - placeholder.FadeTo(newUser == null ? 1 : 0, fade_duration, Easing.Out); + placeholder.FadeIn(fade_duration, Easing.Out); if (newUser == null) { @@ -110,6 +110,8 @@ namespace osu.Game.Overlays.Profile if (ranks.Length > 1) { + placeholder.FadeOut(fade_duration, Easing.Out); + graph.DefaultValueCount = ranks.Length; graph.Values = ranks.Select(x => -(float)Math.Log(x.Value)); graph.SetStaticBallPosition(); @@ -133,16 +135,6 @@ namespace osu.Game.Overlays.Profile relativeText.Text = dayIndex + 1 == ranks.Length ? "Now" : $"{ranked_days - ranks[dayIndex].Key} days ago"; } - public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) - { - if ((invalidation & Invalidation.DrawSize) != 0) - { - graph.Height = DrawHeight - padding * 2 - primary_textsize - secondary_textsize * 2; - } - - return base.Invalidate(invalidation, source, shallPropagate); - } - protected override bool OnHover(InputState state) { if (ranks?.Length > 1) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 199d51a8c1..1004d9dc95 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -499,7 +499,7 @@ - + From e5faced9bab698b14bcaf91b8eb1e73eb643650b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Dec 2017 19:25:59 +0900 Subject: [PATCH 10/11] Better variable name --- osu.Game/Overlays/Profile/RankGraph.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/RankGraph.cs b/osu.Game/Overlays/Profile/RankGraph.cs index b5933d6fec..d216789b1a 100644 --- a/osu.Game/Overlays/Profile/RankGraph.cs +++ b/osu.Game/Overlays/Profile/RankGraph.cs @@ -91,11 +91,11 @@ namespace osu.Game.Overlays.Profile graph.Colour = colours.Yellow; } - private void userChanged(User newUser) + private void userChanged(User user) { placeholder.FadeIn(fade_duration, Easing.Out); - if (newUser == null) + if (user == null) { rankText.Text = string.Empty; performanceText.Text = string.Empty; @@ -105,7 +105,7 @@ namespace osu.Game.Overlays.Profile return; } - int[] userRanks = newUser.RankHistory?.Data ?? new[] { newUser.Statistics.Rank }; + int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; ranks = userRanks.Select((x, index) => new KeyValuePair(index, x)).Where(x => x.Value != 0).ToArray(); if (ranks.Length > 1) From def2e5bd179857d2c56a41a056c2a23a385a8437 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 22 Dec 2017 22:15:22 +0900 Subject: [PATCH 11/11] Make editor discard approach circles Temporary solution for now. --- osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs | 2 ++ osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs index d5fc1b606b..0d7fa6c334 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs @@ -9,5 +9,7 @@ namespace osu.Game.Rulesets.Osu.Edit public class OsuEditPlayfield : OsuPlayfield { protected override CursorContainer CreateCursor() => null; + + protected override bool ProxyApproachCircles => false; } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index f03acb2fa0..0dc6feee75 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -25,6 +25,10 @@ namespace osu.Game.Rulesets.Osu.UI public override bool ProvidingUserCursor => true; + // Todo: This should not be a thing, but is currently required for the editor + // https://github.com/ppy/osu-framework/issues/1283 + protected virtual bool ProxyApproachCircles => true; + public static readonly Vector2 BASE_SIZE = new Vector2(512, 384); public override Vector2 Size @@ -80,7 +84,7 @@ namespace osu.Game.Rulesets.Osu.UI h.Depth = (float)h.HitObject.StartTime; var c = h as IDrawableHitObjectWithProxiedApproach; - if (c != null) + if (c != null && ProxyApproachCircles) approachCircles.Add(c.ProxiedLayer.CreateProxy()); base.Add(h);