From 43727493cee7412420c5f98a339c31c098ea2857 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 21 Apr 2024 10:54:55 +0800 Subject: [PATCH 1/6] Adjust the margin to make it looks better. --- .../Lyrics/Carets/DrawableRecordingTimeTagCaret.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Components/Lyrics/Carets/DrawableRecordingTimeTagCaret.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Components/Lyrics/Carets/DrawableRecordingTimeTagCaret.cs index b02010a7e..0549cbaae 100644 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Components/Lyrics/Carets/DrawableRecordingTimeTagCaret.cs +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Components/Lyrics/Carets/DrawableRecordingTimeTagCaret.cs @@ -191,12 +191,19 @@ public void UpdateCaret(RecordingTimeTagCaretPosition caret) for (int i = 0; i < paddingIndicator; i++) { + bool isFirst = i == 0; + bool isLast = i == paddingIndicator - 1; + pendingTextIndexes.Add(new DrawableTextIndex { Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(12), - Margin = new MarginPadding(5), + Margin = new MarginPadding(5) + { + Left = isFirst ? 5 : 0, + Right = isLast ? 5 : 0, + }, State = caret.TimeTag.Index.State, Colour = colours.Yellow, Alpha = 0.5f, From effef08336197acdae2fa11ec892d6538e888239 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 21 Apr 2024 11:50:53 +0800 Subject: [PATCH 2/6] Copy the `TapButton` and `TapTimingControl` from osu.Game. --- .../Settings/TimeTags/RecordingTapControl.cs | 146 ++++++ .../Lyrics/Settings/TimeTags/TapButton.cs | 418 ++++++++++++++++++ 2 files changed, 564 insertions(+) create mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs create mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs new file mode 100644 index 000000000..e01069761 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs @@ -0,0 +1,146 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; +using osu.Game.Screens.Edit.Timing; +using osuTK; + +namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags; + +public partial class RecordingTapControl : CompositeDrawable +{ + private readonly BindableBool isHandlingTapping = new(); + + private readonly MetronomeDisplay metronome = null!; + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChildren = new Container + { + new Container + { + RelativeSizeAxes = Axes.Y, + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Height = 0.98f, + Width = TapButton.SIZE / 1.3f, + Masking = true, + CornerRadius = 15, + Children = new Drawable[] + { + new InlineButton(FontAwesome.Solid.Stop, Anchor.TopLeft) + { + BackgroundColour = colourProvider.Background1, + RelativeSizeAxes = Axes.Both, + Height = 0.49f, + Action = reset, + }, + new InlineButton(FontAwesome.Solid.Play, Anchor.BottomLeft) + { + BackgroundColour = colourProvider.Background1, + RelativeSizeAxes = Axes.Both, + Height = 0.49f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Action = start, + }, + }, + }, + new TapButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + IsHandlingTapping = { BindTarget = isHandlingTapping }, + }, + }; + + isHandlingTapping.BindValueChanged(handling => + { + metronome.EnableClicking = !handling.NewValue; + + if (handling.NewValue) + start(); + }, true); + } + + private void start() + { + } + + private void reset() + { + } + + private partial class InlineButton : OsuButton + { + private readonly IconUsage icon; + private readonly Anchor anchor; + + private SpriteIcon spriteIcon = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + + public InlineButton(IconUsage icon, Anchor anchor) + { + this.icon = icon; + this.anchor = anchor; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Content.CornerRadius = 0; + Content.Masking = false; + + BackgroundColour = colourProvider.Background2; + + Content.Add(new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(15), + Children = new Drawable[] + { + spriteIcon = new SpriteIcon + { + Icon = icon, + Size = new Vector2(22), + Anchor = anchor, + Origin = anchor, + Colour = colourProvider.Background1, + }, + }, + }); + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + // scale looks bad so don't call base. + return false; + } + + protected override bool OnHover(HoverEvent e) + { + spriteIcon.FadeColour(colourProvider.Content2, 200, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + spriteIcon.FadeColour(colourProvider.Background1, 200, Easing.OutQuint); + base.OnHoverLost(e); + } + } +} diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs new file mode 100644 index 000000000..0d9ede3f3 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs @@ -0,0 +1,418 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Framework.Threading; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; +using osu.Game.Overlays; +using osuTK; +using osuTK.Graphics; +using osuTK.Input; + +namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags; + +internal partial class TapButton : CircularContainer, IKeyBindingHandler +{ + public const float SIZE = 140; + + public readonly BindableBool IsHandlingTapping = new(); + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + + [Resolved] + private Bindable? selectedGroup { get; set; } + + [Resolved] + private IBeatSyncProvider? beatSyncSource { get; set; } + + private Circle hoverLayer = null!; + + private CircularContainer innerCircle = null!; + private Box innerCircleHighlight = null!; + + private int currentLight; + + private Container scaleContainer = null!; + private Container lights = null!; + private Container lightsGlow = null!; + private OsuSpriteText bpmText = null!; + private Container textContainer = null!; + + private bool grabbedMouseDown; + + private ScheduledDelegate? resetDelegate; + + private const int light_count = 8; + + private const int initial_taps_to_ignore = 4; + + private const int max_taps_to_consider = 128; + + private const double transition_length = 500; + + private const float angular_light_gap = 0.007f; + + private readonly List tapTimings = new(); + + [BackgroundDependencyLoader] + private void load() + { + Size = new Vector2(SIZE); + + const float ring_width = 22; + const float light_padding = 3; + + InternalChild = scaleContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4, + }, + lights = new Container + { + RelativeSizeAxes = Axes.Both, + }, + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Name = "outer masking", + Masking = true, + BorderThickness = light_padding, + BorderColour = colourProvider.Background4, + Children = new Drawable[] + { + new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true, + }, + }, + }, + new Circle + { + Name = "inner masking", + Size = new Vector2(SIZE - ring_width * 2 + light_padding * 2), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = colourProvider.Background4, + }, + lightsGlow = new Container + { + RelativeSizeAxes = Axes.Both, + }, + innerCircle = new CircularContainer + { + Size = new Vector2(SIZE - ring_width * 2), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + Children = new Drawable[] + { + new Box + { + Colour = colourProvider.Background2, + RelativeSizeAxes = Axes.Both, + }, + innerCircleHighlight = new Box + { + Colour = colourProvider.Colour3, + Blending = BlendingParameters.Additive, + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + textContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background1, + Children = new Drawable[] + { + new OsuSpriteText + { + Font = OsuFont.Torus.With(size: 34, weight: FontWeight.SemiBold), + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Y = 5, + Text = "Tap", + }, + bpmText = new OsuSpriteText + { + Font = OsuFont.Torus.With(size: 23, weight: FontWeight.Regular), + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Y = -1, + }, + }, + }, + hoverLayer = new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background1.Opacity(0.3f), + Blending = BlendingParameters.Additive, + Alpha = 0, + }, + }, + }, + }, + }; + + for (int i = 0; i < light_count; i++) + { + var light = new Light + { + Rotation = (i + 1) * (360f / light_count) + 360 * angular_light_gap / 2, + }; + + lights.Add(light); + lightsGlow.Add(light.Glow.CreateProxy()); + } + + reset(); + } + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + hoverLayer.ReceivePositionalInputAt(screenSpacePos); + + private ColourInfo textColour + { + get + { + if (grabbedMouseDown) + return colourProvider.Background4; + + if (IsHovered) + return colourProvider.Content2; + + return colourProvider.Background1; + } + } + + protected override bool OnHover(HoverEvent e) + { + hoverLayer.FadeIn(transition_length, Easing.OutQuint); + textContainer.FadeColour(textColour, transition_length, Easing.OutQuint); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hoverLayer.FadeOut(transition_length, Easing.OutQuint); + textContainer.FadeColour(textColour, transition_length, Easing.OutQuint); + base.OnHoverLost(e); + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + const double in_duration = 100; + + grabbedMouseDown = true; + IsHandlingTapping.Value = true; + + resetDelegate?.Cancel(); + + handleTap(); + + textContainer.FadeColour(textColour, in_duration, Easing.OutQuint); + + scaleContainer.ScaleTo(0.99f, in_duration, Easing.OutQuint); + innerCircle.ScaleTo(0.96f, in_duration, Easing.OutQuint); + + innerCircleHighlight + .FadeIn(50, Easing.OutQuint) + .FlashColour(Color4.White, 1000, Easing.OutQuint); + + lights[currentLight % light_count].Hide(); + lights[(currentLight + light_count / 2) % light_count].Hide(); + + currentLight++; + + lights[currentLight % light_count].Show(); + lights[(currentLight + light_count / 2) % light_count].Show(); + + return true; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + const double out_duration = 800; + + grabbedMouseDown = false; + + textContainer.FadeColour(textColour, out_duration, Easing.OutQuint); + + scaleContainer.ScaleTo(1, out_duration, Easing.OutQuint); + innerCircle.ScaleTo(1, out_duration, Easing.OutQuint); + + innerCircleHighlight.FadeOut(out_duration, Easing.OutQuint); + + resetDelegate = Scheduler.AddDelayed(reset, 1000); + + base.OnMouseUp(e); + } + + public bool OnPressed(KeyBindingPressEvent e) + { + if (e.Action == GlobalAction.EditorTapForBPM && !e.Repeat) + { + // Direct through mouse handling to achieve animation + OnMouseDown(new MouseDownEvent(e.CurrentState, MouseButton.Left)); + return true; + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + if (e.Action == GlobalAction.EditorTapForBPM) + OnMouseUp(new MouseUpEvent(e.CurrentState, MouseButton.Left)); + } + + private void handleTap() + { + if (selectedGroup?.Value == null) + return; + + tapTimings.Add(Clock.CurrentTime); + + if (tapTimings.Count > initial_taps_to_ignore + max_taps_to_consider) + tapTimings.RemoveAt(0); + + if (tapTimings.Count < initial_taps_to_ignore * 2) + { + bpmText.Text = new string('.', tapTimings.Count); + return; + } + + double averageBeatLength = (tapTimings.Last() - tapTimings.Skip(initial_taps_to_ignore).First()) / (tapTimings.Count - initial_taps_to_ignore - 1); + double clockRate = beatSyncSource?.Clock.Rate ?? 1; + + double bpm = Math.Round(60000 / averageBeatLength / clockRate); + + bpmText.Text = $"{bpm} BPM"; + + var timingPoint = selectedGroup?.Value.ControlPoints.OfType().FirstOrDefault(); + + if (timingPoint != null) + { + // Intentionally use the rounded BPM here. + timingPoint.BeatLength = 60000 / bpm; + } + } + + private void reset() + { + bpmText.FadeOut(transition_length, Easing.OutQuint); + + using (BeginDelayedSequence(tapTimings.Count > 0 ? transition_length : 0)) + { + Schedule(() => bpmText.Text = "the beat!"); + bpmText.FadeIn(800, Easing.OutQuint); + } + + foreach (var light in lights) + light.Hide(); + + tapTimings.Clear(); + currentLight = 0; + IsHandlingTapping.Value = false; + } + + private partial class Light : CompositeDrawable + { + public Drawable Glow { get; private set; } = null!; + + private Container fillContent = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Size = new Vector2(0.98f); // Avoid bleed into masking edge. + + InternalChildren = new Drawable[] + { + new CircularProgress + { + RelativeSizeAxes = Axes.Both, + Progress = 1f / light_count - angular_light_gap, + Colour = colourProvider.Background2, + }, + fillContent = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Colour = colourProvider.Colour1, + Children = new[] + { + new CircularProgress + { + RelativeSizeAxes = Axes.Both, + Progress = 1f / light_count - angular_light_gap, + Blending = BlendingParameters.Additive, + }, + // Please do not try and make sense of this. + // Getting the visual effect I was going for relies on what I can only imagine is broken implementation + // of `PadExtent`. If that's ever fixed in the future this will likely need to be adjusted. + Glow = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + Progress = 1f / light_count - 0.01f, + Blending = BlendingParameters.Additive, + }.WithEffect(new GlowEffect + { + Colour = colourProvider.Colour1.Opacity(0.4f), + BlurSigma = new Vector2(9f), + Strength = 10, + PadExtent = true, + }), + }, + }, + }; + } + + public override void Show() + { + fillContent + .FadeIn(50, Easing.OutQuint) + .FlashColour(Color4.White, 1000, Easing.OutQuint); + } + + public override void Hide() + { + fillContent + .FadeOut(300, Easing.OutQuint); + } + } +} From 2e4da4e5156a77d4a7923162ac154173842f32e5 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 21 Apr 2024 13:25:43 +0800 Subject: [PATCH 3/6] Adjust the tap control for let it focus on recording time-tag time. --- .../Settings/TimeTags/RecordingTapControl.cs | 135 ++++++++++++--- .../Lyrics/Settings/TimeTags/TapButton.cs | 155 ++++++------------ 2 files changed, 158 insertions(+), 132 deletions(-) diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs index e01069761..a6baf6df1 100644 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordingTapControl.cs @@ -1,32 +1,48 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; -using osu.Game.Screens.Edit.Timing; +using osu.Game.Rulesets.Karaoke.Configuration; +using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics; +using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.CaretPosition; +using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States; +using osu.Game.Screens.Edit; using osuTK; namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags; -public partial class RecordingTapControl : CompositeDrawable +public partial class RecordingTapControl : CompositeDrawable, IKeyBindingHandler { - private readonly BindableBool isHandlingTapping = new(); + [Resolved] + private KaraokeRulesetLyricEditorConfigManager lyricEditorConfigManager { get; set; } = null!; - private readonly MetronomeDisplay metronome = null!; + [Resolved] + private ILyricCaretState lyricCaretState { get; set; } = null!; + + [Resolved] + private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!; + + [Resolved] + private EditorClock editorClock { get; set; } = null!; + + private InlineButton undoButton = null!; + private InlineButton resetButton = null!; + private TapButton tapButton = null!; [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load(ILyricEditorState state, LyricEditorColourProvider colourProvider) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChildren = new Container + InternalChildren = new Drawable[] { new Container { @@ -39,47 +55,111 @@ private void load(OverlayColourProvider colourProvider) CornerRadius = 15, Children = new Drawable[] { - new InlineButton(FontAwesome.Solid.Stop, Anchor.TopLeft) + undoButton = new InlineButton(FontAwesome.Solid.Trash, Anchor.TopLeft) { - BackgroundColour = colourProvider.Background1, + BackgroundColour = colourProvider.Background1(state.Mode), RelativeSizeAxes = Axes.Both, Height = 0.49f, Action = reset, }, - new InlineButton(FontAwesome.Solid.Play, Anchor.BottomLeft) + resetButton = new InlineButton(FontAwesome.Solid.AngleLeft, Anchor.BottomLeft) { - BackgroundColour = colourProvider.Background1, + BackgroundColour = colourProvider.Background1(state.Mode), RelativeSizeAxes = Axes.Both, Height = 0.49f, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Action = start, + Action = undo, }, }, }, - new TapButton + tapButton = new TapButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, - IsHandlingTapping = { BindTarget = isHandlingTapping }, + Tapped = onTapped, }, }; + } - isHandlingTapping.BindValueChanged(handling => + public bool OnPressed(KeyBindingPressEvent e) + { + switch (e.Action) { - metronome.EnableClicking = !handling.NewValue; + case KaraokeEditAction.ClearTime: + resetButton.TriggerClick(); - if (handling.NewValue) - start(); - }, true); + return true; + + case KaraokeEditAction.SetTime: + tapButton.TriggerClick(); + + return true; + + default: + return false; + } } - private void start() + public void OnReleased(KeyBindingReleaseEvent e) { } private void reset() { + if (lyricCaretState.CaretPosition is not RecordingTimeTagCaretPosition timeTagCaretPosition) + throw new InvalidOperationException(); + + var timingInfo = timeTagCaretPosition.Lyric.LyricTimingInfo; + + lyricTimeTagsChangeHandler.ClearAllTimeTagTime(); + + if (timingInfo != null) + { + editorClock.Seek(timingInfo.StartTime - 1000); + } + + if (lyricCaretState.GetCaretPositionByAction(MovingCaretAction.FirstIndex)?.Lyric != timeTagCaretPosition.Lyric) + return; + + lyricCaretState.MoveCaret(MovingCaretAction.FirstIndex); + } + + private void undo() + { + if (lyricCaretState.CaretPosition is not RecordingTimeTagCaretPosition timeTagCaretPosition) + throw new InvalidOperationException(); + + double? currentTimeTagTime = timeTagCaretPosition.TimeTag.Time; + + var timeTag = timeTagCaretPosition.TimeTag; + lyricTimeTagsChangeHandler.ClearTimeTagTime(timeTag); + + if (lyricCaretState.GetCaretPositionByAction(MovingCaretAction.PreviousIndex)?.Lyric != timeTagCaretPosition.Lyric) + return; + + lyricCaretState.MoveCaret(MovingCaretAction.PreviousIndex); + + if (currentTimeTagTime != null) + { + editorClock.Seek(currentTimeTagTime.Value - 1000); + } + else + { + editorClock.Seek(editorClock.CurrentTime - 1000); + } + } + + private void onTapped(double currentTime) + { + if (lyricCaretState.CaretPosition is not RecordingTimeTagCaretPosition timeTagCaretPosition) + throw new InvalidOperationException(); + + var timeTag = timeTagCaretPosition.TimeTag; + lyricTimeTagsChangeHandler.SetTimeTagTime(timeTag, currentTime); + + if (lyricEditorConfigManager.Get(KaraokeRulesetLyricEditorSetting.RecordingAutoMoveToNextTimeTag)) + lyricCaretState.MoveCaret(MovingCaretAction.NextIndex); } private partial class InlineButton : OsuButton @@ -90,7 +170,10 @@ private partial class InlineButton : OsuButton private SpriteIcon spriteIcon = null!; [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; + private ILyricEditorState lyricEditorState { get; set; } = null!; + + [Resolved] + private LyricEditorColourProvider colourProvider { get; set; } = null!; public InlineButton(IconUsage icon, Anchor anchor) { @@ -105,7 +188,7 @@ protected override void LoadComplete() Content.CornerRadius = 0; Content.Masking = false; - BackgroundColour = colourProvider.Background2; + BackgroundColour = colourProvider.Background2(lyricEditorState.Mode); Content.Add(new Container { @@ -119,7 +202,7 @@ protected override void LoadComplete() Size = new Vector2(22), Anchor = anchor, Origin = anchor, - Colour = colourProvider.Background1, + Colour = colourProvider.Background1(lyricEditorState.Mode), }, }, }); @@ -133,13 +216,13 @@ protected override bool OnMouseDown(MouseDownEvent e) protected override bool OnHover(HoverEvent e) { - spriteIcon.FadeColour(colourProvider.Content2, 200, Easing.OutQuint); + spriteIcon.FadeColour(colourProvider.Content2(lyricEditorState.Mode), 200, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - spriteIcon.FadeColour(colourProvider.Background1, 200, Easing.OutQuint); + spriteIcon.FadeColour(colourProvider.Background1(lyricEditorState.Mode), 200, Easing.OutQuint); base.OnHoverLost(e); } } diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs index 0d9ede3f3..e349198e4 100644 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TapButton.cs @@ -2,10 +2,7 @@ // 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.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -13,35 +10,31 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Threading; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Input.Bindings; -using osu.Game.Overlays; +using osu.Game.Screens.Edit; using osuTK; using osuTK.Graphics; -using osuTK.Input; namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags; -internal partial class TapButton : CircularContainer, IKeyBindingHandler +internal partial class TapButton : CircularContainer { public const float SIZE = 140; - public readonly BindableBool IsHandlingTapping = new(); + public Action? Tapped; [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; + private EditorClock editorClock { get; set; } = null!; [Resolved] - private Bindable? selectedGroup { get; set; } + private ILyricEditorState lyricEditorState { get; set; } = null!; [Resolved] - private IBeatSyncProvider? beatSyncSource { get; set; } + private LyricEditorColourProvider colourProvider { get; set; } = null!; private Circle hoverLayer = null!; @@ -53,7 +46,7 @@ internal partial class TapButton : CircularContainer, IKeyBindingHandler tapTimings = new(); - [BackgroundDependencyLoader] private void load() { @@ -90,7 +77,7 @@ private void load() new Circle { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4, + Colour = colourProvider.Background4(lyricEditorState.Mode), }, lights = new Container { @@ -102,7 +89,7 @@ private void load() Name = "outer masking", Masking = true, BorderThickness = light_padding, - BorderColour = colourProvider.Background4, + BorderColour = colourProvider.Background4(lyricEditorState.Mode), Children = new Drawable[] { new Box @@ -120,7 +107,7 @@ private void load() Size = new Vector2(SIZE - ring_width * 2 + light_padding * 2), Anchor = Anchor.Centre, Origin = Anchor.Centre, - Colour = colourProvider.Background4, + Colour = colourProvider.Background4(lyricEditorState.Mode), }, lightsGlow = new Container { @@ -136,12 +123,12 @@ private void load() { new Box { - Colour = colourProvider.Background2, + Colour = colourProvider.Background2(lyricEditorState.Mode), RelativeSizeAxes = Axes.Both, }, innerCircleHighlight = new Box { - Colour = colourProvider.Colour3, + Colour = colourProvider.Colour3(lyricEditorState.Mode), Blending = BlendingParameters.Additive, RelativeSizeAxes = Axes.Both, Alpha = 0, @@ -149,7 +136,7 @@ private void load() textContainer = new Container { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background1, + Colour = colourProvider.Background1(lyricEditorState.Mode), Children = new Drawable[] { new OsuSpriteText @@ -160,19 +147,19 @@ private void load() Y = 5, Text = "Tap", }, - bpmText = new OsuSpriteText + timeTagInfoText = new OsuSpriteText { - Font = OsuFont.Torus.With(size: 23, weight: FontWeight.Regular), + Font = OsuFont.Torus.With(size: 18, weight: FontWeight.Regular), Anchor = Anchor.Centre, Origin = Anchor.TopCentre, - Y = -1, + Y = 2, }, }, }, hoverLayer = new Circle { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background1.Opacity(0.3f), + Colour = colourProvider.Background1(lyricEditorState.Mode).Opacity(0.3f), Blending = BlendingParameters.Additive, Alpha = 0, }, @@ -203,12 +190,12 @@ private ColourInfo textColour get { if (grabbedMouseDown) - return colourProvider.Background4; + return colourProvider.Background4(lyricEditorState.Mode); if (IsHovered) - return colourProvider.Content2; + return colourProvider.Content2(lyricEditorState.Mode); - return colourProvider.Background1; + return colourProvider.Background1(lyricEditorState.Mode); } } @@ -226,17 +213,24 @@ protected override void OnHoverLost(HoverLostEvent e) base.OnHoverLost(e); } - protected override bool OnMouseDown(MouseDownEvent e) + protected override bool OnClick(ClickEvent e) + { + Tapped?.Invoke(editorClock.CurrentTime); + + mouseDownAnimation(); + mouseUpAnimation(); + + return true; + } + + private void mouseDownAnimation() { const double in_duration = 100; grabbedMouseDown = true; - IsHandlingTapping.Value = true; resetDelegate?.Cancel(); - handleTap(); - textContainer.FadeColour(textColour, in_duration, Easing.OutQuint); scaleContainer.ScaleTo(0.99f, in_duration, Easing.OutQuint); @@ -253,11 +247,9 @@ protected override bool OnMouseDown(MouseDownEvent e) lights[currentLight % light_count].Show(); lights[(currentLight + light_count / 2) % light_count].Show(); - - return true; } - protected override void OnMouseUp(MouseUpEvent e) + private void mouseUpAnimation() { const double out_duration = 800; @@ -271,76 +263,24 @@ protected override void OnMouseUp(MouseUpEvent e) innerCircleHighlight.FadeOut(out_duration, Easing.OutQuint); resetDelegate = Scheduler.AddDelayed(reset, 1000); - - base.OnMouseUp(e); - } - - public bool OnPressed(KeyBindingPressEvent e) - { - if (e.Action == GlobalAction.EditorTapForBPM && !e.Repeat) - { - // Direct through mouse handling to achieve animation - OnMouseDown(new MouseDownEvent(e.CurrentState, MouseButton.Left)); - return true; - } - - return false; - } - - public void OnReleased(KeyBindingReleaseEvent e) - { - if (e.Action == GlobalAction.EditorTapForBPM) - OnMouseUp(new MouseUpEvent(e.CurrentState, MouseButton.Left)); - } - - private void handleTap() - { - if (selectedGroup?.Value == null) - return; - - tapTimings.Add(Clock.CurrentTime); - - if (tapTimings.Count > initial_taps_to_ignore + max_taps_to_consider) - tapTimings.RemoveAt(0); - - if (tapTimings.Count < initial_taps_to_ignore * 2) - { - bpmText.Text = new string('.', tapTimings.Count); - return; - } - - double averageBeatLength = (tapTimings.Last() - tapTimings.Skip(initial_taps_to_ignore).First()) / (tapTimings.Count - initial_taps_to_ignore - 1); - double clockRate = beatSyncSource?.Clock.Rate ?? 1; - - double bpm = Math.Round(60000 / averageBeatLength / clockRate); - - bpmText.Text = $"{bpm} BPM"; - - var timingPoint = selectedGroup?.Value.ControlPoints.OfType().FirstOrDefault(); - - if (timingPoint != null) - { - // Intentionally use the rounded BPM here. - timingPoint.BeatLength = 60000 / bpm; - } } private void reset() { - bpmText.FadeOut(transition_length, Easing.OutQuint); - - using (BeginDelayedSequence(tapTimings.Count > 0 ? transition_length : 0)) - { - Schedule(() => bpmText.Text = "the beat!"); - bpmText.FadeIn(800, Easing.OutQuint); - } + timeTagInfoText.FadeOut(transition_length, Easing.OutQuint); + timeTagInfoText.FadeIn(800, Easing.OutQuint); foreach (var light in lights) light.Hide(); - tapTimings.Clear(); currentLight = 0; - IsHandlingTapping.Value = false; + } + + protected override void Update() + { + base.Update(); + + timeTagInfoText.Text = editorClock.CurrentTime.ToEditorFormattedString(); } private partial class Light : CompositeDrawable @@ -350,7 +290,10 @@ private partial class Light : CompositeDrawable private Container fillContent = null!; [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; + private ILyricEditorState lyricEditorState { get; set; } = null!; + + [Resolved] + private LyricEditorColourProvider colourProvider { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -367,13 +310,13 @@ private void load() { RelativeSizeAxes = Axes.Both, Progress = 1f / light_count - angular_light_gap, - Colour = colourProvider.Background2, + Colour = colourProvider.Background2(lyricEditorState.Mode), }, fillContent = new Container { RelativeSizeAxes = Axes.Both, Alpha = 0, - Colour = colourProvider.Colour1, + Colour = colourProvider.Colour1(lyricEditorState.Mode), Children = new[] { new CircularProgress @@ -392,7 +335,7 @@ private void load() Blending = BlendingParameters.Additive, }.WithEffect(new GlowEffect { - Colour = colourProvider.Colour1.Opacity(0.4f), + Colour = colourProvider.Colour1(lyricEditorState.Mode).Opacity(0.4f), BlurSigma = new Vector2(9f), Strength = 10, PadExtent = true, From 5d6cf8b3f3507a6b7511e1f49eaaa69ae6f853c4 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 21 Apr 2024 13:39:09 +0800 Subject: [PATCH 4/6] Apply this shit into the config section. --- .../Lyrics/Settings/TimeTagSettings.cs | 1 + .../TimeTags/TimeTagRecordingToolSection.cs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TimeTagRecordingToolSection.cs diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs index c8779358a..3cf052b85 100644 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs @@ -40,6 +40,7 @@ private void load(IEditTimeTagModeState editTimeTagModeState) TimeTagEditStep.Recording => new Drawable[] { new TimeTagEditStepSection(), + new TimeTagRecordingToolSection(), new TimeTagRecordingConfigSection(), new RecordTimeTagActionReceiver(), }, diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TimeTagRecordingToolSection.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TimeTagRecordingToolSection.cs new file mode 100644 index 000000000..dd0f439f1 --- /dev/null +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/TimeTagRecordingToolSection.cs @@ -0,0 +1,22 @@ +// Copyright (c) andy840119 . Licensed under the GPL Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Localisation; + +namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags; + +public partial class TimeTagRecordingToolSection : EditorSection +{ + protected override LocalisableString Title => "Tool"; + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new RecordingTapControl(), + }; + } +} From 06876f90e4e98fc06378685b3984d06a18c33b57 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 21 Apr 2024 13:49:26 +0800 Subject: [PATCH 5/6] Remove old action in the toolbar. Those action buttons is not easy to be noticed and maybe people might not using it. --- .../Lyrics/Compose/SpecialActionToolbar.cs | 4 -- .../TimeTags/ClearAllTimeTagTimeButton.cs | 24 ----------- .../TimeTags/ClearTimeTagTimeButton.cs | 36 ---------------- .../Toolbar/TimeTags/SetTimeTagTimeButton.cs | 41 ------------------- 4 files changed, 105 deletions(-) delete mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearAllTimeTagTimeButton.cs delete mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearTimeTagTimeButton.cs delete mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/SetTimeTagTimeButton.cs diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/SpecialActionToolbar.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/SpecialActionToolbar.cs index 9f91dc3ca..fb0d7a69d 100644 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/SpecialActionToolbar.cs +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/SpecialActionToolbar.cs @@ -166,10 +166,6 @@ static IEnumerable createItemsForTimeTagEditStep(TimeTagEditStep timeT new MoveToPreviousIndexButton(), new MoveToNextIndexButton(), new MoveToLastIndexButton(), - new Separator(), - new SetTimeTagTimeButton(), - new ClearTimeTagTimeButton(), - new ClearAllTimeTagTimeButton(), }, TimeTagEditStep.Adjust => new Drawable[] { diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearAllTimeTagTimeButton.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearAllTimeTagTimeButton.cs deleted file mode 100644 index 003867bea..000000000 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearAllTimeTagTimeButton.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) andy840119 . Licensed under the GPL Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics; - -namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Compose.Toolbar.TimeTags; - -public partial class ClearAllTimeTagTimeButton : ActionButton -{ - [Resolved] - private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!; - - public ClearAllTimeTagTimeButton() - { - SetIcon(FontAwesome.Solid.Redo); - - Action = () => - { - lyricTimeTagsChangeHandler.ClearAllTimeTagTime(); - }; - } -} diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearTimeTagTimeButton.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearTimeTagTimeButton.cs deleted file mode 100644 index f71ab7ac3..000000000 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/ClearTimeTagTimeButton.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) andy840119 . Licensed under the GPL Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics; -using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.CaretPosition; -using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States; - -namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Compose.Toolbar.TimeTags; - -public partial class ClearTimeTagTimeButton : KeyActionButton -{ - protected override KaraokeEditAction EditAction => KaraokeEditAction.ClearTime; - - [Resolved] - private ILyricCaretState lyricCaretState { get; set; } = null!; - - [Resolved] - private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!; - - public ClearTimeTagTimeButton() - { - SetIcon(FontAwesome.Solid.Eraser); - - Action = () => - { - if (lyricCaretState.CaretPosition is not TimeTagCaretPosition timeTagCaretPosition) - throw new InvalidOperationException(); - - var timeTag = timeTagCaretPosition.TimeTag; - lyricTimeTagsChangeHandler.ClearTimeTagTime(timeTag); - }; - } -} diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/SetTimeTagTimeButton.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/SetTimeTagTimeButton.cs deleted file mode 100644 index aeac1eaf0..000000000 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Compose/Toolbar/TimeTags/SetTimeTagTimeButton.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) andy840119 . Licensed under the GPL Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics; -using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.CaretPosition; -using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States; -using osu.Game.Screens.Edit; - -namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Compose.Toolbar.TimeTags; - -public partial class SetTimeTagTimeButton : KeyActionButton -{ - protected override KaraokeEditAction EditAction => KaraokeEditAction.SetTime; - - [Resolved] - private ILyricCaretState lyricCaretState { get; set; } = null!; - - [Resolved] - private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!; - - [Resolved] - private EditorClock editorClock { get; set; } = null!; - - public SetTimeTagTimeButton() - { - SetIcon(FontAwesome.Solid.Stopwatch); - - Action = () => - { - if (lyricCaretState.CaretPosition is not TimeTagCaretPosition timeTagCaretPosition) - throw new InvalidOperationException(); - - var timeTag = timeTagCaretPosition.TimeTag; - double currentTime = editorClock.CurrentTime; - lyricTimeTagsChangeHandler.SetTimeTagTime(timeTag, currentTime); - }; - } -} From 66ee1920d19236a13f951cddc871722fcb9a57c7 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 21 Apr 2024 13:59:17 +0800 Subject: [PATCH 6/6] Remove old action receiver to make sure that all recording actions is handled by timing control. --- .../Lyrics/Settings/TimeTagSettings.cs | 1 - .../TimeTags/RecordTimeTagActionReceiver.cs | 62 ------------------- 2 files changed, 63 deletions(-) delete mode 100644 osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordTimeTagActionReceiver.cs diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs index 3cf052b85..a4cc45a75 100644 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs +++ b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTagSettings.cs @@ -42,7 +42,6 @@ private void load(IEditTimeTagModeState editTimeTagModeState) new TimeTagEditStepSection(), new TimeTagRecordingToolSection(), new TimeTagRecordingConfigSection(), - new RecordTimeTagActionReceiver(), }, TimeTagEditStep.Adjust => new Drawable[] { diff --git a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordTimeTagActionReceiver.cs b/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordTimeTagActionReceiver.cs deleted file mode 100644 index 37e1e5b2e..000000000 --- a/osu.Game.Rulesets.Karaoke/Screens/Edit/Beatmaps/Lyrics/Settings/TimeTags/RecordTimeTagActionReceiver.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) andy840119 . Licensed under the GPL Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Input.Bindings; -using osu.Framework.Input.Events; -using osu.Game.Rulesets.Karaoke.Configuration; -using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Lyrics; -using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.CaretPosition; -using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States; -using osu.Game.Screens.Edit; - -namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags; - -public partial class RecordTimeTagActionReceiver : Component, IKeyBindingHandler -{ - [Resolved] - private KaraokeRulesetLyricEditorConfigManager lyricEditorConfigManager { get; set; } = null!; - - [Resolved] - private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!; - - [Resolved] - private ILyricCaretState lyricCaretState { get; set; } = null!; - - [Resolved] - private EditorClock editorClock { get; set; } = null!; - - public bool OnPressed(KeyBindingPressEvent e) - { - var caretPosition = lyricCaretState.CaretPosition; - if (caretPosition is not RecordingTimeTagCaretPosition timeTagCaretPosition) - throw new NotSupportedException(nameof(caretPosition)); - - var currentTimeTag = timeTagCaretPosition.TimeTag; - - switch (e.Action) - { - case KaraokeEditAction.ClearTime: - lyricTimeTagsChangeHandler.ClearTimeTagTime(currentTimeTag); - return true; - - case KaraokeEditAction.SetTime: - double currentTime = editorClock.CurrentTime; - lyricTimeTagsChangeHandler.SetTimeTagTime(currentTimeTag, currentTime); - - if (lyricEditorConfigManager.Get(KaraokeRulesetLyricEditorSetting.RecordingAutoMoveToNextTimeTag)) - lyricCaretState.MoveCaret(MovingCaretAction.NextIndex); - - return true; - - default: - return false; - } - } - - public void OnReleased(KeyBindingReleaseEvent e) - { - } -}