1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-21 04:23:00 +08:00

Merge remote-tracking branch 'refs/remotes/ppy/master' into subcomments-alter-new

This commit is contained in:
Andrei Zavatski 2020-02-12 23:32:28 +03:00
commit ec9c01a75f
26 changed files with 201 additions and 76 deletions

View File

@ -5,9 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapSet; using osu.Game.Overlays.BeatmapSet;
using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Details;
@ -22,6 +24,9 @@ namespace osu.Game.Tests.Visual.Online
private RatingsExposingDetails details; private RatingsExposingDetails details;
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
[SetUp] [SetUp]
public void Setup() => Schedule(() => public void Setup() => Schedule(() =>
{ {
@ -55,8 +60,12 @@ namespace osu.Game.Tests.Visual.Online
{ {
Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(), Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(), Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(),
} },
} }
},
OnlineInfo = new BeatmapSetOnlineInfo
{
Status = BeatmapSetOnlineStatus.Ranked
} }
}; };
} }

View File

@ -5,11 +5,13 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapSet; using osu.Game.Overlays.BeatmapSet;
using osu.Game.Screens.Select.Details; using osu.Game.Screens.Select.Details;
using osuTK; using osuTK;
@ -26,6 +28,9 @@ namespace osu.Game.Tests.Visual.Online
private GraphExposingSuccessRate successRate; private GraphExposingSuccessRate successRate;
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
[SetUp] [SetUp]
public void Setup() => Schedule(() => public void Setup() => Schedule(() =>
{ {

View File

@ -7,11 +7,16 @@ using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Screens.Select.Leaderboards; using osu.Game.Screens.Select.Leaderboards;
using osu.Framework.Allocation;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
{ {
public class TestSceneLeaderboardScopeSelector : OsuTestScene public class TestSceneLeaderboardScopeSelector : OsuTestScene
{ {
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(LeaderboardScopeSelector), typeof(LeaderboardScopeSelector),

View File

@ -17,6 +17,7 @@ using osu.Framework.Screens;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -426,6 +427,44 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("start not requested", () => !startRequested); AddAssert("start not requested", () => !startRequested);
} }
[TestCase(false)]
[TestCase(true)]
public void TestExternalBeatmapChangeWhileFiltered(bool differentRuleset)
{
createSongSelect();
addManyTestMaps();
changeRuleset(0);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null);
AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nonono");
AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap);
AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmap == null);
BeatmapInfo target = null;
AddStep("select beatmap externally", () =>
{
target = manager.GetAllUsableBeatmapSets().Where(b => b.Beatmaps.Any(bi => bi.RulesetID == (differentRuleset ? 1 : 0)))
.ElementAt(5).Beatmaps.First();
Beatmap.Value = manager.GetWorkingBeatmap(target);
});
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null);
AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID);
AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
AddStep("reset filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = string.Empty);
AddAssert("game still correct", () => Beatmap.Value?.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
AddAssert("carousel still correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID);
}
[Test] [Test]
public void TestAutoplayViaCtrlEnter() public void TestAutoplayViaCtrlEnter()
{ {
@ -468,6 +507,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void importForRuleset(int id) => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())).Wait(); private void importForRuleset(int id) => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())).Wait();
private static int importId; private static int importId;
private int getImportId() => ++importId; private int getImportId() => ++importId;
private void checkMusicPlaying(bool playing) => private void checkMusicPlaying(bool playing) =>
@ -551,6 +591,8 @@ namespace osu.Game.Tests.Visual.SongSelect
public new Bindable<RulesetInfo> Ruleset => base.Ruleset; public new Bindable<RulesetInfo> Ruleset => base.Ruleset;
public new FilterControl FilterControl => base.FilterControl;
public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap;
public new BeatmapCarousel Carousel => base.Carousel; public new BeatmapCarousel Carousel => base.Carousel;

View File

@ -13,6 +13,7 @@ namespace osu.Game.Beatmaps.Drawables
public class BeatmapSetOnlineStatusPill : CircularContainer public class BeatmapSetOnlineStatusPill : CircularContainer
{ {
private readonly OsuSpriteText statusText; private readonly OsuSpriteText statusText;
private readonly Box background;
private BeatmapSetOnlineStatus status; private BeatmapSetOnlineStatus status;
@ -43,6 +44,12 @@ namespace osu.Game.Beatmaps.Drawables
set => statusText.Padding = value; set => statusText.Padding = value;
} }
public Color4 BackgroundColour
{
get => background.Colour;
set => background.Colour = value;
}
public BeatmapSetOnlineStatusPill() public BeatmapSetOnlineStatusPill()
{ {
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
@ -50,7 +57,7 @@ namespace osu.Game.Beatmaps.Drawables
Children = new Drawable[] Children = new Drawable[]
{ {
new Box background = new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black, Colour = Color4.Black,

View File

@ -49,14 +49,7 @@ namespace osu.Game.Graphics.UserInterface
public GradientLine() public GradientLine()
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Size = new Vector2(0.8f, 1.5f); Size = new Vector2(0.8f, 1f);
ColumnDimensions = new[]
{
new Dimension(),
new Dimension(mode: GridSizeMode.Relative, size: 0.4f),
new Dimension(),
};
Content = new[] Content = new[]
{ {
@ -65,16 +58,12 @@ namespace osu.Game.Graphics.UserInterface
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(Color4.Transparent, Color4.White) Colour = ColourInfo.GradientHorizontal(Color4.Transparent, Colour)
}, },
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, Colour = ColourInfo.GradientHorizontal(Colour, Color4.Transparent)
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Transparent)
}, },
} }
}; };

View File

@ -446,7 +446,7 @@ namespace osu.Game
/// </summary> /// </summary>
/// <param name="action">The action to perform once we are in the correct state.</param> /// <param name="action">The action to perform once we are in the correct state.</param>
/// <param name="validScreens">An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. <see cref="MainMenu"/> is used if not specified.</param> /// <param name="validScreens">An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. <see cref="MainMenu"/> is used if not specified.</param>
protected void PerformFromScreen(Action<IScreen> action, IEnumerable<Type> validScreens = null) public void PerformFromScreen(Action<IScreen> action, IEnumerable<Type> validScreens = null)
{ {
performFromMainMenuTask?.Cancel(); performFromMainMenuTask?.Cancel();

View File

@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
}, },
new OsuSpriteText new OsuSpriteText
{ {
Text = BeatmapSet.Value.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty, Text = getVideoSuffixText(),
Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold) Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold)
}, },
}; };
@ -163,5 +163,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
private void userChanged(ValueChangedEvent<User> e) => button.Enabled.Value = !(e.NewValue is GuestUser); 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 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.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
@ -14,7 +13,6 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Overlays.Direct; using osu.Game.Overlays.Direct;
using osuTK; using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet.Buttons namespace osu.Game.Overlays.BeatmapSet.Buttons
{ {
@ -22,7 +20,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
{ {
private const float transition_duration = 500; private const float transition_duration = 500;
private readonly Box bg, progress; private readonly Box background, progress;
private readonly PlayButton playButton; private readonly PlayButton playButton;
private PreviewTrack preview => playButton.Preview; private PreviewTrack preview => playButton.Preview;
@ -40,10 +38,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Children = new Drawable[] Children = new Drawable[]
{ {
bg = new Box background = new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.25f), Alpha = 0.5f
}, },
new Container new Container
{ {
@ -71,9 +69,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours, OverlayColourProvider colourProvider)
{ {
progress.Colour = colours.Yellow; progress.Colour = colours.Yellow;
background.Colour = colourProvider.Background6;
} }
protected override void Update() protected override void Update()
@ -91,13 +90,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
protected override bool OnHover(HoverEvent e) protected override bool OnHover(HoverEvent e)
{ {
bg.FadeColour(Color4.Black.Opacity(0.5f), 100); background.FadeTo(0.75f, 80);
return base.OnHover(e); return base.OnHover(e);
} }
protected override void OnHoverLost(HoverLostEvent e) protected override void OnHoverLost(HoverLostEvent e)
{ {
bg.FadeColour(Color4.Black.Opacity(0.25f), 100); background.FadeTo(0.5f, 80);
base.OnHoverLost(e); base.OnHoverLost(e);
} }
} }

View File

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

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Linq; using System.Linq;
@ -30,6 +30,7 @@ namespace osu.Game.Overlays.BeatmapSet
private const float buttons_spacing = 5; private const float buttons_spacing = 5;
private readonly UpdateableBeatmapSetCover cover; private readonly UpdateableBeatmapSetCover cover;
private readonly Box coverGradient;
private readonly OsuSpriteText title, artist; private readonly OsuSpriteText title, artist;
private readonly AuthorInfo author; private readonly AuthorInfo author;
private readonly FillFlowContainer downloadButtonsContainer; private readonly FillFlowContainer downloadButtonsContainer;
@ -93,10 +94,9 @@ namespace osu.Game.Overlays.BeatmapSet
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Masking = true, Masking = true,
}, },
new Box coverGradient = new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)),
}, },
}, },
}, },
@ -106,8 +106,7 @@ namespace osu.Game.Overlays.BeatmapSet
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding Padding = new MarginPadding
{ {
Top = 20, Vertical = BeatmapSetOverlay.Y_PADDING,
Bottom = 30,
Left = BeatmapSetOverlay.X_PADDING, Left = BeatmapSetOverlay.X_PADDING,
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
}, },
@ -130,11 +129,12 @@ namespace osu.Game.Overlays.BeatmapSet
{ {
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 15 },
Children = new Drawable[] Children = new Drawable[]
{ {
title = new OsuSpriteText title = new OsuSpriteText
{ {
Font = OsuFont.GetFont(size: 37, weight: FontWeight.Bold, italics: true) Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true)
}, },
externalLink = new ExternalLinkButton externalLink = new ExternalLinkButton
{ {
@ -144,7 +144,7 @@ namespace osu.Game.Overlays.BeatmapSet
}, },
} }
}, },
artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.SemiBold, italics: true) }, artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true) },
new Container new Container
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
@ -187,7 +187,7 @@ namespace osu.Game.Overlays.BeatmapSet
Anchor = Anchor.BottomRight, Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight, Origin = Anchor.BottomRight,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING }, Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING },
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Spacing = new Vector2(10), Spacing = new Vector2(10),
Children = new Drawable[] Children = new Drawable[]
@ -197,7 +197,7 @@ namespace osu.Game.Overlays.BeatmapSet
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
TextSize = 14, TextSize = 14,
TextPadding = new MarginPadding { Horizontal = 25, Vertical = 8 } TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 }
}, },
Details = new Details(), Details = new Details(),
}, },
@ -215,8 +215,11 @@ namespace osu.Game.Overlays.BeatmapSet
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OverlayColourProvider colourProvider)
{ {
coverGradient.Colour = ColourInfo.GradientVertical(colourProvider.Background6.Opacity(0.3f), colourProvider.Background6.Opacity(0.8f));
onlineStatusPill.BackgroundColour = colourProvider.Background6;
State.BindValueChanged(_ => updateDownloadButtons()); State.BindValueChanged(_ => updateDownloadButtons());
BeatmapSet.BindValueChanged(setInfo => BeatmapSet.BindValueChanged(setInfo =>

View File

@ -38,6 +38,8 @@ namespace osu.Game.Overlays.BeatmapSet
public Info() public Info()
{ {
MetadataSection source, tags, genre, language; MetadataSection source, tags, genre, language;
OsuSpriteText unrankedPlaceholder;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = 220; Height = 220;
Masking = true; Masking = true;
@ -110,6 +112,14 @@ namespace osu.Game.Overlays.BeatmapSet
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 20, Horizontal = 15 }, 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)
},
}, },
}, },
}, },
@ -122,6 +132,9 @@ namespace osu.Game.Overlays.BeatmapSet
tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty;
genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty; genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty;
language.Text = b.NewValue?.OnlineInfo?.Language?.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;
}; };
} }

View File

@ -26,10 +26,10 @@ namespace osu.Game.Overlays.BeatmapSet
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OverlayColourProvider colourProvider)
{ {
AccentColour = colours.Blue; AccentColour = colourProvider.Highlight1;
LineColour = Color4.Gray; LineColour = colourProvider.Background1;
} }
private class ScopeSelectorTabItem : PageTabItem private class ScopeSelectorTabItem : PageTabItem

View File

@ -77,9 +77,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
new TableColumn("rank", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), new TableColumn("rank", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("", Anchor.Centre, new Dimension(GridSizeMode.Absolute, 70)), // grade new TableColumn("", Anchor.Centre, new Dimension(GridSizeMode.Absolute, 70)), // grade
new TableColumn("score", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), new TableColumn("score", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 60, maxSize: 70)),
new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 150)), 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("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 110))
}; };
foreach (var statistic in score.SortedStatistics) foreach (var statistic in score.SortedStatistics)

View File

@ -30,7 +30,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = 25; Height = 25;
CornerRadius = 3; CornerRadius = 5;
Masking = true; Masking = true;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]

View File

@ -164,7 +164,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Masking = true, Masking = true,
CornerRadius = 10, CornerRadius = 5,
Child = loading = new DimmedLoadingLayer(iconScale: 0.8f) Child = loading = new DimmedLoadingLayer(iconScale: 0.8f)
{ {
Alpha = 0, Alpha = 0,

View File

@ -118,26 +118,42 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{ {
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
InternalChild = new FillFlowContainer InternalChild = new GridContainer
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical, ColumnDimensions = new[]
Spacing = new Vector2(0, 1),
Children = new[]
{ {
text = new OsuSpriteText new Dimension(GridSizeMode.AutoSize, minSize: minWidth ?? 0)
},
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.Absolute, 4),
new Dimension(GridSizeMode.AutoSize)
},
Content = new[]
{
new Drawable[]
{ {
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), text = new OsuSpriteText
Text = title.ToUpper() {
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold),
Text = title.ToUpper()
}
}, },
separator = new Box new Drawable[]
{ {
RelativeSizeAxes = minWidth == null ? Axes.X : Axes.None, separator = new Box
Width = minWidth ?? 1f, {
Height = 2, Anchor = Anchor.CentreLeft,
Margin = new MarginPadding { Top = 2 } RelativeSizeAxes = Axes.X,
Height = 2
}
}, },
content new[]
{
content
}
} }
}; };
} }

View File

@ -96,13 +96,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) Font = OsuFont.GetFont(size: 10)
}, },
flag = new UpdateableFlag flag = new UpdateableFlag
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Size = new Vector2(19, 13), Size = new Vector2(19, 13),
Margin = new MarginPadding { Top = 3 }, // makes spacing look more even
ShowPlaceholderOnNull = false, ShowPlaceholderOnNull = false,
}, },
} }

View File

@ -42,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet
int playCount = beatmap?.OnlineInfo?.PlayCount ?? 0; int playCount = beatmap?.OnlineInfo?.PlayCount ?? 0;
var rate = playCount != 0 ? (float)passCount / playCount : 0; var rate = playCount != 0 ? (float)passCount / playCount : 0;
successPercent.Text = rate.ToString("0%"); successPercent.Text = rate.ToString("0.#%");
successRate.Length = rate; successRate.Length = rate;
percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic);
@ -105,10 +105,10 @@ namespace osu.Game.Overlays.BeatmapSet
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours, OverlayColourProvider colourProvider)
{ {
successRate.AccentColour = colours.Green; successRate.AccentColour = colours.Green;
successRate.BackgroundColour = colours.GrayD; successRate.BackgroundColour = colourProvider.Background6;
updateDisplay(); updateDisplay();
} }

View File

@ -21,7 +21,7 @@ namespace osu.Game.Overlays
public class BeatmapSetOverlay : FullscreenOverlay public class BeatmapSetOverlay : FullscreenOverlay
{ {
public const float X_PADDING = 40; public const float X_PADDING = 40;
public const float TOP_PADDING = 25; public const float Y_PADDING = 25;
public const float RIGHT_WIDTH = 275; public const float RIGHT_WIDTH = 275;
protected readonly Header Header; protected readonly Header Header;

View File

@ -265,7 +265,7 @@ namespace osu.Game.Rulesets.Edit
{ {
EditorBeatmap.Add(hitObject); EditorBeatmap.Add(hitObject);
adjustableClock.Seek(hitObject.StartTime); adjustableClock.Seek(hitObject.GetEndTime());
} }
showGridFor(Enumerable.Empty<HitObject>()); showGridFor(Enumerable.Empty<HitObject>());

View File

@ -141,12 +141,15 @@ namespace osu.Game.Screens.Menu
preloadSongSelect(); preloadSongSelect();
} }
[Resolved]
private OsuGame game { get; set; }
private void confirmAndExit() private void confirmAndExit()
{ {
if (exitConfirmed) return; if (exitConfirmed) return;
exitConfirmed = true; exitConfirmed = true;
this.Exit(); game.PerformFromScreen(menu => menu.Exit());
} }
private void preloadSongSelect() private void preloadSongSelect()

View File

@ -229,6 +229,17 @@ namespace osu.Game.Screens.Select
if (item != null) if (item != null)
{ {
select(item); select(item);
// if we got here and the set is filtered, it means we were bypassing filters.
// in this case, reapplying the filter is necessary to ensure the panel is in the correct place
// (since it is forcefully being included in the carousel).
if (set.Filtered.Value)
{
Debug.Assert(bypassFilters);
applyActiveCriteria(false, true);
}
return true; return true;
} }
} }

View File

@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select.Carousel
/// <summary> /// <summary>
/// All beatmaps which are not filtered and valid for display. /// All beatmaps which are not filtered and valid for display.
/// </summary> /// </summary>
protected IEnumerable<BeatmapInfo> ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value).Select(b => b.Beatmap); protected IEnumerable<BeatmapInfo> ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value || b.State.Value == CarouselItemState.Selected).Select(b => b.Beatmap);
private int compareUsingAggregateMax(CarouselBeatmapSet other, Func<BeatmapInfo, double> func) private int compareUsingAggregateMax(CarouselBeatmapSet other, Func<BeatmapInfo, double> func)
{ {

View File

@ -16,7 +16,7 @@ namespace osu.Game.Screens.Select.Carousel
/// <summary> /// <summary>
/// This item is not in a hidden state. /// This item is not in a hidden state.
/// </summary> /// </summary>
public bool Visible => State.Value != CarouselItemState.Collapsed && !Filtered.Value; public bool Visible => State.Value == CarouselItemState.Selected || (State.Value != CarouselItemState.Collapsed && !Filtered.Value);
public virtual List<DrawableCarouselItem> Drawables public virtual List<DrawableCarouselItem> Drawables
{ {

View File

@ -376,16 +376,22 @@ namespace osu.Game.Screens.Select
private void workingBeatmapChanged(ValueChangedEvent<WorkingBeatmap> e) private void workingBeatmapChanged(ValueChangedEvent<WorkingBeatmap> e)
{ {
if (e.NewValue is DummyWorkingBeatmap) return; if (e.NewValue is DummyWorkingBeatmap || !this.IsCurrentScreen()) return;
if (this.IsCurrentScreen() && !Carousel.SelectBeatmap(e.NewValue?.BeatmapInfo, false)) if (!Carousel.SelectBeatmap(e.NewValue.BeatmapInfo, false))
{ {
// If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch // A selection may not have been possible with filters applied.
if (e.NewValue?.BeatmapInfo?.Ruleset != null && !e.NewValue.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value))
// There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match.
if (e.NewValue.BeatmapInfo.Ruleset != null && !e.NewValue.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value))
{ {
Ruleset.Value = e.NewValue.BeatmapInfo.Ruleset; Ruleset.Value = e.NewValue.BeatmapInfo.Ruleset;
Carousel.SelectBeatmap(e.NewValue.BeatmapInfo); transferRulesetValue();
} }
// Even if a ruleset mismatch was not the cause (ie. a text filter is applied),
// we still want to forcefully show the new beatmap, bypassing filters.
Carousel.SelectBeatmap(e.NewValue.BeatmapInfo);
} }
} }