1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 15:26:07 +08:00

Merge branch 'master' into fix-crash-hidden-sets#2

This commit is contained in:
Dean Herbert 2017-12-11 13:16:30 +09:00 committed by GitHub
commit c880386fde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 569 additions and 216 deletions

View File

@ -0,0 +1,47 @@
// 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;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Overlays.Profile.Sections;
using osu.Game.Overlays.Profile.Sections.Historical;
using osu.Game.Users;
namespace osu.Game.Tests.Visual
{
internal class TestCaseHistoricalSection : OsuTestCase
{
public override IReadOnlyList<Type> RequiredTypes =>
new[]
{
typeof(HistoricalSection),
typeof(PaginatedMostPlayedBeatmapContainer),
typeof(DrawableMostPlayedRow),
typeof(DrawableProfileRow)
};
public TestCaseHistoricalSection()
{
HistoricalSection section;
Add(new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(0.2f)
});
Add(new ScrollContainer
{
RelativeSizeAxes = Axes.Both,
Child = section = new HistoricalSection(),
});
AddStep("Show peppy", () => section.User.Value = new User { Id = 2 });
AddStep("Show WubWoofWolf", () => section.User.Value = new User { Id = 39828 });
}
}
}

View File

@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual
{ {
internal class TestCaseUserRanks : OsuTestCase internal class TestCaseUserRanks : OsuTestCase
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableScore), typeof(RanksSection) }; public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableProfileScore), typeof(RanksSection) };
public TestCaseUserRanks() public TestCaseUserRanks()
{ {

View File

@ -110,6 +110,7 @@
<Compile Include="Visual\TestCaseEditorSummaryTimeline.cs" /> <Compile Include="Visual\TestCaseEditorSummaryTimeline.cs" />
<Compile Include="Visual\TestCaseGamefield.cs" /> <Compile Include="Visual\TestCaseGamefield.cs" />
<Compile Include="Visual\TestCaseGraph.cs" /> <Compile Include="Visual\TestCaseGraph.cs" />
<Compile Include="Visual\TestCaseHistoricalSection.cs" />
<Compile Include="Visual\TestCaseIconButton.cs" /> <Compile Include="Visual\TestCaseIconButton.cs" />
<Compile Include="Visual\TestCaseIntroSequence.cs" /> <Compile Include="Visual\TestCaseIntroSequence.cs" />
<Compile Include="Visual\TestCaseKeyConfiguration.cs" /> <Compile Include="Visual\TestCaseKeyConfiguration.cs" />

View File

@ -115,6 +115,7 @@ namespace osu.Game.Beatmaps
// Metadata // Metadata
public string Version { get; set; } public string Version { get; set; }
[JsonProperty("difficulty_rating")]
public double StarDifficulty { get; set; } public double StarDifficulty { get; set; }
public bool Equals(BeatmapInfo other) public bool Equals(BeatmapInfo other)

View File

@ -11,21 +11,44 @@ namespace osu.Game.Beatmaps.Drawables
public class BeatmapSetCover : Sprite public class BeatmapSetCover : Sprite
{ {
private readonly BeatmapSetInfo set; private readonly BeatmapSetInfo set;
public BeatmapSetCover(BeatmapSetInfo set) private readonly BeatmapSetCoverType type;
public BeatmapSetCover(BeatmapSetInfo set, BeatmapSetCoverType type = BeatmapSetCoverType.Cover)
{ {
if (set == null) if (set == null)
throw new ArgumentNullException(nameof(set)); throw new ArgumentNullException(nameof(set));
this.set = set; this.set = set;
this.type = type;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(TextureStore textures)
{ {
string resource = set.OnlineInfo.Covers.Cover; string resource = null;
switch (type)
{
case BeatmapSetCoverType.Cover:
resource = set.OnlineInfo.Covers.Cover;
break;
case BeatmapSetCoverType.Card:
resource = set.OnlineInfo.Covers.Card;
break;
case BeatmapSetCoverType.List:
resource = set.OnlineInfo.Covers.List;
break;
}
if (resource != null) if (resource != null)
Texture = textures.Get(resource); Texture = textures.Get(resource);
} }
} }
public enum BeatmapSetCoverType
{
Cover,
Card,
List,
}
} }

View File

@ -10,7 +10,7 @@ using System;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class GetBeatmapSetsResponse : BeatmapMetadata // todo: this is a bit wrong... public class APIResponseBeatmapSet : BeatmapMetadata // todo: this is a bit wrong...
{ {
[JsonProperty(@"covers")] [JsonProperty(@"covers")]
private BeatmapSetOnlineCovers covers { get; set; } private BeatmapSetOnlineCovers covers { get; set; }
@ -45,7 +45,7 @@ namespace osu.Game.Online.API.Requests
} }
[JsonProperty(@"beatmaps")] [JsonProperty(@"beatmaps")]
private IEnumerable<GetBeatmapSetsBeatmapResponse> beatmaps { get; set; } private IEnumerable<APIResponseBeatmap> beatmaps { get; set; }
public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets) public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets)
{ {
@ -65,11 +65,11 @@ namespace osu.Game.Online.API.Requests
Ranked = ranked, Ranked = ranked,
LastUpdated = lastUpdated, LastUpdated = lastUpdated,
}, },
Beatmaps = beatmaps.Select(b => b.ToBeatmap(rulesets)).ToList(), Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(),
}; };
} }
private class GetBeatmapSetsBeatmapResponse : BeatmapMetadata private class APIResponseBeatmap : BeatmapMetadata
{ {
[JsonProperty(@"id")] [JsonProperty(@"id")]
private int onlineBeatmapID { get; set; } private int onlineBeatmapID { get; set; }

View File

@ -3,7 +3,7 @@
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class GetBeatmapSetRequest : APIRequest<GetBeatmapSetsResponse> public class GetBeatmapSetRequest : APIRequest<APIResponseBeatmapSet>
{ {
private readonly int beatmapSetId; private readonly int beatmapSetId;

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class GetUserBeatmapsRequest : APIRequest<List<GetBeatmapSetsResponse>> public class GetUserBeatmapsRequest : APIRequest<List<APIResponseBeatmapSet>>
{ {
private readonly long userId; private readonly long userId;
private readonly int offset; private readonly int offset;
@ -24,7 +24,6 @@ namespace osu.Game.Online.API.Requests
public enum BeatmapSetType public enum BeatmapSetType
{ {
MostPlayed,
Favourite, Favourite,
RankedAndApproved, RankedAndApproved,
Unranked, Unranked,

View File

@ -0,0 +1,48 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using System.Collections.Generic;
namespace osu.Game.Online.API.Requests
{
public class GetUserMostPlayedBeatmapsRequest : APIRequest<List<MostPlayedBeatmap>>
{
private readonly long userId;
private readonly int offset;
public GetUserMostPlayedBeatmapsRequest(long userId, int offset = 0)
{
this.userId = userId;
this.offset = offset;
}
protected override string Target => $@"users/{userId}/beatmapsets/most_played?offset={offset}";
}
public class MostPlayedBeatmap
{
[JsonProperty("beatmap_id")]
public int BeatmapID;
[JsonProperty("count")]
public int PlayCount;
[JsonProperty]
private BeatmapInfo beatmap;
[JsonProperty]
private APIResponseBeatmapSet beatmapSet;
public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets)
{
BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets);
beatmap.BeatmapSet = setInfo;
beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID;
beatmap.Metadata = setInfo.Metadata;
return beatmap;
}
}
}

View File

@ -9,7 +9,7 @@ using osu.Game.Rulesets;
namespace osu.Game.Online.API.Requests namespace osu.Game.Online.API.Requests
{ {
public class SearchBeatmapSetsRequest : APIRequest<IEnumerable<GetBeatmapSetsResponse>> public class SearchBeatmapSetsRequest : APIRequest<IEnumerable<APIResponseBeatmapSet>>
{ {
private readonly string query; private readonly string query;
private readonly RulesetInfo ruleset; private readonly RulesetInfo ruleset;

View File

@ -251,7 +251,7 @@ namespace osu.Game.Overlays
playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o;
if (track.HasCompleted && !beatmapBacking.Disabled && playlist.BeatmapSets.Any()) if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && playlist.BeatmapSets.Any())
next(); next();
} }
else else

View File

@ -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",
},
},
};
}
}
}

View 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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -1,7 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// 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 osu.Framework.Graphics;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Profile.Sections.Historical;
using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Overlays.Profile.Sections.Ranks;
namespace osu.Game.Overlays.Profile.Sections namespace osu.Game.Overlays.Profile.Sections
@ -14,7 +16,11 @@ namespace osu.Game.Overlays.Profile.Sections
public HistoricalSection() 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. :("),
};
} }
} }
} }

View File

@ -9,7 +9,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Overlays.Profile.Sections.Ranks namespace osu.Game.Overlays.Profile.Sections.Ranks
{ {
public class DrawablePerformanceScore : DrawableScore public class DrawablePerformanceScore : DrawableProfileScore
{ {
private readonly double? weight; private readonly double? weight;
@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
private void load(OsuColour colour) private void load(OsuColour colour)
{ {
double pp = Score.PP ?? 0; double pp = Score.PP ?? 0;
Stats.Add(new OsuSpriteText RightFlowContainer.Add(new OsuSpriteText
{ {
Text = $"{pp:0}pp", Text = $"{pp:0}pp",
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
if (weight.HasValue) if (weight.HasValue)
{ {
Stats.Add(new OsuSpriteText RightFlowContainer.Add(new OsuSpriteText
{ {
Text = $"weighted: {pp * weight:0}pp ({weight:P0})", Text = $"weighted: {pp * weight:0}pp ({weight:P0})",
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,

View File

@ -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,
};
}
}

View File

@ -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}";
}
}
}
}

View File

@ -8,7 +8,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Overlays.Profile.Sections.Ranks namespace osu.Game.Overlays.Profile.Sections.Ranks
{ {
public class DrawableTotalScore : DrawableScore public class DrawableTotalScore : DrawableProfileScore
{ {
public DrawableTotalScore(Score score) public DrawableTotalScore(Score score)
: base(score) : base(score)
@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Stats.Add(new OsuSpriteText RightFlowContainer.Add(new OsuSpriteText
{ {
Text = Score.TotalScore.ToString("#,###"), Text = Score.TotalScore.ToString("#,###"),
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,

View File

@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
foreach (OnlineScore score in scores) foreach (OnlineScore score in scores)
{ {
DrawableScore drawableScore; DrawableProfileScore drawableScore;
switch (type) switch (type)
{ {

View File

@ -287,13 +287,18 @@
</Compile> </Compile>
<Compile Include="Migrations\OsuDbContextModelSnapshot.cs" /> <Compile Include="Migrations\OsuDbContextModelSnapshot.cs" />
<Compile Include="Online\API\Requests\GetBeatmapSetRequest.cs" /> <Compile Include="Online\API\Requests\GetBeatmapSetRequest.cs" />
<Compile Include="Online\API\Requests\GetBeatmapSetsResponse.cs" /> <Compile Include="Online\API\Requests\APIResponseBeatmapSet.cs" />
<Compile Include="Online\API\Requests\GetUserMostPlayedBeatmapsRequest.cs" />
<Compile Include="Overlays\BeatmapSet\Scores\ClickableUsername.cs" /> <Compile Include="Overlays\BeatmapSet\Scores\ClickableUsername.cs" />
<Compile Include="Overlays\BeatmapSet\Scores\DrawableScore.cs" /> <Compile Include="Overlays\BeatmapSet\Scores\DrawableScore.cs" />
<Compile Include="Overlays\BeatmapSet\Scores\DrawableTopScore.cs" /> <Compile Include="Overlays\BeatmapSet\Scores\DrawableTopScore.cs" />
<Compile Include="Overlays\BeatmapSet\Scores\ScoresContainer.cs" /> <Compile Include="Overlays\BeatmapSet\Scores\ScoresContainer.cs" />
<Compile Include="Online\API\Requests\GetUserBeatmapsRequest.cs" /> <Compile Include="Online\API\Requests\GetUserBeatmapsRequest.cs" />
<Compile Include="Overlays\Profile\Sections\BeatmapMetadataContainer.cs" />
<Compile Include="Overlays\Profile\Sections\Beatmaps\PaginatedBeatmapContainer.cs" /> <Compile Include="Overlays\Profile\Sections\Beatmaps\PaginatedBeatmapContainer.cs" />
<Compile Include="Overlays\Profile\Sections\DrawableProfileRow.cs" />
<Compile Include="Overlays\Profile\Sections\Historical\DrawableMostPlayedRow.cs" />
<Compile Include="Overlays\Profile\Sections\Historical\PaginatedMostPlayedBeatmapContainer.cs" />
<Compile Include="Overlays\Profile\Sections\Kudosu\KudosuInfo.cs" /> <Compile Include="Overlays\Profile\Sections\Kudosu\KudosuInfo.cs" />
<Compile Include="Overlays\Profile\Sections\PaginatedContainer.cs" /> <Compile Include="Overlays\Profile\Sections\PaginatedContainer.cs" />
<Compile Include="Overlays\Profile\Sections\Ranks\DrawablePerformanceScore.cs" /> <Compile Include="Overlays\Profile\Sections\Ranks\DrawablePerformanceScore.cs" />
@ -483,7 +488,7 @@
<Compile Include="Overlays\Notifications\ProgressNotification.cs" /> <Compile Include="Overlays\Notifications\ProgressNotification.cs" />
<Compile Include="Overlays\Notifications\SimpleNotification.cs" /> <Compile Include="Overlays\Notifications\SimpleNotification.cs" />
<Compile Include="Overlays\OnScreenDisplay.cs" /> <Compile Include="Overlays\OnScreenDisplay.cs" />
<Compile Include="Overlays\Profile\Sections\Ranks\DrawableScore.cs" /> <Compile Include="Overlays\Profile\Sections\Ranks\DrawableProfileScore.cs" />
<Compile Include="Overlays\Profile\ProfileHeader.cs" /> <Compile Include="Overlays\Profile\ProfileHeader.cs" />
<Compile Include="Overlays\Profile\ProfileSection.cs" /> <Compile Include="Overlays\Profile\ProfileSection.cs" />
<Compile Include="Overlays\Profile\RankChart.cs" /> <Compile Include="Overlays\Profile\RankChart.cs" />