mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 09:07:25 +08:00
Add initial implementation of beatmap carousel no-results-placeholder
This commit is contained in:
parent
df9174ec00
commit
0d32c94104
@ -18,6 +18,7 @@ using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets;
|
||||
@ -80,6 +81,37 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
AddStep("delete all beatmaps", () => manager?.Delete());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPlaceholderBeatmapPresence()
|
||||
{
|
||||
createSongSelect();
|
||||
|
||||
AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Visible);
|
||||
|
||||
addRulesetImportStep(0);
|
||||
AddUntilStep("wait for placeholder hidden", () => getPlaceholder()?.State.Value == Visibility.Hidden);
|
||||
|
||||
AddStep("delete all beatmaps", () => manager?.Delete());
|
||||
AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Visible);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPlaceholderConvertSetting()
|
||||
{
|
||||
changeRuleset(2);
|
||||
addRulesetImportStep(0);
|
||||
AddStep("change convert setting", () => config.SetValue(OsuSetting.ShowConvertedBeatmaps, false));
|
||||
|
||||
createSongSelect();
|
||||
|
||||
AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Visible);
|
||||
|
||||
AddStep("click link in placeholder", () => getPlaceholder().ChildrenOfType<DrawableLinkCompiler>().First().TriggerClick());
|
||||
|
||||
AddUntilStep("convert setting changed", () => config.Get<bool>(OsuSetting.ShowConvertedBeatmaps));
|
||||
AddUntilStep("wait for placeholder visible", () => getPlaceholder()?.State.Value == Visibility.Hidden);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSingleFilterOnEnter()
|
||||
{
|
||||
@ -941,6 +973,8 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
|
||||
private int getBeatmapIndex(BeatmapSetInfo set, BeatmapInfo info) => set.Beatmaps.IndexOf(info);
|
||||
|
||||
private NoResultsPlaceholder getPlaceholder() => songSelect.ChildrenOfType<NoResultsPlaceholder>().FirstOrDefault();
|
||||
|
||||
private int getCurrentBeatmapIndex() => getBeatmapIndex(songSelect.Carousel.SelectedBeatmapSet, songSelect.Carousel.SelectedBeatmapInfo);
|
||||
|
||||
private int getDifficultyIconIndex(DrawableCarouselBeatmapSet set, FilterableDifficultyIcon icon)
|
||||
|
@ -97,6 +97,8 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
protected readonly CarouselScrollContainer Scroll;
|
||||
|
||||
private readonly NoResultsPlaceholder noResultsPlaceholder;
|
||||
|
||||
private IEnumerable<CarouselBeatmapSet> beatmapSets => root.Children.OfType<CarouselBeatmapSet>();
|
||||
|
||||
// todo: only used for testing, maybe remove.
|
||||
@ -170,7 +172,8 @@ namespace osu.Game.Screens.Select
|
||||
Scroll = new CarouselScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
},
|
||||
noResultsPlaceholder = new NoResultsPlaceholder()
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -648,8 +651,18 @@ namespace osu.Game.Screens.Select
|
||||
// First we iterate over all non-filtered carousel items and populate their
|
||||
// vertical position data.
|
||||
if (revalidateItems)
|
||||
{
|
||||
updateYPositions();
|
||||
|
||||
if (visibleItems.Count == 0)
|
||||
{
|
||||
noResultsPlaceholder.Filter = activeCriteria;
|
||||
noResultsPlaceholder.Show();
|
||||
}
|
||||
else
|
||||
noResultsPlaceholder.Hide();
|
||||
}
|
||||
|
||||
// if there is a pending scroll action we apply it without animation and transfer the difference in position to the panels.
|
||||
// this is intentionally applied before updating the visible range below, to avoid animating new items (sourced from pool) from locations off-screen, as it looks bad.
|
||||
if (pendingScrollOperation != PendingScrollOperation.None)
|
||||
|
122
osu.Game/Screens/Select/NoResultsPlaceholder.cs
Normal file
122
osu.Game/Screens/Select/NoResultsPlaceholder.cs
Normal file
@ -0,0 +1,122 @@
|
||||
// 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 osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
public class NoResultsPlaceholder : CompositeDrawable
|
||||
{
|
||||
private FilterCriteria filter;
|
||||
|
||||
private LinkFlowContainer textFlow;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private FirstRunSetupOverlay firstRunSetupOverlay { get; set; }
|
||||
|
||||
public FilterCriteria Filter
|
||||
{
|
||||
get => filter;
|
||||
set
|
||||
{
|
||||
filter = value;
|
||||
Scheduler.AddOnce(updateText);
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Masking = true;
|
||||
CornerRadius = 10;
|
||||
|
||||
Width = 300;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = colours.Gray2,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.Regular.QuestionCircle,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Margin = new MarginPadding(10),
|
||||
Size = new Vector2(50),
|
||||
},
|
||||
textFlow = new LinkFlowContainer
|
||||
{
|
||||
Y = 70,
|
||||
Padding = new MarginPadding(10),
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
this.FadeIn(600, Easing.OutQuint);
|
||||
|
||||
this.ScaleTo(0.8f)
|
||||
.ScaleTo(1f, 1000, Easing.OutElastic);
|
||||
|
||||
Scheduler.AddOnce(updateText);
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
this.FadeOut(200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private void updateText()
|
||||
{
|
||||
textFlow.Clear();
|
||||
|
||||
if (beatmaps.QueryBeatmapSet(s => !s.Protected && !s.DeletePending) == null)
|
||||
{
|
||||
textFlow.AddParagraph("No beatmaps found!");
|
||||
textFlow.AddParagraph(string.Empty);
|
||||
|
||||
textFlow.AddParagraph("Consider running the ");
|
||||
textFlow.AddLink("first run setup", () => firstRunSetupOverlay?.Show());
|
||||
textFlow.AddText(" to load or import some beatmaps!");
|
||||
}
|
||||
else
|
||||
{
|
||||
textFlow.AddParagraph("No beatmaps match your filter criteria!");
|
||||
textFlow.AddParagraph(string.Empty);
|
||||
|
||||
// TODO: hint when beatmaps are available in another ruleset
|
||||
// TODO: hint when beatmaps are available by toggling "show converted".
|
||||
if (!string.IsNullOrEmpty(filter?.SearchText))
|
||||
{
|
||||
textFlow.AddParagraph("You can try ");
|
||||
textFlow.AddLink("searching online", LinkAction.SearchBeatmapSet, filter.SearchText);
|
||||
textFlow.AddText(" for this query.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user