Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite romaji edit mode. #2136

Merged
merged 13 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -184,24 +184,7 @@ public void TestGetRubyPosition()
{
AddStep($"Show ruby-tag position: {TextTagUtils.PositionFormattedString(rubyTag)}", () =>
{
var position = karaokeSpriteText.GetTextTagByPosition(rubyTag);
showPosition(position);
});
}
}

#endregion

#region Romaji tag

[Test]
public void TestGetRomajiTagPosition()
{
foreach (var romajiTag in lyric.RomajiTags)
{
AddStep($"Show romaji-tag position: {TextTagUtils.PositionFormattedString(romajiTag)}", () =>
{
var position = karaokeSpriteText.GetTextTagByPosition(romajiTag);
var position = karaokeSpriteText.GetRubyTagByPosition(rubyTag);
showPosition(position);
});
}
Expand Down
18 changes: 9 additions & 9 deletions osu.Game.Rulesets.Karaoke/KaraokeEditInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ public enum KaraokeEditAction
[Description("Next edit mode")]
NextEditMode,

// Edit Ruby / romaji tag.
[Description("Reduce start index")]
EditTextTagReduceStartIndex,
// Edit Ruby tag.
[Description("Reduce ruby-tag start index")]
EditRubyTagReduceStartIndex,

[Description("Increase start index")]
EditTextTagIncreaseStartIndex,
[Description("Increase ruby-tag start index")]
EditRubyTagIncreaseStartIndex,

[Description("Reduce end index")]
EditTextTagReduceEndIndex,
[Description("Reduce ruby-tag end index")]
EditRubyTagReduceEndIndex,

[Description("Increase end index")]
EditTextTagIncreaseEndIndex,
[Description("Increase ruby-tag end index")]
EditRubyTagIncreaseEndIndex,

// Edit time-tag.
[Description("Create start time-tag")]
Expand Down
8 changes: 4 additions & 4 deletions osu.Game.Rulesets.Karaoke/KaraokeRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) =
new KeyBinding(new[] { InputKey.Alt, InputKey.BracketRight }, KaraokeEditAction.NextEditMode),

// Edit Ruby / romaji tag.
new KeyBinding(new[] { InputKey.Z, InputKey.Left }, KaraokeEditAction.EditTextTagReduceStartIndex),
new KeyBinding(new[] { InputKey.Z, InputKey.Right }, KaraokeEditAction.EditTextTagIncreaseStartIndex),
new KeyBinding(new[] { InputKey.X, InputKey.Left }, KaraokeEditAction.EditTextTagReduceEndIndex),
new KeyBinding(new[] { InputKey.X, InputKey.Right }, KaraokeEditAction.EditTextTagIncreaseEndIndex),
new KeyBinding(new[] { InputKey.Z, InputKey.Left }, KaraokeEditAction.EditRubyTagReduceStartIndex),
new KeyBinding(new[] { InputKey.Z, InputKey.Right }, KaraokeEditAction.EditRubyTagIncreaseStartIndex),
new KeyBinding(new[] { InputKey.X, InputKey.Left }, KaraokeEditAction.EditRubyTagReduceEndIndex),
new KeyBinding(new[] { InputKey.X, InputKey.Right }, KaraokeEditAction.EditRubyTagIncreaseEndIndex),

// edit time-tag.
new KeyBinding(InputKey.Q, KaraokeEditAction.CreateStartTimeTag),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ protected void InitializeBlueprint()
{
LyricEditorMode.EditRuby => rubyTagEditMode == RubyTagEditMode.Create ? null : new RubyBlueprintContainer(lyric),
LyricEditorMode.EditTimeTag => modeWithEditStep.EditStep is TimeTagEditStep.Adjust ? new TimeTagBlueprintContainer(lyric) : null,
LyricEditorMode.EditRomaji => new RomajiBlueprintContainer(lyric),
_ => null,
};
}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Objects.Utils;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States.Modes;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;

namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Components.Lyrics.Blueprints;

public partial class RubyBlueprintContainer : TextTagBlueprintContainer<RubyTag>
public partial class RubyBlueprintContainer : LyricPropertyBlueprintContainer<RubyTag>
{
public RubyBlueprintContainer(Lyric lyric)
: base(lyric)
Expand All @@ -28,18 +34,127 @@ protected override SelectionHandler<RubyTag> CreateSelectionHandler()
protected override SelectionBlueprint<RubyTag> CreateBlueprintFor(RubyTag item)
=> new RubyTagSelectionBlueprint(item);

protected partial class RubyTagSelectionHandler : TextTagSelectionHandler<IEditRubyModeState>
protected partial class RubyTagSelectionHandler : LyricPropertySelectionHandler<IEditRubyModeState>
{
[Resolved]
private ILyricRubyTagsChangeHandler rubyTagsChangeHandler { get; set; } = null!;

protected override void DeleteItems(IEnumerable<RubyTag> items)
=> rubyTagsChangeHandler.RemoveRange(items);
[Resolved]
private IPreviewLyricPositionProvider previewLyricPositionProvider { get; set; } = null!;

private float deltaScaleSize;

protected override void OnSelectionChanged()
{
base.OnSelectionChanged();

// only select one ruby / romaji tag can let user drag to change start and end index.
SelectionBox.CanScaleX = SelectedItems.Count == 1;

// should clear delta size before change start/end index.
deltaScaleSize = 0;
}

#region User Input Handling

// for now we always allow movement. snapping is provided by the Timeline's "distance" snap implementation
public override bool HandleMovement(MoveSelectionEvent<RubyTag> moveEvent)
{
if (!SelectedItems.Any())
throw new InvalidOperationException("Should have at least one selected item.");

float deltaXPosition = moveEvent.ScreenSpaceDelta.X;
Logger.LogPrint($"position: {deltaXPosition}", LoggingTarget.Information);

if (deltaXPosition < 0)
{
var firstTimeTag = SelectedItems.MinBy(x => x.StartIndex) ?? throw new InvalidOperationException();
int? newStartIndex = calculateNewIndex(firstTimeTag, deltaXPosition, Anchor.CentreLeft);
int? offset = newStartIndex - firstTimeTag.StartIndex;
if (offset is null or 0)
return false;

setRubyTagShifting(SelectedItems, -1);
}
else
{
var lastTimeTag = SelectedItems.MaxBy(x => x.EndIndex) ?? throw new InvalidOperationException();
int? newEndIndex = calculateNewIndex(lastTimeTag, deltaXPosition, Anchor.CentreRight);
int? offset = newEndIndex - lastTimeTag.EndIndex;
if (offset is null or 0)
return false;

setRubyTagShifting(SelectedItems, 1);
}

return true;

void setRubyTagShifting(IEnumerable<RubyTag> rubyTags, int offset)
=> rubyTagsChangeHandler.ShiftingIndex(rubyTags, offset);
}

protected override void SetTextTagShifting(IEnumerable<RubyTag> textTags, int offset)
=> rubyTagsChangeHandler.ShiftingIndex(textTags, offset);
public override bool HandleScale(Vector2 scale, Anchor anchor)
{
deltaScaleSize += scale.X;

protected override void SetTextTagIndex(RubyTag textTag, int? startPosition, int? endPosition)
=> rubyTagsChangeHandler.SetIndex(textTag, startPosition, endPosition);
// this feature only works if only select one ruby / romaji tag.
var selectedRubyTag = SelectedItems.FirstOrDefault();
if (selectedRubyTag == null)
return false;

switch (anchor)
{
case Anchor.CentreLeft:
int? newStartIndex = calculateNewIndex(selectedRubyTag, deltaScaleSize, anchor);
if (newStartIndex == null || !TextTagUtils.ValidNewStartIndex(selectedRubyTag, newStartIndex.Value))
return false;

setRubyTagIndex(selectedRubyTag, newStartIndex, null);
return true;

case Anchor.CentreRight:
int? newEndIndex = calculateNewIndex(selectedRubyTag, deltaScaleSize, anchor);
if (newEndIndex == null || !TextTagUtils.ValidNewEndIndex(selectedRubyTag, newEndIndex.Value))
return false;

setRubyTagIndex(selectedRubyTag, null, newEndIndex);
return true;

default:
return false;
}

void setRubyTagIndex(RubyTag rubyTag, int? startPosition, int? endPosition)
=> rubyTagsChangeHandler.SetIndex(rubyTag, startPosition, endPosition);
}

private int? calculateNewIndex(RubyTag rubyTag, float offset, Anchor anchor)
{
// get real left-side and right-side position
var rect = previewLyricPositionProvider.GetRubyTagByPosition(rubyTag);

// todo: need to think about how to handle the case if the text-tag already out of the range of the text.
if (rect == null)
throw new InvalidOperationException($"{nameof(rubyTag)} not in the range of the text.");

switch (anchor)
{
case Anchor.CentreLeft:
float leftPosition = rect.Value.Left + offset;
return previewLyricPositionProvider.GetCharIndexByPosition(leftPosition);

case Anchor.CentreRight:
float rightPosition = rect.Value.Right + offset;
return previewLyricPositionProvider.GetCharIndexByPosition(rightPosition);

default:
throw new ArgumentOutOfRangeException(nameof(anchor));
}
}

#endregion

protected override void DeleteItems(IEnumerable<RubyTag> items)
=> rubyTagsChangeHandler.RemoveRange(items);
}
}
Loading