diff --git a/osu.Android.props b/osu.Android.props
index 13b4b6ebbb..924e9c4a16 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
index 600efefca3..4ef9bbe091 100644
--- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
@@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Osu.UI
{
public class OsuPlayfield : Playfield
{
- private readonly ApproachCircleProxyContainer approachCircles;
+ private readonly ProxyContainer approachCircles;
+ private readonly ProxyContainer spinnerProxies;
private readonly JudgementContainer judgementLayer;
private readonly FollowPointRenderer followPoints;
private readonly OrderedHitPolicy hitPolicy;
@@ -38,6 +39,10 @@ namespace osu.Game.Rulesets.Osu.UI
{
InternalChildren = new Drawable[]
{
+ spinnerProxies = new ProxyContainer
+ {
+ RelativeSizeAxes = Axes.Both
+ },
followPoints = new FollowPointRenderer
{
RelativeSizeAxes = Axes.Both,
@@ -54,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.UI
{
Child = HitObjectContainer,
},
- approachCircles = new ApproachCircleProxyContainer
+ approachCircles = new ProxyContainer
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
@@ -76,6 +81,9 @@ namespace osu.Game.Rulesets.Osu.UI
h.OnNewResult += onNewResult;
h.OnLoadComplete += d =>
{
+ if (d is DrawableSpinner)
+ spinnerProxies.Add(d.CreateProxy());
+
if (d is IDrawableHitObjectWithProxiedApproach c)
approachCircles.Add(c.ProxiedLayer.CreateProxy());
};
@@ -113,9 +121,9 @@ namespace osu.Game.Rulesets.Osu.UI
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);
- private class ApproachCircleProxyContainer : LifetimeManagementContainer
+ private class ProxyContainer : LifetimeManagementContainer
{
- public void Add(Drawable approachCircleProxy) => AddInternal(approachCircleProxy);
+ public void Add(Drawable proxy) => AddInternal(proxy);
}
private class DrawableJudgementPool : DrawablePool
diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs
index c3acc2ebe7..6b95931b21 100644
--- a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs
@@ -6,9 +6,9 @@ using osu.Framework.IO.Stores;
using osu.Framework.Testing;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
-using osu.Game.Skinning;
using osu.Game.Tests.Beatmaps;
using osu.Game.Tests.Resources;
+using static osu.Game.Skinning.LegacySkinConfiguration;
namespace osu.Game.Tests.Gameplay
{
@@ -211,7 +211,7 @@ namespace osu.Game.Tests.Gameplay
}
///
- /// Tests that when a custom sample bank is used, but is disabled,
+ /// Tests that when a custom sample bank is used, but is disabled,
/// only the additional sound will be looked up.
///
[Test]
@@ -230,7 +230,7 @@ namespace osu.Game.Tests.Gameplay
}
///
- /// Tests that when a normal sample bank is used and is disabled,
+ /// Tests that when a normal sample bank is used and is disabled,
/// the normal sound will be looked up anyway.
///
[Test]
@@ -247,6 +247,6 @@ namespace osu.Game.Tests.Gameplay
}
private void disableLayeredHitSounds()
- => AddStep("set LayeredHitSounds to false", () => Skin.Configuration.ConfigDictionary[GlobalSkinConfiguration.LayeredHitSounds.ToString()] = "0");
+ => AddStep("set LayeredHitSounds to false", () => Skin.Configuration.ConfigDictionary[LegacySetting.LayeredHitSounds.ToString()] = "0");
}
}
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs
new file mode 100644
index 0000000000..c51204eaba
--- /dev/null
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs
@@ -0,0 +1,150 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics;
+using osu.Game.Overlays.Dashboard.Home;
+using osu.Game.Beatmaps;
+using osu.Game.Overlays;
+using osu.Framework.Allocation;
+using osu.Game.Users;
+using System;
+using osu.Framework.Graphics.Shapes;
+using System.Collections.Generic;
+
+namespace osu.Game.Tests.Visual.UserInterface
+{
+ public class TestSceneDashboardBeatmapListing : OsuTestScene
+ {
+ [Cached]
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
+
+ private readonly Container content;
+
+ public TestSceneDashboardBeatmapListing()
+ {
+ Add(content = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Y,
+ Width = 300,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = colourProvider.Background4
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Padding = new MarginPadding { Horizontal = 10 },
+ Child = new DashboardBeatmapListing(new_beatmaps, popular_beatmaps)
+ }
+ }
+ });
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ AddStep("Set width to 500", () => content.ResizeWidthTo(500, 500));
+ AddStep("Set width to 300", () => content.ResizeWidthTo(300, 500));
+ }
+
+ private static readonly List new_beatmaps = new List
+ {
+ new BeatmapSetInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Title = "Very Long Title (TV size) [TATOE]",
+ Artist = "This artist has a really long name how is this possible",
+ Author = new User
+ {
+ Username = "author",
+ Id = 100
+ }
+ },
+ OnlineInfo = new BeatmapSetOnlineInfo
+ {
+ Covers = new BeatmapSetOnlineCovers
+ {
+ Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608",
+ },
+ Ranked = DateTimeOffset.Now
+ }
+ },
+ new BeatmapSetInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Title = "Very Long Title (TV size) [TATOE]",
+ Artist = "This artist has a really long name how is this possible",
+ Author = new User
+ {
+ Username = "author",
+ Id = 100
+ }
+ },
+ OnlineInfo = new BeatmapSetOnlineInfo
+ {
+ Covers = new BeatmapSetOnlineCovers
+ {
+ Cover = "https://assets.ppy.sh/beatmaps/1189904/covers/cover.jpg?1595456608",
+ },
+ Ranked = DateTimeOffset.MinValue
+ }
+ }
+ };
+
+ private static readonly List popular_beatmaps = new List
+ {
+ new BeatmapSetInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Title = "Title",
+ Artist = "Artist",
+ Author = new User
+ {
+ Username = "author",
+ Id = 100
+ }
+ },
+ OnlineInfo = new BeatmapSetOnlineInfo
+ {
+ Covers = new BeatmapSetOnlineCovers
+ {
+ Cover = "https://assets.ppy.sh/beatmaps/1079428/covers/cover.jpg?1595295586",
+ },
+ FavouriteCount = 100
+ }
+ },
+ new BeatmapSetInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Title = "Title 2",
+ Artist = "Artist 2",
+ Author = new User
+ {
+ Username = "someone",
+ Id = 100
+ }
+ },
+ OnlineInfo = new BeatmapSetOnlineInfo
+ {
+ Covers = new BeatmapSetOnlineCovers
+ {
+ Cover = "https://assets.ppy.sh/beatmaps/1079428/covers/cover.jpg?1595295586",
+ },
+ FavouriteCount = 10
+ }
+ }
+ };
+ }
+}
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
index 010e4330d7..5582cc6826 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -263,7 +264,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private void moveLogoFacade()
{
- if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0)
+ if (!(logoFacade?.Transforms).Any() && !(transferContainer?.Transforms).Any())
{
Random random = new Random();
trackingContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300);
diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs
index 278f2d849f..98f60d52d3 100644
--- a/osu.Game/OsuGameBase.cs
+++ b/osu.Game/OsuGameBase.cs
@@ -36,6 +36,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Skinning;
using osuTK.Input;
+using RuntimeInfo = osu.Framework.RuntimeInfo;
namespace osu.Game
{
@@ -134,8 +135,17 @@ namespace osu.Game
[BackgroundDependencyLoader]
private void load()
{
- using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location))
- VersionHash = str.ComputeMD5Hash();
+ try
+ {
+ using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location))
+ VersionHash = str.ComputeMD5Hash();
+ }
+ catch
+ {
+ // special case for android builds, which can't read DLLs from a packed apk.
+ // should eventually be handled in a better way.
+ VersionHash = $"{Version}-{RuntimeInfo.OS}".ComputeMD5Hash();
+ }
Resources.AddStore(new DllResourceStore(OsuResources.ResourceAssembly));
diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs
new file mode 100644
index 0000000000..4d96825353
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs
@@ -0,0 +1,43 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Beatmaps;
+using osuTK;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public class DashboardBeatmapListing : CompositeDrawable
+ {
+ private readonly List newBeatmaps;
+ private readonly List popularBeatmaps;
+
+ public DashboardBeatmapListing(List newBeatmaps, List popularBeatmaps)
+ {
+ this.newBeatmaps = newBeatmaps;
+ this.popularBeatmaps = popularBeatmaps;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
+ InternalChild = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 10),
+ Children = new DrawableBeatmapList[]
+ {
+ new DrawableNewBeatmapList(newBeatmaps),
+ new DrawablePopularBeatmapList(popularBeatmaps)
+ }
+ };
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs
new file mode 100644
index 0000000000..3badea155d
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs
@@ -0,0 +1,168 @@
+// Copyright (c) ppy Pty Ltd . 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.Framework.Input.Events;
+using osu.Game.Beatmaps;
+using osu.Game.Beatmaps.Drawables;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public abstract class DashboardBeatmapPanel : OsuClickableContainer
+ {
+ [Resolved]
+ protected OverlayColourProvider ColourProvider { get; private set; }
+
+ [Resolved(canBeNull: true)]
+ private BeatmapSetOverlay beatmapOverlay { get; set; }
+
+ protected readonly BeatmapSetInfo SetInfo;
+
+ private Box hoverBackground;
+ private SpriteIcon chevron;
+
+ protected DashboardBeatmapPanel(BeatmapSetInfo setInfo)
+ {
+ SetInfo = setInfo;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ RelativeSizeAxes = Axes.X;
+ Height = 60;
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Horizontal = -10 },
+ Child = hoverBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = ColourProvider.Background3,
+ Alpha = 0
+ }
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = new GridContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ ColumnDimensions = new[]
+ {
+ new Dimension(GridSizeMode.Absolute, 70),
+ new Dimension(),
+ new Dimension(GridSizeMode.AutoSize)
+ },
+ RowDimensions = new[]
+ {
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ CornerRadius = 6,
+ Child = new UpdateableBeatmapSetCover
+ {
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ BeatmapSet = SetInfo
+ }
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Horizontal = 10 },
+ Child = new FillFlowContainer
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ AutoSizeAxes = Axes.Y,
+ RelativeSizeAxes = Axes.X,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ RelativeSizeAxes = Axes.X,
+ Truncate = true,
+ Font = OsuFont.GetFont(weight: FontWeight.Regular),
+ Text = SetInfo.Metadata.Title
+ },
+ new OsuSpriteText
+ {
+ RelativeSizeAxes = Axes.X,
+ Truncate = true,
+ Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular),
+ Text = SetInfo.Metadata.Artist
+ },
+ new LinkFlowContainer(f => f.Font = OsuFont.GetFont(size: 10, weight: FontWeight.Regular))
+ {
+ AutoSizeAxes = Axes.Y,
+ RelativeSizeAxes = Axes.X,
+ Spacing = new Vector2(3),
+ Margin = new MarginPadding { Top = 2 }
+ }.With(c =>
+ {
+ c.AddText("by");
+ c.AddUserLink(SetInfo.Metadata.Author);
+ c.AddArbitraryDrawable(CreateInfo());
+ })
+ }
+ }
+ },
+ chevron = new SpriteIcon
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ Size = new Vector2(16),
+ Icon = FontAwesome.Solid.ChevronRight,
+ Colour = ColourProvider.Foreground1
+ }
+ }
+ }
+ }
+ }
+ };
+
+ Action = () =>
+ {
+ if (SetInfo.OnlineBeatmapSetID.HasValue)
+ beatmapOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value);
+ };
+ }
+
+ protected abstract Drawable CreateInfo();
+
+ protected override bool OnHover(HoverEvent e)
+ {
+ base.OnHover(e);
+ hoverBackground.FadeIn(200, Easing.OutQuint);
+ chevron.FadeColour(ColourProvider.Light1, 200, Easing.OutQuint);
+ return true;
+ }
+
+ protected override void OnHoverLost(HoverLostEvent e)
+ {
+ base.OnHoverLost(e);
+ hoverBackground.FadeOut(200, Easing.OutQuint);
+ chevron.FadeColour(ColourProvider.Foreground1, 200, Easing.OutQuint);
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs
new file mode 100644
index 0000000000..b212eaf20a
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs
@@ -0,0 +1,23 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Framework.Graphics;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public class DashboardNewBeatmapPanel : DashboardBeatmapPanel
+ {
+ public DashboardNewBeatmapPanel(BeatmapSetInfo setInfo)
+ : base(setInfo)
+ {
+ }
+
+ protected override Drawable CreateInfo() => new DrawableDate(SetInfo.OnlineInfo.Ranked ?? DateTimeOffset.Now, 10, false)
+ {
+ Colour = ColourProvider.Foreground1
+ };
+ }
+}
diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs
new file mode 100644
index 0000000000..e9066c0657
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs
@@ -0,0 +1,42 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public class DashboardPopularBeatmapPanel : DashboardBeatmapPanel
+ {
+ public DashboardPopularBeatmapPanel(BeatmapSetInfo setInfo)
+ : base(setInfo)
+ {
+ }
+
+ protected override Drawable CreateInfo() => new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(3, 0),
+ Colour = ColourProvider.Foreground1,
+ Children = new Drawable[]
+ {
+ new SpriteIcon
+ {
+ Size = new Vector2(10),
+ Icon = FontAwesome.Solid.Heart
+ },
+ new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 10, weight: FontWeight.Regular),
+ Text = SetInfo.OnlineInfo.FavouriteCount.ToString()
+ }
+ }
+ };
+ }
+}
diff --git a/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs
new file mode 100644
index 0000000000..f6535b7db3
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs
@@ -0,0 +1,56 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using System.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public abstract class DrawableBeatmapList : CompositeDrawable
+ {
+ private readonly List beatmaps;
+
+ protected DrawableBeatmapList(List beatmaps)
+ {
+ this.beatmaps = beatmaps;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
+ FillFlowContainer flow;
+
+ RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
+ InternalChild = flow = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 10),
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold),
+ Colour = colourProvider.Light1,
+ Text = Title
+ }
+ }
+ };
+
+ flow.AddRange(beatmaps.Select(CreateBeatmapPanel));
+ }
+
+ protected abstract string Title { get; }
+
+ protected abstract DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo);
+ }
+}
diff --git a/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs
new file mode 100644
index 0000000000..75e8ca336d
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs
@@ -0,0 +1,20 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Game.Beatmaps;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public class DrawableNewBeatmapList : DrawableBeatmapList
+ {
+ public DrawableNewBeatmapList(List beatmaps)
+ : base(beatmaps)
+ {
+ }
+
+ protected override DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo) => new DashboardNewBeatmapPanel(setInfo);
+
+ protected override string Title => "New Ranked Beatmaps";
+ }
+}
diff --git a/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs
new file mode 100644
index 0000000000..90bd00008c
--- /dev/null
+++ b/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs
@@ -0,0 +1,20 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Game.Beatmaps;
+
+namespace osu.Game.Overlays.Dashboard.Home
+{
+ public class DrawablePopularBeatmapList : DrawableBeatmapList
+ {
+ public DrawablePopularBeatmapList(List beatmaps)
+ : base(beatmaps)
+ {
+ }
+
+ protected override DashboardBeatmapPanel CreateBeatmapPanel(BeatmapSetInfo setInfo) => new DashboardPopularBeatmapPanel(setInfo);
+
+ protected override string Title => "Popular Beatmaps";
+ }
+}
diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs
index 77075b2abe..9afc0ecaf4 100644
--- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs
+++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs
@@ -434,7 +434,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
///
///
/// Layered hit samples are automatically added in all modes (except osu!mania), but can be disabled
- /// using the skin config option.
+ /// using the skin config option.
///
public bool IsLayered { get; set; }
}
diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs
index 269eab5772..4912df17b1 100644
--- a/osu.Game/Screens/Multi/Multiplayer.cs
+++ b/osu.Game/Screens/Multi/Multiplayer.cs
@@ -17,6 +17,7 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Input;
using osu.Game.Online.API;
using osu.Game.Online.Multiplayer;
+using osu.Game.Overlays;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Multi.Components;
using osu.Game.Screens.Multi.Lounge;
@@ -50,6 +51,9 @@ namespace osu.Game.Screens.Multi
[Cached]
private readonly Bindable currentFilter = new Bindable(new FilterCriteria());
+ [Resolved]
+ private MusicController music { get; set; }
+
[Cached(Type = typeof(IRoomManager))]
private RoomManager roomManager;
@@ -346,8 +350,7 @@ namespace osu.Game.Screens.Multi
track.RestartPoint = Beatmap.Value.Metadata.PreviewTime;
track.Looping = true;
- if (!track.IsRunning)
- track.Restart();
+ music.EnsurePlayingSomething();
}
}
else
diff --git a/osu.Game/Skinning/GlobalSkinConfiguration.cs b/osu.Game/Skinning/GlobalSkinConfiguration.cs
deleted file mode 100644
index d405702ea5..0000000000
--- a/osu.Game/Skinning/GlobalSkinConfiguration.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-namespace osu.Game.Skinning
-{
- public enum GlobalSkinConfiguration
- {
- AnimationFramerate,
- LayeredHitSounds,
- }
-}
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index fc04383a64..02d07eee45 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -126,15 +126,6 @@ namespace osu.Game.Skinning
break;
- case LegacySkinConfiguration.LegacySetting legacy:
- switch (legacy)
- {
- case LegacySkinConfiguration.LegacySetting.Version:
- return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION));
- }
-
- break;
-
case SkinCustomColourLookup customColour:
return SkinUtils.As(getCustomColour(Configuration, customColour.Lookup.ToString()));
@@ -148,28 +139,11 @@ namespace osu.Game.Skinning
break;
+ case LegacySkinConfiguration.LegacySetting legacy:
+ return legacySettingLookup(legacy);
+
default:
- // handles lookups like GlobalSkinConfiguration
-
- try
- {
- if (Configuration.ConfigDictionary.TryGetValue(lookup.ToString(), out var val))
- {
- // special case for handling skins which use 1 or 0 to signify a boolean state.
- if (typeof(TValue) == typeof(bool))
- val = val == "1" ? "true" : "false";
-
- var bindable = new Bindable();
- if (val != null)
- bindable.Parse(val);
- return bindable;
- }
- }
- catch
- {
- }
-
- break;
+ return genericLookup(lookup);
}
return null;
@@ -292,6 +266,43 @@ namespace osu.Game.Skinning
private IBindable getManiaImage(LegacyManiaSkinConfiguration source, string lookup)
=> source.ImageLookups.TryGetValue(lookup, out var image) ? new Bindable(image) : null;
+ [CanBeNull]
+ private IBindable legacySettingLookup(LegacySkinConfiguration.LegacySetting legacySetting)
+ {
+ switch (legacySetting)
+ {
+ case LegacySkinConfiguration.LegacySetting.Version:
+ return SkinUtils.As(new Bindable(Configuration.LegacyVersion ?? LegacySkinConfiguration.LATEST_VERSION));
+
+ default:
+ return genericLookup(legacySetting);
+ }
+ }
+
+ [CanBeNull]
+ private IBindable genericLookup(TLookup lookup)
+ {
+ try
+ {
+ if (Configuration.ConfigDictionary.TryGetValue(lookup.ToString(), out var val))
+ {
+ // special case for handling skins which use 1 or 0 to signify a boolean state.
+ if (typeof(TValue) == typeof(bool))
+ val = val == "1" ? "true" : "false";
+
+ var bindable = new Bindable();
+ if (val != null)
+ bindable.Parse(val);
+ return bindable;
+ }
+ }
+ catch
+ {
+ }
+
+ return null;
+ }
+
public override Drawable GetDrawableComponent(ISkinComponent component)
{
switch (component)
diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs
index 027f5b8883..41b7aea34b 100644
--- a/osu.Game/Skinning/LegacySkinConfiguration.cs
+++ b/osu.Game/Skinning/LegacySkinConfiguration.cs
@@ -15,6 +15,8 @@ namespace osu.Game.Skinning
public enum LegacySetting
{
Version,
+ AnimationFramerate,
+ LayeredHitSounds,
}
}
}
diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs
index 7cf41ef3c1..bb46dc8b9f 100644
--- a/osu.Game/Skinning/LegacySkinExtensions.cs
+++ b/osu.Game/Skinning/LegacySkinExtensions.cs
@@ -9,6 +9,7 @@ using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
+using static osu.Game.Skinning.LegacySkinConfiguration;
namespace osu.Game.Skinning
{
@@ -89,7 +90,7 @@ namespace osu.Game.Skinning
{
if (applyConfigFrameRate)
{
- var iniRate = source.GetConfig(GlobalSkinConfiguration.AnimationFramerate);
+ var iniRate = source.GetConfig(LegacySetting.AnimationFramerate);
if (iniRate?.Value > 0)
return 1000f / iniRate.Value;
diff --git a/osu.Game/Skinning/LegacySkinTransformer.cs b/osu.Game/Skinning/LegacySkinTransformer.cs
index 786056b932..ebc4757e75 100644
--- a/osu.Game/Skinning/LegacySkinTransformer.cs
+++ b/osu.Game/Skinning/LegacySkinTransformer.cs
@@ -8,6 +8,7 @@ using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Textures;
using osu.Game.Audio;
using osu.Game.Rulesets.Objects.Legacy;
+using static osu.Game.Skinning.LegacySkinConfiguration;
namespace osu.Game.Skinning
{
@@ -38,7 +39,7 @@ namespace osu.Game.Skinning
if (!(sampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacySample))
return Source.GetSample(sampleInfo);
- var playLayeredHitSounds = GetConfig(GlobalSkinConfiguration.LayeredHitSounds);
+ var playLayeredHitSounds = GetConfig(LegacySetting.LayeredHitSounds);
if (legacySample.IsLayered && playLayeredHitSounds?.Value == false)
return new SampleChannelVirtual();
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 745555e0e2..627c2f3d33 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -24,7 +24,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index f1080f0c8b..f443937017 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -70,7 +70,7 @@
-
+
@@ -80,7 +80,7 @@
-
+