Skip to content

Commit

Permalink
Merge pull request #2242 from andy840119/implement-switch-create-type…
Browse files Browse the repository at this point in the history
…-section

Implement switch create type section
  • Loading branch information
andy840119 authored Jun 2, 2024
2 parents 51d3a63 + b6a81be commit 906d47f
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using osu.Game.Rulesets.Karaoke.Edit.Components.Sprites;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.CaretPosition;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States.Modes;
using osu.Game.Rulesets.Karaoke.Utils;
using osuTK;

Expand Down Expand Up @@ -107,7 +108,10 @@ public TimeTagsInfo(TextIndex.IndexState indexState)
}

[BackgroundDependencyLoader]
private void load(LyricEditorColourProvider colourProvider, ILyricEditorState state, ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler)
private void load(LyricEditorColourProvider colourProvider,
ILyricEditorState state,
ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler,
IEditTimeTagModeState editTimeTagModeState)
{
InternalChildren = new Drawable[]
{
Expand Down Expand Up @@ -171,6 +175,7 @@ private void load(LyricEditorColourProvider colourProvider, ILyricEditorState st

var textIndex = new TextIndex(previousCaret.Value.CharIndex, indexState);
lyricTimeTagsChangeHandler.AddByPosition(textIndex);
editTimeTagModeState.BindableCreateType.Value = CreateTimeTagType.Mouse;
},
},
},
Expand Down Expand Up @@ -254,6 +259,9 @@ private partial class TimeTagVisualization : CompositeDrawable, IHasTooltip
[Resolved]
private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!;

[Resolved]
private IEditTimeTagModeState editTimeTagModeState { get; set; } = null!;

private readonly TimeTag timeTag;

public TimeTagVisualization(TimeTag timeTag)
Expand All @@ -277,6 +285,7 @@ public TimeTagVisualization(TimeTag timeTag)
protected override bool OnClick(ClickEvent e)
{
lyricTimeTagsChangeHandler.Remove(timeTag);
editTimeTagModeState.BindableCreateType.Value = CreateTimeTagType.Mouse;

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,19 +394,11 @@ private void load(EditorBeatmap beatmap, KaraokeRulesetLyricEditorConfigManager
lyricEditorConfigManager.BindWith(KaraokeRulesetLyricEditorSetting.LyricEditorPreferLayout, bindablePreferLayout);
}

public virtual bool OnPressed(KeyBindingPressEvent<KaraokeEditAction> e) =>
e.Action switch
{
KaraokeEditAction.MoveToPreviousLyric => lyricCaretState.MoveCaret(MovingCaretAction.PreviousLyric),
KaraokeEditAction.MoveToNextLyric => lyricCaretState.MoveCaret(MovingCaretAction.NextLyric),
KaraokeEditAction.MoveToFirstLyric => lyricCaretState.MoveCaret(MovingCaretAction.FirstLyric),
KaraokeEditAction.MoveToLastLyric => lyricCaretState.MoveCaret(MovingCaretAction.LastLyric),
KaraokeEditAction.MoveToPreviousIndex => lyricCaretState.MoveCaret(MovingCaretAction.PreviousIndex),
KaraokeEditAction.MoveToNextIndex => lyricCaretState.MoveCaret(MovingCaretAction.NextIndex),
KaraokeEditAction.MoveToFirstIndex => lyricCaretState.MoveCaret(MovingCaretAction.FirstIndex),
KaraokeEditAction.MoveToLastIndex => lyricCaretState.MoveCaret(MovingCaretAction.LastIndex),
_ => false,
};
public virtual bool OnPressed(KeyBindingPressEvent<KaraokeEditAction> e)
{
var movingCaretAction = ToMovingCaretAction(e.Action);
return movingCaretAction != null && lyricCaretState.MoveCaret(movingCaretAction.Value);
}

public void OnReleased(KeyBindingReleaseEvent<KaraokeEditAction> e)
{
Expand Down Expand Up @@ -469,6 +461,22 @@ public virtual void NavigateToFix(LyricEditorMode mode)
}
}

public static MovingCaretAction? ToMovingCaretAction(KaraokeEditAction action)
{
return action switch
{
KaraokeEditAction.MoveToPreviousLyric => MovingCaretAction.PreviousLyric,
KaraokeEditAction.MoveToNextLyric => MovingCaretAction.NextLyric,
KaraokeEditAction.MoveToFirstLyric => MovingCaretAction.FirstLyric,
KaraokeEditAction.MoveToLastLyric => MovingCaretAction.LastLyric,
KaraokeEditAction.MoveToPreviousIndex => MovingCaretAction.PreviousIndex,
KaraokeEditAction.MoveToNextIndex => MovingCaretAction.NextIndex,
KaraokeEditAction.MoveToFirstIndex => MovingCaretAction.FirstIndex,
KaraokeEditAction.MoveToLastIndex => MovingCaretAction.LastIndex,
_ => null,
};
}

private class LocalScrollingInfo : IScrollingInfo
{
public IBindable<ScrollingDirection> Direction { get; } = new Bindable<ScrollingDirection>(ScrollingDirection.Left);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,88 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
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.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States.Modes;

namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags;

// todo: this section will display the action for creating time-tag.
// will the visual part of https://github.com/karaoke-dev/karaoke/discussions/2225#discussioncomment-9244747
public partial class CreateTimeTagActionSection : EditorSection, IKeyBindingHandler<KaraokeEditAction>
{
protected override LocalisableString Title => "Action";

[Resolved]
private ILyricTimeTagsChangeHandler lyricTimeTagsChangeHandler { get; set; } = null!;

[Resolved]
private ILyricCaretState lyricCaretState { get; set; } = null!;
private readonly IBindable<ICaretPosition?> bindableCaretPosition = new Bindable<ICaretPosition?>();
private readonly Bindable<CreateTimeTagType> bindableCreateType = new();

public CreateTimeTagActionSection()
{
Children = new[]
{
new CreateTimeTagTypeSubsection
{
Current = bindableCreateType,
},
};
}

[BackgroundDependencyLoader]
private void load(IEditTimeTagModeState editTimeTagModeState, ILyricCaretState lyricCaretState)
{
bindableCaretPosition.BindTo(lyricCaretState.BindableCaretPosition);
bindableCreateType.BindTo(editTimeTagModeState.BindableCreateType);
}

public bool OnPressed(KeyBindingPressEvent<KaraokeEditAction> e)
{
var action = e.Action;
var caretPosition = lyricCaretState.CaretPosition;
var caretPosition = bindableCaretPosition.Value;

return caretPosition switch
if (caretPosition is not CreateRemoveTimeTagCaretPosition createRemoveTimeTagCaretPosition)
return false;

if (LyricEditor.ToMovingCaretAction(e.Action) != null)
{
CreateRemoveTimeTagCaretPosition timeTagIndexCaretPosition => processCreateTimeTagAction(timeTagIndexCaretPosition, action),
_ => throw new NotSupportedException(nameof(caretPosition)),
};
bindableCreateType.Value = CreateTimeTagType.Keyboard;
return false;
}

if (createTimeTagByKeyboard(createRemoveTimeTagCaretPosition.CharIndex, action))
{
bindableCreateType.Value = CreateTimeTagType.Keyboard;
return true;
}

return false;
}

private bool processCreateTimeTagAction(CreateRemoveTimeTagCaretPosition createRemoveTimeTagCaretPosition, KaraokeEditAction action)
private bool createTimeTagByKeyboard(int charIndex, KaraokeEditAction action)
{
int index = createRemoveTimeTagCaretPosition.CharIndex;

switch (action)
{
case KaraokeEditAction.CreateStartTimeTag:
lyricTimeTagsChangeHandler.AddByPosition(new TextIndex(index));
lyricTimeTagsChangeHandler.AddByPosition(new TextIndex(charIndex));
return true;

case KaraokeEditAction.CreateEndTimeTag:
lyricTimeTagsChangeHandler.AddByPosition(new TextIndex(index, TextIndex.IndexState.End));
lyricTimeTagsChangeHandler.AddByPosition(new TextIndex(charIndex, TextIndex.IndexState.End));
return true;

case KaraokeEditAction.RemoveStartTimeTag:
lyricTimeTagsChangeHandler.RemoveByPosition(new TextIndex(index));
lyricTimeTagsChangeHandler.RemoveByPosition(new TextIndex(charIndex));
return true;

case KaraokeEditAction.RemoveEndTimeTag:
lyricTimeTagsChangeHandler.RemoveByPosition(new TextIndex(index, TextIndex.IndexState.End));
lyricTimeTagsChangeHandler.RemoveByPosition(new TextIndex(charIndex, TextIndex.IndexState.End));
return true;

default:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States.Modes;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Components.Markdown;
using osuTK;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.Settings.TimeTags;

public partial class CreateTimeTagTypeSubsection : SwitchSubsection<CreateTimeTagType>
{
protected override SwitchTabControl CreateTabControl()
=> new CreateTimeTagTypeTabControl();

protected override DescriptionFormat GetDescription(CreateTimeTagType mode) =>
mode switch
{
CreateTimeTagType.Mouse => "Use mouse to move the caret, and click the button in the UI to create/remove the start/end time tag. It's for the beginner.",
CreateTimeTagType.HotkeyThenPress => "Press the hotkey to prepare create/remove the start/end time tag. This kind of create mode is still implementing.",
CreateTimeTagType.Keyboard => new DescriptionFormat
{
Text =
$"Use [{DescriptionFormat.LINK_KEY_ACTION}](navigate_time_tag) to control caret position, press [{DescriptionFormat.LINK_KEY_ACTION}](create_time_tag) to create new time-tag and press [{DescriptionFormat.LINK_KEY_ACTION}](remove_time_tag) to delete exist time-tag.",
Actions = new Dictionary<string, IDescriptionAction>
{
{
"navigate_time_tag", new InputKeyDescriptionAction
{
Text = "Keyboard",
AdjustableActions = new List<KaraokeEditAction>
{
KaraokeEditAction.MoveToPreviousLyric,
KaraokeEditAction.MoveToNextLyric,
KaraokeEditAction.MoveToPreviousIndex,
KaraokeEditAction.MoveToNextIndex,
},
}
},
{
"create_time_tag", new InputKeyDescriptionAction
{
Text = "Create Time-tag keys",
AdjustableActions = new List<KaraokeEditAction>
{
KaraokeEditAction.CreateStartTimeTag,
KaraokeEditAction.CreateEndTimeTag,
},
}
},
{
"remove_time_tag", new InputKeyDescriptionAction
{
Text = "Remove Time-tag keys",
AdjustableActions = new List<KaraokeEditAction>
{
KaraokeEditAction.RemoveStartTimeTag,
KaraokeEditAction.RemoveEndTimeTag,
},
}
},
},
},
_ => throw new InvalidOperationException(nameof(mode)),
};

private partial class CreateTimeTagTypeTabControl : SwitchTabControl
{
protected override SwitchTabItem CreateStepButton(OsuColour colours, CreateTimeTagType value)
{
return value switch
{
CreateTimeTagType.Mouse => new CreateTimeTagTypeTabButton(value)
{
Icon = FontAwesome.Solid.MousePointer,
TooltipText = "Mouse",
SelectedColour = colours.Green,
UnSelectedColour = colours.GreenDarker,
},
CreateTimeTagType.HotkeyThenPress => new CreateTimeTagTypeTabButton(value)
{
Icon = FontAwesome.Solid.PencilAlt,
TooltipText = "Keyboard + Mouse",
SelectedColour = colours.Yellow,
UnSelectedColour = colours.YellowDarker,
},
CreateTimeTagType.Keyboard => new CreateTimeTagTypeTabButton(value)
{
Icon = FontAwesome.Solid.Keyboard,
TooltipText = "Keyboard",
SelectedColour = colours.Blue,
UnSelectedColour = colours.BlueDarker,
},
_ => throw new ArgumentOutOfRangeException(nameof(value), value, null),
};
}

private partial class CreateTimeTagTypeTabButton : SwitchTabItem, IHasTooltip
{
private readonly Box background;
private readonly SpriteIcon spriteIcon;

public CreateTimeTagTypeTabButton(CreateTimeTagType value)
: base(value)
{
Child = new Container
{
Masking = true,
CornerRadius = 15,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
},
spriteIcon = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(25),
},
},
};
}

public IconUsage Icon
{
get => spriteIcon.Icon;
set => spriteIcon.Icon = value;
}

public LocalisableString TooltipText { get; init; }

public Color4 SelectedColour { get; init; }

public Color4 UnSelectedColour { get; init; }

protected override void UpdateState()
{
background.Colour = Active.Value ? SelectedColour : UnSelectedColour;
Child.Alpha = Active.Value ? 0.8f : 0.4f;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

namespace osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.States.Modes;

public enum CreateTimeTagType
{
/// <summary>
/// Use mouse to move the caret, and click the button in the UI to create/remove the start/end time tag.
/// It's the slowest way to create the time tag.
/// </summary>
Mouse,

/// <summary>
/// Press the hotkey to prepare create/remove the start/end time tag, click the character in the lyric to confirm.
/// It might be useful for those english-like lyric.
/// </summary>
HotkeyThenPress,

/// <summary>
/// Use keyboard to move the caret, and press hotkey to create/remove the start/end time tag.
/// It's the fastest way to create the time tag for Japanese/Chinses lyric.
/// </summary>
Keyboard,
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public partial class EditTimeTagModeState : ModeStateWithBlueprintContainer<Time

public BindableFloat BindableAdjustZoom { get; } = new();

public Bindable<CreateTimeTagType> BindableCreateType { get; } = new();

[BackgroundDependencyLoader]
private void load(EditorClock editorClock)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public interface IEditTimeTagModeState : IHasEditStep<TimeTagEditStep>, IHasBlue
BindableFloat BindableRecordZoom { get; }

BindableFloat BindableAdjustZoom { get; }

Bindable<CreateTimeTagType> BindableCreateType { get; }
}

0 comments on commit 906d47f

Please sign in to comment.