diff --git a/src/Forms/EffectKaraoke.cs b/src/Forms/EffectKaraoke.cs index d4f08e8c5..0010dec53 100644 --- a/src/Forms/EffectKaraoke.cs +++ b/src/Forms/EffectKaraoke.cs @@ -52,7 +52,7 @@ namespace Nikse.SubtitleEdit.Forms numericUpDownDelay.Left = labelEndDelay.Left + labelEndDelay.Width + 5; } - private class ColorEntry + internal class ColorEntry { public int Start { get; set; } @@ -60,7 +60,7 @@ namespace Nikse.SubtitleEdit.Forms public Color Color { get; set; } } - private class FontEntry + internal class FontEntry { public int Start { get; set; } public int Length { get; set; } diff --git a/src/Forms/EffectTypewriter.Designer.cs b/src/Forms/EffectTypewriter.Designer.cs index 9ba442951..24e960f51 100644 --- a/src/Forms/EffectTypewriter.Designer.cs +++ b/src/Forms/EffectTypewriter.Designer.cs @@ -29,7 +29,6 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.labelPreview = new System.Windows.Forms.Label(); this.buttonPreview = new System.Windows.Forms.Button(); this.buttonOK = new System.Windows.Forms.Button(); this.buttonCancel = new System.Windows.Forms.Button(); @@ -38,23 +37,10 @@ this.numericUpDownDelay = new System.Windows.Forms.NumericUpDown(); this.labelTM = new System.Windows.Forms.Label(); this.labelTotalMilliseconds = new System.Windows.Forms.Label(); + this.richTextBoxPreview = new System.Windows.Forms.RichTextBox(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownDelay)).BeginInit(); this.SuspendLayout(); // - // labelPreview - // - this.labelPreview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelPreview.BackColor = System.Drawing.Color.Black; - this.labelPreview.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelPreview.ForeColor = System.Drawing.Color.White; - this.labelPreview.Location = new System.Drawing.Point(12, 72); - this.labelPreview.Name = "labelPreview"; - this.labelPreview.Size = new System.Drawing.Size(409, 40); - this.labelPreview.TabIndex = 25; - this.labelPreview.Text = "labelPreview"; - this.labelPreview.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // // buttonPreview // this.buttonPreview.Location = new System.Drawing.Point(12, 119); @@ -139,11 +125,25 @@ this.labelTotalMilliseconds.TabIndex = 37; this.labelTotalMilliseconds.Text = "labelTotalMilliseconds"; // + // richTextBoxPreview + // + this.richTextBoxPreview.BackColor = System.Drawing.Color.Black; + this.richTextBoxPreview.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richTextBoxPreview.DetectUrls = false; + this.richTextBoxPreview.Location = new System.Drawing.Point(12, 69); + this.richTextBoxPreview.Name = "richTextBoxPreview"; + this.richTextBoxPreview.ReadOnly = true; + this.richTextBoxPreview.Size = new System.Drawing.Size(409, 44); + this.richTextBoxPreview.TabIndex = 51; + this.richTextBoxPreview.TabStop = false; + this.richTextBoxPreview.Text = ""; + // // EffectTypewriter // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(433, 179); + this.Controls.Add(this.richTextBoxPreview); this.Controls.Add(this.labelTotalMilliseconds); this.Controls.Add(this.labelTM); this.Controls.Add(this.numericUpDownDelay); @@ -151,7 +151,6 @@ this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonOK); this.Controls.Add(this.buttonPreview); - this.Controls.Add(this.labelPreview); this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.KeyPreview = true; @@ -170,7 +169,6 @@ #endregion - private System.Windows.Forms.Label labelPreview; private System.Windows.Forms.Button buttonPreview; private System.Windows.Forms.Button buttonOK; private System.Windows.Forms.Button buttonCancel; @@ -179,5 +177,6 @@ private System.Windows.Forms.NumericUpDown numericUpDownDelay; private System.Windows.Forms.Label labelTM; private System.Windows.Forms.Label labelTotalMilliseconds; + private System.Windows.Forms.RichTextBox richTextBoxPreview; } } \ No newline at end of file diff --git a/src/Forms/EffectTypewriter.cs b/src/Forms/EffectTypewriter.cs index 53a60f58f..dce564e96 100644 --- a/src/Forms/EffectTypewriter.cs +++ b/src/Forms/EffectTypewriter.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Drawing; +using System.Text; using System.Windows.Forms; using Nikse.SubtitleEdit.Logic; using Nikse.SubtitleEdit.Core; @@ -43,13 +45,151 @@ namespace Nikse.SubtitleEdit.Forms { _paragraph = paragraph; - labelPreview.Text = paragraph.Text; + AddToPreview(richTextBoxPreview, paragraph.Text); + RefreshPreview(); + labelTotalMilliseconds.Text = string.Format("{0:#,##0.000}", paragraph.Duration.TotalMilliseconds / 1000); numericUpDownDelay.Maximum = (decimal)((paragraph.Duration.TotalMilliseconds - 500) / 1000); numericUpDownDelay.Minimum = 0; numericUpDownDelay.Left = labelEndDelay.Left + labelEndDelay.Width + 5; } + + private List _colorList; + private List _fontList; + + private void AddToPreview(RichTextBox rtb, string text) + { + richTextBoxPreview.ForeColor = Color.White; + _colorList = new List(); + _fontList = new List(); + + int bold = 0; + int underline = 0; + int italic = 0; + var fontColors = new Stack(); + string currentColor = string.Empty; + + var sb = new StringBuilder(); + int i = 0; + while (i < text.Length) + { + if (text[i] == '<') + { + AddTextToRichTextBox(rtb, bold > 0, italic > 0, underline > 0, currentColor, sb.ToString()); + sb.Clear(); + string tag = GetTag(text.Substring(i).ToLower()); + if (i + 1 < text.Length && text[i + 1] == '/') + { + if (tag == "" && italic > 0) + italic--; + else if (tag == "" && bold > 0) + bold--; + else if (tag == "" && underline > 0) + underline--; + else if (tag == "") + currentColor = fontColors.Count > 0 ? fontColors.Pop() : string.Empty; + } + else + { + if (tag == "") + italic++; + else if (tag == "") + bold++; + else if (tag == "") + underline++; + else if (tag.StartsWith(" 0) + AddTextToRichTextBox(rtb, bold > 0, italic > 0, underline > 0, currentColor, sb.ToString()); + + foreach (var fontEntry in _fontList) + { + rtb.SelectionStart = fontEntry.Start; + rtb.SelectionLength = fontEntry.Length; + rtb.SelectionFont = fontEntry.Font; + rtb.DeselectAll(); + } + + foreach (var colorEntry in _colorList) + { + rtb.SelectionStart = colorEntry.Start; + rtb.SelectionLength = colorEntry.Length; + rtb.SelectionColor = colorEntry.Color; + rtb.DeselectAll(); + } + } + + private void AddTextToRichTextBox(RichTextBox rtb, bool bold, bool italic, bool underline, string color, string text) + { + if (text.Length > 0) + { + int length = rtb.Text.Length; + richTextBoxPreview.Text += text; + + _colorList.Add(new EffectKaraoke.ColorEntry { Start = length, Length = text.Length, Color = string.IsNullOrWhiteSpace(color) ? Color.White : ColorTranslator.FromHtml(color) }); + + var fontStyle = new FontStyle(); + if (underline) + fontStyle = fontStyle | FontStyle.Underline; + if (italic) + fontStyle = fontStyle | FontStyle.Italic; + if (bold) + fontStyle = fontStyle | FontStyle.Bold; + _fontList.Add(new EffectKaraoke.FontEntry { Start = length, Length = text.Length, Font = new Font(rtb.Font.FontFamily, rtb.Font.Size, fontStyle) }); + } + } + + private static string GetTag(string text) + { + var sb = new StringBuilder(); + for (int i = 0; i < text.Length; i++) + { + sb.Append(text[i]); + if (text[i] == '>') + return sb.ToString(); + } + return sb.ToString(); + } + + private void ClearPreview() + { + richTextBoxPreview.Text = string.Empty; + } + + private void RefreshPreview() + { + richTextBoxPreview.SelectAll(); + richTextBoxPreview.SelectionAlignment = HorizontalAlignment.Center; + richTextBoxPreview.Refresh(); + } private void ButtonPreviewClick(object sender, EventArgs e) { @@ -154,14 +294,16 @@ namespace Nikse.SubtitleEdit.Forms _timerCount += timer1.Interval; string s = GetText(_timerCount, _animation); - labelPreview.Text = s; - labelPreview.Refresh(); + ClearPreview(); + AddToPreview(richTextBoxPreview, s); + RefreshPreview(); if (_timerCount > _paragraph.EndTime.TotalMilliseconds) { timer1.Stop(); System.Threading.Thread.Sleep(200); - labelPreview.Text = _paragraph.Text; + ClearPreview(); + AddToPreview(richTextBoxPreview, _paragraph.Text); } }