Merge branch 'master' into allow-loading-layer-scrolling

This commit is contained in:
Dean Herbert 2020-01-08 21:19:37 +08:00 committed by GitHub
commit a74fc70627
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 364 additions and 192 deletions

View File

@ -54,6 +54,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1227.1" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2020.103.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -4,7 +4,7 @@
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">

View File

@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
return 0; return 0;
case HitResult.Perfect: case HitResult.Perfect:
return 0.008; return 0.01;
} }
} }

View File

@ -18,17 +18,5 @@ namespace osu.Game.Rulesets.Catch.Judgements
return 30; return 30;
} }
} }
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
default:
return base.HealthIncreaseFor(result);
case HitResult.Perfect:
return 0.007;
}
}
} }
} }

View File

@ -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;
}
}
/// <summary> /// <summary>
/// Whether fruit on the platter should explode or drop. /// Whether fruit on the platter should explode or drop.
/// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" /> /// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" />

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
return 0; return 0;
case HitResult.Perfect: case HitResult.Perfect:
return 0.004; return 0.02;
} }
} }
} }

View File

@ -4,7 +4,7 @@
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">

View File

@ -15,11 +15,11 @@ namespace osu.Game.Rulesets.Mania.Judgements
{ {
switch (result) switch (result)
{ {
case HitResult.Miss: default:
return 0; return 0;
default: case HitResult.Perfect:
return 0.040; return 0.01;
} }
} }
} }

View File

@ -29,32 +29,5 @@ namespace osu.Game.Rulesets.Mania.Judgements
return 300; 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;
}
}
} }
} }

View File

@ -4,7 +4,7 @@
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">

View File

@ -0,0 +1,51 @@
// 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 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);
}
}
}

View File

@ -7,6 +7,7 @@ using osu.Framework.Graphics;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards; using osu.Game.Online.Leaderboards;
using osu.Game.Online.Placeholders;
using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens.Select.Leaderboards; using osu.Game.Screens.Select.Leaderboards;

View File

@ -4,8 +4,10 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Timing; using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Rulesets.Osu;
namespace osu.Game.Tests.Visual.UserInterface namespace osu.Game.Tests.Visual.UserInterface
{ {
@ -15,22 +17,48 @@ namespace osu.Game.Tests.Visual.UserInterface
[Cached] [Cached]
private MusicController musicController = new MusicController(); private MusicController musicController = new MusicController();
public TestSceneNowPlayingOverlay() private WorkingBeatmap currentBeatmap;
{
Clock = new FramedClock();
var np = new NowPlayingOverlay private NowPlayingOverlay nowPlayingOverlay;
[BackgroundDependencyLoader]
private void load()
{
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
nowPlayingOverlay = new NowPlayingOverlay
{ {
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre Anchor = Anchor.Centre
}; };
Add(musicController); 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); 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);
} }
} }
} }

View File

@ -5,7 +5,7 @@
<PackageReference Include="DeepEqual" Version="2.0.0" /> <PackageReference Include="DeepEqual" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" /> <PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">

View File

@ -7,7 +7,7 @@
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" /> <PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Project"> <PropertyGroup Label="Project">
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>

View File

@ -48,11 +48,9 @@ namespace osu.Game.Beatmaps.Drawables
InternalChild = iconContainer = new Container { Size = new Vector2(20f) }; InternalChild = iconContainer = new Container { Size = new Vector2(20f) };
} }
public string TooltipText { get; set; }
public ITooltip GetCustomTooltip() => new DifficultyIconTooltip(); public ITooltip GetCustomTooltip() => new DifficultyIconTooltip();
public object TooltipContent { get; set; } public object TooltipContent { get; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)

View File

@ -92,8 +92,6 @@ namespace osu.Game.Database
notification.CancelRequested += () => notification.CancelRequested += () =>
{ {
request.Cancel(); request.Cancel();
currentDownloads.Remove(request);
notification.State = ProgressNotificationState.Cancelled;
return true; return true;
}; };
@ -109,11 +107,11 @@ namespace osu.Game.Database
{ {
DownloadFailed?.Invoke(request); DownloadFailed?.Invoke(request);
if (error is OperationCanceledException) return;
notification.State = ProgressNotificationState.Cancelled;
Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
currentDownloads.Remove(request); currentDownloads.Remove(request);
notification.State = ProgressNotificationState.Cancelled;
if (!(error is OperationCanceledException))
Logger.Error(error, $"{HumanisedModelName.Titleize()} download failed!");
} }
} }

View File

@ -29,8 +29,33 @@ namespace osu.Game.Graphics.Backgrounds
/// </summary> /// </summary>
private const float edge_smoothness = 1; private const float edge_smoothness = 1;
public Color4 ColourLight = Color4.White; private Color4 colourLight = Color4.White;
public Color4 ColourDark = Color4.Black;
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();
}
}
/// <summary> /// <summary>
/// Whether we want to expire triangles as they exit our draw area completely. /// 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(); TriangleParticle particle = CreateTriangle();
particle.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() : 1); particle.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() : 1);
particle.Colour = CreateTriangleShade(); particle.ColourShade = RNG.NextSingle();
particle.Colour = CreateTriangleShade(particle.ColourShade);
return particle; return particle;
} }
@ -177,7 +203,17 @@ namespace osu.Game.Graphics.Backgrounds
/// Creates a shade of colour for the triangles. /// Creates a shade of colour for the triangles.
/// </summary> /// </summary>
/// <returns>The colour.</returns> /// <returns>The colour.</returns>
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); protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(this);
@ -264,6 +300,12 @@ namespace osu.Game.Graphics.Backgrounds
/// </summary> /// </summary>
public Vector2 Position; public Vector2 Position;
/// <summary>
/// The colour shade of the triangle.
/// This is needed for colour recalculation of visible triangles when <see cref="ColourDark"/> or <see cref="ColourLight"/> is changed.
/// </summary>
public float ColourShade;
/// <summary> /// <summary>
/// The colour of the triangle. /// The colour of the triangle.
/// </summary> /// </summary>

View File

@ -123,8 +123,6 @@ namespace osu.Game.Graphics.Containers
Masking = true; Masking = true;
Child = box = new Box { RelativeSizeAxes = Axes.Both }; Child = box = new Box { RelativeSizeAxes = Axes.Both };
ResizeTo(1);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -14,7 +14,7 @@ namespace osu.Game.Online.API
/// <typeparam name="T">Type of the response (used for deserialisation).</typeparam> /// <typeparam name="T">Type of the response (used for deserialisation).</typeparam>
public abstract class APIRequest<T> : APIRequest public abstract class APIRequest<T> : APIRequest
{ {
protected override WebRequest CreateWebRequest() => new JsonWebRequest<T>(Uri); protected override WebRequest CreateWebRequest() => new OsuJsonWebRequest<T>(Uri);
public T Result => ((JsonWebRequest<T>)WebRequest).ResponseObject; public T Result => ((JsonWebRequest<T>)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). /// This will be scheduled to the API's internal scheduler (run on update thread automatically).
/// </summary> /// </summary>
public new event APISuccessHandler<T> Success; public new event APISuccessHandler<T> Success;
private class OsuJsonWebRequest<U> : JsonWebRequest<U>
{
public OsuJsonWebRequest(string uri)
: base(uri)
{
}
protected override string UserAgent => "osu!";
}
} }
/// <summary> /// <summary>
@ -39,7 +49,7 @@ namespace osu.Game.Online.API
{ {
protected abstract string Target { get; } 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}"; protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}";
@ -152,6 +162,16 @@ namespace osu.Game.Online.API
[JsonProperty("error")] [JsonProperty("error")]
public string ErrorMessage { get; set; } public string ErrorMessage { get; set; }
} }
private class OsuWebRequest : WebRequest
{
public OsuWebRequest(string uri)
: base(uri)
{
}
protected override string UserAgent => "osu!";
}
} }
public class APIException : InvalidOperationException public class APIException : InvalidOperationException

View File

@ -14,6 +14,7 @@ using osu.Framework.Threading;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Placeholders;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -150,7 +151,7 @@ namespace osu.Game.Online.Leaderboards
break; break;
case PlaceholderState.NotLoggedIn: case PlaceholderState.NotLoggedIn:
replacePlaceholder(new MessagePlaceholder(@"Please sign in to view online leaderboards!")); replacePlaceholder(new LoginPlaceholder());
break; break;
case PlaceholderState.NotSupporter: case PlaceholderState.NotSupporter:

View File

@ -6,6 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Online.Placeholders;
using osuTK; using osuTK;
namespace osu.Game.Online.Leaderboards namespace osu.Game.Online.Leaderboards

View File

@ -0,0 +1,46 @@
// 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.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);
}
}
}

View File

@ -4,7 +4,7 @@
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
namespace osu.Game.Online.Leaderboards namespace osu.Game.Online.Placeholders
{ {
public class MessagePlaceholder : Placeholder public class MessagePlaceholder : Placeholder
{ {

View File

@ -5,7 +5,7 @@ using System;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
namespace osu.Game.Online.Leaderboards namespace osu.Game.Online.Placeholders
{ {
public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder> public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder>
{ {

View File

@ -41,11 +41,17 @@ namespace osu.Game.Overlays
private SampleChannel getSample; private SampleChannel getSample;
private readonly Container content;
public MedalOverlay(Medal medal) public MedalOverlay(Medal medal)
{ {
this.medal = medal; this.medal = medal;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
Child = content = new Container
{
Alpha = 0,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
background = new Box background = new Box
@ -139,7 +145,10 @@ namespace osu.Game.Overlays
}, },
}, },
}, },
}
}; };
Show();
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -154,19 +163,22 @@ namespace osu.Game.Overlays
Colour = colours.Blue.Opacity(0.5f), Colour = colours.Blue.Opacity(0.5f),
Radius = 50, Radius = 50,
}; };
disc.Add(drawableMedal = new DrawableMedal(medal)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Both,
});
} }
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.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() protected override void Update()
@ -190,11 +202,10 @@ namespace osu.Game.Overlays
private const double initial_duration = 400; private const double initial_duration = 400;
private const double step_duration = 900; 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); background.FlashColour(Color4.White.Opacity(0.25f), 400);
getSample.Play(); getSample.Play();

View File

@ -51,7 +51,7 @@ namespace osu.Game.Overlays.MedalSplash
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Scale = new Vector2(0.81f), Scale = new Vector2(0.41f),
}, },
medalGlow = new Sprite medalGlow = new Sprite
{ {

View File

@ -27,6 +27,11 @@ namespace osu.Game.Overlays
public IBindableList<BeatmapSetInfo> BeatmapSets => beatmapSets; public IBindableList<BeatmapSetInfo> BeatmapSets => beatmapSets;
/// <summary>
/// Point in time after which the current track will be restarted on triggering a "previous track" action.
/// </summary>
private const double restart_cutoff_point = 5000;
private readonly BindableList<BeatmapSetInfo> beatmapSets = new BindableList<BeatmapSetInfo>(); private readonly BindableList<BeatmapSetInfo> beatmapSets = new BindableList<BeatmapSetInfo>();
public bool IsUserPaused { get; private set; } public bool IsUserPaused { get; private set; }
@ -151,11 +156,19 @@ namespace osu.Game.Overlays
} }
/// <summary> /// <summary>
/// Play the previous track. /// Play the previous track or restart the current track if it's current time below <see cref="restart_cutoff_point"/>
/// </summary> /// </summary>
/// <returns>Whether the operation was successful.</returns> /// <returns>The <see cref="PreviousTrackResult"/> that indicate the decided action</returns>
public bool PrevTrack() public PreviousTrackResult PreviousTrack()
{ {
var currentTrackPosition = current?.Track.CurrentTime;
if (currentTrackPosition >= restart_cutoff_point)
{
SeekTo(0);
return PreviousTrackResult.Restart;
}
queuedDirection = TrackChangeDirection.Prev; queuedDirection = TrackChangeDirection.Prev;
var playable = BeatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? BeatmapSets.LastOrDefault(); 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); working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
beatmap.Value.Track.Restart(); beatmap.Value.Track.Restart();
return true; return PreviousTrackResult.Previous;
} }
return false; return PreviousTrackResult.None;
} }
/// <summary> /// <summary>
@ -296,8 +309,16 @@ namespace osu.Game.Overlays
return true; return true;
case GlobalAction.MusicPrev: case GlobalAction.MusicPrev:
if (PrevTrack()) switch (PreviousTrack())
{
case PreviousTrackResult.Restart:
onScreenDisplay?.Display(new MusicControllerToast("Restart track"));
break;
case PreviousTrackResult.Previous:
onScreenDisplay?.Display(new MusicControllerToast("Previous track")); onScreenDisplay?.Display(new MusicControllerToast("Previous track"));
break;
}
return true; return true;
} }
@ -322,4 +343,11 @@ namespace osu.Game.Overlays
Next, Next,
Prev Prev
} }
public enum PreviousTrackResult
{
None,
Restart,
Previous
}
} }

View File

@ -137,7 +137,7 @@ namespace osu.Game.Overlays
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Action = () => musicController.PrevTrack(), Action = () => musicController.PreviousTrack(),
Icon = FontAwesome.Solid.StepBackward, Icon = FontAwesome.Solid.StepBackward,
}, },
playButton = new MusicIconButton playButton = new MusicIconButton

View File

@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.1227.1" /> <PackageReference Include="ppy.osu.Framework" Version="2020.103.0" />
<PackageReference Include="Sentry" Version="1.2.0" /> <PackageReference Include="Sentry" Version="1.2.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />

View File

@ -74,7 +74,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.1227.1" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2020.103.0" />
</ItemGroup> </ItemGroup>
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. --> <!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
<ItemGroup Label="Transitive Dependencies"> <ItemGroup Label="Transitive Dependencies">
@ -82,7 +82,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2019.1227.1" /> <PackageReference Include="ppy.osu.Framework" Version="2020.103.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />