Merge branch 'master' of https://github.com/ppy/osu into linkify-metadata

This commit is contained in:
unknown
2020-03-18 14:18:53 +08:00
833 changed files with 23519 additions and 11624 deletions

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -50,7 +51,7 @@ namespace osu.Game.Overlays.BeatmapSet
fields.Children = new Drawable[]
{
new Field("mapped by", BeatmapSet.Metadata.Author.Username, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)),
new Field("submitted on", online.Submitted.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold))
new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold))
{
Margin = new MarginPadding { Top = 5 },
},
@ -58,11 +59,11 @@ namespace osu.Game.Overlays.BeatmapSet
if (online.Ranked.HasValue)
{
fields.Add(new Field("ranked on", online.Ranked.Value.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold)));
fields.Add(new Field(online.Status.ToString().ToLowerInvariant(), online.Ranked.Value, OsuFont.GetFont(weight: FontWeight.Bold)));
}
else if (online.LastUpdated.HasValue)
{
fields.Add(new Field("last updated on", online.LastUpdated.Value.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold)));
fields.Add(new Field("last updated", online.LastUpdated.Value, OsuFont.GetFont(weight: FontWeight.Bold)));
}
}
@ -76,7 +77,7 @@ namespace osu.Game.Overlays.BeatmapSet
new Container
{
AutoSizeAxes = Axes.Both,
CornerRadius = 3,
CornerRadius = 4,
Masking = true,
Child = avatar = new UpdateableAvatar
{
@ -87,7 +88,7 @@ namespace osu.Game.Overlays.BeatmapSet
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Radius = 4,
Offset = new Vector2(0f, 1f),
},
},
@ -117,15 +118,34 @@ namespace osu.Game.Overlays.BeatmapSet
new OsuSpriteText
{
Text = $"{first} ",
Font = OsuFont.GetFont(size: 13)
Font = OsuFont.GetFont(size: 11)
},
new OsuSpriteText
{
Text = second,
Font = secondFont.With(size: 13)
Font = secondFont.With(size: 11)
},
};
}
public Field(string first, DateTimeOffset second, FontUsage secondFont)
{
AutoSizeAxes = Axes.Both;
Direction = FillDirection.Horizontal;
Children = new[]
{
new OsuSpriteText
{
Text = $"{first} ",
Font = OsuFont.GetFont(size: 13)
},
new DrawableDate(second)
{
Font = secondFont.With(size: 13)
}
};
}
}
}
}

View File

@ -3,6 +3,7 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
@ -105,7 +106,7 @@ namespace osu.Game.Overlays.BeatmapSet
{
TooltipText = name;
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Height = 24f;
Children = new Drawable[]
{
@ -113,7 +114,8 @@ namespace osu.Game.Overlays.BeatmapSet
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
Children = new Drawable[]
{
new SpriteIcon
@ -121,17 +123,17 @@ namespace osu.Game.Overlays.BeatmapSet
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.Square,
Size = new Vector2(13),
Size = new Vector2(12),
Rotation = 45,
Colour = OsuColour.FromHex(@"441288"),
Colour = Color4Extensions.FromHex(@"441288"),
},
new SpriteIcon
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
Icon = icon,
Size = new Vector2(13),
Colour = OsuColour.FromHex(@"f7dd55"),
Size = new Vector2(12),
Colour = Color4Extensions.FromHex(@"f7dd55"),
Scale = new Vector2(0.8f),
},
value = new OsuSpriteText
@ -139,7 +141,7 @@ namespace osu.Game.Overlays.BeatmapSet
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 10 },
Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold),
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
},
},
},

View File

@ -6,7 +6,6 @@ using System.Linq;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -19,7 +18,6 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
@ -34,7 +32,6 @@ namespace osu.Game.Overlays.BeatmapSet
public readonly DifficultiesContainer Difficulties;
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
@ -67,7 +64,7 @@ namespace osu.Game.Overlays.BeatmapSet
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) },
Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2), Bottom = 10 },
OnLostHover = () =>
{
showBeatmap(Beatmap.Value);
@ -77,7 +74,6 @@ namespace osu.Game.Overlays.BeatmapSet
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 10 },
Spacing = new Vector2(5f),
Children = new[]
{
@ -85,13 +81,13 @@ namespace osu.Game.Overlays.BeatmapSet
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold)
Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold)
},
starRating = new OsuSpriteText
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold),
Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold),
Text = "Star Difficulty",
Alpha = 0,
Margin = new MarginPadding { Bottom = 1 },
@ -192,9 +188,11 @@ namespace osu.Game.Overlays.BeatmapSet
public class DifficultySelectorButton : OsuClickableContainer, IStateful<DifficultySelectorState>
{
private const float transition_duration = 100;
private const float size = 52;
private const float size = 54;
private const float background_size = size - 2;
private readonly Container bg;
private readonly Container background;
private readonly Box backgroundBox;
private readonly DifficultyIcon icon;
public readonly BeatmapInfo Beatmap;
@ -230,16 +228,16 @@ namespace osu.Game.Overlays.BeatmapSet
Children = new Drawable[]
{
bg = new Container
background = new Container
{
RelativeSizeAxes = Axes.Both,
Size = new Vector2(background_size),
Masking = true,
CornerRadius = 4,
Child = new Box
Child = backgroundBox = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
Alpha = 0.5f
}
},
icon = new DifficultyIcon(beatmap, shouldShowTooltip: false)
{
@ -273,15 +271,21 @@ namespace osu.Game.Overlays.BeatmapSet
private void fadeIn()
{
bg.FadeIn(transition_duration);
background.FadeIn(transition_duration);
icon.FadeIn(transition_duration);
}
private void fadeOut()
{
bg.FadeOut();
background.FadeOut();
icon.FadeTo(0.7f, transition_duration);
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
backgroundBox.Colour = colourProvider.Background6;
}
}
private class Statistic : FillFlowContainer
@ -314,13 +318,13 @@ namespace osu.Game.Overlays.BeatmapSet
Origin = Anchor.CentreLeft,
Icon = icon,
Shadow = true,
Size = new Vector2(13),
Size = new Vector2(12),
},
text = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold, italics: true),
},
};
}

View File

@ -2,17 +2,14 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osuTK;
using System.Linq;
namespace osu.Game.Overlays.BeatmapSet
{
public class BeatmapRulesetSelector : RulesetSelector
public class BeatmapRulesetSelector : OverlayRulesetSelector
{
private readonly Bindable<BeatmapSetInfo> beatmapSet = new Bindable<BeatmapSetInfo>();
@ -28,21 +25,9 @@ namespace osu.Game.Overlays.BeatmapSet
}
}
public BeatmapRulesetSelector()
{
AutoSizeAxes = Axes.Both;
}
protected override TabItem<RulesetInfo> CreateTabItem(RulesetInfo value) => new BeatmapRulesetTabItem(value)
{
BeatmapSet = { BindTarget = beatmapSet }
};
protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10, 0),
};
}
}

View File

@ -3,143 +3,74 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osuTK;
using osuTK.Graphics;
using System.Linq;
namespace osu.Game.Overlays.BeatmapSet
{
public class BeatmapRulesetTabItem : TabItem<RulesetInfo>
public class BeatmapRulesetTabItem : OverlayRulesetTabItem
{
private readonly OsuSpriteText name, count;
private readonly Box bar;
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree;
[Resolved]
private OverlayColourProvider colourProvider { get; set; }
private OsuSpriteText count;
private Container countContainer;
public BeatmapRulesetTabItem(RulesetInfo value)
: base(value)
{
AutoSizeAxes = Axes.Both;
}
FillFlowContainer nameContainer;
Children = new Drawable[]
[BackgroundDependencyLoader]
private void load()
{
Add(countContainer = new Container
{
nameContainer = new FillFlowContainer
AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Masking = true,
CornerRadius = 4f,
Children = new Drawable[]
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Margin = new MarginPadding { Bottom = 7.5f },
Spacing = new Vector2(2.5f),
Children = new Drawable[]
new Box
{
name = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = value.Name,
Font = OsuFont.Default.With(size: 18),
},
new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 4f,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
count = new OsuSpriteText
{
Alpha = 0,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Margin = new MarginPadding { Horizontal = 5f },
Font = OsuFont.Default.With(weight: FontWeight.SemiBold),
}
}
}
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background6
},
count = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Margin = new MarginPadding { Horizontal = 5f },
Font = OsuFont.Default.With(weight: FontWeight.SemiBold),
Colour = colourProvider.Foreground1,
}
},
bar = new Box
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.X,
},
new HoverClickSounds(),
};
}
});
}
protected override void LoadComplete()
{
base.LoadComplete();
BeatmapSet.BindValueChanged(setInfo =>
{
var beatmapsCount = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.Equals(Value)) ?? 0;
count.Text = beatmapsCount.ToString();
count.Alpha = beatmapsCount > 0 ? 1f : 0f;
countContainer.FadeTo(beatmapsCount > 0 ? 1 : 0);
Enabled.Value = beatmapsCount > 0;
}, true);
Enabled.BindValueChanged(v => nameContainer.Alpha = v.NewValue ? 1f : 0.5f, true);
}
[Resolved]
private OsuColour colour { get; set; }
protected override void LoadComplete()
{
base.LoadComplete();
count.Colour = colour.Gray9;
bar.Colour = colour.Blue;
updateState();
}
private void updateState()
{
var isHoveredOrActive = IsHovered || Active.Value;
bar.ResizeHeightTo(isHoveredOrActive ? 4 : 0, 200, Easing.OutQuint);
name.Colour = isHoveredOrActive ? colour.GrayE : colour.GrayC;
name.Font = name.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular);
}
#region Hovering and activation logic
protected override void OnActivated() => updateState();
protected override void OnDeactivated() => updateState();
protected override bool OnHover(HoverEvent e)
{
updateState();
return false;
}
protected override void OnHoverLost(HoverLostEvent e) => updateState();
#endregion
}
}

View File

@ -0,0 +1,35 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
namespace osu.Game.Overlays.BeatmapSet
{
public class BeatmapSetHeader : OverlayHeader
{
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
public BeatmapRulesetSelector RulesetSelector { get; private set; }
protected override ScreenTitle CreateTitle() => new BeatmapHeaderTitle();
protected override Drawable CreateTitleContent() => RulesetSelector = new BeatmapRulesetSelector
{
Current = Ruleset
};
private class BeatmapHeaderTitle : ScreenTitle
{
public BeatmapHeaderTitle()
{
Title = @"beatmap";
Section = @"info";
}
protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog");
}
}
}

View File

@ -0,0 +1,29 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class BeatmapSetLayoutSection : Container
{
public BeatmapSetLayoutSection()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Masking = true;
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Offset = new Vector2(0f, 1f),
};
}
}
}

View File

@ -5,7 +5,6 @@ using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
@ -25,7 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
private readonly BindableBool favourited = new BindableBool();
private PostBeatmapFavouriteRequest request;
private DimmedLoadingLayer loading;
private LoadingLayer loading;
private readonly Bindable<User> localUser = new Bindable<User>();
@ -54,14 +53,11 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Size = new Vector2(18),
Shadow = false,
},
loading = new DimmedLoadingLayer(0.8f, 0.5f),
loading = new LoadingLayer(icon, false),
});
Action = () =>
{
if (loading.State.Value == Visibility.Visible)
return;
// guaranteed by disabled state above.
Debug.Assert(BeatmapSet.Value.OnlineBeatmapSetID != null);

View File

@ -2,8 +2,8 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.BeatmapSet.Buttons
@ -19,9 +19,9 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
[BackgroundDependencyLoader]
private void load()
{
BackgroundColour = OsuColour.FromHex(@"094c5f");
Triangles.ColourLight = OsuColour.FromHex(@"0f7c9b");
Triangles.ColourDark = OsuColour.FromHex(@"094c5f");
BackgroundColour = Color4Extensions.FromHex(@"094c5f");
Triangles.ColourLight = Color4Extensions.FromHex(@"0f7c9b");
Triangles.ColourDark = Color4Extensions.FromHex(@"094c5f");
Triangles.TriangleScale = 1.5f;
}
}

View File

@ -22,6 +22,8 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
{
public class HeaderDownloadButton : BeatmapDownloadTrackingComposite, IHasTooltip
{
private const int text_size = 12;
private readonly bool noVideo;
public string TooltipText => button.Enabled.Value ? "download this beatmap" : "login to download";
@ -80,8 +82,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Icon = FontAwesome.Solid.Download,
Size = new Vector2(16),
Margin = new MarginPadding { Right = 5 },
Size = new Vector2(18),
},
}
},
@ -120,7 +121,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
new OsuSpriteText
{
Text = "Downloading...",
Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold)
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
},
};
break;
@ -131,7 +132,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
new OsuSpriteText
{
Text = "Importing...",
Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold)
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
},
};
break;
@ -146,12 +147,12 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
new OsuSpriteText
{
Text = "Download",
Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold)
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
},
new OsuSpriteText
{
Text = BeatmapSet.Value.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty,
Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold)
Text = getVideoSuffixText(),
Font = OsuFont.GetFont(size: text_size - 2, weight: FontWeight.Bold)
},
};
this.FadeIn(200);
@ -163,5 +164,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
private void userChanged(ValueChangedEvent<User> e) => button.Enabled.Value = !(e.NewValue is GuestUser);
private void enabledChanged(ValueChangedEvent<bool> e) => this.FadeColour(e.NewValue ? Color4.White : Color4.Gray, 200, Easing.OutQuint);
private string getVideoSuffixText()
{
if (!BeatmapSet.Value.OnlineInfo.HasVideo)
return string.Empty;
return noVideo ? "without Video" : "with Video";
}
}
}

View File

@ -3,7 +3,6 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -14,7 +13,6 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays.Direct;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet.Buttons
{
@ -22,7 +20,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
{
private const float transition_duration = 500;
private readonly Box bg, progress;
private readonly Box background, progress;
private readonly PlayButton playButton;
private PreviewTrack preview => playButton.Preview;
@ -40,10 +38,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Children = new Drawable[]
{
bg = new Box
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.25f),
Alpha = 0.5f
},
new Container
{
@ -71,9 +69,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, OverlayColourProvider colourProvider)
{
progress.Colour = colours.Yellow;
background.Colour = colourProvider.Background6;
}
protected override void Update()
@ -91,13 +90,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
protected override bool OnHover(HoverEvent e)
{
bg.FadeColour(Color4.Black.Opacity(0.5f), 100);
background.FadeTo(0.75f, 80);
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
bg.FadeColour(Color4.Black.Opacity(0.25f), 100);
background.FadeTo(0.5f, 80);
base.OnHoverLost(e);
}
}

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -10,7 +9,6 @@ using osu.Game.Beatmaps;
using osu.Game.Overlays.BeatmapSet.Buttons;
using osu.Game.Screens.Select.Details;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
@ -21,6 +19,7 @@ namespace osu.Game.Overlays.BeatmapSet
private readonly PreviewButton preview;
private readonly BasicStats basic;
private readonly AdvancedStats advanced;
private readonly DetailBox ratingBox;
private BeatmapSetInfo beatmapSet;
@ -54,6 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet
private void updateDisplay()
{
Ratings.Metrics = BeatmapSet?.Metrics;
ratingBox.Alpha = BeatmapSet?.OnlineInfo?.Status > 0 ? 1 : 0;
}
public Details()
@ -74,7 +74,7 @@ namespace osu.Game.Overlays.BeatmapSet
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Vertical = 10 },
Padding = new MarginPadding { Vertical = 10 }
},
},
new DetailBox
@ -86,7 +86,7 @@ namespace osu.Game.Overlays.BeatmapSet
Margin = new MarginPadding { Vertical = 7.5f },
},
},
new DetailBox
ratingBox = new DetailBox
{
Child = Ratings = new UserRatings
{
@ -107,6 +107,8 @@ namespace osu.Game.Overlays.BeatmapSet
private class DetailBox : Container
{
private readonly Container content;
private readonly Box background;
protected override Container<Drawable> Content => content;
public DetailBox()
@ -116,10 +118,10 @@ namespace osu.Game.Overlays.BeatmapSet
InternalChildren = new Drawable[]
{
new Box
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
Alpha = 0.5f
},
content = new Container
{
@ -129,6 +131,12 @@ namespace osu.Game.Overlays.BeatmapSet
},
};
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
background.Colour = colourProvider.Background6;
}
}
}
}

View File

@ -26,12 +26,11 @@ namespace osu.Game.Overlays.BeatmapSet
public class Header : BeatmapDownloadTrackingComposite
{
private const float transition_duration = 200;
private const float tabs_height = 50;
private const float buttons_height = 45;
private const float buttons_spacing = 5;
private readonly Box tabsBg;
private readonly UpdateableBeatmapSetCover cover;
private readonly Box coverGradient;
private readonly OsuSpriteText title, artist;
private readonly AuthorInfo author;
private readonly FillFlowContainer downloadButtonsContainer;
@ -41,14 +40,13 @@ namespace osu.Game.Overlays.BeatmapSet
public bool DownloadButtonsVisible => downloadButtonsContainer.Any();
public readonly BeatmapRulesetSelector RulesetSelector;
public BeatmapRulesetSelector RulesetSelector => beatmapSetHeader.RulesetSelector;
public readonly BeatmapPicker Picker;
private readonly FavouriteButton favouriteButton;
private readonly FillFlowContainer fadeContent;
private readonly LoadingAnimation loading;
private readonly LoadingSpinner loading;
private readonly BeatmapSetHeader beatmapSetHeader;
[Cached(typeof(IBindable<RulesetInfo>))]
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
@ -69,154 +67,147 @@ namespace osu.Game.Overlays.BeatmapSet
Offset = new Vector2(0f, 1f),
};
InternalChildren = new Drawable[]
InternalChild = new FillFlowContainer
{
new Container
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.X,
Height = tabs_height,
Children = new Drawable[]
beatmapSetHeader = new BeatmapSetHeader
{
tabsBg = new Box
{
RelativeSizeAxes = Axes.Both,
},
RulesetSelector = new BeatmapRulesetSelector
{
Current = ruleset,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
}
Ruleset = { BindTarget = ruleset },
},
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Top = tabs_height },
Children = new Drawable[]
new Container
{
new Container
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
new Container
{
cover = new UpdateableBeatmapSetCover
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Masking = true,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)),
},
},
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding
{
Top = 20,
Bottom = 30,
Left = BeatmapSetOverlay.X_PADDING,
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
},
Children = new Drawable[]
{
fadeContent = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
cover = new UpdateableBeatmapSetCover
{
new Container
RelativeSizeAxes = Axes.Both,
Masking = true,
},
coverGradient = new Box
{
RelativeSizeAxes = Axes.Both
},
},
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding
{
Vertical = BeatmapSetOverlay.Y_PADDING,
Left = BeatmapSetOverlay.X_PADDING,
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
},
Children = new Drawable[]
{
fadeContent = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Child = Picker = new BeatmapPicker(),
},
new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
new Container
{
title = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 37, weight: FontWeight.Bold, italics: true)
},
externalLink = new ExternalLinkButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Margin = new MarginPadding { Left = 3, Bottom = 4 }, //To better lineup with the font
},
}
},
artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.SemiBold, italics: true) },
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Top = 20 },
Child = author = new AuthorInfo(),
},
beatmapAvailability = new BeatmapAvailability(),
new Container
{
RelativeSizeAxes = Axes.X,
Height = buttons_height,
Margin = new MarginPadding { Top = 10 },
Children = new Drawable[]
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Child = Picker = new BeatmapPicker(),
},
new FillFlowContainer
{
favouriteButton = new FavouriteButton
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 15 },
Children = new Drawable[]
{
BeatmapSet = { BindTarget = BeatmapSet }
},
downloadButtonsContainer = new FillFlowContainer
title = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true)
},
externalLink = new ExternalLinkButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Margin = new MarginPadding { Left = 3, Bottom = 4 }, //To better lineup with the font
},
}
},
artist = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true),
Margin = new MarginPadding { Bottom = 20 }
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Child = author = new AuthorInfo(),
},
beatmapAvailability = new BeatmapAvailability(),
new Container
{
RelativeSizeAxes = Axes.X,
Height = buttons_height,
Margin = new MarginPadding { Top = 10 },
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = buttons_height + buttons_spacing },
Spacing = new Vector2(buttons_spacing),
favouriteButton = new FavouriteButton
{
BeatmapSet = { BindTarget = BeatmapSet }
},
downloadButtonsContainer = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = buttons_height + buttons_spacing },
Spacing = new Vector2(buttons_spacing),
},
},
},
},
},
},
}
},
loading = new LoadingAnimation
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.5f),
},
new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING },
Direction = FillDirection.Vertical,
Spacing = new Vector2(10),
Children = new Drawable[]
}
},
loading = new LoadingSpinner
{
onlineStatusPill = new BeatmapSetOnlineStatusPill
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.5f),
},
new FillFlowContainer
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING },
Direction = FillDirection.Vertical,
Spacing = new Vector2(10),
Children = new Drawable[]
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
TextSize = 14,
TextPadding = new MarginPadding { Horizontal = 25, Vertical = 8 }
onlineStatusPill = new BeatmapSetOnlineStatusPill
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
TextSize = 14,
TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 }
},
Details = new Details(),
},
Details = new Details(),
},
},
},
},
}
};
Picker.Beatmap.ValueChanged += b =>
@ -227,9 +218,10 @@ namespace osu.Game.Overlays.BeatmapSet
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
tabsBg.Colour = colours.Gray3;
coverGradient.Colour = ColourInfo.GradientVertical(colourProvider.Background6.Opacity(0.3f), colourProvider.Background6.Opacity(0.8f));
onlineStatusPill.BackgroundColour = colourProvider.Background6;
State.BindValueChanged(_ => updateDownloadButtons());

View File

@ -3,10 +3,8 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
@ -16,17 +14,18 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Online.Chat;
using osu.Game.Screens.Select;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class Info : Container
{
private const float transition_duration = 250;
private const float metadata_width = 225;
private const float metadata_width = 175;
private const float spacing = 20;
private const float base_height = 220;
private readonly Box successRateBackground;
private readonly Box background;
private readonly SuccessRate successRate;
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
@ -40,23 +39,16 @@ namespace osu.Game.Overlays.BeatmapSet
public Info()
{
MetadataSection source, tags, genre, language;
OsuSpriteText unrankedPlaceholder;
RelativeSizeAxes = Axes.X;
Height = 220;
Masking = true;
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Offset = new Vector2(0f, 1f),
};
Height = base_height;
Children = new Drawable[]
{
new Box
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
RelativeSizeAxes = Axes.Both
},
new Container
{
@ -113,6 +105,14 @@ namespace osu.Game.Overlays.BeatmapSet
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 20, Horizontal = 15 },
},
unrankedPlaceholder = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0,
Text = "Unranked beatmap",
Font = OsuFont.GetFont(size: 12)
},
},
},
},
@ -125,13 +125,18 @@ namespace osu.Game.Overlays.BeatmapSet
tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty;
genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty;
language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? string.Empty;
var setHasLeaderboard = b.NewValue?.OnlineInfo?.Status > 0;
successRate.Alpha = setHasLeaderboard ? 1 : 0;
unrankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1;
Height = setHasLeaderboard ? 270 : base_height;
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
successRateBackground.Colour = colours.GrayE;
successRateBackground.Colour = colourProvider.Background4;
background.Colour = colourProvider.Background5;
}
private class MetadataSection : FillFlowContainer
@ -153,7 +158,7 @@ namespace osu.Game.Overlays.BeatmapSet
this.FadeIn(transition_duration);
textFlow.Clear();
static void format(SpriteText t) => t.Font = t.Font.With(size: 14);
static void format(SpriteText t) => t.Font = t.Font.With(size: 12);
switch (type)
{
@ -189,12 +194,11 @@ namespace osu.Game.Overlays.BeatmapSet
InternalChildren = new Drawable[]
{
header = new OsuSpriteText
new OsuSpriteText
{
Text = this.type.ToString(),
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
Shadow = false,
Margin = new MarginPadding { Top = 20 },
Margin = new MarginPadding { Top = 15 },
},
textFlow = new LinkFlowContainer
{
@ -203,12 +207,6 @@ namespace osu.Game.Overlays.BeatmapSet
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
header.Colour = textFlow.Colour = colours.Gray5;
}
}
}
}

View File

@ -3,7 +3,6 @@
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Framework.Allocation;
using osuTK.Graphics;
using osu.Framework.Graphics.UserInterface;
@ -26,10 +25,10 @@ namespace osu.Game.Overlays.BeatmapSet
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
AccentColour = colours.Blue;
LineColour = Color4.Gray;
AccentColour = colourProvider.Highlight1;
LineColour = colourProvider.Background1;
}
private class ScopeSelectorTabItem : PageTabItem
@ -37,7 +36,6 @@ namespace osu.Game.Overlays.BeatmapSet
public ScopeSelectorTabItem(BeatmapLeaderboardScope value)
: base(value)
{
Text.Font = OsuFont.GetFont(size: 16);
}
protected override bool OnHover(HoverEvent e)

View File

@ -7,8 +7,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Scoring;
using osuTK;
using osuTK.Graphics;
@ -17,20 +15,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
public class DrawableTopScore : CompositeDrawable
{
private const float fade_duration = 100;
private Color4 backgroundIdleColour;
private Color4 backgroundHoveredColour;
private readonly Box background;
public DrawableTopScore(ScoreInfo score, int position = 1)
public DrawableTopScore(ScoreInfo score, int? position = 1)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Masking = true;
CornerRadius = 10;
CornerRadius = 4;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
@ -49,7 +42,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding(10),
Padding = new MarginPadding
{
Vertical = 10,
Left = 10,
Right = 30,
},
Children = new Drawable[]
{
new AutoSizingGrid
@ -84,24 +82,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
backgroundIdleColour = colours.Gray3;
backgroundHoveredColour = colours.Gray4;
background.Colour = backgroundIdleColour;
}
protected override bool OnHover(HoverEvent e)
{
background.FadeColour(backgroundHoveredColour, fade_duration, Easing.OutQuint);
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
background.FadeColour(backgroundIdleColour, fade_duration, Easing.OutQuint);
base.OnHoverLost(e);
background.Colour = colourProvider.Background4;
}
private class AutoSizingGrid : GridContainer

View File

@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 10),
Spacing = new Vector2(0, 20),
Children = new Drawable[]
{
new OsuSpriteText
@ -29,9 +29,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = @"You need to be an osu!supporter to access the friend and country rankings!",
Font = OsuFont.GetFont(weight: FontWeight.Bold),
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
},
text = new LinkFlowContainer(t => t.Font = t.Font.With(size: 12))
text = new LinkFlowContainer(t => t.Font = t.Font.With(size: 11))
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,

View File

@ -22,8 +22,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
public class ScoreTable : TableContainer
{
private const float horizontal_inset = 20;
private const float row_height = 25;
private const int text_size = 14;
private const float row_height = 22;
private const int text_size = 12;
private readonly FillFlowContainer backgroundFlow;
@ -52,22 +52,28 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
highAccuracyColour = colours.GreenLight;
}
public IReadOnlyList<ScoreInfo> Scores
private bool showPerformancePoints;
public void DisplayScores(IReadOnlyList<ScoreInfo> scores, bool showPerformanceColumn)
{
set
{
Content = null;
backgroundFlow.Clear();
ClearScores();
if (value?.Any() != true)
return;
if (!scores.Any())
return;
for (int i = 0; i < value.Count; i++)
backgroundFlow.Add(new ScoreTableRowBackground(i, value[i]));
showPerformancePoints = showPerformanceColumn;
Columns = createHeaders(value[0]);
Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular();
}
for (int i = 0; i < scores.Count; i++)
backgroundFlow.Add(new ScoreTableRowBackground(i, scores[i], row_height));
Columns = createHeaders(scores.FirstOrDefault());
Content = scores.Select((s, i) => createContent(i, s)).ToArray().ToRectangular();
}
public void ClearScores()
{
Content = null;
backgroundFlow.Clear();
}
private TableColumn[] createHeaders(ScoreInfo score)
@ -77,25 +83,30 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
new TableColumn("rank", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("", Anchor.Centre, new Dimension(GridSizeMode.Absolute, 70)), // grade
new TableColumn("score", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 150)),
new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 90))
new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, minSize: 60, maxSize: 70)),
new TableColumn("", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 25)), // flag
new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 125)),
new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 120))
};
foreach (var statistic in score.Statistics)
columns.Add(new TableColumn(statistic.Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70)));
foreach (var statistic in score.SortedStatistics.Take(score.SortedStatistics.Count() - 1))
columns.Add(new TableColumn(statistic.Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 35, maxSize: 60)));
columns.AddRange(new[]
{
new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70)),
new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)),
});
columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95)));
if (showPerformancePoints)
columns.Add(new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30)));
columns.Add(new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)));
return columns.ToArray();
}
private Drawable[] createContent(int index, ScoreInfo score)
{
var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: text_size)) { AutoSizeAxes = Axes.Both };
username.AddUserLink(score.User);
var content = new List<Drawable>
{
new OsuSpriteText
@ -105,7 +116,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
},
new UpdateableRank(score.Rank)
{
Size = new Vector2(30, 20)
Size = new Vector2(28, 14)
},
new OsuSpriteText
{
@ -116,41 +127,25 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
new OsuSpriteText
{
Margin = new MarginPadding { Right = horizontal_inset },
Text = $@"{score.Accuracy:P2}",
Text = score.DisplayAccuracy,
Font = OsuFont.GetFont(size: text_size),
Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White
},
};
var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: text_size)) { AutoSizeAxes = Axes.Both };
username.AddUserLink(score.User);
content.AddRange(new Drawable[]
{
new FillFlowContainer
new UpdateableFlag(score.User.Country)
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Margin = new MarginPadding { Right = horizontal_inset },
Spacing = new Vector2(5, 0),
Children = new Drawable[]
{
new UpdateableFlag(score.User.Country)
{
Size = new Vector2(20, 13),
ShowPlaceholderOnNull = false,
},
username
}
Size = new Vector2(19, 13),
ShowPlaceholderOnNull = false,
},
username,
new OsuSpriteText
{
Text = $@"{score.MaxCombo:N0}x",
Font = OsuFont.GetFont(size: text_size)
Font = OsuFont.GetFont(size: text_size),
Colour = score.MaxCombo == score.Beatmap?.MaxCombo ? highAccuracyColour : Color4.White
}
});
};
foreach (var kvp in score.Statistics)
foreach (var kvp in score.SortedStatistics)
{
content.Add(new OsuSpriteText
{
@ -160,24 +155,25 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
});
}
content.AddRange(new Drawable[]
if (showPerformancePoints)
{
new OsuSpriteText
content.Add(new OsuSpriteText
{
Text = $@"{score.PP:N0}",
Font = OsuFont.GetFont(size: text_size)
},
new FillFlowContainer
});
}
content.Add(new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(1),
ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m)
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(1),
ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m)
{
AutoSizeAxes = Axes.Both,
Scale = new Vector2(0.3f)
})
},
Scale = new Vector2(0.3f)
})
});
return content.ToArray();
@ -190,7 +186,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
public HeaderText(string text)
{
Text = text.ToUpper();
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black);
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold);
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
Colour = colourProvider.Foreground1;
}
}
}

View File

@ -22,15 +22,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private readonly int index;
private readonly ScoreInfo score;
public ScoreTableRowBackground(int index, ScoreInfo score)
public ScoreTableRowBackground(int index, ScoreInfo score, float height)
{
this.index = index;
this.score = score;
RelativeSizeAxes = Axes.X;
Height = 25;
Height = height;
CornerRadius = 3;
CornerRadius = 5;
Masking = true;
InternalChildren = new Drawable[]
@ -48,18 +48,18 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, IAPIProvider api)
private void load(OsuColour colours, OverlayColourProvider colourProvider, IAPIProvider api)
{
var isOwnScore = api.LocalUser.Value.Id == score.UserID;
if (isOwnScore)
background.Colour = colours.GreenDarker;
else if (index % 2 == 0)
background.Colour = colours.Gray3;
background.Colour = colourProvider.Background4;
else
background.Alpha = 0;
hoveredBackground.Colour = isOwnScore ? colours.GreenDark : colours.Gray4;
hoveredBackground.Colour = isOwnScore ? colours.GreenDark : colourProvider.Background3;
}
protected override bool OnHover(HoverEvent e)

View File

@ -5,8 +5,6 @@ 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.UserInterface;
using osuTK;
using System.Linq;
using osu.Game.Online.API.Requests.Responses;
@ -14,13 +12,14 @@ using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Framework.Bindables;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
namespace osu.Game.Overlays.BeatmapSet.Scores
{
public class ScoresContainer : CompositeDrawable
public class ScoresContainer : BeatmapSetLayoutSection
{
private const int spacing = 15;
@ -32,10 +31,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private readonly Box background;
private readonly ScoreTable scoreTable;
private readonly FillFlowContainer topScoresContainer;
private readonly DimmedLoadingLayer loading;
private readonly LoadingLayer loading;
private readonly LeaderboardModSelector modSelector;
private readonly NoScoresPlaceholder noScoresPlaceholder;
private readonly FillFlowContainer content;
private readonly NotSupporterPlaceholder notSupporterPlaceholder;
[Resolved]
@ -54,17 +52,17 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
if (value?.Scores.Any() != true)
{
scoreTable.Scores = null;
scoreTable.ClearScores();
scoreTable.Hide();
return;
}
var scoreInfos = value.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToList();
var topScore = scoreInfos.First();
scoreTable.Scores = scoreInfos;
scoreTable.DisplayScores(scoreInfos, topScore.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked);
scoreTable.Show();
var topScore = scoreInfos.First();
var userScore = value.UserScore;
var userScoreInfo = userScore?.Score.CreateScoreInfo(rulesets);
@ -77,23 +75,21 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
public ScoresContainer()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChildren = new Drawable[]
AddRange(new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
},
content = new FillFlowContainer
new FillFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Width = 0.95f,
Direction = FillDirection.Vertical,
Margin = new MarginPadding { Vertical = spacing },
Padding = new MarginPadding { Horizontal = 50 },
Margin = new MarginPadding { Vertical = 20 },
Children = new Drawable[]
{
new FillFlowContainer
@ -122,7 +118,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Margin = new MarginPadding { Vertical = spacing },
Margin = new MarginPadding { Top = spacing },
Children = new Drawable[]
{
noScoresPlaceholder = new NoScoresPlaceholder
@ -161,27 +157,18 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
}
}
},
new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 10,
Child = loading = new DimmedLoadingLayer(iconScale: 0.8f)
{
Alpha = 0,
},
}
loading = new LoadingLayer()
}
}
}
},
};
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
background.Colour = colours.Gray2;
background.Colour = colourProvider.Background5;
user.BindTo(api.LocalUser);
}
@ -192,8 +179,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
scope.BindValueChanged(_ => getScores());
ruleset.BindValueChanged(_ => getScores());
modSelector.SelectedMods.ItemsAdded += _ => getScores();
modSelector.SelectedMods.ItemsRemoved += _ => getScores();
modSelector.SelectedMods.CollectionChanged += (_, __) => getScores();
Beatmap.BindValueChanged(onBeatmapChanged);
user.BindValueChanged(onUserChanged, true);
@ -234,7 +220,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
if (Beatmap.Value?.OnlineBeatmapID.HasValue != true || Beatmap.Value.Status <= BeatmapSetOnlineStatus.Pending)
{
Scores = null;
content.Hide();
Hide();
return;
}
@ -248,7 +234,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
notSupporterPlaceholder.Hide();
content.Show();
Show();
loading.Show();
getScoresRequest = new GetScoresRequest(Beatmap.Value, Beatmap.Value.Ruleset, scope.Value, modSelector.SelectedMods);

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
@ -23,9 +24,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
public class TopScoreStatisticsSection : CompositeDrawable
{
private const float margin = 10;
private const float top_columns_min_width = 64;
private const float bottom_columns_min_width = 45;
private readonly FontUsage smallFont = OsuFont.GetFont(size: 20);
private readonly FontUsage largeFont = OsuFont.GetFont(size: 25);
private readonly FontUsage smallFont = OsuFont.GetFont(size: 16);
private readonly FontUsage largeFont = OsuFont.GetFont(size: 22, weight: FontWeight.Light);
private readonly TextColumn totalScoreColumn;
private readonly TextColumn accuracyColumn;
@ -44,9 +47,23 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(10, 0),
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(margin, 0),
Children = new Drawable[]
{
totalScoreColumn = new TextColumn("total score", largeFont, top_columns_min_width),
accuracyColumn = new TextColumn("accuracy", largeFont, top_columns_min_width),
maxComboColumn = new TextColumn("max combo", largeFont, top_columns_min_width)
}
},
new FillFlowContainer
{
Anchor = Anchor.TopRight,
@ -62,24 +79,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Direction = FillDirection.Horizontal,
Spacing = new Vector2(margin, 0),
},
ppColumn = new TextColumn("pp", smallFont),
ppColumn = new TextColumn("pp", smallFont, bottom_columns_min_width),
modsColumn = new ModsInfoColumn(),
}
},
new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(margin, 0),
Children = new Drawable[]
{
totalScoreColumn = new TextColumn("total score", largeFont),
accuracyColumn = new TextColumn("accuracy", largeFont),
maxComboColumn = new TextColumn("max combo", largeFont)
}
},
}
};
}
@ -92,16 +95,17 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
set
{
totalScoreColumn.Text = $@"{value.TotalScore:N0}";
accuracyColumn.Text = $@"{value.Accuracy:P2}";
accuracyColumn.Text = value.DisplayAccuracy;
maxComboColumn.Text = $@"{value.MaxCombo:N0}x";
ppColumn.Alpha = value.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0;
ppColumn.Text = $@"{value.PP:N0}";
statisticsColumns.ChildrenEnumerable = value.Statistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value));
statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value));
modsColumn.Mods = value.Mods;
}
}
private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont)
private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont, bottom_columns_min_width)
{
Text = count.ToString()
};
@ -109,37 +113,61 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private class InfoColumn : CompositeDrawable
{
private readonly Box separator;
private readonly OsuSpriteText text;
public InfoColumn(string title, Drawable content)
public InfoColumn(string title, Drawable content, float? minWidth = null)
{
AutoSizeAxes = Axes.Both;
Margin = new MarginPadding { Vertical = 5 };
InternalChild = new FillFlowContainer
InternalChild = new GridContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 2),
Children = new[]
ColumnDimensions = new[]
{
new OsuSpriteText
new Dimension(GridSizeMode.AutoSize, minSize: minWidth ?? 0)
},
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.Absolute, 2),
new Dimension(GridSizeMode.AutoSize)
},
Content = new[]
{
new Drawable[]
{
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black),
Text = title.ToUpper()
text = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold),
Text = title.ToUpper(),
// 2px padding bottom + 1px vertical to compensate for the additional spacing because of 1.25 line-height in osu-web
Padding = new MarginPadding { Top = 1, Bottom = 3 }
}
},
separator = new Box
new Drawable[]
{
RelativeSizeAxes = Axes.X,
Height = 2
separator = new Box
{
Anchor = Anchor.TopLeft,
RelativeSizeAxes = Axes.X,
Height = 2,
},
},
content
new[]
{
// osu-web has 4px margin here but also uses 0.9 line-height, reducing margin to 2px seems like a good alternative to that
content.With(c => c.Margin = new MarginPadding { Top = 2 })
}
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OverlayColourProvider colourProvider)
{
separator.Colour = colours.Gray5;
text.Colour = colourProvider.Foreground1;
separator.Colour = colourProvider.Background3;
}
}
@ -147,13 +175,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
private readonly SpriteText text;
public TextColumn(string title, FontUsage font)
: this(title, new OsuSpriteText { Font = font })
public TextColumn(string title, FontUsage font, float? minWidth = null)
: this(title, new OsuSpriteText { Font = font }, minWidth)
{
}
private TextColumn(string title, SpriteText text)
: base(title, text)
private TextColumn(string title, SpriteText text, float? minWidth = null)
: base(title, text, minWidth)
{
this.text = text;
}
@ -171,9 +199,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
public ModsInfoColumn()
: this(new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
AutoSizeAxes = Axes.X,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(1),
Height = 18f
})
{
}
@ -189,15 +218,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
set
{
modsContainer.Clear();
foreach (Mod mod in value)
modsContainer.Children = value.Select(mod => new ModIcon(mod)
{
modsContainer.Add(new ModIcon(mod)
{
AutoSizeAxes = Axes.Both,
Scale = new Vector2(0.3f),
});
}
AutoSizeAxes = Axes.Both,
Scale = new Vector2(0.25f),
}).ToList();
}
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using System;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -13,7 +13,6 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Online.Leaderboards;
using osu.Game.Scoring;
using osu.Game.Users.Drawables;
using osu.Game.Utils;
using osuTK;
using osuTK.Graphics;
@ -25,7 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private readonly UpdateableRank rank;
private readonly UpdateableAvatar avatar;
private readonly LinkFlowContainer usernameText;
private readonly SpriteText date;
private readonly DrawableDate achievedOn;
private readonly UpdateableFlag flag;
public TopScoreUserSection()
@ -51,13 +50,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 24, weight: FontWeight.Bold, italics: true)
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold)
},
rank = new UpdateableRank(ScoreRank.D)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(40),
Size = new Vector2(28),
FillMode = FillMode.Fit,
},
}
@ -66,9 +65,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(80),
Size = new Vector2(70),
Masking = true,
CornerRadius = 5,
CornerRadius = 4,
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
@ -87,23 +86,37 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Spacing = new Vector2(0, 3),
Children = new Drawable[]
{
usernameText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true))
usernameText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true))
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
},
date = new OsuSpriteText
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold)
Children = new[]
{
new OsuSpriteText
{
Text = "achieved ",
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold)
},
achievedOn = new DrawableDate(DateTimeOffset.MinValue)
{
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold)
},
}
},
flag = new UpdateableFlag
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(20, 13),
Size = new Vector2(19, 13),
Margin = new MarginPadding { Top = 3 }, // makes spacing look more even
ShowPlaceholderOnNull = false,
},
}
@ -112,15 +125,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
public int? ScorePosition
{
rankText.Colour = colours.Yellow;
}
public int ScorePosition
{
set => rankText.Text = $"#{value}";
set => rankText.Text = value == null ? "-" : $"#{value}";
}
/// <summary>
@ -132,7 +139,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
avatar.User = value.User;
flag.Country = value.User.Country;
date.Text = $@"achieved {HumanizerUtils.Humanize(value.Date)}";
achievedOn.Date = value.Date;
usernameText.Clear();
usernameText.AddUserLink(value.User);

View File

@ -17,7 +17,7 @@ namespace osu.Game.Overlays.BeatmapSet
protected readonly FailRetryGraph Graph;
private readonly FillFlowContainer header;
private readonly OsuSpriteText successRateLabel, successPercent, graphLabel;
private readonly OsuSpriteText successPercent;
private readonly Bar successRate;
private readonly Container percentContainer;
@ -42,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet
int playCount = beatmap?.OnlineInfo?.PlayCount ?? 0;
var rate = playCount != 0 ? (float)passCount / playCount : 0;
successPercent.Text = rate.ToString("0%");
successPercent.Text = rate.ToString("0.#%");
successRate.Length = rate;
percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic);
@ -60,12 +60,12 @@ namespace osu.Game.Overlays.BeatmapSet
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
successRateLabel = new OsuSpriteText
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Success Rate",
Font = OsuFont.GetFont(size: 13)
Font = OsuFont.GetFont(size: 12)
},
successRate = new Bar
{
@ -82,15 +82,15 @@ namespace osu.Game.Overlays.BeatmapSet
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopCentre,
Font = OsuFont.GetFont(size: 13),
Font = OsuFont.GetFont(size: 12),
},
},
graphLabel = new OsuSpriteText
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Points of Failure",
Font = OsuFont.GetFont(size: 13),
Font = OsuFont.GetFont(size: 12),
Margin = new MarginPadding { Vertical = 20 },
},
},
@ -105,11 +105,10 @@ namespace osu.Game.Overlays.BeatmapSet
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, OverlayColourProvider colourProvider)
{
successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5;
successRate.AccentColour = colours.Green;
successRate.BackgroundColour = colours.GrayD;
successRate.BackgroundColour = colourProvider.Background6;
updateDisplay();
}