diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs index 387340c57..9e22af41e 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs @@ -18,6 +18,12 @@ public abstract class HitObjectChangeHandler : Component where THitO protected IEnumerable HitObjects => beatmap.HitObjects.OfType(); + protected void CheckExactlySelectedOneHitObject() + { + if (beatmap.SelectedHitObjects.OfType().Count() != 1) + throw new InvalidOperationException($"Should be exactly one {nameof(THitObject)} being selected."); + } + protected void PerformOnSelection(Action action) => beatmap.PerformOnSelection(h => { if (h is THitObject tHitObject) diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextChangeHandler.cs index 20e91f3fa..69c255a81 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextChangeHandler.cs @@ -11,6 +11,8 @@ public class LyricTextChangeHandler : HitObjectChangeHandler, ILyricTextC { public void InsertText(int index, string text) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { LyricUtils.AddText(lyric, index, text); @@ -19,6 +21,8 @@ public void InsertText(int index, string text) public void DeleteLyricText(int index) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { LyricUtils.RemoveText(lyric, index - 1); diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextTagsChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextTagsChangeHandler.cs index 9baa9a891..a7c2415f0 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextTagsChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextTagsChangeHandler.cs @@ -14,6 +14,8 @@ namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics { public void Add(TTextTag textTag) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { bool containsInLyric = ContainsInLyric(lyric, textTag); @@ -26,6 +28,8 @@ public void Add(TTextTag textTag) public void Remove(TTextTag textTag) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { bool containsInLyric = ContainsInLyric(lyric, textTag); @@ -38,6 +42,8 @@ public void Remove(TTextTag textTag) public void RemoveAll(IEnumerable textTags) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { // should convert to array because enumerable might change while deleting. @@ -54,6 +60,8 @@ public void RemoveAll(IEnumerable textTags) public void SetIndex(TTextTag textTag, int? startIndex, int? endIndex) { + CheckExactlySelectedOneHitObject(); + // note: it's ok not sort the text tag by index. PerformOnSelection(lyric => { @@ -71,6 +79,8 @@ public void SetIndex(TTextTag textTag, int? startIndex, int? endIndex) public void ShiftingIndex(IEnumerable textTags, int offset) { + CheckExactlySelectedOneHitObject(); + // note: it's ok not sort the text tag by index. PerformOnSelection(lyric => { @@ -89,6 +99,8 @@ public void ShiftingIndex(IEnumerable textTags, int offset) public void SetText(TTextTag textTag, string text) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { bool containsInLyric = ContainsInLyric(lyric, textTag); diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandler.cs index 8e9a38a13..94f45f7c9 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandler.cs @@ -32,6 +32,8 @@ public void AutoGenerate() public void SetTimeTagTime(TimeTag timeTag, double time) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { bool containsInLyric = lyric.TimeTags?.Contains(timeTag) ?? false; @@ -44,6 +46,8 @@ public void SetTimeTagTime(TimeTag timeTag, double time) public void ClearTimeTagTime(TimeTag timeTag) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { bool containsInLyric = lyric.TimeTags?.Contains(timeTag) ?? false; @@ -56,6 +60,8 @@ public void ClearTimeTagTime(TimeTag timeTag) public void Add(TimeTag timeTag) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { bool containsInLyric = lyric.TimeTags.Contains(timeTag); @@ -68,6 +74,8 @@ public void Add(TimeTag timeTag) public void Remove(TimeTag timeTag) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { // delete time tag from list @@ -77,6 +85,8 @@ public void Remove(TimeTag timeTag) public void AddByPosition(TextIndex index) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { lyric.TimeTags.Add(new TimeTag(index)); @@ -85,6 +95,8 @@ public void AddByPosition(TextIndex index) public void RemoveByPosition(TextIndex index) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { var matchedTimeTags = lyric.TimeTags.Where(x => x.Index == index).ToList(); diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTranslateChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTranslateChangeHandler.cs index cbf861d10..bd003813e 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTranslateChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTranslateChangeHandler.cs @@ -11,6 +11,8 @@ public class LyricTranslateChangeHandler : HitObjectChangeHandler, ILyric { public void UpdateTranslate(CultureInfo cultureInfo, string translate) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { // should not save translate if is null or empty or whitespace diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricsChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricsChangeHandler.cs index efb63d154..d020724ea 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricsChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricsChangeHandler.cs @@ -13,6 +13,8 @@ public class LyricsChangeHandler : HitObjectChangeHandler, ILyricsChangeH { public void Split(int index) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { // Shifting order that order is larger than current lyric. @@ -35,6 +37,8 @@ public void Split(int index) public void Combine() { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { var previousLyric = HitObjects.GetPrevious(lyric); @@ -57,6 +61,8 @@ public void Combine() public void CreateAtPosition() { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(lyric => { int order = lyric.Order; diff --git a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/NotesChangeHandler.cs b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/NotesChangeHandler.cs index 5a98cc469..76d996f3e 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/NotesChangeHandler.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/NotesChangeHandler.cs @@ -38,6 +38,8 @@ public void AutoGenerate() public void Split(float percentage = 0.5f) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(note => { var (firstNote, secondNote) = NotesUtils.SplitNote(note); @@ -70,6 +72,8 @@ public void Combine() public void ChangeText(string text) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(note => { note.Text = text; @@ -78,6 +82,8 @@ public void ChangeText(string text) public void ChangeRubyText(string ruby) { + CheckExactlySelectedOneHitObject(); + PerformOnSelection(note => { note.RubyText = ruby;