using QuikDawEditor.EditingClasses; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using static QuikDawEditor.EDITING.MiscMethods; using static QuikDawEditor.EDITING.StaticProperties; namespace QuikDawEditor; public partial class LyricWindow : Window { public LyricWindow() { InitializeComponent(); myRTB.Document.Blocks.Clear(); foreach (LyricLine lline in editingProject.LyricLines) myRTB.Document.Blocks.Add(lline.myPar); myRTB.TextChanged += MyRTB_TextChanged; CurrentBlockCount = myRTB.Document.Blocks.Count; } int CurrentBlockCount = 0; TextPointer ParagraphsChangedSelectionPointer; private void MyRTB_TextChanged(object sender, TextChangedEventArgs e) { if (myRTB.Document.Blocks.Count != CurrentBlockCount) { bool Added = myRTB.Document.Blocks.Count > CurrentBlockCount; if (CurrentBlockCount == 0 && myRTB.Document.Blocks.Count == 1) myRTB.Document.Blocks.FirstBlock.Tag = "ShowLine"; CurrentBlockCount = myRTB.Document.Blocks.Count; if (Added) AddLyricLinesFromParagraphs(ParagraphsChangedSelectionPointer); else { foreach (TextChange tchange in e.Changes) RemoveLyricLines(); } } else { foreach (LyricLine lline in SelectedLyricLines) { lline.LineXaml = GetMinimalXaml(new TextRange(lline.myPar.ContentStart, lline.myPar.ContentEnd)); lline.CreateInlinesFromPar(); lline.UpdateVisibility(); } } editingProject.NeedsSaving = true; } private void RemoveLyricLines() { List removedLines = editingProject.LyricLines.Where(ll => !myRTB.Document.Blocks.Contains(ll.myPar)).ToList(); foreach (LyricLine rline in removedLines) editingProject.LyricLines.Remove(rline); foreach (LyricLine lline in editingProject.LyricLines) { lline.LineXaml = GetMinimalXaml(new TextRange(lline.myPar.ContentStart, lline.myPar.ContentEnd)); lline.CreateInlinesFromPar(); lline.UpdateLyricLine(); lline.UpdateVisibility(); } editingProject.shownLyricLines = editingProject.LyricLines.Where(ll => ll.ShowOnLyricLane).ToList(); } double defaultLineTimeSpacing = MillisecondsPerBeat * 8; bool currentShowLineStateSelection { get { bool returnVal = myRTB.Selection.Start.Paragraph?.Tag == "ShowLine" || myRTB.Selection.End.Paragraph?.Tag == "ShowLine"; return returnVal; } } private void AddLyricLinesFromParagraphs(TextPointer paragraphsChangedPointer) { //Insert paragraph here: LyricLine InsertLL = editingProject.LyricLines.FirstOrDefault(ll => ll.myPar.ContentStart.CompareTo(myRTB.Selection.Start) > 0); int insertIdx = InsertLL == null ? editingProject.LyricLines.Count : editingProject.LyricLines.IndexOf(InsertLL); Paragraph newPar = (Paragraph)myRTB.Document.Blocks.LastOrDefault(b => b.ContentStart.CompareTo(myRTB.Selection.Start) <= 0); newPar.Tag = currentShowLineStateSelection ? "ShowLine" : ""; //MessageBox.Show((new TextRange(InsertLL.myPar.ContentStart, InsertLL.myPar.ContentEnd)).Text); //MessageBox.Show((new TextRange(newPar.ContentStart, newPar.ContentEnd)).Text); ; LyricLine newLyricLine = new LyricLine(newPar); editingProject.LyricLines.Insert(insertIdx, newLyricLine); //update the shown list editingProject.shownLyricLines = editingProject.LyricLines.Where(ll => ll.ShowOnLyricLane).ToList(); if (newLyricLine.ShowOnLyricLane) { int shownIdx = editingProject.shownLyricLines.IndexOf(newLyricLine); double minRightTimePosMs = shownIdx == editingProject.shownLyricLines.Count - 1 ? Double.PositiveInfinity : editingProject.shownLyricLines[shownIdx + 1].timePosMs - defaultLineTimeSpacing / 2; newLyricLine.timePosMs = shownIdx == 0 ? 0 : Math.Min(minRightTimePosMs, editingProject.shownLyricLines[shownIdx - 1].timePosMs + defaultLineTimeSpacing); } else newLyricLine.timePosMs = insertIdx == 0 ? 0 : editingProject.LyricLines[insertIdx - 1].timePosMs + defaultLineTimeSpacing; foreach (LyricLine lline in editingProject.LyricLines) { lline.LineXaml = GetMinimalXaml(new TextRange(lline.myPar.ContentStart, lline.myPar.ContentEnd)); lline.timePosMs = lline.timePosMs; lline.CreateInlinesFromPar(); lline.UpdateLyricLine(); lline.UpdateVisibility(); } editingProject.shownLyricLines = editingProject.LyricLines.Where(ll => ll.ShowOnLyricLane).ToList(); } private void myRTB_ContextMenuOpening(object sender, ContextMenuEventArgs e) { foreach (MenuItem mi in FontColorMI.Items) mi.Click -= NewMI_Click; FontColorMI.Items.Clear(); SolidColorBrush fBrush = Brushes.Black; for (int i = 0; i < 10; i++) { switch (i) { case 1: fBrush = Brushes.Aqua; break; case 2: fBrush = Brushes.Red; break; case 3: fBrush = Brushes.Orange; break; case 4: fBrush = Brushes.DimGray; break; case 5: fBrush = Brushes.Brown; break; case 6: fBrush = Brushes.MediumPurple; break; case 7: fBrush = Brushes.DarkGreen; break; case 8: fBrush = Brushes.LightSkyBlue; break; case 9: fBrush = Brushes.HotPink; break; } string selText = myRTB.Selection.Text; string dispText = selText.Substring(0, Math.Min(50, selText.Contains("\r") ? selText.IndexOf("\r") : selText.Length)); if (dispText == "") dispText = "[New font color]"; MenuItem newMI = new MenuItem() { Header = dispText, Foreground = fBrush }; newMI.Click += NewMI_Click; FontColorMI.Items.Add(newMI); } foreach (MenuItem mi in HighlightMI.Items) mi.Click -= NewHighlightMI_Click; HighlightMI.Items.Clear(); SolidColorBrush hBrush = Brushes.Transparent; for (int i = 0; i < 10; i++) { switch (i) { case 1: hBrush = Brushes.Aqua; break; case 2: hBrush = Brushes.Red; break; case 3: hBrush = Brushes.Orange; break; case 4: hBrush = Brushes.DimGray; break; case 5: hBrush = Brushes.Brown; break; case 6: hBrush = Brushes.MediumPurple; break; case 7: hBrush = Brushes.DarkGreen; break; case 8: hBrush = Brushes.LightSkyBlue; break; case 9: hBrush = Brushes.HotPink; break; } MenuItem newHighlightMI = new MenuItem() { Width = 80, Height = 25, Margin = new Thickness(30, 0, 0, 0), Header = new Border(), Background = hBrush }; newHighlightMI.Click += NewHighlightMI_Click; HighlightMI.Items.Add(newHighlightMI); } ShowLineMI.IsChecked = myRTB.Selection.Start.Paragraph.Tag == "ShowLine"; } private void NewHighlightMI_Click(object sender, RoutedEventArgs e) { MenuItem thisMI = (MenuItem)sender; myRTB.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, thisMI.Background); } private void NewMI_Click(object sender, RoutedEventArgs e) { MenuItem thisMI = (MenuItem)sender; SolidColorBrush applyForegroundBrush = new SolidColorBrush(((SolidColorBrush)thisMI.Foreground).Color) { Opacity = myRTB.Selection.Start.Paragraph.Tag == "ShowLine" ? 1 : 0.5 }; myRTB.Selection.ApplyPropertyValue(ForegroundProperty, applyForegroundBrush); } internal bool userClosing = true; private void LyricWin_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (userClosing) { e.Cancel = true; editingProject.IsLyricEditorVisible = false; //this.Visibility = Visibility.Hidden; } } private void LyricWin_StateChanged(object sender, EventArgs e) { if (this.WindowState == WindowState.Maximized) this.WindowState = WindowState.Normal; } private List SelectedLyricLines { get { Paragraph selStartPar = myRTB.Selection.Start.Paragraph; Paragraph selEndPar = myRTB.Selection.End.Paragraph; if (selEndPar == null) selEndPar = (Paragraph)myRTB.Document.Blocks.LastBlock; return editingProject.LyricLines.Where(lll => lll.myPar.ContentEnd.CompareTo(selStartPar.ContentStart) >= 0 && lll.myPar.ContentStart.CompareTo(selEndPar.ContentEnd) <= 0).ToList(); } } private void ShowLineMenuItem_Click(object sender, RoutedEventArgs e) { foreach (LyricLine ll in SelectedLyricLines) ll.IsShowLine = ShowLineMI.IsChecked; } private void myRTB_SelectionChanged(object sender, RoutedEventArgs e) { //if (myRTB.Selection.Start.Paragraph != null) // currentShowLineStateSelection = myRTB.Selection.Start.Paragraph.Tag == "ShowLine"; } private void LyricWin_LocationChanged(object sender, EventArgs e) { if (windowLoaded) editingProject.NeedsSaving = true; } private void LyricWin_SizeChanged(object sender, SizeChangedEventArgs e) { if (windowLoaded) editingProject.NeedsSaving = true; } bool windowLoaded = false; private void LyricWin_Loaded(object sender, RoutedEventArgs e) { windowLoaded = true; } private void myRTB_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == Key.S && Keyboard.IsKeyDown(Key.LeftCtrl)) { //route saving to Project save editingProject.Save(); } } }