Merge remote-tracking branch 'origin/master' into proper-taiko-hitsounds

This commit is contained in:
smoogipoo 2017-12-27 13:04:10 +09:00
commit ddee9e992a
9 changed files with 289 additions and 131 deletions

View File

@ -1,69 +1,161 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System; using System.Collections.Generic;
using System.Linq;
using OpenTK; using OpenTK;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
public class TestCaseBeatmapInfoWedge : OsuTestCase public class TestCaseBeatmapInfoWedge : OsuTestCase
{ {
private BeatmapManager beatmaps; private RulesetStore rulesets;
private readonly Random random; private TestBeatmapInfoWedge infoWedge;
private readonly BeatmapInfoWedge infoWedge; private readonly List<Beatmap> beatmaps = new List<Beatmap>();
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>(); private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
public TestCaseBeatmapInfoWedge() [BackgroundDependencyLoader]
private void load(OsuGameBase game, RulesetStore rulesets)
{ {
random = new Random(0123); this.rulesets = rulesets;
Add(infoWedge = new BeatmapInfoWedge beatmap.BindTo(game.Beatmap);
}
protected override void LoadComplete()
{
base.LoadComplete();
Add(infoWedge = new TestBeatmapInfoWedge
{ {
Size = new Vector2(0.5f, 245), Size = new Vector2(0.5f, 245),
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Margin = new MarginPadding Margin = new MarginPadding { Top = 20 }
{
Top = 20,
},
}); });
AddStep("show", () => AddStep("show", () =>
{ {
Content.FadeInFromZero(250);
infoWedge.State = Visibility.Visible; infoWedge.State = Visibility.Visible;
infoWedge.UpdateBeatmap(beatmap); infoWedge.UpdateBeatmap(beatmap);
}); });
AddStep("hide", () =>
AddWaitStep(3);
AddStep("hide", () => { infoWedge.State = Visibility.Hidden; });
AddWaitStep(3);
AddStep("show", () => { infoWedge.State = Visibility.Visible; });
foreach (var rulesetInfo in rulesets.AvailableRulesets)
{ {
infoWedge.State = Visibility.Hidden; var ruleset = rulesetInfo.CreateInstance();
Content.FadeOut(100); beatmaps.Add(createTestBeatmap(rulesetInfo));
var name = rulesetInfo.ShortName;
selectBeatmap(name);
// TODO: adjust cases once more info is shown for other gamemodes
switch (ruleset)
{
case OsuRuleset osu:
testOsuBeatmap(osu);
testInfoLabels(5);
break;
default:
testInfoLabels(2);
break;
}
}
testNullBeatmap();
}
private void testOsuBeatmap(OsuRuleset ruleset)
{
AddAssert("check version", () => infoWedge.Info.VersionLabel.Text == $"{ruleset.ShortName}Version");
AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title");
AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Text == $"{ruleset.ShortName}Artist");
AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType<OsuSpriteText>().Any(s => s.Text == $"{ruleset.ShortName}Author"));
}
private void testInfoLabels(int expectedCount)
{
AddAssert("check infolabels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any());
AddAssert("check infolabels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount);
}
private void testNullBeatmap()
{
selectNullBeatmap();
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text));
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title);
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist);
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
}
private void selectBeatmap(string name)
{
var infoBefore = infoWedge.Info;
AddStep($"select {name} beatmap", () =>
{
beatmap.Value = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name));
infoWedge.UpdateBeatmap(beatmap);
}); });
AddStep("random beatmap", randomBeatmap);
AddStep("null beatmap", () => infoWedge.UpdateBeatmap(beatmap.Default)); AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load");
} }
[BackgroundDependencyLoader] private void selectNullBeatmap()
private void load(OsuGameBase game, BeatmapManager beatmaps)
{ {
this.beatmaps = beatmaps; AddStep("select null beatmap", () =>
beatmap.BindTo(game.Beatmap); {
beatmap.Value = beatmap.Default;
infoWedge.UpdateBeatmap(beatmap);
});
} }
private void randomBeatmap() private Beatmap createTestBeatmap(RulesetInfo ruleset)
{ {
var sets = beatmaps.GetAllUsableBeatmapSets(); List<HitObject> objects = new List<HitObject>();
if (sets.Count == 0) for (double i = 0; i < 50000; i += 1000)
return; objects.Add(new HitObject { StartTime = i });
var b = sets[random.Next(0, sets.Count)].Beatmaps[0]; return new Beatmap
beatmap.Value = beatmaps.GetWorkingBeatmap(b); {
infoWedge.UpdateBeatmap(beatmap); BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata
{
AuthorString = $"{ruleset.ShortName}Author",
Artist = $"{ruleset.ShortName}Artist",
Source = $"{ruleset.ShortName}Source",
Title = $"{ruleset.ShortName}Title"
},
Ruleset = ruleset,
StarDifficulty = 6,
Version = $"{ruleset.ShortName}Version"
},
HitObjects = objects
};
}
private class TestBeatmapInfoWedge : BeatmapInfoWedge
{
public new BufferedWedgeInfo Info => base.Info;
} }
} }
} }

View File

@ -26,6 +26,7 @@ namespace osu.Game.Tests.Visual
private RulesetStore rulesets; private RulesetStore rulesets;
private DependencyContainer dependencies; private DependencyContainer dependencies;
private WorkingBeatmap defaultBeatmap;
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
@ -47,31 +48,61 @@ namespace osu.Game.Tests.Visual
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent);
private class TestSongSelect : PlaySongSelect
{
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
public new BeatmapCarousel Carousel => base.Carousel;
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(BeatmapManager baseManager) private void load(BeatmapManager baseManager)
{ {
PlaySongSelect songSelect; TestSongSelect songSelect = null;
if (manager == null) var storage = new TestStorage(@"TestCasePlaySongSelect");
// this is by no means clean. should be replacing inside of OsuGameBase somehow.
var context = new OsuDbContext();
Func<OsuDbContext> contextFactory = () => context;
dependencies.Cache(rulesets = new RulesetStore(contextFactory));
dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null)
{ {
var storage = new TestStorage(@"TestCasePlaySongSelect"); DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null)
});
// this is by no means clean. should be replacing inside of OsuGameBase somehow. void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () =>
var context = new OsuDbContext(); {
if (deleteMaps) manager.DeleteAll();
Func<OsuDbContext> contextFactory = () => context; if (songSelect != null)
dependencies.Cache(rulesets = new RulesetStore(contextFactory));
dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null)
{ {
DefaultBeatmap = baseManager.GetWorkingBeatmap(null) Remove(songSelect);
}); songSelect.Dispose();
}
Add(songSelect = new TestSongSelect());
});
loadNewSongSelect(true);
AddWaitStep(3);
AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap);
AddStep("import test maps", () =>
{
for (int i = 0; i < 100; i += 10) for (int i = 0; i < 100; i += 10)
manager.Import(createTestBeatmapSet(i)); manager.Import(createTestBeatmapSet(i));
} });
Add(songSelect = new PlaySongSelect()); AddWaitStep(3);
AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap);
loadNewSongSelect();
AddWaitStep(3);
AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap);
AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; });
AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; });

View File

@ -21,8 +21,7 @@ namespace osu.Game.Beatmaps
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
{ {
Artist = "please load a beatmap!", Artist = "please load a beatmap!",
Title = "no beatmaps available!", Title = "no beatmaps available!"
AuthorString = "no one",
}, },
BeatmapSet = new BeatmapSetInfo(), BeatmapSet = new BeatmapSetInfo(),
BaseDifficulty = new BeatmapDifficulty BaseDifficulty = new BeatmapDifficulty

View File

@ -47,6 +47,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
if (Beatmap.Value == null) if (Beatmap.Value == null)
return; return;
if (Beatmap.Value.Track.Length == double.PositiveInfinity) return;
float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth);
seekTo(markerPos / DrawWidth * Beatmap.Value.Track.Length); seekTo(markerPos / DrawWidth * Beatmap.Value.Track.Length);
} }

View File

@ -250,7 +250,7 @@ namespace osu.Game.Screens.Play
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
}, },
new MetadataLine("Mapper", metadata.Author.Username) new MetadataLine("Mapper", metadata.AuthorString)
{ {
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,

View File

@ -324,7 +324,14 @@ namespace osu.Game.Screens.Ranking
title.Colour = artist.Colour = colours.BlueDarker; title.Colour = artist.Colour = colours.BlueDarker;
versionMapper.Colour = colours.Gray8; versionMapper.Colour = colours.Gray8;
versionMapper.Text = $"{beatmap.Version} - mapped by {beatmap.Metadata.Author.Username}"; var creator = beatmap.Metadata.Author?.Username;
if (!string.IsNullOrEmpty(creator)) {
versionMapper.Text = $"mapped by {creator}";
if (!string.IsNullOrEmpty(beatmap.Version))
versionMapper.Text = $"{beatmap.Version} - " + versionMapper.Text;
}
title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title); title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title);
artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist); artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist);
} }

View File

@ -75,7 +75,8 @@ namespace osu.Game.Screens.Select
scrollableContent.Clear(false); scrollableContent.Clear(false);
itemsCache.Invalidate(); itemsCache.Invalidate();
scrollPositionCache.Invalidate(); scrollPositionCache.Invalidate();
BeatmapSetsChanged?.Invoke();
Schedule(() => BeatmapSetsChanged?.Invoke());
})); }));
} }
} }
@ -154,6 +155,7 @@ namespace osu.Game.Screens.Select
select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet); select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet);
itemsCache.Invalidate(); itemsCache.Invalidate();
Schedule(() => BeatmapSetsChanged?.Invoke());
}); });
} }
@ -511,7 +513,7 @@ namespace osu.Game.Screens.Select
currentY += DrawHeight / 2; currentY += DrawHeight / 2;
scrollableContent.Height = currentY; scrollableContent.Height = currentY;
if (selectedBeatmapSet != null && (selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)) if (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)
{ {
selectedBeatmapSet = null; selectedBeatmapSet = null;
SelectionChanged?.Invoke(null); SelectionChanged?.Invoke(null);

View File

@ -27,7 +27,7 @@ namespace osu.Game.Screens.Select
{ {
private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0); private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0);
private Drawable info; protected BufferedWedgeInfo Info;
public BeatmapInfoWedge() public BeatmapInfoWedge()
{ {
@ -35,6 +35,7 @@ namespace osu.Game.Screens.Select
Masking = true; Masking = true;
BorderColour = new Color4(221, 255, 255, 255); BorderColour = new Color4(221, 255, 255, 255);
BorderThickness = 2.5f; BorderThickness = 2.5f;
Alpha = 0;
EdgeEffect = new EdgeEffectParameters EdgeEffect = new EdgeEffectParameters
{ {
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,
@ -50,12 +51,14 @@ namespace osu.Game.Screens.Select
{ {
this.MoveToX(0, 800, Easing.OutQuint); this.MoveToX(0, 800, Easing.OutQuint);
this.RotateTo(0, 800, Easing.OutQuint); this.RotateTo(0, 800, Easing.OutQuint);
this.FadeIn(250);
} }
protected override void PopOut() protected override void PopOut()
{ {
this.MoveToX(-100, 800, Easing.InQuint); this.MoveToX(-100, 800, Easing.In);
this.RotateTo(10, 800, Easing.InQuint); this.RotateTo(10, 800, Easing.In);
this.FadeOut(500, Easing.In);
} }
public void UpdateBeatmap(WorkingBeatmap beatmap) public void UpdateBeatmap(WorkingBeatmap beatmap)
@ -63,23 +66,30 @@ namespace osu.Game.Screens.Select
LoadComponentAsync(new BufferedWedgeInfo(beatmap) LoadComponentAsync(new BufferedWedgeInfo(beatmap)
{ {
Shear = -Shear, Shear = -Shear,
Depth = info?.Depth + 1 ?? 0, Depth = Info?.Depth + 1 ?? 0,
}, newInfo => }, newInfo =>
{ {
State = beatmap == null ? Visibility.Hidden : Visibility.Visible;
// ensure we ourselves are visible if not already. // ensure we ourselves are visible if not already.
if (!IsPresent) if (!IsPresent)
this.FadeIn(250); State = Visibility.Visible;
info?.FadeOut(250); Info?.FadeOut(250);
info?.Expire(); Info?.Expire();
Add(info = newInfo); Add(Info = newInfo);
}); });
} }
public class BufferedWedgeInfo : BufferedContainer public class BufferedWedgeInfo : BufferedContainer
{ {
private readonly WorkingBeatmap working; private readonly WorkingBeatmap working;
public OsuSpriteText VersionLabel { get; private set; }
public OsuSpriteText TitleLabel { get; private set; }
public OsuSpriteText ArtistLabel { get; private set; }
public FillFlowContainer MapperContainer { get; private set; }
public FillFlowContainer InfoLabelContainer { get; private set; }
public BufferedWedgeInfo(WorkingBeatmap working) public BufferedWedgeInfo(WorkingBeatmap working)
{ {
@ -89,34 +99,8 @@ namespace osu.Game.Screens.Select
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
BeatmapInfo beatmapInfo = working.BeatmapInfo; var beatmapInfo = working.BeatmapInfo;
BeatmapMetadata metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
Beatmap beatmap = working.Beatmap;
List<InfoLabel> labels = new List<InfoLabel>();
if (beatmap != null)
{
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0;
labels.Add(new InfoLabel(new BeatmapStatistic
{
Name = "Length",
Icon = FontAwesome.fa_clock_o,
Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
}));
labels.Add(new InfoLabel(new BeatmapStatistic
{
Name = "BPM",
Icon = FontAwesome.fa_circle,
Content = getBPMRange(beatmap),
}));
//get statistics from the current ruleset.
labels.AddRange(beatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s)));
}
PixelSnapping = true; PixelSnapping = true;
CacheDrawnFrameBuffer = true; CacheDrawnFrameBuffer = true;
@ -165,7 +149,7 @@ namespace osu.Game.Screens.Select
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
new OsuSpriteText VersionLabel = new OsuSpriteText
{ {
Font = @"Exo2.0-MediumItalic", Font = @"Exo2.0-MediumItalic",
Text = beatmapInfo.Version, Text = beatmapInfo.Version,
@ -175,69 +159,112 @@ namespace osu.Game.Screens.Select
}, },
new FillFlowContainer new FillFlowContainer
{ {
Name = "Bottom-aligned metadata", Name = "Centre-aligned metadata",
Anchor = Anchor.BottomLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.BottomLeft, Origin = Anchor.TopLeft,
Y = -22,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 }, Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 },
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
new OsuSpriteText TitleLabel = new OsuSpriteText
{ {
Font = @"Exo2.0-MediumItalic", Font = @"Exo2.0-MediumItalic",
Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title, Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title,
TextSize = 28, TextSize = 28,
}, },
new OsuSpriteText ArtistLabel = new OsuSpriteText
{ {
Font = @"Exo2.0-MediumItalic", Font = @"Exo2.0-MediumItalic",
Text = metadata.Artist, Text = metadata.Artist,
TextSize = 17, TextSize = 17,
}, },
new FillFlowContainer MapperContainer = new FillFlowContainer
{ {
Margin = new MarginPadding { Top = 10 }, Margin = new MarginPadding { Top = 10 },
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = new[] Children = getMapper(metadata)
{
new OsuSpriteText
{
Font = @"Exo2.0-Medium",
Text = "mapped by ",
TextSize = 15,
},
new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = metadata.Author.Username,
TextSize = 15,
},
}
}, },
new FillFlowContainer InfoLabelContainer = new FillFlowContainer
{ {
Margin = new MarginPadding { Top = 20 }, Margin = new MarginPadding { Top = 20 },
Spacing = new Vector2(20, 0), Spacing = new Vector2(20, 0),
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Children = labels Children = getInfoLabels()
}, }
} }
}, }
}; };
} }
private InfoLabel[] getInfoLabels()
{
var beatmap = working.Beatmap;
var info = working.BeatmapInfo;
List<InfoLabel> labels = new List<InfoLabel>();
if (beatmap?.HitObjects?.Count > 0)
{
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0;
labels.Add(new InfoLabel(new BeatmapStatistic
{
Name = "Length",
Icon = FontAwesome.fa_clock_o,
Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"),
}));
labels.Add(new InfoLabel(new BeatmapStatistic
{
Name = "BPM",
Icon = FontAwesome.fa_circle,
Content = getBPMRange(beatmap),
}));
//get statistics from the current ruleset.
labels.AddRange(info.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s)));
}
return labels.ToArray();
}
private string getBPMRange(Beatmap beatmap) private string getBPMRange(Beatmap beatmap)
{ {
double bpmMax = beatmap.ControlPointInfo.BPMMaximum; double bpmMax = beatmap.ControlPointInfo.BPMMaximum;
double bpmMin = beatmap.ControlPointInfo.BPMMinimum; double bpmMin = beatmap.ControlPointInfo.BPMMinimum;
if (Precision.AlmostEquals(bpmMin, bpmMax)) return $"{bpmMin:0}"; if (Precision.AlmostEquals(bpmMin, bpmMax))
return $"{bpmMin:0}";
return $"{bpmMin:0}-{bpmMax:0} (mostly {beatmap.ControlPointInfo.BPMMode:0})"; return $"{bpmMin:0}-{bpmMax:0} (mostly {beatmap.ControlPointInfo.BPMMode:0})";
} }
private OsuSpriteText[] getMapper(BeatmapMetadata metadata)
{
if (string.IsNullOrEmpty(metadata.Author?.Username))
return Array.Empty<OsuSpriteText>();
return new[]
{
new OsuSpriteText
{
Font = @"Exo2.0-Medium",
Text = "mapped by ",
TextSize = 15,
},
new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = metadata.Author.Username,
TextSize = 15,
}
};
}
public class InfoLabel : Container, IHasTooltip public class InfoLabel : Container, IHasTooltip
{ {
public string TooltipText { get; private set; } public string TooltipText { get; private set; }

View File

@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select
protected Container LeftContent; protected Container LeftContent;
private readonly BeatmapCarousel carousel; protected readonly BeatmapCarousel Carousel;
private readonly BeatmapInfoWedge beatmapInfoWedge; private readonly BeatmapInfoWedge beatmapInfoWedge;
private DialogOverlay dialogOverlay; private DialogOverlay dialogOverlay;
private BeatmapManager beatmaps; private BeatmapManager beatmaps;
@ -118,7 +118,7 @@ namespace osu.Game.Screens.Select
Width = 0.5f, Width = 0.5f,
Children = new Drawable[] Children = new Drawable[]
{ {
carousel = new BeatmapCarousel Carousel = new BeatmapCarousel
{ {
Masking = false, Masking = false,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
@ -132,7 +132,7 @@ namespace osu.Game.Screens.Select
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = filter_height, Height = filter_height,
FilterChanged = c => carousel.Filter(c), FilterChanged = c => Carousel.Filter(c),
Background = { Width = 2 }, Background = { Width = 2 },
Exit = Exit, Exit = Exit,
}, },
@ -141,7 +141,6 @@ namespace osu.Game.Screens.Select
}, },
beatmapInfoWedge = new BeatmapInfoWedge beatmapInfoWedge = new BeatmapInfoWedge
{ {
Alpha = 0,
Size = wedged_container_size, Size = wedged_container_size,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Margin = new MarginPadding Margin = new MarginPadding
@ -150,7 +149,7 @@ namespace osu.Game.Screens.Select
Right = left_area_padding, Right = left_area_padding,
}, },
}, },
new ResetScrollContainer(() => carousel.ScrollToSelected()) new ResetScrollContainer(() => Carousel.ScrollToSelected())
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Width = 250, Width = 250,
@ -210,15 +209,15 @@ namespace osu.Game.Screens.Select
initialAddSetsTask = new CancellationTokenSource(); initialAddSetsTask = new CancellationTokenSource();
carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets(); Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets();
Beatmap.DisabledChanged += disabled => carousel.AllowSelection = !disabled; Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled;
Beatmap.TriggerChange(); Beatmap.TriggerChange();
Beatmap.ValueChanged += b => Beatmap.ValueChanged += b =>
{ {
if (IsCurrentScreen) if (IsCurrentScreen)
carousel.SelectBeatmap(b?.BeatmapInfo); Carousel.SelectBeatmap(b?.BeatmapInfo);
}; };
} }
@ -232,9 +231,9 @@ namespace osu.Game.Screens.Select
{ {
// if we have a pending filter operation, we want to run it now. // if we have a pending filter operation, we want to run it now.
// it could change selection (ie. if the ruleset has been changed). // it could change selection (ie. if the ruleset has been changed).
carousel.FlushPendingFilterOperations(); Carousel.FlushPendingFilterOperations();
carousel.SelectBeatmap(beatmap); Carousel.SelectBeatmap(beatmap);
if (selectionChangedDebounce?.Completed == false) if (selectionChangedDebounce?.Completed == false)
{ {
@ -302,9 +301,9 @@ namespace osu.Game.Screens.Select
private void triggerRandom() private void triggerRandom()
{ {
if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed) if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed)
carousel.SelectPreviousRandom(); Carousel.SelectPreviousRandom();
else else
carousel.SelectNextRandom(); Carousel.SelectNextRandom();
} }
protected override void OnEntering(Screen last) protected override void OnEntering(Screen last)
@ -419,7 +418,6 @@ namespace osu.Game.Screens.Select
backgroundModeBeatmap.FadeTo(1, 250); backgroundModeBeatmap.FadeTo(1, 250);
} }
beatmapInfoWedge.State = Visibility.Visible;
beatmapInfoWedge.UpdateBeatmap(beatmap); beatmapInfoWedge.UpdateBeatmap(beatmap);
} }
@ -437,17 +435,17 @@ namespace osu.Game.Screens.Select
} }
} }
private void onBeatmapSetAdded(BeatmapSetInfo s) => carousel.UpdateBeatmapSet(s); private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s);
private void onBeatmapSetRemoved(BeatmapSetInfo s) => carousel.RemoveBeatmapSet(s); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s);
private void onBeatmapRestored(BeatmapInfo b) => carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));
private void onBeatmapHidden(BeatmapInfo b) => carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));
private void carouselBeatmapsLoaded() private void carouselBeatmapsLoaded()
{ {
if (Beatmap.Value.BeatmapSetInfo?.DeletePending == false) if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false)
carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo);
else else
carousel.SelectNextRandom(); Carousel.SelectNextRandom();
} }
private void delete(BeatmapSetInfo beatmap) private void delete(BeatmapSetInfo beatmap)