mirror of
https://github.com/ppy/osu.git
synced 2024-12-13 07:43:00 +08:00
Implement visual appearance of "system title" message in main menu
This commit is contained in:
parent
28f5e90aba
commit
d9299a8a55
30
osu.Game.Tests/Visual/Menus/TestSceneMainMenu.cs
Normal file
30
osu.Game.Tests/Visual/Menus/TestSceneMainMenu.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.Menu;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Menus
|
||||
{
|
||||
public partial class TestSceneMainMenu : OsuGameTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestSystemTitle()
|
||||
{
|
||||
AddStep("set system title", () => Game.ChildrenOfType<SystemTitle>().Single().Current.Value = new APISystemTitle
|
||||
{
|
||||
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",
|
||||
});
|
||||
AddStep("set another title", () => Game.ChildrenOfType<SystemTitle>().Single().Current.Value = new APISystemTitle
|
||||
{
|
||||
Image = @"https://assets.ppy.sh/main-menu/wf2023-vote@2x.png",
|
||||
Url = @"https://osu.ppy.sh/community/contests/189",
|
||||
});
|
||||
AddStep("unset system title", () => Game.ChildrenOfType<SystemTitle>().Single().Current.Value = null);
|
||||
}
|
||||
}
|
||||
}
|
16
osu.Game/Online/API/Requests/Responses/APISystemTitle.cs
Normal file
16
osu.Game/Online/API/Requests/Responses/APISystemTitle.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// 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 Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APISystemTitle
|
||||
{
|
||||
[JsonProperty(@"image")]
|
||||
public string Image { get; set; } = string.Empty;
|
||||
|
||||
[JsonProperty(@"url")]
|
||||
public string Url { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -995,7 +995,10 @@ namespace osu.Game
|
||||
}, topMostOverlayContent.Add);
|
||||
|
||||
if (!args?.Any(a => a == @"--no-version-overlay") ?? true)
|
||||
loadComponentSingleFile(versionManager = new VersionManager { Depth = int.MinValue }, ScreenContainer.Add);
|
||||
{
|
||||
dependencies.Cache(versionManager = new VersionManager { Depth = int.MinValue });
|
||||
loadComponentSingleFile(versionManager, ScreenContainer.Add);
|
||||
}
|
||||
|
||||
loadComponentSingleFile(osuLogo, _ =>
|
||||
{
|
||||
|
@ -76,6 +76,9 @@ namespace osu.Game.Screens.Menu
|
||||
[Resolved(canBeNull: true)]
|
||||
private IDialogOverlay dialogOverlay { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private VersionManager versionManager { get; set; }
|
||||
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault();
|
||||
|
||||
protected override bool PlayExitSound => false;
|
||||
@ -91,6 +94,7 @@ namespace osu.Game.Screens.Menu
|
||||
private ParallaxContainer buttonsContainer;
|
||||
private SongTicker songTicker;
|
||||
private Container logoTarget;
|
||||
private SystemTitle systemTitle;
|
||||
|
||||
private Sample reappearSampleSwoosh;
|
||||
|
||||
@ -153,6 +157,7 @@ namespace osu.Game.Screens.Menu
|
||||
Margin = new MarginPadding { Right = 15, Top = 5 }
|
||||
},
|
||||
new KiaiMenuFountains(),
|
||||
systemTitle = new SystemTitle(),
|
||||
holdToExitGameOverlay?.CreateProxy() ?? Empty()
|
||||
});
|
||||
|
||||
@ -263,6 +268,16 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
systemTitle.Margin = new MarginPadding
|
||||
{
|
||||
Bottom = (versionManager?.DrawHeight + 5) ?? 0
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LogoSuspending(OsuLogo logo)
|
||||
{
|
||||
var seq = logo.FadeOut(300, Easing.InSine)
|
||||
|
101
osu.Game/Screens/Menu/SystemTitle.cs
Normal file
101
osu.Game/Screens/Menu/SystemTitle.cs
Normal file
@ -0,0 +1,101 @@
|
||||
// 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.Threading;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public partial class SystemTitle : CompositeDrawable
|
||||
{
|
||||
internal Bindable<APISystemTitle?> Current { get; } = new Bindable<APISystemTitle?>();
|
||||
|
||||
private Container content = null!;
|
||||
private CancellationTokenSource? cancellationTokenSource;
|
||||
private SystemTitleImage? currentImage;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost? gameHost)
|
||||
{
|
||||
Anchor = Anchor.BottomCentre;
|
||||
Origin = Anchor.BottomCentre;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChild = content = new ClickableContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Action = () =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Current.Value?.Url))
|
||||
gameHost?.OpenUrlExternally(Current.Value.Url);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
content.ScaleTo(1.1f, 500, Easing.OutBounce);
|
||||
return base.OnHover(e);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
content.ScaleTo(1f, 500, Easing.OutBounce);
|
||||
base.OnHoverLost(e);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Current.BindValueChanged(_ => loadNewImage(), true);
|
||||
}
|
||||
|
||||
private void loadNewImage()
|
||||
{
|
||||
cancellationTokenSource?.Cancel();
|
||||
cancellationTokenSource = null;
|
||||
currentImage?.FadeOut(500, Easing.OutQuint).Expire();
|
||||
|
||||
if (string.IsNullOrEmpty(Current.Value?.Image))
|
||||
return;
|
||||
|
||||
LoadComponentAsync(new SystemTitleImage(Current.Value), loaded =>
|
||||
{
|
||||
if (loaded.SystemTitle != Current.Value)
|
||||
loaded.Dispose();
|
||||
|
||||
loaded.FadeInFromZero(500, Easing.OutQuint);
|
||||
content.Add(currentImage = loaded);
|
||||
}, (cancellationTokenSource ??= new CancellationTokenSource()).Token);
|
||||
}
|
||||
|
||||
[LongRunningLoad]
|
||||
private partial class SystemTitleImage : Sprite
|
||||
{
|
||||
public readonly APISystemTitle SystemTitle;
|
||||
|
||||
public SystemTitleImage(APISystemTitle systemTitle)
|
||||
{
|
||||
SystemTitle = systemTitle;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LargeTextureStore textureStore)
|
||||
{
|
||||
var texture = textureStore.Get(SystemTitle.Image);
|
||||
if (SystemTitle.Image.Contains(@"@2x"))
|
||||
texture.ScaleAdjust *= 2;
|
||||
Texture = texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user