-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #325 from andy840119/lyric-editor/implement-each-m…
…ode-cursor Create state manager into lyric editor
- Loading branch information
Showing
19 changed files
with
836 additions
and
259 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
osu.Game.Rulesets.Karaoke.Tests/Utils/TimeTagIndexUtilsTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>(); | ||
|
||
|
@@ -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 | ||
|
Oops, something went wrong.