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

Add romaji text into time tag. #2070

Merged
merged 5 commits into from
Jul 16, 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
6 changes: 3 additions & 3 deletions osu.Game.Rulesets.Karaoke.Tests/Objects/LyricTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void TestClone()
Assert.AreNotSame(clonedLyric.TextBindable, lyric.TextBindable);
Assert.AreEqual(clonedLyric.Text, lyric.Text);

Assert.AreNotSame(clonedLyric.TimeTagsVersion, lyric.TimeTagsVersion);
Assert.AreNotSame(clonedLyric.TimeTagsTimingVersion, lyric.TimeTagsTimingVersion);
Assert.AreNotSame(clonedLyric.TimeTagsBindable, lyric.TimeTagsBindable);
TimeTagAssert.ArePropertyEqual(clonedLyric.TimeTags, lyric.TimeTags);

Expand Down Expand Up @@ -202,7 +202,7 @@ public void TestReferenceLyricListPropertyChanged()
TextTagAssert.ArePropertyEqual(referencedLyric.RomajiTags, lyric.RomajiTags);

// and because there's no change inside the tag, so there's version change.
Assert.AreEqual(0, lyric.TimeTagsVersion.Value);
Assert.AreEqual(0, lyric.TimeTagsTimingVersion.Value);
Assert.AreEqual(0, lyric.RubyTagsVersion.Value);
Assert.AreEqual(0, lyric.RomajiTagsVersion.Value);

Expand All @@ -217,7 +217,7 @@ public void TestReferenceLyricListPropertyChanged()
TextTagAssert.ArePropertyEqual(referencedLyric.RomajiTags, lyric.RomajiTags);

// and note that because only one property is different, so version should change once.
Assert.AreEqual(1, lyric.TimeTagsVersion.Value);
Assert.AreEqual(1, lyric.TimeTagsTimingVersion.Value);
Assert.AreEqual(1, lyric.RubyTagsVersion.Value);
Assert.AreEqual(1, lyric.RomajiTagsVersion.Value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Karaoke.Graphics.Sprites;
private const int whole_chunk_index = -1;

private readonly IBindable<string> textBindable = new Bindable<string>();
private readonly IBindable<int> timeTagsVersion = new Bindable<int>();
private readonly IBindable<int> timeTagsTimingVersion = new Bindable<int>();
private readonly IBindableList<TimeTag> timeTagsBindable = new BindableList<TimeTag>();
private readonly IBindable<int> rubyTagsVersion = new Bindable<int>();
private readonly IBindableList<RubyTag> rubyTagsBindable = new BindableList<RubyTag>();
Expand All @@ -29,15 +29,15 @@ protected DrawableKaraokeSpriteText(Lyric lyric, int chunkIndex = whole_chunk_in
this.chunkIndex = chunkIndex;

textBindable.BindValueChanged(_ => UpdateText(), true);
timeTagsVersion.BindValueChanged(_ => UpdateTimeTags());
timeTagsTimingVersion.BindValueChanged(_ => UpdateTimeTags());
timeTagsBindable.BindCollectionChanged((_, _) => UpdateTimeTags());
rubyTagsVersion.BindValueChanged(_ => UpdateRubies());
rubyTagsBindable.BindCollectionChanged((_, _) => UpdateRubies());
romajiTagsVersion.BindValueChanged(_ => UpdateRomajies());
romajiTagsBindable.BindCollectionChanged((_, _) => UpdateRomajies());

textBindable.BindTo(lyric.TextBindable);
timeTagsVersion.BindTo(lyric.TimeTagsVersion);
timeTagsTimingVersion.BindTo(lyric.TimeTagsTimingVersion);
timeTagsBindable.BindTo(lyric.TimeTagsBindable);
rubyTagsVersion.BindTo(lyric.RubyTagsVersion);
rubyTagsBindable.BindTo(lyric.RubyTagsBindable);
Expand Down
25 changes: 0 additions & 25 deletions osu.Game.Rulesets.Karaoke/Objects/Lyric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ public string Text
set => TextBindable.Value = value;
}

[JsonIgnore]
public IBindable<int> TimeTagsVersion => timeTagsVersion;

private readonly Bindable<int> timeTagsVersion = new();

[JsonIgnore]
public readonly BindableList<TimeTag> TimeTagsBindable = new();

Expand All @@ -66,11 +61,6 @@ public IList<TimeTag> TimeTags
}
}

[JsonIgnore]
public IBindable<int> RubyTagsVersion => rubyTagsVersion;

private readonly Bindable<int> rubyTagsVersion = new();

[JsonIgnore]
public readonly BindableList<RubyTag> RubyTagsBindable = new();

Expand All @@ -87,11 +77,6 @@ public IList<RubyTag> RubyTags
}
}

[JsonIgnore]
public IBindable<int> RomajiTagsVersion => romajiTagsVersion;

private readonly Bindable<int> romajiTagsVersion = new();

[JsonIgnore]
public readonly BindableList<RomajiTag> RomajiTagsBindable = new();

Expand Down Expand Up @@ -188,11 +173,6 @@ public ElementId? ReferenceLyricId
}
}

[JsonIgnore]
public IBindable<int> ReferenceLyricConfigVersion => referenceLyricConfigVersion;

private readonly Bindable<int> referenceLyricConfigVersion = new();

[JsonIgnore]
public readonly Bindable<IReferenceLyricPropertyConfig?> ReferenceLyricConfigBindable = new();

Expand All @@ -205,11 +185,6 @@ public IReferenceLyricPropertyConfig? ReferenceLyricConfig
set => ReferenceLyricConfigBindable.Value = value;
}

[JsonIgnore]
public IBindable<int> LyricPropertyWritableVersion => lyricPropertyWritableVersion;

private readonly Bindable<int> lyricPropertyWritableVersion = new();

public Lyric()
{
workingPropertyValidator = new LyricWorkingPropertyValidator(this);
Expand Down
50 changes: 45 additions & 5 deletions osu.Game.Rulesets.Karaoke/Objects/Lyric_Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Karaoke.Objects.Properties;
using osu.Game.Rulesets.Karaoke.Objects.Utils;
Expand All @@ -18,6 +19,36 @@ namespace osu.Game.Rulesets.Karaoke.Objects;
/// </summary>
public partial class Lyric
{
[JsonIgnore]
public IBindable<int> TimeTagsTimingVersion => timeTagsTimingVersion;

private readonly Bindable<int> timeTagsTimingVersion = new();

[JsonIgnore]
public IBindable<int> TimeTagsRomajiVersion => timeTagsRomajiVersion;

private readonly Bindable<int> timeTagsRomajiVersion = new();

[JsonIgnore]
public IBindable<int> RubyTagsVersion => rubyTagsVersion;

private readonly Bindable<int> rubyTagsVersion = new();

[JsonIgnore]
public IBindable<int> RomajiTagsVersion => romajiTagsVersion;

private readonly Bindable<int> romajiTagsVersion = new();

[JsonIgnore]
public IBindable<int> ReferenceLyricConfigVersion => referenceLyricConfigVersion;

private readonly Bindable<int> referenceLyricConfigVersion = new();

[JsonIgnore]
public IBindable<int> LyricPropertyWritableVersion => lyricPropertyWritableVersion;

private readonly Bindable<int> lyricPropertyWritableVersion = new();

private void initInternalBindingEvent()
{
TimeTagsBindable.CollectionChanged += (_, args) =>
Expand All @@ -28,24 +59,33 @@ private void initInternalBindingEvent()
Debug.Assert(args.NewItems != null);

foreach (var c in args.NewItems.Cast<TimeTag>())
c.Changed += invalidate;
{
c.TimingChanged += timingInvalidate;
c.RomajiChanged += romajiInvalidate;
}

break;

case NotifyCollectionChangedAction.Reset:
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);

foreach (var c in args.OldItems.Cast<TimeTag>())
c.Changed -= invalidate;
{
c.TimingChanged -= timingInvalidate;
c.RomajiChanged -= romajiInvalidate;
}

break;
}

updateLyricTime();

void invalidate() => timeTagsVersion.Value++;
void timingInvalidate() => timeTagsTimingVersion.Value++;
void romajiInvalidate() => timeTagsRomajiVersion.Value++;
};

TimeTagsVersion.ValueChanged += _ =>
TimeTagsTimingVersion.ValueChanged += _ =>
{
updateLyricTime();
};
Expand Down Expand Up @@ -168,7 +208,7 @@ private void initReferenceLyricEvent()
}).ToArray();
});

bindValueChange(e, l => l.TimeTagsVersion, (_, config) =>
bindValueChange(e, l => l.TimeTagsTimingVersion, (_, config) =>
{
if (config is not SyncLyricConfig syncLyricConfig || !syncLyricConfig.SyncTimeTagProperty)
return;
Expand Down
6 changes: 3 additions & 3 deletions osu.Game.Rulesets.Karaoke/Objects/Note_Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ private void initReferenceLyricEvent()
ReferenceLyricBindable.ValueChanged += e =>
{
if (e.OldValue != null)
e.OldValue.TimeTagsVersion.ValueChanged -= timeTagVersionChanged;
e.OldValue.TimeTagsTimingVersion.ValueChanged -= timeTagsTimingVersionChanged;

if (e.NewValue != null)
e.NewValue.TimeTagsVersion.ValueChanged += timeTagVersionChanged;
e.NewValue.TimeTagsTimingVersion.ValueChanged += timeTagsTimingVersionChanged;

syncStartTimeAndDurationFromTimeTag();
syncReferenceLyricSingers();
};

void timeTagVersionChanged(ValueChangedEvent<int> e) => syncStartTimeAndDurationFromTimeTag();
void timeTagsTimingVersionChanged(ValueChangedEvent<int> e) => syncStartTimeAndDurationFromTimeTag();
}

private void syncStartTimeAndDurationFromTimeTag()
Expand Down
47 changes: 44 additions & 3 deletions osu.Game.Rulesets.Karaoke/Objects/TimeTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,23 @@ namespace osu.Game.Rulesets.Karaoke.Objects;
public class TimeTag : IDeepCloneable<TimeTag>
{
/// <summary>
/// Invoked when any property of this <see cref="RubyTag"/> is changed.
/// Invoked when <see cref="Time"/> of this <see cref="TimeTag"/> is changed.
/// </summary>
public event Action? Changed;
public event Action? TimingChanged;

/// <summary>
/// Invoked when <see cref="InitialRomaji"/> or <see cref="RomajiText"/> of this <see cref="TimeTag"/> is changed.
/// </summary>
public event Action? RomajiChanged;

public TimeTag(TextIndex index, double? time = null)
{
Index = index;
Time = time;

TimeBindable.ValueChanged += _ => Changed?.Invoke();
TimeBindable.ValueChanged += _ => TimingChanged?.Invoke();
InitialRomajiBindable.ValueChanged += _ => RomajiChanged?.Invoke();
RomajiTextBindable.ValueChanged += _ => RomajiChanged?.Invoke();
}

/// <summary>
Expand All @@ -42,6 +49,40 @@ public double? Time
set => TimeBindable.Value = value;
}

[JsonIgnore]
public readonly Bindable<bool> InitialRomajiBindable = new();

/// <summary>
/// Mark if this romaji is the first letter of the romaji word.
/// </summary>
/// <example>
/// There's the Japanese lyric:
/// 枯れた世界に輝く
/// There's the Romaji:
/// kareta sekai ni kagayaku.
/// And it will be separated as:
/// ka|re|ta se|kai ni ka|ga|ya|ku.
/// If this is the first or(4th) time-tag, then this value should be true.
/// If this ts the 2th or 3th time-tag, then this value should be false.
/// </example>
public bool InitialRomaji
{
get => InitialRomajiBindable.Value;
set => InitialRomajiBindable.Value = value;
}

[JsonIgnore]
public readonly Bindable<string?> RomajiTextBindable = new();

/// <summary>
/// Romaji
/// </summary>
public string? RomajiText
{
get => RomajiTextBindable.Value;
set => RomajiTextBindable.Value = value;
}

public TimeTag DeepClone()
{
return new TimeTag(Index, Time);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public abstract partial class TimeTagScrollContainer : BindableScrollContainer
{
private readonly IBindable<Lyric?> bindableFocusedLyric = new Bindable<Lyric?>();

private readonly IBindable<int> timeTagsVersion = new Bindable<int>();
private readonly IBindable<int> timeTagsTimingVersion = new Bindable<int>();

[Cached]
private readonly BindableList<TimeTag> timeTagsBindable = new();
Expand All @@ -42,19 +42,19 @@ protected TimeTagScrollContainer()
{
RelativeSizeAxes = Axes.X;

timeTagsVersion.BindValueChanged(_ => updateTimeRange());
timeTagsTimingVersion.BindValueChanged(_ => updateTimeRange());
timeTagsBindable.BindCollectionChanged((_, _) => updateTimeRange());

bindableFocusedLyric.BindValueChanged(e =>
{
timeTagsVersion.UnbindBindings();
timeTagsTimingVersion.UnbindBindings();
timeTagsBindable.UnbindBindings();

var lyric = e.NewValue;
if (lyric == null)
return;

timeTagsVersion.BindTo(lyric.TimeTagsVersion);
timeTagsTimingVersion.BindTo(lyric.TimeTagsTimingVersion);
timeTagsBindable.BindTo(lyric.TimeTagsBindable);

Schedule(() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.LyricList.Rows.

public partial class TimeTagInfo : SubInfo
{
private readonly IBindable<int> bindableTimeTagsVersion;
private readonly IBindable<int> bindableTimeTagsTimingVersion;
private readonly IBindableList<TimeTag> bindableTimeTags;

public TimeTagInfo(Lyric lyric)
: base(lyric)
{
bindableTimeTagsVersion = lyric.TimeTagsVersion.GetBoundCopy();
bindableTimeTagsTimingVersion = lyric.TimeTagsTimingVersion.GetBoundCopy();
bindableTimeTags = lyric.TimeTagsBindable.GetBoundCopy();
}

Expand All @@ -26,7 +26,7 @@ private void load(OsuColour colours)
{
BadgeColour = colours.Green;

bindableTimeTagsVersion.BindValueChanged(_ => updateBadgeText());
bindableTimeTagsTimingVersion.BindValueChanged(_ => updateBadgeText());
bindableTimeTags.BindCollectionChanged((_, _) => updateBadgeText());

updateBadgeText();
Expand Down