1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 08:07:24 +08:00

Merge pull request #1472 from EVAST9919/user-overlay-crash-fix

RankChartLineGraph improvements
This commit is contained in:
Dan Balasescu 2017-11-09 19:37:38 +09:00 committed by GitHub
commit f430529776
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenTK; using OpenTK;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -33,6 +32,9 @@ namespace osu.Game.Overlays.Profile
{ {
this.user = user; this.user = user;
int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank };
ranks = userRanks.SkipWhile(x => x == 0).ToArray();
Padding = new MarginPadding { Vertical = padding }; Padding = new MarginPadding { Vertical = padding };
Children = new Drawable[] Children = new Drawable[]
{ {
@ -58,19 +60,21 @@ namespace osu.Game.Overlays.Profile
Font = @"Exo2.0-RegularItalic", Font = @"Exo2.0-RegularItalic",
TextSize = secondary_textsize TextSize = secondary_textsize
}, },
graph = new RankChartLineGraph };
if (ranks.Length > 0)
{
Add(graph = new RankChartLineGraph
{ {
Anchor = Anchor.BottomCentre, Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Y = -secondary_textsize, Y = -secondary_textsize,
DefaultValueCount = 90, DefaultValueCount = ranks.Length,
BallRelease = updateRankTexts, });
BallMove = showHistoryRankTexts
}
};
ranks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; graph.OnBallMove += showHistoryRankTexts;
}
} }
private void updateRankTexts() private void updateRankTexts()
@ -82,7 +86,8 @@ namespace osu.Game.Overlays.Profile
private void showHistoryRankTexts(int dayIndex) private void showHistoryRankTexts(int dayIndex)
{ {
rankText.Text = ranks[dayIndex] > 0 ? $"#{ranks[dayIndex]:#,0}" : "no rank"; rankText.Text = $"#{ranks[dayIndex]:#,0}";
dayIndex++;
relativeText.Text = dayIndex == ranks.Length ? "Now" : $"{ranks.Length - dayIndex} days ago"; relativeText.Text = dayIndex == ranks.Length ? "Now" : $"{ranks.Length - dayIndex} days ago";
//plural should be handled in a general way //plural should be handled in a general way
} }
@ -90,14 +95,15 @@ namespace osu.Game.Overlays.Profile
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
graph.Colour = colours.Yellow; if (graph != null)
if (user.Statistics.Rank > 0)
{ {
graph.Colour = colours.Yellow;
// use logarithmic coordinates // use logarithmic coordinates
graph.Values = ranks.Select(x => -(float)Math.Log(x)); graph.Values = ranks.Select(x => -(float)Math.Log(x));
graph.ResetBall(); graph.SetStaticBallPosition();
} }
updateRankTexts();
} }
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
@ -110,67 +116,78 @@ namespace osu.Game.Overlays.Profile
return base.Invalidate(invalidation, source, shallPropagate); return base.Invalidate(invalidation, source, shallPropagate);
} }
protected override bool OnHover(InputState state)
{
graph?.UpdateBallPosition(state.Mouse.Position.X);
graph?.ShowBall();
return base.OnHover(state);
}
protected override bool OnMouseMove(InputState state)
{
graph?.UpdateBallPosition(state.Mouse.Position.X);
return base.OnMouseMove(state);
}
protected override void OnHoverLost(InputState state)
{
if (graph != null)
{
graph.HideBall();
updateRankTexts();
}
base.OnHoverLost(state);
}
private class RankChartLineGraph : LineGraph private class RankChartLineGraph : LineGraph
{ {
private readonly CircularContainer ball; private const double fade_duration = 200;
private bool ballShown;
private const double transform_duration = 100; private readonly CircularContainer staticBall;
private readonly CircularContainer movingBall;
public Action<int> BallMove; public Action<int> OnBallMove;
public Action BallRelease;
public RankChartLineGraph() public RankChartLineGraph()
{ {
Add(ball = new CircularContainer Add(staticBall = new CircularContainer
{ {
Origin = Anchor.Centre,
Size = new Vector2(8), Size = new Vector2(8),
Masking = true, Masking = true,
Origin = Anchor.Centre,
Alpha = 0,
RelativePositionAxes = Axes.Both, RelativePositionAxes = Axes.Both,
Children = new Drawable[] Child = new Box { RelativeSizeAxes = Axes.Both }
{ });
new Box { RelativeSizeAxes = Axes.Both } Add(movingBall = new CircularContainer
} {
Origin = Anchor.Centre,
Size = new Vector2(8),
Alpha = 0,
Masking = true,
RelativePositionAxes = Axes.Both,
Child = new Box { RelativeSizeAxes = Axes.Both }
}); });
} }
public void ResetBall() public void SetStaticBallPosition() => staticBall.Position = new Vector2(1, GetYPosition(Values.Last()));
public void UpdateBallPosition(float mouseXPosition)
{ {
ball.MoveTo(new Vector2(1, GetYPosition(Values.Last())), ballShown ? transform_duration : 0, Easing.OutQuint); int index = calculateIndex(mouseXPosition);
ball.Show(); movingBall.Position = calculateBallPosition(index);
BallRelease(); OnBallMove.Invoke(index);
ballShown = true;
} }
protected override bool OnMouseMove(InputState state) public void ShowBall() => movingBall.FadeIn(fade_duration);
{
if (ballShown)
{
var values = (IList<float>)Values;
var position = ToLocalSpace(state.Mouse.NativeState.Position);
int count = Math.Max(values.Count, DefaultValueCount);
int index = (int)Math.Round(position.X / DrawWidth * (count - 1));
if (index >= count - values.Count)
{
int i = index + values.Count - count;
float y = GetYPosition(values[i]);
if (Math.Abs(y * DrawHeight - position.Y) <= 8f)
{
ball.MoveTo(new Vector2(index / (float)(count - 1), y), transform_duration, Easing.OutQuint);
BallMove(i);
}
}
}
return base.OnMouseMove(state);
}
protected override void OnHoverLost(InputState state) public void HideBall() => movingBall.FadeOut(fade_duration);
private int calculateIndex(float mouseXPosition) => (int)Math.Round(mouseXPosition / DrawWidth * (DefaultValueCount - 1));
private Vector2 calculateBallPosition(int index)
{ {
if (ballShown) float y = GetYPosition(Values.ElementAt(index));
ResetBall(); return new Vector2(index / (float)(DefaultValueCount - 1), y);
base.OnHoverLost(state);
} }
} }
} }