// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable disable using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Overlays; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Setup; using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { public partial class TestSceneMetadataSection : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine); [Cached] private EditorBeatmap editorBeatmap = new EditorBeatmap(new Beatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo }, }); private TestMetadataSection metadataSection; [Test] public void TestUpdateViaTextBoxOnFocusLoss() { AddStep("set metadata", () => { editorBeatmap.Metadata.Artist = "Example Artist"; editorBeatmap.Metadata.ArtistUnicode = string.Empty; }); createSection(); TextBox textbox; AddStep("focus first textbox", () => { textbox = metadataSection.ChildrenOfType().First(); InputManager.MoveMouseTo(textbox); InputManager.Click(MouseButton.Left); }); AddStep("simulate changing textbox", () => { // Can't simulate text input but this should work. InputManager.Keys(PlatformAction.SelectAll); InputManager.Keys(PlatformAction.Copy); InputManager.Keys(PlatformAction.Paste); InputManager.Keys(PlatformAction.Paste); }); assertArtistMetadata("Example Artist"); // It's important values are committed immediately on focus loss so the editor exit sequence detects them. AddAssert("value immediately changed on focus loss", () => { ((IFocusManager)InputManager).TriggerFocusContention(metadataSection); return editorBeatmap.Metadata.Artist; }, () => Is.EqualTo("Example ArtistExample Artist")); } [Test] public void TestUpdateViaTextBoxOnCommit() { AddStep("set metadata", () => { editorBeatmap.Metadata.Artist = "Example Artist"; editorBeatmap.Metadata.ArtistUnicode = string.Empty; }); createSection(); TextBox textbox; AddStep("focus first textbox", () => { textbox = metadataSection.ChildrenOfType().First(); InputManager.MoveMouseTo(textbox); InputManager.Click(MouseButton.Left); }); AddStep("simulate changing textbox", () => { // Can't simulate text input but this should work. InputManager.Keys(PlatformAction.SelectAll); InputManager.Keys(PlatformAction.Copy); InputManager.Keys(PlatformAction.Paste); InputManager.Keys(PlatformAction.Paste); }); assertArtistMetadata("Example Artist"); AddStep("commit", () => InputManager.Key(Key.Enter)); assertArtistMetadata("Example ArtistExample Artist"); } [Test] public void TestMinimalMetadata() { AddStep("set metadata", () => { editorBeatmap.Metadata.Artist = "Example Artist"; editorBeatmap.Metadata.ArtistUnicode = string.Empty; editorBeatmap.Metadata.Title = "Example Title"; editorBeatmap.Metadata.TitleUnicode = string.Empty; }); createSection(); assertArtistTextBox("Example Artist"); assertRomanisedArtist("Example Artist", false); assertTitle("Example Title"); assertRomanisedTitle("Example Title", false); } [Test] public void TestInitialisationFromNonRomanisedVariant() { AddStep("set metadata", () => { editorBeatmap.Metadata.ArtistUnicode = "*なみりん"; editorBeatmap.Metadata.Artist = string.Empty; editorBeatmap.Metadata.TitleUnicode = "コイシテイク・プラネット"; editorBeatmap.Metadata.Title = string.Empty; }); createSection(); assertArtistTextBox("*なみりん"); assertRomanisedArtist(string.Empty, true); assertTitle("コイシテイク・プラネット"); assertRomanisedTitle(string.Empty, true); } [Test] public void TestInitialisationPreservesOriginalValues() { AddStep("set metadata", () => { editorBeatmap.Metadata.ArtistUnicode = "*なみりん"; editorBeatmap.Metadata.Artist = "*namirin"; editorBeatmap.Metadata.TitleUnicode = "コイシテイク・プラネット"; editorBeatmap.Metadata.Title = "Koishiteiku Planet"; }); createSection(); assertArtistTextBox("*なみりん"); assertRomanisedArtist("*namirin", true); assertTitle("コイシテイク・プラネット"); assertRomanisedTitle("Koishiteiku Planet", true); } [Test] public void TestValueTransfer() { AddStep("set metadata", () => { editorBeatmap.Metadata.ArtistUnicode = "*なみりん"; editorBeatmap.Metadata.Artist = string.Empty; editorBeatmap.Metadata.TitleUnicode = "コイシテイク・プラネット"; editorBeatmap.Metadata.Title = string.Empty; }); createSection(); AddStep("set romanised artist name", () => metadataSection.ArtistTextBox.Current.Value = "*namirin"); assertArtistTextBox("*namirin"); assertRomanisedArtist("*namirin", false); AddStep("set native artist name", () => metadataSection.ArtistTextBox.Current.Value = "*なみりん"); assertArtistTextBox("*なみりん"); assertRomanisedArtist("*namirin", true); AddStep("set romanised title", () => metadataSection.TitleTextBox.Current.Value = "Hitokoto no kyori"); assertTitle("Hitokoto no kyori"); assertRomanisedTitle("Hitokoto no kyori", false); AddStep("set native title", () => metadataSection.TitleTextBox.Current.Value = "ヒトコトの距離"); assertTitle("ヒトコトの距離"); assertRomanisedTitle("Hitokoto no kyori", true); } private void createSection() => AddStep("create metadata section", () => Child = metadataSection = new TestMetadataSection { RelativeSizeAxes = Axes.X }); private void assertArtistMetadata(string expected) => AddAssert($"artist metadata is {expected}", () => editorBeatmap.Metadata.Artist, () => Is.EqualTo(expected)); private void assertArtistTextBox(string expected) => AddAssert($"artist textbox is {expected}", () => metadataSection.ArtistTextBox.Current.Value, () => Is.EqualTo(expected)); private void assertRomanisedArtist(string expected, bool editable) { AddAssert($"romanised artist is {expected}", () => metadataSection.RomanisedArtistTextBox.Current.Value, () => Is.EqualTo(expected)); AddAssert($"romanised artist is {(editable ? "" : "not ")}editable", () => metadataSection.RomanisedArtistTextBox.ReadOnly == !editable); } private void assertTitle(string expected) => AddAssert($"title is {expected}", () => metadataSection.TitleTextBox.Current.Value, () => Is.EqualTo(expected)); private void assertRomanisedTitle(string expected, bool editable) { AddAssert($"romanised title is {expected}", () => metadataSection.RomanisedTitleTextBox.Current.Value, () => Is.EqualTo(expected)); AddAssert($"romanised title is {(editable ? "" : "not ")}editable", () => metadataSection.RomanisedTitleTextBox.ReadOnly == !editable); } private partial class TestMetadataSection : MetadataSection { public new FormTextBox ArtistTextBox => base.ArtistTextBox; public new FormTextBox RomanisedArtistTextBox => base.RomanisedArtistTextBox; public new FormTextBox TitleTextBox => base.TitleTextBox; public new FormTextBox RomanisedTitleTextBox => base.RomanisedTitleTextBox; } } }