diff --git a/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandlerTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandlerTest.cs index ec6302edf..01ad22e69 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandlerTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandlerTest.cs @@ -197,7 +197,7 @@ public void TestAutoGenerateRomajiTagsWithNonSupportedLyric() #endregion - #region TimeTag + #region Time-tag [Test] public void TestAutoGenerateTimeTags() @@ -241,6 +241,44 @@ public void TestAutoGenerateTimeTagsWithNonSupportedLyric() #endregion + #region Time-tag romaji + + [Test] + public void TestAutoGenerateTimeTagRomaji() + { + PrepareHitObject(() => new Lyric + { + Text = "カラオケ", + Language = new CultureInfo(17), + TimeTags = TestCaseTagHelper.ParseTimeTags(new[] { "[0,start]", "[3,end]" }), + }); + + TriggerHandlerChanged(c => c.AutoGenerate(AutoGenerateType.AutoGenerateTimeTagRomaji)); + + AssertSelectedHitObject(h => + { + Assert.AreEqual("karaoke", h.TimeTags[0].RomajiText); + }); + } + + [Test] + public void TestAutoGenerateTimeTagRomajiWithNonSupportedLyric() + { + PrepareHitObjects(() => new[] + { + new Lyric + { + Text = "カラオケ", + Language = new CultureInfo(17), + // with no time-tag. + }, + }); + + TriggerHandlerChangedWithException(c => c.AutoGenerate(AutoGenerateType.AutoGenerateTimeTagRomaji)); + } + + #endregion + #region Note [Test] diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IAutoGenerateChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IAutoGenerateChangeHandler.cs index f586224da..4f11b9c61 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IAutoGenerateChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IAutoGenerateChangeHandler.cs @@ -11,9 +11,9 @@ namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers; /// public interface IEnumAutoGenerateChangeHandler where TEnum : Enum { - bool CanGenerate(TEnum property); + bool CanGenerate(TEnum type); - void AutoGenerate(TEnum property); + void AutoGenerate(TEnum type); } /// diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyAutoGenerateChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyAutoGenerateChangeHandler.cs index 64490137c..7f9e7b850 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyAutoGenerateChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyAutoGenerateChangeHandler.cs @@ -24,5 +24,7 @@ public enum AutoGenerateType AutoGenerateTimeTags, + AutoGenerateTimeTagRomaji, + AutoGenerateNotes, } diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandler.cs index 19b457ca7..c62c3c1ff 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandler.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Language; using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Notes; using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.ReferenceLyric; +using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Romajies; using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.RomajiTags; using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.RubyTags; using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.TimeTags; @@ -27,16 +28,16 @@ public partial class LyricPropertyAutoGenerateChangeHandler : LyricPropertyChang { // should change this flag if wants to change property in the lyrics. // Not a good to waite a global property for that but there's no better choice. - private AutoGenerateType? currentAutoGenerateProperty; + private AutoGenerateType? currentAutoGenerateType; [Resolved] private EditorBeatmap beatmap { get; set; } = null!; - public bool CanGenerate(AutoGenerateType autoGenerateProperty) + public bool CanGenerate(AutoGenerateType type) { - currentAutoGenerateProperty = autoGenerateProperty; + currentAutoGenerateType = type; - switch (autoGenerateProperty) + switch (type) { case AutoGenerateType.DetectReferenceLyric: var referenceLyricDetector = getDetector(HitObjects); @@ -58,12 +59,16 @@ public bool CanGenerate(AutoGenerateType autoGenerateProperty) var timeTagGenerator = getSelector(); return canGenerate(timeTagGenerator); + case AutoGenerateType.AutoGenerateTimeTagRomaji: + var timeTagRomajiGenerator = getSelector, RomajiGeneratorConfig>(); + return canGenerate(timeTagRomajiGenerator); + case AutoGenerateType.AutoGenerateNotes: var noteGenerator = getGenerator(); return canGenerate(noteGenerator); default: - throw new ArgumentOutOfRangeException(nameof(autoGenerateProperty)); + throw new ArgumentOutOfRangeException(nameof(type)); } bool canDetect(PropertyDetector detector) @@ -73,11 +78,11 @@ bool canGenerate(PropertyGenerator generator) => HitObjects.Where(x => !IsWritePropertyLocked(x)).Any(generator.CanGenerate); } - public IDictionary GetGeneratorNotSupportedLyrics(AutoGenerateType autoGenerateProperty) + public IDictionary GetGeneratorNotSupportedLyrics(AutoGenerateType type) { - currentAutoGenerateProperty = autoGenerateProperty; + currentAutoGenerateType = type; - switch (autoGenerateProperty) + switch (type) { case AutoGenerateType.DetectReferenceLyric: var referenceLyricDetector = getDetector(HitObjects); @@ -99,12 +104,16 @@ public IDictionary GetGeneratorNotSupportedLyrics(Auto var timeTagGenerator = getSelector(); return getInvalidMessageFromGenerator(timeTagGenerator); + case AutoGenerateType.AutoGenerateTimeTagRomaji: + var timeTagRomajiGenerator = getSelector, RomajiGeneratorConfig>(); + return getInvalidMessageFromGenerator(timeTagRomajiGenerator); + case AutoGenerateType.AutoGenerateNotes: var noteGenerator = getGenerator(); return getInvalidMessageFromGenerator(noteGenerator); default: - throw new ArgumentOutOfRangeException(nameof(autoGenerateProperty)); + throw new ArgumentOutOfRangeException(nameof(type)); } IDictionary getInvalidMessageFromDetector(PropertyDetector detector) @@ -124,11 +133,11 @@ IDictionary getInvalidMessageFromGenerator(Property } } - public void AutoGenerate(AutoGenerateType autoGenerateProperty) + public void AutoGenerate(AutoGenerateType type) { - currentAutoGenerateProperty = autoGenerateProperty; + currentAutoGenerateType = type; - switch (autoGenerateProperty) + switch (type) { case AutoGenerateType.DetectReferenceLyric: var referenceLyricDetector = getDetector(HitObjects); @@ -178,6 +187,21 @@ public void AutoGenerate(AutoGenerateType autoGenerateProperty) }); break; + case AutoGenerateType.AutoGenerateTimeTagRomaji: + var timeTagRomajiGenerator = getSelector, RomajiGeneratorConfig>(); + PerformOnSelection(lyric => + { + var results = timeTagRomajiGenerator.Generate(lyric); + + foreach (var (key, value) in results) + { + var matchedTimeTag = lyric.TimeTags.Single(x => x == key); + matchedTimeTag.InitialRomaji = value.InitialRomaji; + matchedTimeTag.RomajiText = value.RomajiText; + } + }); + break; + case AutoGenerateType.AutoGenerateNotes: var noteGenerator = getGenerator(); PerformOnSelection(lyric => @@ -192,7 +216,7 @@ public void AutoGenerate(AutoGenerateType autoGenerateProperty) break; default: - throw new ArgumentOutOfRangeException(nameof(autoGenerateProperty)); + throw new ArgumentOutOfRangeException(nameof(type)); } } @@ -200,13 +224,14 @@ public override bool IsSelectionsLocked() => throw new InvalidOperationException("Auto-generator does not support this check method."); protected override bool IsWritePropertyLocked(Lyric lyric) => - currentAutoGenerateProperty switch + currentAutoGenerateType switch { AutoGenerateType.DetectReferenceLyric => HitObjectWritableUtils.IsWriteLyricPropertyLocked(lyric, nameof(Lyric.ReferenceLyric), nameof(Lyric.ReferenceLyricConfig)), AutoGenerateType.DetectLanguage => HitObjectWritableUtils.IsWriteLyricPropertyLocked(lyric, nameof(Lyric.Language)), AutoGenerateType.AutoGenerateRubyTags => HitObjectWritableUtils.IsWriteLyricPropertyLocked(lyric, nameof(Lyric.RubyTags)), AutoGenerateType.AutoGenerateRomajiTags => HitObjectWritableUtils.IsWriteLyricPropertyLocked(lyric, nameof(Lyric.RomajiTags)), AutoGenerateType.AutoGenerateTimeTags => HitObjectWritableUtils.IsWriteLyricPropertyLocked(lyric, nameof(Lyric.TimeTags)), + AutoGenerateType.AutoGenerateTimeTagRomaji => HitObjectWritableUtils.IsWriteLyricPropertyLocked(lyric, nameof(Lyric.TimeTags)), AutoGenerateType.AutoGenerateNotes => HitObjectWritableUtils.IsCreateOrRemoveNoteLocked(lyric), _ => throw new ArgumentOutOfRangeException(), };