Skip to content

Commit

Permalink
Merge pull request #325 from andy840119/lyric-editor/implement-each-m…
Browse files Browse the repository at this point in the history
…ode-cursor

Create state manager into lyric editor
  • Loading branch information
andy840119 authored Dec 19, 2020
2 parents 3eb23f1 + 1e52b7d commit 3f55d66
Show file tree
Hide file tree
Showing 19 changed files with 836 additions and 259 deletions.
30 changes: 30 additions & 0 deletions osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagIndexUtilsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using NUnit.Framework;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Karaoke.Utils;

namespace osu.Game.Rulesets.Karaoke.Tests.Utils
{
[TestFixture]
public class TimeTagIndexUtilsTest
{
[TestCase(0, TimeTagIndex.IndexState.Start, 0)]
[TestCase(0, TimeTagIndex.IndexState.End, 1)]
[TestCase(-1, TimeTagIndex.IndexState.Start, -1)] // In utils not checking is index out of range
[TestCase(-1, TimeTagIndex.IndexState.End, 0)]
public void TestToLyricIndex(int index, TimeTagIndex.IndexState state, int actualIndex)
{
var timeTagIndex = new TimeTagIndex(index, state);
Assert.AreEqual(TimeTagIndexUtils.ToLyricIndex(timeTagIndex), actualIndex);
}

[TestCase(TimeTagIndex.IndexState.Start, TimeTagIndex.IndexState.End)]
[TestCase(TimeTagIndex.IndexState.End, TimeTagIndex.IndexState.Start)]
public void TestReverseState(TimeTagIndex.IndexState state, TimeTagIndex.IndexState actualState)
{
Assert.AreEqual(TimeTagIndexUtils.ReverseState(state), actualState);
}
}
}
21 changes: 21 additions & 0 deletions osu.Game.Rulesets.Karaoke/Edit/Lyrics/CursorPosition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Edit.Lyrics
{
public readonly struct CursorPosition
{
public CursorPosition(Lyric lyric, TimeTagIndex timeTagIndex)
{
Lyric = lyric;
Index = timeTagIndex;
}

public Lyric Lyric { get; }

public TimeTagIndex Index { get; }
}
}
7 changes: 5 additions & 2 deletions osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ protected override bool OnKeyDown(KeyDownEvent e)
return lyricEditorStateManager.MoveCursor(CursorAction.Last);
}

if (lyricEditorStateManager.Mode != Mode.TimeTagEditMode)
return false;

// edit time tag action
var currentTimeTag = lyricEditorStateManager.BindableCursorPosition.Value;
var currentTimeTag = lyricEditorStateManager.BindableRecordCursorPosition.Value;

switch (e.Key)
{
Expand All @@ -110,7 +113,7 @@ protected override bool OnKeyDown(KeyDownEvent e)
case Key.N:
var createdTimeTag = timeTagManager?.AddTimeTag(currentTimeTag);
if (createdTimeTag != null)
lyricEditorStateManager.MoveCursorToTargetPosition(createdTimeTag);
lyricEditorStateManager.MoveRecordCursorToTargetPosition(createdTimeTag);
return createdTimeTag != null;

case Key.Delete:
Expand Down
153 changes: 21 additions & 132 deletions osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditorStateManager.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Screens.Edit;

namespace osu.Game.Rulesets.Karaoke.Edit.Lyrics
{
public class LyricEditorStateManager
public partial class LyricEditorStateManager
{
private EditorBeatmap beatmap { get; set; }

public Bindable<Lyric> BindableSplitLyric { get; } = new Bindable<Lyric>();
public Bindable<int> BindableSplitPosition { get; } = new Bindable<int>();
private EditorBeatmap beatmap { get; }

public Bindable<Mode> BindableMode { get; } = new Bindable<Mode>();

Expand All @@ -24,148 +18,43 @@ public class LyricEditorStateManager

public LyricFastEditMode FastEditMode => BindableFastEditMode.Value;

public Bindable<TimeTag> BindableCursorPosition { get; } = new Bindable<TimeTag>();

public LyricEditorStateManager(EditorBeatmap beatmap)
{
this.beatmap = beatmap;
}

#region Cursor position by time-tag

public void UpdateSplitCursorPosition(Lyric lyric, int index)
{
BindableSplitLyric.Value = lyric;
BindableSplitPosition.Value = index;
}

public void ClearSplitCursorPosition()
{
BindableSplitLyric.Value = null;
}

#endregion

#region Cursor position by lyric

public bool MoveCursor(CursorAction action)
public void SetMode(Mode mode)
{
var currentTimeTag = BindableCursorPosition.Value;

TimeTag nextTimeTag = null;
BindableMode.Value = mode;

switch (action)
switch (mode)
{
case CursorAction.MoveUp:
nextTimeTag = getPreviousLyricTimeTag(currentTimeTag);
break;

case CursorAction.MoveDown:
nextTimeTag = getNextLyricTimeTag(currentTimeTag);
break;

case CursorAction.MoveLeft:
nextTimeTag = getPreviousTimeTag(currentTimeTag);
break;

case CursorAction.MoveRight:
nextTimeTag = getNextTimeTag(currentTimeTag);
break;

case CursorAction.First:
nextTimeTag = getFirstTimeTag(currentTimeTag);
break;

case CursorAction.Last:
nextTimeTag = getLastTimeTag(currentTimeTag);
break;
case Mode.RecordMode:
MoveCursor(CursorAction.First);
return;
}

if (nextTimeTag == null)
return false;

moveCursorTo(nextTimeTag);
return true;
}

public bool MoveCursorToTargetPosition(TimeTag timeTag)
{
if (timeTagInLyric(timeTag) == null)
return false;

moveCursorTo(timeTag);
return true;
}

private Lyric timeTagInLyric(TimeTag timeTag)
{
if (timeTag == null)
return null;

return beatmap.HitObjects.OfType<Lyric>().FirstOrDefault(x => x.TimeTags?.Contains(timeTag) ?? false);
}

private TimeTag getPreviousLyricTimeTag(TimeTag timeTag)
{
var lyrics = beatmap.HitObjects.OfType<Lyric>().ToList();
var currentLyric = timeTagInLyric(timeTag);
return lyrics.GetPrevious(currentLyric)?.TimeTags?.FirstOrDefault(x => x.Index >= timeTag.Index);
}

private TimeTag getNextLyricTimeTag(TimeTag timeTag)
{
var lyrics = beatmap.HitObjects.OfType<Lyric>().ToList();
var currentLyric = timeTagInLyric(timeTag);
return lyrics.GetNext(currentLyric)?.TimeTags?.FirstOrDefault(x => x.Index >= timeTag.Index);
}

private TimeTag getPreviousTimeTag(TimeTag timeTag)
{
var timeTags = beatmap.HitObjects.OfType<Lyric>().SelectMany(x => x.TimeTags).ToArray();
return timeTags.GetPrevious(timeTag);
}

private TimeTag getNextTimeTag(TimeTag timeTag)
{
var timeTags = beatmap.HitObjects.OfType<Lyric>().SelectMany(x => x.TimeTags).ToArray();
return timeTags.GetNext(timeTag);
}

private TimeTag getFirstTimeTag(TimeTag timeTag)
{
var timeTags = beatmap.HitObjects.OfType<Lyric>().SelectMany(x => x.TimeTags).ToArray();
return timeTags.FirstOrDefault();
}

private TimeTag getLastTimeTag(TimeTag timeTag)
public void SetFastEditMode(LyricFastEditMode fastEditMode)
{
var timeTags = beatmap.HitObjects.OfType<Lyric>().SelectMany(x => x.TimeTags).ToArray();
return timeTags.LastOrDefault();
BindableFastEditMode.Value = fastEditMode;
}

private void moveCursorTo(TimeTag timeTag)
public bool MoveCursor(CursorAction action)
{
if (timeTag == null)
return;

BindableCursorPosition.Value = timeTag;
}

#endregion
switch (Mode)
{
case Mode.RecordMode:
return moveRecordCursor(action);

#region Mode
case Mode.EditMode:
case Mode.TimeTagEditMode:
return moveCursor(action);

public void SetMode(Mode mode)
{
BindableMode.Value = mode;
}

public void SetFastEditMode(LyricFastEditMode fastEditMode)
{
BindableFastEditMode.Value = fastEditMode;
default:
return false;
}
}

#endregion
}

public enum Mode
Expand Down
Loading

0 comments on commit 3f55d66

Please sign in to comment.