mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 23:24:04 +09:00
Merge master into netstandard
This commit is contained in:
@ -27,8 +27,10 @@ namespace osu.Game.Overlays.Profile
|
||||
private readonly OsuTextFlowContainer infoTextLeft;
|
||||
private readonly LinkFlowContainer infoTextRight;
|
||||
private readonly FillFlowContainer<SpriteText> scoreText, scoreNumberText;
|
||||
private readonly RankGraph rankGraph;
|
||||
|
||||
private readonly Container coverContainer, chartContainer, supporterTag;
|
||||
public readonly SupporterIcon SupporterTag;
|
||||
private readonly Container coverContainer;
|
||||
private readonly Sprite levelBadge;
|
||||
private readonly SpriteText levelText;
|
||||
private readonly GradeBadge gradeSSPlus, gradeSS, gradeSPlus, gradeS, gradeA;
|
||||
@ -53,6 +55,7 @@ namespace osu.Game.Overlays.Profile
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = cover_height,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@ -92,32 +95,13 @@ namespace osu.Game.Overlays.Profile
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
supporterTag = new CircularContainer
|
||||
SupporterTag = new SupporterIcon
|
||||
{
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Y = -75,
|
||||
Size = new Vector2(25, 25),
|
||||
Masking = true,
|
||||
BorderThickness = 3,
|
||||
BorderColour = Color4.White,
|
||||
Alpha = 0,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_heart,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(12),
|
||||
}
|
||||
}
|
||||
Size = new Vector2(25, 25)
|
||||
},
|
||||
new LinkFlowContainer.ProfileLink(user)
|
||||
{
|
||||
@ -272,7 +256,7 @@ namespace osu.Game.Overlays.Profile
|
||||
}
|
||||
}
|
||||
},
|
||||
chartContainer = new Container
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
@ -284,6 +268,10 @@ namespace osu.Game.Overlays.Profile
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.25f),
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
rankGraph = new RankGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,11 +290,7 @@ namespace osu.Game.Overlays.Profile
|
||||
|
||||
public User User
|
||||
{
|
||||
get
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
||||
get { return user; }
|
||||
set
|
||||
{
|
||||
user = value;
|
||||
@ -324,10 +308,10 @@ namespace osu.Game.Overlays.Profile
|
||||
FillMode = FillMode.Fill,
|
||||
OnLoadComplete = d => d.FadeInFromZero(200),
|
||||
Depth = float.MaxValue,
|
||||
},
|
||||
coverContainer.Add);
|
||||
}, coverContainer.Add);
|
||||
|
||||
if (user.IsSupporter) supporterTag.Show();
|
||||
if (user.IsSupporter)
|
||||
SupporterTag.Show();
|
||||
|
||||
if (!string.IsNullOrEmpty(user.Colour))
|
||||
{
|
||||
@ -382,7 +366,7 @@ namespace osu.Game.Overlays.Profile
|
||||
}
|
||||
|
||||
tryAddInfoRightLine(FontAwesome.fa_map_marker, user.Location);
|
||||
tryAddInfoRightLine(FontAwesome.fa_heart_o, user.Intrerests);
|
||||
tryAddInfoRightLine(FontAwesome.fa_heart_o, user.Interests);
|
||||
tryAddInfoRightLine(FontAwesome.fa_suitcase, user.Occupation);
|
||||
infoTextRight.NewParagraph();
|
||||
if (!string.IsNullOrEmpty(user.Twitter))
|
||||
@ -420,7 +404,7 @@ namespace osu.Game.Overlays.Profile
|
||||
gradeSPlus.DisplayCount = 0;
|
||||
gradeSSPlus.DisplayCount = 0;
|
||||
|
||||
chartContainer.Add(new RankChart(user) { RelativeSizeAxes = Axes.Both });
|
||||
rankGraph.User.Value = user;
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,7 +456,7 @@ namespace osu.Game.Overlays.Profile
|
||||
Width = width,
|
||||
Height = 26
|
||||
});
|
||||
Add(numberText = new SpriteText
|
||||
Add(numberText = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
@ -514,7 +498,7 @@ namespace osu.Game.Overlays.Profile
|
||||
{
|
||||
set
|
||||
{
|
||||
if(value != null)
|
||||
if (value != null)
|
||||
content.Action = () => Process.Start(value);
|
||||
}
|
||||
}
|
||||
|
@ -14,30 +14,39 @@ using osu.Game.Graphics;
|
||||
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
|
||||
{
|
||||
public class RankChart : Container
|
||||
public class RankGraph : 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 ranked_days = 88;
|
||||
|
||||
private readonly SpriteText rankText, performanceText, relativeText;
|
||||
private readonly RankChartLineGraph graph;
|
||||
private readonly OsuSpriteText placeholder;
|
||||
|
||||
private readonly int[] ranks;
|
||||
private KeyValuePair<int, int>[] ranks;
|
||||
public Bindable<User> User = new Bindable<User>();
|
||||
|
||||
private const float primary_textsize = 25, secondary_textsize = 13, padding = 10;
|
||||
|
||||
private readonly User user;
|
||||
|
||||
public RankChart(User user)
|
||||
public RankGraph()
|
||||
{
|
||||
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.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = "No recent plays",
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-RegularItalic",
|
||||
},
|
||||
rankText = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
@ -60,89 +69,103 @@ 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,
|
||||
Height = 75,
|
||||
Y = -secondary_textsize,
|
||||
DefaultValueCount = ranks.Length,
|
||||
});
|
||||
Alpha = 0,
|
||||
}
|
||||
};
|
||||
|
||||
graph.OnBallMove += showHistoryRankTexts;
|
||||
}
|
||||
}
|
||||
graph.OnBallMove += showHistoryRankTexts;
|
||||
|
||||
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}";
|
||||
}
|
||||
|
||||
private void showHistoryRankTexts(int dayIndex)
|
||||
{
|
||||
rankText.Text = $"#{ranks[dayIndex]:#,0}";
|
||||
dayIndex++;
|
||||
relativeText.Text = dayIndex == ranks.Length ? "Now" : $"{ranks.Length - dayIndex} days ago";
|
||||
//plural should be handled in a general way
|
||||
User.ValueChanged += userChanged;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
if (graph != null)
|
||||
graph.Colour = colours.Yellow;
|
||||
}
|
||||
|
||||
private void userChanged(User user)
|
||||
{
|
||||
placeholder.FadeIn(fade_duration, Easing.Out);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
graph.Colour = colours.Yellow;
|
||||
// use logarithmic coordinates
|
||||
graph.Values = ranks.Select(x => -(float)Math.Log(x));
|
||||
rankText.Text = string.Empty;
|
||||
performanceText.Text = string.Empty;
|
||||
relativeText.Text = string.Empty;
|
||||
graph.FadeOut(fade_duration, Easing.Out);
|
||||
ranks = null;
|
||||
return;
|
||||
}
|
||||
|
||||
int[] userRanks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank };
|
||||
ranks = userRanks.Select((x, index) => new KeyValuePair<int, int>(index, x)).Where(x => x.Value != 0).ToArray();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
graph.FadeTo(ranks.Length > 1 ? 1 : 0, fade_duration, Easing.Out);
|
||||
|
||||
updateRankTexts();
|
||||
}
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
private void updateRankTexts()
|
||||
{
|
||||
if ((invalidation & Invalidation.DrawSize) != 0)
|
||||
{
|
||||
graph.Height = DrawHeight - padding * 2 - primary_textsize - secondary_textsize * 2;
|
||||
}
|
||||
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}";
|
||||
}
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
private void showHistoryRankTexts(int dayIndex)
|
||||
{
|
||||
rankText.Text = $"#{ranks[dayIndex].Value:#,0}";
|
||||
relativeText.Text = dayIndex + 1 == ranks.Length ? "Now" : $"{ranked_days - ranks[dayIndex].Key} days ago";
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
graph?.UpdateBallPosition(state.Mouse.Position.X);
|
||||
graph?.ShowBall();
|
||||
if (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?.Length > 1)
|
||||
graph.UpdateBallPosition(state.Mouse.Position.X);
|
||||
|
||||
return base.OnMouseMove(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
if (graph != null)
|
||||
if (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;
|
||||
|
@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
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.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
{
|
||||
/// <summary>
|
||||
/// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row (see <see cref="DrawableProfileRow"/>).
|
||||
/// </summary>
|
||||
public class BeatmapMetadataContainer : OsuHoverContainer, IHasTooltip
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
|
||||
public BeatmapMetadataContainer(BeatmapInfo beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
TooltipText = $"{beatmap.Metadata.Artist} - {beatmap.Metadata.Title}";
|
||||
}
|
||||
|
||||
public string TooltipText { get; }
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay)
|
||||
{
|
||||
Action = () =>
|
||||
{
|
||||
if (beatmap.OnlineBeatmapSetID.HasValue) beatmapSetOverlay?.ShowBeatmapSet(beatmap.OnlineBeatmapSetID.Value);
|
||||
};
|
||||
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = locale.GetUnicodePreference(
|
||||
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ",
|
||||
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] "
|
||||
),
|
||||
TextSize = 15,
|
||||
Font = "Exo2.0-SemiBoldItalic",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = locale.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist),
|
||||
TextSize = 12,
|
||||
Padding = new MarginPadding { Top = 3 },
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
124
osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs
Normal file
124
osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
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.Input;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
{
|
||||
public abstract class DrawableProfileRow : Container
|
||||
{
|
||||
private const int fade_duration = 200;
|
||||
|
||||
private Box underscoreLine;
|
||||
private readonly Box coloredBackground;
|
||||
private readonly Container background;
|
||||
|
||||
/// <summary>
|
||||
/// A visual element displayed to the left of <see cref="LeftFlowContainer"/> content.
|
||||
/// </summary>
|
||||
protected abstract Drawable CreateLeftVisual();
|
||||
|
||||
protected FillFlowContainer LeftFlowContainer { get; private set; }
|
||||
protected FillFlowContainer RightFlowContainer { get; private set; }
|
||||
|
||||
protected override Container<Drawable> Content { get; }
|
||||
|
||||
protected DrawableProfileRow()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 60;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
background = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 3,
|
||||
Alpha = 0,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
Radius = 1f,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
},
|
||||
Child = coloredBackground = new Box { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
Content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Width = 0.97f,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colour)
|
||||
{
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
underscoreLine = new Box
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 1,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
CreateLeftVisual(),
|
||||
LeftFlowContainer = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 10 },
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
}
|
||||
},
|
||||
RightFlowContainer = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
});
|
||||
|
||||
coloredBackground.Colour = underscoreLine.Colour = colour.Gray4;
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state) => true;
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
background.FadeIn(fade_duration, Easing.OutQuint);
|
||||
underscoreLine.FadeOut(fade_duration, Easing.OutQuint);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
background.FadeOut(fade_duration, Easing.OutQuint);
|
||||
underscoreLine.FadeIn(fade_duration, Easing.OutQuint);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Historical
|
||||
{
|
||||
public class DrawableMostPlayedRow : DrawableProfileRow
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
private readonly int playCount;
|
||||
private OsuHoverContainer mapperContainer;
|
||||
|
||||
public DrawableMostPlayedRow(BeatmapInfo beatmap, int playCount)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
this.playCount = playCount;
|
||||
}
|
||||
|
||||
protected override Drawable CreateLeftVisual() => new DelayedLoadWrapper(new BeatmapSetCover(beatmap.BeatmapSet, BeatmapSetCoverType.List)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fit,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
OnLoadComplete = d => d.FadeInFromZero(500, Easing.OutQuint)
|
||||
})
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Size = new Vector2(80, 50),
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(UserProfileOverlay profileOverlay)
|
||||
{
|
||||
LeftFlowContainer.Add(new BeatmapMetadataContainer(beatmap));
|
||||
LeftFlowContainer.Add(new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = @"mapped by ",
|
||||
TextSize = 12,
|
||||
},
|
||||
mapperContainer = new OsuHoverContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = beatmap.Metadata.AuthorString,
|
||||
TextSize = 12,
|
||||
Font = @"Exo2.0-MediumItalic"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
RightFlowContainer.Add(new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Text = playCount.ToString(),
|
||||
TextSize = 18,
|
||||
Font = @"Exo2.0-SemiBoldItalic"
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Text = @"times played ",
|
||||
TextSize = 12,
|
||||
Font = @"Exo2.0-RegularItalic"
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
if (profileOverlay != null)
|
||||
mapperContainer.Action = () => profileOverlay.ShowUser(beatmap.BeatmapSet.Metadata.Author);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Historical
|
||||
{
|
||||
public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer
|
||||
{
|
||||
public PaginatedMostPlayedBeatmapContainer(Bindable<User> user)
|
||||
:base(user, "Most Played Beatmaps", "No records. :(")
|
||||
{
|
||||
ItemsPerPage = 5;
|
||||
|
||||
ItemsContainer.Direction = FillDirection.Vertical;
|
||||
}
|
||||
|
||||
protected override void ShowMore()
|
||||
{
|
||||
base.ShowMore();
|
||||
|
||||
var req = new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++ * ItemsPerPage);
|
||||
|
||||
req.Success += beatmaps =>
|
||||
{
|
||||
ShowMoreButton.FadeTo(beatmaps.Count == ItemsPerPage ? 1 : 0);
|
||||
ShowMoreLoading.Hide();
|
||||
|
||||
if (!beatmaps.Any() && VisiblePages == 1)
|
||||
{
|
||||
MissingText.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
MissingText.Hide();
|
||||
|
||||
foreach (var beatmap in beatmaps)
|
||||
{
|
||||
ItemsContainer.Add(new DrawableMostPlayedRow(beatmap.GetBeatmapInfo(Rulesets), beatmap.PlayCount));
|
||||
}
|
||||
};
|
||||
|
||||
Api.Queue(req);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.Profile.Sections.Historical;
|
||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
@ -14,7 +16,11 @@ namespace osu.Game.Overlays.Profile.Sections
|
||||
|
||||
public HistoricalSection()
|
||||
{
|
||||
Child = new PaginatedScoreContainer(ScoreType.Recent, User, "Recent Plays (24h)", "No performance records. :(");
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new PaginatedMostPlayedBeatmapContainer(User),
|
||||
new PaginatedScoreContainer(ScoreType.Recent, User, "Recent Plays (24h)", "No performance records. :("),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
|
||||
@ -120,7 +121,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
||||
}
|
||||
}
|
||||
},
|
||||
new TextFlowContainer(t => { t.TextSize = 19; })
|
||||
new OsuTextFlowContainer(t => { t.TextSize = 19; })
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
|
@ -9,7 +9,7 @@ using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
{
|
||||
public class DrawablePerformanceScore : DrawableScore
|
||||
public class DrawablePerformanceScore : DrawableProfileScore
|
||||
{
|
||||
private readonly double? weight;
|
||||
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
private void load(OsuColour colour)
|
||||
{
|
||||
double pp = Score.PP ?? 0;
|
||||
Stats.Add(new OsuSpriteText
|
||||
RightFlowContainer.Add(new OsuSpriteText
|
||||
{
|
||||
Text = $"{pp:0}pp",
|
||||
Anchor = Anchor.TopRight,
|
||||
@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
|
||||
if (weight.HasValue)
|
||||
{
|
||||
Stats.Add(new OsuSpriteText
|
||||
RightFlowContainer.Add(new OsuSpriteText
|
||||
{
|
||||
Text = $"weighted: {pp * weight:0}pp ({weight:P0})",
|
||||
Anchor = Anchor.TopRight,
|
||||
|
@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
{
|
||||
public abstract class DrawableProfileScore : DrawableProfileRow
|
||||
{
|
||||
private readonly FillFlowContainer metadata;
|
||||
private readonly ScoreModsContainer modsContainer;
|
||||
protected readonly Score Score;
|
||||
|
||||
protected DrawableProfileScore(Score score)
|
||||
{
|
||||
Score = score;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 60;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
modsContainer = new ScoreModsContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Width = 60,
|
||||
Margin = new MarginPadding { Right = 160 }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colour)
|
||||
{
|
||||
RightFlowContainer.Add(new OsuSpriteText
|
||||
{
|
||||
Text = $"accuracy: {Score.Accuracy:P2}",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Colour = colour.GrayA,
|
||||
TextSize = 11,
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
Depth = -1,
|
||||
});
|
||||
|
||||
LeftFlowContainer.Add(new BeatmapMetadataContainer(Score.Beatmap));
|
||||
LeftFlowContainer.Add(new OsuSpriteText
|
||||
{
|
||||
Text = Score.Date.LocalDateTime.ToShortDateString(),
|
||||
TextSize = 11,
|
||||
Colour = OsuColour.Gray(0xAA),
|
||||
});
|
||||
|
||||
foreach (Mod mod in Score.Mods)
|
||||
modsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.5f) });
|
||||
}
|
||||
|
||||
protected override Drawable CreateLeftVisual() => new DrawableRank(Score.Rank)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 60,
|
||||
FillMode = FillMode.Fit,
|
||||
};
|
||||
}
|
||||
}
|
@ -1,195 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
{
|
||||
public abstract class DrawableScore : Container
|
||||
{
|
||||
private const int fade_duration = 200;
|
||||
|
||||
protected readonly FillFlowContainer<OsuSpriteText> Stats;
|
||||
private readonly FillFlowContainer metadata;
|
||||
private readonly ScoreModsContainer modsContainer;
|
||||
protected readonly Score Score;
|
||||
private readonly Box underscoreLine;
|
||||
private readonly Box coloredBackground;
|
||||
private readonly Container background;
|
||||
|
||||
protected DrawableScore(Score score)
|
||||
{
|
||||
Score = score;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 60;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 3,
|
||||
Alpha = 0,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
Radius = 1f,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
},
|
||||
Child = coloredBackground = new Box { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Width = 0.97f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
underscoreLine = new Box
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 1,
|
||||
},
|
||||
new DrawableRank(score.Rank)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 60,
|
||||
FillMode = FillMode.Fit,
|
||||
},
|
||||
Stats = new FillFlowContainer<OsuSpriteText>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
metadata = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 70 },
|
||||
Direction = FillDirection.Vertical,
|
||||
Child = new OsuSpriteText
|
||||
{
|
||||
Text = score.Date.LocalDateTime.ToShortDateString(),
|
||||
TextSize = 11,
|
||||
Colour = OsuColour.Gray(0xAA),
|
||||
Depth = -1,
|
||||
},
|
||||
},
|
||||
modsContainer = new ScoreModsContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Width = 60,
|
||||
Margin = new MarginPadding { Right = 160 }
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colour, LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay)
|
||||
{
|
||||
coloredBackground.Colour = underscoreLine.Colour = colour.Gray4;
|
||||
|
||||
Stats.Add(new OsuSpriteText
|
||||
{
|
||||
Text = $"accuracy: {Score.Accuracy:P2}",
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Colour = colour.GrayA,
|
||||
TextSize = 11,
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
Depth = -1,
|
||||
});
|
||||
|
||||
metadata.Add(new MetadataContainer(Score.Beatmap.Metadata.Title, Score.Beatmap.Metadata.Artist)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Action = () =>
|
||||
{
|
||||
if (Score.Beatmap.OnlineBeatmapSetID.HasValue) beatmapSetOverlay?.ShowBeatmapSet(Score.Beatmap.OnlineBeatmapSetID.Value);
|
||||
},
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = locale.GetUnicodePreference(
|
||||
$"{Score.Beatmap.Metadata.TitleUnicode ?? Score.Beatmap.Metadata.Title} [{Score.Beatmap.Version}] ",
|
||||
$"{Score.Beatmap.Metadata.Title ?? Score.Beatmap.Metadata.TitleUnicode} [{Score.Beatmap.Version}] "
|
||||
),
|
||||
TextSize = 15,
|
||||
Font = "Exo2.0-SemiBoldItalic",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Current = locale.GetUnicodePreference(Score.Beatmap.Metadata.ArtistUnicode, Score.Beatmap.Metadata.Artist),
|
||||
TextSize = 12,
|
||||
Padding = new MarginPadding { Top = 3 },
|
||||
Font = "Exo2.0-RegularItalic",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
foreach (Mod mod in Score.Mods)
|
||||
modsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.5f) });
|
||||
}
|
||||
|
||||
protected override bool OnClick(InputState state) => true;
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
background.FadeIn(fade_duration, Easing.OutQuint);
|
||||
underscoreLine.FadeOut(fade_duration, Easing.OutQuint);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
background.FadeOut(fade_duration, Easing.OutQuint);
|
||||
underscoreLine.FadeIn(fade_duration, Easing.OutQuint);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
|
||||
private class MetadataContainer : OsuHoverContainer, IHasTooltip
|
||||
{
|
||||
public string TooltipText { get; set; }
|
||||
|
||||
public MetadataContainer(string title, string artist)
|
||||
{
|
||||
TooltipText = $"{artist} - {title}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
{
|
||||
public class DrawableTotalScore : DrawableScore
|
||||
public class DrawableTotalScore : DrawableProfileScore
|
||||
{
|
||||
public DrawableTotalScore(Score score)
|
||||
: base(score)
|
||||
@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Stats.Add(new OsuSpriteText
|
||||
RightFlowContainer.Add(new OsuSpriteText
|
||||
{
|
||||
Text = Score.TotalScore.ToString("#,###"),
|
||||
Anchor = Anchor.TopRight,
|
||||
|
@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||
|
||||
foreach (OnlineScore score in scores)
|
||||
{
|
||||
DrawableScore drawableScore;
|
||||
DrawableProfileScore drawableScore;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
61
osu.Game/Overlays/Profile/SupporterIcon.cs
Normal file
61
osu.Game/Overlays/Profile/SupporterIcon.cs
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
|
||||
namespace osu.Game.Overlays.Profile
|
||||
{
|
||||
public class SupporterIcon : CircularContainer
|
||||
{
|
||||
private readonly Box background;
|
||||
|
||||
public SupporterIcon()
|
||||
{
|
||||
Masking = true;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box { RelativeSizeAxes = Axes.Both },
|
||||
new CircularContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.8f),
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new Box { RelativeSizeAxes = Axes.Both },
|
||||
new Triangles
|
||||
{
|
||||
TriangleScale = 0.2f,
|
||||
ColourLight = OsuColour.FromHex(@"ff7db7"),
|
||||
ColourDark = OsuColour.FromHex(@"de5b95"),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Velocity = 0.3f,
|
||||
},
|
||||
}
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Icon = FontAwesome.fa_heart,
|
||||
Scale = new Vector2(0.45f),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
background.Colour = colours.Pink;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user