diff --git a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditor.cs b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditor.cs index a8ea20269..f4f75f0bb 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditor.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditor.cs @@ -58,6 +58,7 @@ protected override bool OnKeyDown(KeyDownEvent e) if (timeTagManager == null) return false; + // moving cursor action switch (e.Key) { case Key.Up: @@ -72,6 +73,27 @@ protected override bool OnKeyDown(KeyDownEvent e) return timeTagManager.MoveCursor(CursorAction.First); case Key.PageDown: return timeTagManager.MoveCursor(CursorAction.Last); + } + + // edit time tag action + var currentTimeTag = timeTagManager?.BindableCursorPosition?.Value; + switch (e.Key) + { + case Key.BackSpace: + return timeTagManager?.ClearTimeTagTime(currentTimeTag) ?? false; + case Key.Space: + var setTimeSuccess = timeTagManager?.SetTimeTagTime(currentTimeTag) ?? false; + if (setTimeSuccess) + timeTagManager.MoveCursor(CursorAction.MoveRight); + return setTimeSuccess; + case Key.N: + var createdTimeTag = timeTagManager?.AddTimeTag(currentTimeTag); + if (createdTimeTag != null) + timeTagManager.MoveCursorToTargetPosition(createdTimeTag); + return createdTimeTag != null; + case Key.Delete: + timeTagManager?.MoveCursor(CursorAction.MoveRight); + return timeTagManager?.RemoveTimeTag(currentTimeTag) ?? false; default: return base.OnKeyDown(e); } diff --git a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs index e5c105dfd..d1c2a2cd9 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/TimeTagManager.cs @@ -5,9 +5,11 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; +using osu.Framework.Timing; using osu.Game.Rulesets.Karaoke.Edit.Generator.TimeTags.Ja; using osu.Game.Rulesets.Karaoke.Edit.Generator.TimeTags.Zh; using osu.Game.Rulesets.Karaoke.Objects; +using osu.Game.Rulesets.Karaoke.Utils; using osu.Game.Screens.Edit; using System; using System.Linq; @@ -23,11 +25,16 @@ public class TimeTagManager : Component [Resolved] private EditorBeatmap beatmap { get; set; } - [Resolved(CanBeNull = true)] + [Resolved(canBeNull: true)] private IEditorChangeHandler changeHandler { get; set; } + [Resolved(canBeNull: true)] + private IFrameBasedClock framedClock { get; set; } + public Bindable BindableCursorPosition { get; set; } = new Bindable(); + #region Edit Time Tag + /// /// Will auto-detect each 's and apply on them. /// @@ -50,6 +57,95 @@ public void AutoGenerateTimeTags() changeHandler?.EndChange(); } + public bool SetTimeTagTime(TimeTag timeTag) + { + if (framedClock == null) + return false; + + var currentLyric = timeTagInLyric(timeTag); + if (currentLyric == null) + return false; + + changeHandler?.BeginChange(); + + timeTag.Time = framedClock.CurrentTime; + refreshTimeTag(currentLyric); + + changeHandler?.EndChange(); + + currentLyric.TimeTagsBindable.TriggerChange(); + return true; + } + + public bool ClearTimeTagTime(TimeTag timeTag) + { + if (framedClock == null) + return false; + + var currentLyric = timeTagInLyric(timeTag); + if (currentLyric == null) + return false; + + changeHandler?.BeginChange(); + + timeTag.Time = null; + refreshTimeTag(currentLyric); + + changeHandler?.EndChange(); + + return true; + } + + public TimeTag AddTimeTag(TimeTag timeTag) + { + var currentLyric = timeTagInLyric(timeTag); + if (currentLyric == null) + return null; + + var timeTags = currentLyric.TimeTags.ToList(); + var targetIndex = timeTags.IndexOf(timeTag); + if (targetIndex < 0) + return null; + + var newTimeTag = new TimeTag(timeTag.Index); + timeTags.Insert(targetIndex, newTimeTag); + + changeHandler?.BeginChange(); + + currentLyric.TimeTags = timeTags.ToArray(); + sortingTimeTag(currentLyric); + + changeHandler?.EndChange(); + + return newTimeTag; + } + + public bool RemoveTimeTag(TimeTag timeTag) + { + var currentLyric = timeTagInLyric(timeTag); + if (currentLyric == null) + return false; + + changeHandler?.BeginChange(); + + // delete time tag from list + currentLyric.TimeTags = currentLyric.TimeTags.Where(x => x != timeTag).ToArray(); + + changeHandler?.EndChange(); + + return true; + } + + private void refreshTimeTag(Lyric lyric) + => lyric.TimeTags = lyric.TimeTags.ToArray(); + + private void sortingTimeTag(Lyric lyric) + => lyric.TimeTags = TimeTagsUtils.Sort(lyric.TimeTags); + + #endregion + + #region Time Tag cursor + public bool MoveCursor(CursorAction action) { var currentTimeTag = BindableCursorPosition.Value; @@ -185,6 +281,8 @@ public TimeTag[] GenerateTimeTags(Lyric lyric) } } } + + #endregion } public enum CursorAction