mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 16:13:34 +08:00
Various renaming and class updates to allow multiple menu banners
This commit is contained in:
parent
77660e57ea
commit
ef2a16dd8f
@ -13,30 +13,48 @@ namespace osu.Game.Tests.Visual.Menus
|
||||
{
|
||||
public partial class TestSceneMainMenu : OsuGameTestScene
|
||||
{
|
||||
private SystemTitle systemTitle => Game.ChildrenOfType<SystemTitle>().Single();
|
||||
private OnlineMenuBanner onlineMenuBanner => Game.ChildrenOfType<OnlineMenuBanner>().Single();
|
||||
|
||||
[Test]
|
||||
public void TestSystemTitle()
|
||||
public void TestOnlineMenuBanner()
|
||||
{
|
||||
AddStep("set system title", () => systemTitle.Current.Value = new APISystemTitle
|
||||
AddStep("set online content", () => onlineMenuBanner.Current.Value = new APIMenuContent
|
||||
{
|
||||
Image = @"https://assets.ppy.sh/main-menu/project-loved-2@2x.png",
|
||||
Url = @"https://osu.ppy.sh/home/news/2023-12-21-project-loved-december-2023",
|
||||
Images = new[]
|
||||
{
|
||||
new APIMenuImage
|
||||
{
|
||||
Image = @"https://assets.ppy.sh/main-menu/project-loved-2@2x.png",
|
||||
Url = @"https://osu.ppy.sh/home/news/2023-12-21-project-loved-december-2023",
|
||||
}
|
||||
}
|
||||
});
|
||||
AddAssert("system title not visible", () => systemTitle.State.Value, () => Is.EqualTo(Visibility.Hidden));
|
||||
AddAssert("system title not visible", () => onlineMenuBanner.State.Value, () => Is.EqualTo(Visibility.Hidden));
|
||||
AddStep("enter menu", () => InputManager.Key(Key.Enter));
|
||||
AddUntilStep("system title visible", () => systemTitle.State.Value, () => Is.EqualTo(Visibility.Visible));
|
||||
AddStep("set another title", () => systemTitle.Current.Value = new APISystemTitle
|
||||
AddUntilStep("system title visible", () => onlineMenuBanner.State.Value, () => Is.EqualTo(Visibility.Visible));
|
||||
AddStep("set another title", () => onlineMenuBanner.Current.Value = new APIMenuContent
|
||||
{
|
||||
Image = @"https://assets.ppy.sh/main-menu/wf2023-vote@2x.png",
|
||||
Url = @"https://osu.ppy.sh/community/contests/189",
|
||||
Images = new[]
|
||||
{
|
||||
new APIMenuImage
|
||||
{
|
||||
Image = @"https://assets.ppy.sh/main-menu/wf2023-vote@2x.png",
|
||||
Url = @"https://osu.ppy.sh/community/contests/189",
|
||||
}
|
||||
}
|
||||
});
|
||||
AddStep("set title with nonexistent image", () => systemTitle.Current.Value = new APISystemTitle
|
||||
AddStep("set title with nonexistent image", () => onlineMenuBanner.Current.Value = new APIMenuContent
|
||||
{
|
||||
Image = @"https://test.invalid/@2x", // .invalid TLD reserved by https://datatracker.ietf.org/doc/html/rfc2606#section-2
|
||||
Url = @"https://osu.ppy.sh/community/contests/189",
|
||||
Images = new[]
|
||||
{
|
||||
new APIMenuImage
|
||||
{
|
||||
Image = @"https://test.invalid/@2x", // .invalid TLD reserved by https://datatracker.ietf.org/doc/html/rfc2606#section-2
|
||||
Url = @"https://osu.ppy.sh/community/contests/189",
|
||||
}
|
||||
}
|
||||
});
|
||||
AddStep("unset system title", () => systemTitle.Current.Value = null);
|
||||
AddStep("unset system title", () => onlineMenuBanner.Current.Value = new APIMenuContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetSystemTitleRequest : OsuJsonWebRequest<APISystemTitle>
|
||||
public class GetMenuContentRequest : OsuJsonWebRequest<APIMenuContent>
|
||||
{
|
||||
public GetSystemTitleRequest()
|
||||
public GetMenuContentRequest()
|
||||
: base(@"https://assets.ppy.sh/lazer-status.json")
|
||||
{
|
||||
}
|
42
osu.Game/Online/API/Requests/Responses/APIMenuContent.cs
Normal file
42
osu.Game/Online/API/Requests/Responses/APIMenuContent.cs
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIMenuContent : IEquatable<APIMenuContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Images which should be displayed in rotation.
|
||||
/// </summary>
|
||||
[JsonProperty(@"images")]
|
||||
public APIMenuImage[] Images { get; init; } = Array.Empty<APIMenuImage>();
|
||||
|
||||
public DateTimeOffset LastUpdated { get; init; }
|
||||
|
||||
public bool Equals(APIMenuContent? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return LastUpdated.Equals(other.LastUpdated);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
|
||||
return Equals((APIMenuContent)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return LastUpdated.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
57
osu.Game/Online/API/Requests/Responses/APIMenuImage.cs
Normal file
57
osu.Game/Online/API/Requests/Responses/APIMenuImage.cs
Normal file
@ -0,0 +1,57 @@
|
||||
// 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 System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIMenuImage : IEquatable<APIMenuImage>
|
||||
{
|
||||
/// <summary>
|
||||
/// A URL pointing to the image which should be displayed. Generally should be an @2x image filename.
|
||||
/// </summary>
|
||||
[JsonProperty(@"image")]
|
||||
public string Image { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A URL that should be opened on clicking the image.
|
||||
/// </summary>
|
||||
[JsonProperty(@"url")]
|
||||
public string Url { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The time at which this item should begin displaying. If <c>null</c>, will display immediately.
|
||||
/// </summary>
|
||||
[JsonProperty(@"begins")]
|
||||
public DateTimeOffset? Begins { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time at which this item should stop displaying. If <c>null</c>, will display indefinitely.
|
||||
/// </summary>
|
||||
[JsonProperty(@"expires")]
|
||||
public DateTimeOffset? Expires { get; set; }
|
||||
|
||||
public bool Equals(APIMenuImage? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return Image == other.Image && Url == other.Url;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
|
||||
return Equals((APIMenuImage)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Image, Url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
// 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 System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APISystemTitle : IEquatable<APISystemTitle>
|
||||
{
|
||||
[JsonProperty(@"image")]
|
||||
public string Image { get; set; } = string.Empty;
|
||||
|
||||
[JsonProperty(@"url")]
|
||||
public string Url { get; set; } = string.Empty;
|
||||
|
||||
public bool Equals(APISystemTitle? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return Image == other.Image && Url == other.Url;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) => obj is APISystemTitle other && Equals(other);
|
||||
|
||||
// ReSharper disable NonReadonlyMemberInGetHashCode
|
||||
public override int GetHashCode() => HashCode.Combine(Image, Url);
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ namespace osu.Game.Screens.Menu
|
||||
private ParallaxContainer buttonsContainer;
|
||||
private SongTicker songTicker;
|
||||
private Container logoTarget;
|
||||
private SystemTitle systemTitle;
|
||||
private OnlineMenuBanner onlineMenuBanner;
|
||||
private MenuTip menuTip;
|
||||
private FillFlowContainer bottomElementsFlow;
|
||||
private SupporterDisplay supporterDisplay;
|
||||
@ -178,7 +178,7 @@ namespace osu.Game.Screens.Menu
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
systemTitle = new SystemTitle
|
||||
onlineMenuBanner = new OnlineMenuBanner
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
@ -201,12 +201,12 @@ namespace osu.Game.Screens.Menu
|
||||
case ButtonSystemState.Initial:
|
||||
case ButtonSystemState.Exit:
|
||||
ApplyToBackground(b => b.FadeColour(Color4.White, 500, Easing.OutSine));
|
||||
systemTitle.State.Value = Visibility.Hidden;
|
||||
onlineMenuBanner.State.Value = Visibility.Hidden;
|
||||
break;
|
||||
|
||||
default:
|
||||
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(0.8f), 500, Easing.OutSine));
|
||||
systemTitle.State.Value = Visibility.Visible;
|
||||
onlineMenuBanner.State.Value = Visibility.Visible;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
@ -18,42 +19,28 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public partial class SystemTitle : VisibilityContainer
|
||||
public partial class OnlineMenuBanner : VisibilityContainer
|
||||
{
|
||||
internal Bindable<APISystemTitle?> Current { get; } = new Bindable<APISystemTitle?>();
|
||||
internal Bindable<APIMenuContent> Current { get; } = new Bindable<APIMenuContent>(new APIMenuContent());
|
||||
|
||||
private const float transition_duration = 500;
|
||||
|
||||
private Container content = null!;
|
||||
private CancellationTokenSource? cancellationTokenSource;
|
||||
private SystemTitleImage? currentImage;
|
||||
|
||||
private ScheduledDelegate? openUrlAction;
|
||||
private MenuImage? currentImage;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGame? game)
|
||||
private void load()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
AutoSizeDuration = transition_duration;
|
||||
AutoSizeEasing = Easing.OutQuint;
|
||||
|
||||
InternalChild = content = new OsuClickableContainer
|
||||
InternalChild = content = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Action = () =>
|
||||
{
|
||||
currentImage?.Flash();
|
||||
|
||||
// Delay slightly to allow animation to play out.
|
||||
openUrlAction?.Cancel();
|
||||
openUrlAction = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Current.Value?.Url))
|
||||
game?.HandleLink(Current.Value.Url);
|
||||
}, 250);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -98,7 +85,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private void checkForUpdates()
|
||||
{
|
||||
var request = new GetSystemTitleRequest();
|
||||
var request = new GetMenuContentRequest();
|
||||
Task.Run(() => request.Perform())
|
||||
.ContinueWith(r =>
|
||||
{
|
||||
@ -121,12 +108,12 @@ namespace osu.Game.Screens.Menu
|
||||
cancellationTokenSource = null;
|
||||
currentImage?.FadeOut(500, Easing.OutQuint).Expire();
|
||||
|
||||
if (string.IsNullOrEmpty(Current.Value?.Image))
|
||||
if (Current.Value.Images.Length == 0)
|
||||
return;
|
||||
|
||||
LoadComponentAsync(new SystemTitleImage(Current.Value), loaded =>
|
||||
LoadComponentAsync(new MenuImage(Current.Value.Images.First()), loaded =>
|
||||
{
|
||||
if (!loaded.SystemTitle.Equals(Current.Value))
|
||||
if (!loaded.Image.Equals(Current.Value.Images.First()))
|
||||
loaded.Dispose();
|
||||
|
||||
content.Add(currentImage = loaded);
|
||||
@ -134,22 +121,24 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
|
||||
[LongRunningLoad]
|
||||
private partial class SystemTitleImage : CompositeDrawable
|
||||
private partial class MenuImage : OsuClickableContainer
|
||||
{
|
||||
public readonly APISystemTitle SystemTitle;
|
||||
public readonly APIMenuImage Image;
|
||||
|
||||
private Sprite flash = null!;
|
||||
|
||||
public SystemTitleImage(APISystemTitle systemTitle)
|
||||
private ScheduledDelegate? openUrlAction;
|
||||
|
||||
public MenuImage(APIMenuImage image)
|
||||
{
|
||||
SystemTitle = systemTitle;
|
||||
Image = image;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LargeTextureStore textureStore)
|
||||
private void load(LargeTextureStore textureStore, OsuGame game)
|
||||
{
|
||||
Texture? texture = textureStore.Get(SystemTitle.Image);
|
||||
if (texture != null && SystemTitle.Image.Contains(@"@2x"))
|
||||
Texture? texture = textureStore.Get(Image.Image);
|
||||
if (texture != null && Image.Image.Contains(@"@2x"))
|
||||
texture.ScaleAdjust *= 2;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
@ -163,6 +152,19 @@ namespace osu.Game.Screens.Menu
|
||||
Blending = BlendingParameters.Additive,
|
||||
},
|
||||
};
|
||||
|
||||
Action = () =>
|
||||
{
|
||||
Flash();
|
||||
|
||||
// Delay slightly to allow animation to play out.
|
||||
openUrlAction?.Cancel();
|
||||
openUrlAction = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Image.Url))
|
||||
game?.HandleLink(Image.Url);
|
||||
}, 250);
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
Loading…
Reference in New Issue
Block a user