diff --git a/osu.Android.props b/osu.Android.props
index 0b41d5cda4..e1e6f2e478 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -54,6 +54,6 @@
-
+
diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index 0b2862e5bb..9559d13328 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
index 374dd50c11..fc030877f1 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
return 0;
case HitResult.Perfect:
- return 0.008;
+ return 0.01;
}
}
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
index f1399bb5c0..e87ecba749 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
@@ -18,17 +18,5 @@ namespace osu.Game.Rulesets.Catch.Judgements
return 30;
}
}
-
- protected override double HealthIncreaseFor(HitResult result)
- {
- switch (result)
- {
- default:
- return base.HealthIncreaseFor(result);
-
- case HitResult.Perfect:
- return 0.007;
- }
- }
}
}
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
index 8fd9ac92ba..2149ed9712 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
@@ -23,18 +23,6 @@ namespace osu.Game.Rulesets.Catch.Judgements
}
}
- protected override double HealthIncreaseFor(HitResult result)
- {
- switch (result)
- {
- default:
- return -0.02;
-
- case HitResult.Perfect:
- return 0.01;
- }
- }
-
///
/// Whether fruit on the platter should explode or drop.
/// Note that this is only checked if the owning object is also
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
index 3829b5e94f..d607b49ea4 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
return 0;
case HitResult.Perfect:
- return 0.004;
+ return 0.02;
}
}
}
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index 9d362e5819..dea6e6c0fb 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs
index b9c6e3a7f7..00b839f8ec 100644
--- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs
+++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs
@@ -15,11 +15,11 @@ namespace osu.Game.Rulesets.Mania.Judgements
{
switch (result)
{
- case HitResult.Miss:
+ default:
return 0;
- default:
- return 0.040;
+ case HitResult.Perfect:
+ return 0.01;
}
}
}
diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
index 0e4c811945..c2f8fb8678 100644
--- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
+++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
@@ -29,32 +29,5 @@ namespace osu.Game.Rulesets.Mania.Judgements
return 300;
}
}
-
- protected override double HealthIncreaseFor(HitResult result)
- {
- switch (result)
- {
- case HitResult.Miss:
- return -0.125;
-
- case HitResult.Meh:
- return 0.005;
-
- case HitResult.Ok:
- return 0.010;
-
- case HitResult.Good:
- return 0.035;
-
- case HitResult.Great:
- return 0.055;
-
- case HitResult.Perfect:
- return 0.065;
-
- default:
- return 0;
- }
- }
}
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
index da89b37fbf..d728d65bfd 100644
--- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Tests/Online/TestSceneBeatmapManager.cs b/osu.Game.Tests/Online/TestSceneBeatmapManager.cs
new file mode 100644
index 0000000000..0ae0186770
--- /dev/null
+++ b/osu.Game.Tests/Online/TestSceneBeatmapManager.cs
@@ -0,0 +1,51 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Testing;
+using osu.Game.Beatmaps;
+using osu.Game.Overlays.Notifications;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Tests.Online
+{
+ [HeadlessTest]
+ public class TestSceneBeatmapManager : OsuTestScene
+ {
+ private BeatmapManager beatmaps;
+ private ProgressNotification recentNotification;
+
+ private static readonly BeatmapSetInfo test_model = new BeatmapSetInfo { OnlineBeatmapSetID = 1 };
+
+ [BackgroundDependencyLoader]
+ private void load(BeatmapManager beatmaps)
+ {
+ this.beatmaps = beatmaps;
+
+ beatmaps.PostNotification = n => recentNotification = n as ProgressNotification;
+ }
+
+ [Test]
+ public void TestCancelDownloadFromRequest()
+ {
+ AddStep("download beatmap", () => beatmaps.Download(test_model));
+
+ AddStep("cancel download from request", () => beatmaps.GetExistingDownload(test_model).Cancel());
+
+ AddUntilStep("is removed from download list", () => beatmaps.GetExistingDownload(test_model) == null);
+ AddAssert("is notification cancelled", () => recentNotification.State == ProgressNotificationState.Cancelled);
+ }
+
+ [Test]
+ public void TestCancelDownloadFromNotification()
+ {
+ AddStep("download beatmap", () => beatmaps.Download(test_model));
+
+ AddStep("cancel download from notification", () => recentNotification.Close());
+
+ AddUntilStep("is removed from download list", () => beatmaps.GetExistingDownload(test_model) == null);
+ AddAssert("is notification cancelled", () => recentNotification.State == ProgressNotificationState.Cancelled);
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
index 57e297bcd5..2b52deb605 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs
@@ -7,6 +7,7 @@ using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
+using osu.Game.Online.Placeholders;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.Select.Leaderboards;
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs
index e3daa9c279..330ccecd54 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs
@@ -4,8 +4,10 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
-using osu.Framework.Timing;
+using osu.Framework.MathUtils;
+using osu.Game.Beatmaps;
using osu.Game.Overlays;
+using osu.Game.Rulesets.Osu;
namespace osu.Game.Tests.Visual.UserInterface
{
@@ -15,22 +17,48 @@ namespace osu.Game.Tests.Visual.UserInterface
[Cached]
private MusicController musicController = new MusicController();
- public TestSceneNowPlayingOverlay()
- {
- Clock = new FramedClock();
+ private WorkingBeatmap currentBeatmap;
- var np = new NowPlayingOverlay
+ private NowPlayingOverlay nowPlayingOverlay;
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
+
+ nowPlayingOverlay = new NowPlayingOverlay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre
};
Add(musicController);
- Add(np);
+ Add(nowPlayingOverlay);
+ }
- AddStep(@"show", () => np.Show());
+ [Test]
+ public void TestShowHideDisable()
+ {
+ AddStep(@"show", () => nowPlayingOverlay.Show());
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
- AddStep(@"show", () => np.Hide());
+ AddStep(@"hide", () => nowPlayingOverlay.Hide());
+ }
+
+ [Test]
+ public void TestPrevTrackBehavior()
+ {
+ AddStep(@"Play track", () =>
+ {
+ musicController.NextTrack();
+ currentBeatmap = Beatmap.Value;
+ });
+
+ AddStep(@"Seek track to 6 second", () => musicController.SeekTo(6000));
+ AddUntilStep(@"Wait for current time to update", () => currentBeatmap.Track.CurrentTime > 5000);
+ AddAssert(@"Check action is restart track", () => musicController.PreviousTrack() == PreviousTrackResult.Restart);
+ AddUntilStep("Wait for current time to update", () => Precision.AlmostEquals(currentBeatmap.Track.CurrentTime, 0));
+ AddAssert(@"Check track didn't change", () => currentBeatmap == Beatmap.Value);
+ AddAssert(@"Check action is not restart", () => musicController.PreviousTrack() != PreviousTrackResult.Restart);
}
}
}
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index 3f8a548fd5..6c799e5e90 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
index 75b88be1ab..7ecfd6ef70 100644
--- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
+++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
@@ -7,7 +7,7 @@
-
+
WinExe
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 7bd40af512..a3128e36c4 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -48,11 +48,9 @@ namespace osu.Game.Beatmaps.Drawables
InternalChild = iconContainer = new Container { Size = new Vector2(20f) };
}
- public string TooltipText { get; set; }
-
public ITooltip GetCustomTooltip() => new DifficultyIconTooltip();
- public object TooltipContent { get; set; }
+ public object TooltipContent { get; }
[BackgroundDependencyLoader]
private void load(OsuColour colours)
diff --git a/osu.Game/Database/DownloadableArchiveModelManager.cs b/osu.Game/Database/DownloadableArchiveModelManager.cs
index 5f688c149d..71bf195a8d 100644
--- a/osu.Game/Database/DownloadableArchiveModelManager.cs
+++ b/osu.Game/Database/DownloadableArchiveModelManager.cs
@@ -92,8 +92,6 @@ namespace osu.Game.Database
notification.CancelRequested += () =>
{
request.Cancel();
- currentDownloads.Remove(request);
- notification.State = ProgressNotificationState.Cancelled;
return true;
};
@@ -109,11 +107,11 @@ namespace osu.Game.Database
{
DownloadFailed?.Invoke(request);
- if (error is OperationCanceledException) return;
-
- notification.State = ProgressNotificationState.Cancelled;
- Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
currentDownloads.Remove(request);
+ notification.State = ProgressNotificationState.Cancelled;
+
+ if (!(error is OperationCanceledException))
+ Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
}
}
diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs
index 6d88808150..af492bacc9 100644
--- a/osu.Game/Graphics/Backgrounds/Triangles.cs
+++ b/osu.Game/Graphics/Backgrounds/Triangles.cs
@@ -29,8 +29,33 @@ namespace osu.Game.Graphics.Backgrounds
///
private const float edge_smoothness = 1;
- public Color4 ColourLight = Color4.White;
- public Color4 ColourDark = Color4.Black;
+ private Color4 colourLight = Color4.White;
+
+ public Color4 ColourLight
+ {
+ get => colourLight;
+ set
+ {
+ if (colourLight == value) return;
+
+ colourLight = value;
+ updateColours();
+ }
+ }
+
+ private Color4 colourDark = Color4.Black;
+
+ public Color4 ColourDark
+ {
+ get => colourDark;
+ set
+ {
+ if (colourDark == value) return;
+
+ colourDark = value;
+ updateColours();
+ }
+ }
///
/// Whether we want to expire triangles as they exit our draw area completely.
@@ -151,7 +176,8 @@ namespace osu.Game.Graphics.Backgrounds
TriangleParticle particle = CreateTriangle();
particle.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() : 1);
- particle.Colour = CreateTriangleShade();
+ particle.ColourShade = RNG.NextSingle();
+ particle.Colour = CreateTriangleShade(particle.ColourShade);
return particle;
}
@@ -177,7 +203,17 @@ namespace osu.Game.Graphics.Backgrounds
/// Creates a shade of colour for the triangles.
///
/// The colour.
- protected virtual Color4 CreateTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1);
+ protected virtual Color4 CreateTriangleShade(float shade) => Interpolation.ValueAt(shade, colourDark, colourLight, 0, 1);
+
+ private void updateColours()
+ {
+ for (int i = 0; i < parts.Count; i++)
+ {
+ TriangleParticle newParticle = parts[i];
+ newParticle.Colour = CreateTriangleShade(newParticle.ColourShade);
+ parts[i] = newParticle;
+ }
+ }
protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(this);
@@ -264,6 +300,12 @@ namespace osu.Game.Graphics.Backgrounds
///
public Vector2 Position;
+ ///
+ /// The colour shade of the triangle.
+ /// This is needed for colour recalculation of visible triangles when or is changed.
+ ///
+ public float ColourShade;
+
///
/// The colour of the triangle.
///
diff --git a/osu.Game/Graphics/Containers/OsuScrollContainer.cs b/osu.Game/Graphics/Containers/OsuScrollContainer.cs
index ab72276ad0..cfd459da5e 100644
--- a/osu.Game/Graphics/Containers/OsuScrollContainer.cs
+++ b/osu.Game/Graphics/Containers/OsuScrollContainer.cs
@@ -123,8 +123,6 @@ namespace osu.Game.Graphics.Containers
Masking = true;
Child = box = new Box { RelativeSizeAxes = Axes.Both };
-
- ResizeTo(1);
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs
index fcbd4d314a..0956c749a2 100644
--- a/osu.Game/Online/API/APIRequest.cs
+++ b/osu.Game/Online/API/APIRequest.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Online.API
/// Type of the response (used for deserialisation).
public abstract class APIRequest : APIRequest
{
- protected override WebRequest CreateWebRequest() => new JsonWebRequest(Uri);
+ protected override WebRequest CreateWebRequest() => new OsuJsonWebRequest(Uri);
public T Result => ((JsonWebRequest)WebRequest).ResponseObject;
@@ -30,6 +30,16 @@ namespace osu.Game.Online.API
/// This will be scheduled to the API's internal scheduler (run on update thread automatically).
///
public new event APISuccessHandler Success;
+
+ private class OsuJsonWebRequest : JsonWebRequest
+ {
+ public OsuJsonWebRequest(string uri)
+ : base(uri)
+ {
+ }
+
+ protected override string UserAgent => "osu!";
+ }
}
///
@@ -39,7 +49,7 @@ namespace osu.Game.Online.API
{
protected abstract string Target { get; }
- protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri);
+ protected virtual WebRequest CreateWebRequest() => new OsuWebRequest(Uri);
protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}";
@@ -152,6 +162,16 @@ namespace osu.Game.Online.API
[JsonProperty("error")]
public string ErrorMessage { get; set; }
}
+
+ private class OsuWebRequest : WebRequest
+ {
+ public OsuWebRequest(string uri)
+ : base(uri)
+ {
+ }
+
+ protected override string UserAgent => "osu!";
+ }
}
public class APIException : InvalidOperationException
diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs
index 9c48ebd09b..55233bef6e 100644
--- a/osu.Game/Online/Leaderboards/Leaderboard.cs
+++ b/osu.Game/Online/Leaderboards/Leaderboard.cs
@@ -14,6 +14,7 @@ using osu.Framework.Threading;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
+using osu.Game.Online.Placeholders;
using osuTK;
using osuTK.Graphics;
@@ -150,7 +151,7 @@ namespace osu.Game.Online.Leaderboards
break;
case PlaceholderState.NotLoggedIn:
- replacePlaceholder(new MessagePlaceholder(@"Please sign in to view online leaderboards!"));
+ replacePlaceholder(new LoginPlaceholder());
break;
case PlaceholderState.NotSupporter:
diff --git a/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs
index 801f3f8ff0..15d7dabe65 100644
--- a/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs
+++ b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs
@@ -6,6 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
+using osu.Game.Online.Placeholders;
using osuTK;
namespace osu.Game.Online.Leaderboards
diff --git a/osu.Game/Online/Placeholders/LoginPlaceholder.cs b/osu.Game/Online/Placeholders/LoginPlaceholder.cs
new file mode 100644
index 0000000000..ffc6623229
--- /dev/null
+++ b/osu.Game/Online/Placeholders/LoginPlaceholder.cs
@@ -0,0 +1,46 @@
+// 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.Sprites;
+using osu.Framework.Input.Events;
+using osu.Game.Overlays;
+
+namespace osu.Game.Online.Placeholders
+{
+ public sealed class LoginPlaceholder : Placeholder
+ {
+ [Resolved(CanBeNull = true)]
+ private LoginOverlay login { get; set; }
+
+ public LoginPlaceholder()
+ {
+ AddIcon(FontAwesome.Solid.UserLock, cp =>
+ {
+ cp.Font = cp.Font.With(size: TEXT_SIZE);
+ cp.Padding = new MarginPadding { Right = 10 };
+ });
+
+ AddText(@"Please sign in to view online leaderboards!");
+ }
+
+ protected override bool OnMouseDown(MouseDownEvent e)
+ {
+ this.ScaleTo(0.8f, 4000, Easing.OutQuint);
+ return base.OnMouseDown(e);
+ }
+
+ protected override bool OnMouseUp(MouseUpEvent e)
+ {
+ this.ScaleTo(1, 1000, Easing.OutElastic);
+ return base.OnMouseUp(e);
+ }
+
+ protected override bool OnClick(ClickEvent e)
+ {
+ login?.Show();
+ return base.OnClick(e);
+ }
+ }
+}
diff --git a/osu.Game/Online/Leaderboards/MessagePlaceholder.cs b/osu.Game/Online/Placeholders/MessagePlaceholder.cs
similarity index 95%
rename from osu.Game/Online/Leaderboards/MessagePlaceholder.cs
rename to osu.Game/Online/Placeholders/MessagePlaceholder.cs
index ef425dacd8..7342765ca4 100644
--- a/osu.Game/Online/Leaderboards/MessagePlaceholder.cs
+++ b/osu.Game/Online/Placeholders/MessagePlaceholder.cs
@@ -4,7 +4,7 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
-namespace osu.Game.Online.Leaderboards
+namespace osu.Game.Online.Placeholders
{
public class MessagePlaceholder : Placeholder
{
diff --git a/osu.Game/Online/Leaderboards/Placeholder.cs b/osu.Game/Online/Placeholders/Placeholder.cs
similarity index 95%
rename from osu.Game/Online/Leaderboards/Placeholder.cs
rename to osu.Game/Online/Placeholders/Placeholder.cs
index d38110a9d0..f58282bbd9 100644
--- a/osu.Game/Online/Leaderboards/Placeholder.cs
+++ b/osu.Game/Online/Placeholders/Placeholder.cs
@@ -5,7 +5,7 @@ using System;
using osu.Framework.Graphics;
using osu.Game.Graphics.Containers;
-namespace osu.Game.Online.Leaderboards
+namespace osu.Game.Online.Placeholders
{
public abstract class Placeholder : OsuTextFlowContainer, IEquatable
{
diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs
index 1f15c773f4..15aec1f17c 100644
--- a/osu.Game/Overlays/MedalOverlay.cs
+++ b/osu.Game/Overlays/MedalOverlay.cs
@@ -41,105 +41,114 @@ namespace osu.Game.Overlays
private SampleChannel getSample;
+ private readonly Container content;
+
public MedalOverlay(Medal medal)
{
this.medal = medal;
RelativeSizeAxes = Axes.Both;
- Children = new Drawable[]
+ Child = content = new Container
{
- background = new Box
+ Alpha = 0,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black.Opacity(60),
- },
- outerSpin = new Sprite
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Size = new Vector2(DISC_SIZE + 500),
- Alpha = 0f,
- },
- backgroundStrip = new Container
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.X,
- Height = border_width,
- Alpha = 0f,
- Children = new[]
+ background = new Box
{
- new Container
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black.Opacity(60),
+ },
+ outerSpin = new Sprite
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Size = new Vector2(DISC_SIZE + 500),
+ Alpha = 0f,
+ },
+ backgroundStrip = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.X,
+ Height = border_width,
+ Alpha = 0f,
+ Children = new[]
{
- RelativeSizeAxes = Axes.Both,
- Anchor = Anchor.Centre,
- Origin = Anchor.CentreRight,
- Width = 0.5f,
- Padding = new MarginPadding { Right = DISC_SIZE / 2 },
- Children = new[]
+ new Container
{
- leftStrip = new BackgroundStrip(0f, 1f)
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.CentreRight,
+ Width = 0.5f,
+ Padding = new MarginPadding { Right = DISC_SIZE / 2 },
+ Children = new[]
{
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
+ leftStrip = new BackgroundStrip(0f, 1f)
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ },
+ },
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.CentreLeft,
+ Width = 0.5f,
+ Padding = new MarginPadding { Left = DISC_SIZE / 2 },
+ Children = new[]
+ {
+ rightStrip = new BackgroundStrip(1f, 0f),
},
},
},
- new Container
+ },
+ particleContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0f,
+ },
+ disc = new CircularContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Alpha = 0f,
+ Masking = true,
+ AlwaysPresent = true,
+ BorderColour = Color4.White,
+ BorderThickness = border_width,
+ Size = new Vector2(DISC_SIZE),
+ Scale = new Vector2(0.8f),
+ Children = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Anchor = Anchor.Centre,
- Origin = Anchor.CentreLeft,
- Width = 0.5f,
- Padding = new MarginPadding { Left = DISC_SIZE / 2 },
- Children = new[]
+ new Box
{
- rightStrip = new BackgroundStrip(1f, 0f),
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.FromHex(@"05262f"),
+ },
+ new Triangles
+ {
+ RelativeSizeAxes = Axes.Both,
+ TriangleScale = 2,
+ ColourDark = OsuColour.FromHex(@"04222b"),
+ ColourLight = OsuColour.FromHex(@"052933"),
+ },
+ innerSpin = new Sprite
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(1.05f),
+ Alpha = 0.25f,
},
},
},
- },
- particleContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Alpha = 0f,
- },
- disc = new CircularContainer
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Alpha = 0f,
- Masking = true,
- AlwaysPresent = true,
- BorderColour = Color4.White,
- BorderThickness = border_width,
- Size = new Vector2(DISC_SIZE),
- Scale = new Vector2(0.8f),
- Children = new Drawable[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.FromHex(@"05262f"),
- },
- new Triangles
- {
- RelativeSizeAxes = Axes.Both,
- TriangleScale = 2,
- ColourDark = OsuColour.FromHex(@"04222b"),
- ColourLight = OsuColour.FromHex(@"052933"),
- },
- innerSpin = new Sprite
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Size = new Vector2(1.05f),
- Alpha = 0.25f,
- },
- },
- },
+ }
};
+
+ Show();
}
[BackgroundDependencyLoader]
@@ -154,19 +163,22 @@ namespace osu.Game.Overlays
Colour = colours.Blue.Opacity(0.5f),
Radius = 50,
};
-
- disc.Add(drawableMedal = new DrawableMedal(medal)
- {
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- RelativeSizeAxes = Axes.Both,
- });
}
protected override void LoadComplete()
{
base.LoadComplete();
- Show();
+
+ LoadComponentAsync(drawableMedal = new DrawableMedal(medal)
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Both,
+ }, loaded =>
+ {
+ disc.Add(loaded);
+ startAnimation();
+ });
}
protected override void Update()
@@ -190,11 +202,10 @@ namespace osu.Game.Overlays
private const double initial_duration = 400;
private const double step_duration = 900;
- protected override void PopIn()
+ private void startAnimation()
{
- base.PopIn();
+ content.Show();
- this.FadeIn(200);
background.FlashColour(Color4.White.Opacity(0.25f), 400);
getSample.Play();
diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs
index a9b4bed334..3cf7befb45 100644
--- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs
+++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs
@@ -51,7 +51,7 @@ namespace osu.Game.Overlays.MedalSplash
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Scale = new Vector2(0.81f),
+ Scale = new Vector2(0.41f),
},
medalGlow = new Sprite
{
diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs
index bafdad3508..270e90dca5 100644
--- a/osu.Game/Overlays/MusicController.cs
+++ b/osu.Game/Overlays/MusicController.cs
@@ -27,6 +27,11 @@ namespace osu.Game.Overlays
public IBindableList BeatmapSets => beatmapSets;
+ ///
+ /// Point in time after which the current track will be restarted on triggering a "previous track" action.
+ ///
+ private const double restart_cutoff_point = 5000;
+
private readonly BindableList beatmapSets = new BindableList();
public bool IsUserPaused { get; private set; }
@@ -151,11 +156,19 @@ namespace osu.Game.Overlays
}
///
- /// Play the previous track.
+ /// Play the previous track or restart the current track if it's current time below
///
- /// Whether the operation was successful.
- public bool PrevTrack()
+ /// The that indicate the decided action
+ public PreviousTrackResult PreviousTrack()
{
+ var currentTrackPosition = current?.Track.CurrentTime;
+
+ if (currentTrackPosition >= restart_cutoff_point)
+ {
+ SeekTo(0);
+ return PreviousTrackResult.Restart;
+ }
+
queuedDirection = TrackChangeDirection.Prev;
var playable = BeatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? BeatmapSets.LastOrDefault();
@@ -166,10 +179,10 @@ namespace osu.Game.Overlays
working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
beatmap.Value.Track.Restart();
- return true;
+ return PreviousTrackResult.Previous;
}
- return false;
+ return PreviousTrackResult.None;
}
///
@@ -296,8 +309,16 @@ namespace osu.Game.Overlays
return true;
case GlobalAction.MusicPrev:
- if (PrevTrack())
- onScreenDisplay?.Display(new MusicControllerToast("Previous track"));
+ switch (PreviousTrack())
+ {
+ case PreviousTrackResult.Restart:
+ onScreenDisplay?.Display(new MusicControllerToast("Restart track"));
+ break;
+
+ case PreviousTrackResult.Previous:
+ onScreenDisplay?.Display(new MusicControllerToast("Previous track"));
+ break;
+ }
return true;
}
@@ -322,4 +343,11 @@ namespace osu.Game.Overlays
Next,
Prev
}
+
+ public enum PreviousTrackResult
+ {
+ None,
+ Restart,
+ Previous
+ }
}
diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs
index de30e1a754..a8ba7fa427 100644
--- a/osu.Game/Overlays/NowPlayingOverlay.cs
+++ b/osu.Game/Overlays/NowPlayingOverlay.cs
@@ -137,7 +137,7 @@ namespace osu.Game.Overlays
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Action = () => musicController.PrevTrack(),
+ Action = () => musicController.PreviousTrack(),
Icon = FontAwesome.Solid.StepBackward,
},
playButton = new MusicIconButton
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 565608b40f..b497133e62 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 60355b8592..edd35b0774 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -74,7 +74,7 @@
-
+
@@ -82,7 +82,7 @@
-
+