Skip to content

Commit

Permalink
歌词板输入
Browse files Browse the repository at this point in the history
  • Loading branch information
LiuYunPlayer committed May 15, 2024
1 parent 88f4c9c commit d769ea3
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 42 deletions.
53 changes: 53 additions & 0 deletions TuneLab/Utils/LyricUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace TuneLab.Utils;

internal static class LyricUtils
{
public static List<string> SplitLyrics(string lyrics)
{
List<string> result = new List<string>();
var splitedLyrics = SplitByInvailidChars(lyrics);
foreach (var lyric in splitedLyrics)
{
result.AddRange(SplitToWords(lyric));
}

return result;
}

public static List<string> SplitToWords(string lyric)
{
List<string> lyrics = [];
if (string.IsNullOrEmpty(lyric))
return lyrics;

int flag = 0;
bool lastIsLetter = char.IsAsciiLetter(lyric[0]);
for (int i = 1; i < lyric.Length; i++)
{
bool isLetter = char.IsAsciiLetter(lyric[i]);
if (isLetter && lastIsLetter)
continue;

lyrics.Add(lyric.Substring(flag, i - flag));
flag = i;
}
lyrics.Add(lyric.Substring(flag, lyric.Length - flag));

return lyrics;
}

public static IEnumerable<string> SplitByInvailidChars(string lyric)
{
return lyric.Split(['\n', ' ', '\t', '\r',
'.', ',', '!', '?', ';', ':', '"', '(', ')', '[', ']', '{', '}', '/', '\'', '%', '$', '£', '€',
'。', ',', '!', '?', ';', ':', '“', '”', '‘', '’', '(', ')', '【', '】', '『', '』', '—', '·'])
.Where(s => !string.IsNullOrEmpty(s));
}
}
124 changes: 82 additions & 42 deletions TuneLab/Views/LyricInput.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,92 @@
using Avalonia.Layout;
using Button = TuneLab.GUI.Components.Button;
using Avalonia.Media;
using TuneLab.Data;
using System.Collections.Generic;
using System.Linq;

namespace TuneLab.Views
namespace TuneLab.Views;

internal partial class LyricInput : Window
{
public partial class LyricInput : Window
LyricInput()
{
public LyricInput()
InitializeComponent();
Focusable = true;
CanResize = false;
WindowState = WindowState.Normal;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
Topmost = true;

this.DataContext = this;
this.Background = Style.INTERFACE.ToBrush();
TitleBar.Background = Style.BACK.ToBrush();

mLyricInputBox = new TextInput();
mLyricInputBox.AcceptsReturn = true;
mLyricInputBox.Width = 432;
mLyricInputBox.Height = 168;
mLyricInputBox.Background = Style.BACK.ToBrush();
mLyricInputBox.Padding = new(8, 8);
mLyricInputBox.VerticalContentAlignment = Avalonia.Layout.VerticalAlignment.Top;
mLyricInputBox.Foreground = Style.WHITE.ToBrush();
mLyricInputBox.TextWrapping = TextWrapping.Wrap;
TextareaBox.Children.Add(mLyricInputBox);

var SkipTenutoLabelPanel = new StackPanel();
mSkipTenutoCheckBox = new CheckBox();
SkipTenutoLabelPanel.Orientation = Orientation.Horizontal;
SkipTenutoLabelPanel.Height = 24;
SkipTenutoLabelPanel.Children.Add(mSkipTenutoCheckBox);
SkipTenutoLabelPanel.Children.Add(new Label() { Content = "Skip Tenuto", FontSize = 12, Foreground = Style.TEXT_LIGHT.ToBrush(), Margin = new(14, 1) });
ActionsPanel.Children.Add(SkipTenutoLabelPanel);
Grid.SetColumn(SkipTenutoLabelPanel, 0);
var OkButtonPanel = new StackPanel();
OkButtonPanel.Orientation = Orientation.Horizontal;
OkButtonPanel.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right;
var OkButton = new Button() { Width = 64, Height = 28 };
OkButton.AddContent(new() { Item = new BorderItem() { CornerRadius = 6 }, ColorSet = new() { Color = Style.BUTTON_PRIMARY, HoveredColor = Style.BUTTON_PRIMARY_HOVER } });
OkButton.AddContent(new() { Item = new TextItem() { Text = "OK" }, ColorSet = new() { Color = Colors.White } });
OkButtonPanel.Children.Add(OkButton);
ActionsPanel.Children.Add(OkButtonPanel);
Grid.SetColumn(OkButton, 1);

OkButton.Clicked += OnLyricInputConfirm;
}

public static void EnterInput(IReadOnlyCollection<INote> notes)
{
var lyricInput = new LyricInput();
lyricInput.mNotes = notes;
lyricInput.mLyricInputBox.Text = string.Join(' ', notes.Select(note => note.Lyric.Value));
lyricInput.Show();
}

void OnLyricInputConfirm()
{
if (mNotes == null)
return;

if (mNotes.Count == 0)
return;

var lyrics = LyricUtils.SplitLyrics(mLyricInputBox.Text);
var notes = mSkipTenutoCheckBox.IsChecked ? mNotes.Where(note => note.Lyric.Value != "-") : mNotes;
using var enumerator = (mSkipTenutoCheckBox.IsChecked ? lyrics.Where(lyric => lyric != "-") : lyrics).GetEnumerator();
foreach (var note in notes)
{
InitializeComponent();
Focusable = true;
CanResize = false;
WindowState = WindowState.Normal;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
Topmost = true;

this.DataContext = this;
this.Background = Style.INTERFACE.ToBrush();
TitleBar.Background = Style.BACK.ToBrush();

var LyricInputBox = new TextInput();
LyricInputBox.AcceptsReturn = true;
LyricInputBox.Width = 432;
LyricInputBox.Height = 163;
LyricInputBox.Background = Style.BACK.ToBrush();
LyricInputBox.Padding = new(8, 8);
LyricInputBox.VerticalContentAlignment = Avalonia.Layout.VerticalAlignment.Top;
LyricInputBox.Foreground = Style.WHITE.ToBrush();
LyricInputBox.TextWrapping = TextWrapping.Wrap;
TextareaBox.Children.Add(LyricInputBox);

var SkipTenutoLabelPanel = new StackPanel();
var SkipTenutoCheckBox = new CheckBox();
SkipTenutoLabelPanel.Orientation = Orientation.Horizontal;
SkipTenutoLabelPanel.Height = 24;
SkipTenutoLabelPanel.Children.Add(SkipTenutoCheckBox);
SkipTenutoLabelPanel.Children.Add(new Label() { Content = "Skip Tenuto", FontSize = 12, Foreground = Style.TEXT_LIGHT.ToBrush(), Margin = new(14, 1) });
ActionsPanel.Children.Add(SkipTenutoLabelPanel);
Grid.SetColumn(SkipTenutoLabelPanel, 0);
var OkButtonPanel = new StackPanel();
OkButtonPanel.Orientation = Orientation.Horizontal;
OkButtonPanel.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right;
var OkButton = new Button() { Width = 64, Height = 28 };
OkButton.AddContent(new() { Item = new BorderItem() { CornerRadius = 6 }, ColorSet = new() { Color = Style.BUTTON_PRIMARY, HoveredColor = Style.BUTTON_PRIMARY_HOVER } });
OkButton.AddContent(new() { Item = new TextItem() { Text = "OK" }, ColorSet = new() { Color = Colors.White } });
OkButtonPanel.Children.Add(OkButton);
ActionsPanel.Children.Add(OkButtonPanel);
Grid.SetColumn(OkButton, 1);
if (!enumerator.MoveNext())
break;

note.Lyric.Set(enumerator.Current);
}

mNotes.First().Commit();
Close();
}

IReadOnlyCollection<INote>? mNotes = null;

readonly TextInput mLyricInputBox;
readonly CheckBox mSkipTenutoCheckBox;
}
4 changes: 4 additions & 0 deletions TuneLab/Views/PianoGridOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ bool DetectWaveformPrimaryButton()
var menuItem = new MenuItem().SetName("Octave Down").SetAction(OctaveDown).SetInputGesture(new KeyGesture(Key.Down, KeyModifiers.Shift));
menu.Items.Add(menuItem);
}
{
var menuItem = new MenuItem().SetName("Input Lyrics").SetAction(() => { LyricInput.EnterInput(Part.Notes.AllSelectedItems()); });
menu.Items.Add(menuItem);
}
if (note.Next != null)
{
var menuItem = new MenuItem().SetName("Move Lyrics Forward").SetAction(() =>
Expand Down

0 comments on commit d769ea3

Please sign in to comment.