diff --git a/RadioDJViewer/Main.cs b/RadioDJViewer/Main.cs index 2d17459..5d052bb 100644 --- a/RadioDJViewer/Main.cs +++ b/RadioDJViewer/Main.cs @@ -154,114 +154,110 @@ namespace RadioDJViewer // Use the label's actual width and font to estimate visible characters using (Graphics g = label.CreateGraphics()) { - // Use the full label width for measurement SizeF size = g.MeasureString("W", label.Font); int chars = (int)(label.Width / size.Width); - // If the label is single-line, ensure we use the full width return Math.Max(chars, 1); } } + private bool ShouldScroll(Label label, string text) + { + return !string.IsNullOrWhiteSpace(text) && text.Length > GetVisibleChars(label); + } + + private string GetMarqueeWindow(string source, int startIndex, int length) + { + if (string.IsNullOrEmpty(source) || length <= 0) + return string.Empty; + + var builder = new StringBuilder(length); + for (int i = 0; i < length; i++) + { + builder.Append(source[(startIndex + i) % source.Length]); + } + return builder.ToString(); + } + private void SetLabelTextFull(Label label, string text) { - // Always set the full text, and let marquee logic handle scrolling label.Text = text; } + private void StartMarqueeTimers() + { + marqueeOffsetTitle = 0; + marqueeOffsetArtist = 0; + marqueeOffsetAlbum = 0; + + if (pauseTimerTitle != null) pauseTimerTitle.Stop(); + if (pauseTimerArtist != null) pauseTimerArtist.Stop(); + if (pauseTimerAlbum != null) pauseTimerAlbum.Stop(); + + if (ShouldScroll(label4, marqueeTextTitle)) marqueeTimerTitle.Start(); else marqueeTimerTitle.Stop(); + if (ShouldScroll(label5, marqueeTextArtist)) marqueeTimerArtist.Start(); else marqueeTimerArtist.Stop(); + if (ShouldScroll(label6, marqueeTextAlbum)) marqueeTimerAlbum.Start(); else marqueeTimerAlbum.Stop(); + } + + private void UpdateMarqueeLabel(Label label, System.Windows.Forms.Timer marqueeTimer, ref System.Windows.Forms.Timer pauseTimer, string text, string labelName, Func getOffset, Action setOffset, Action resetOffset) + { + string displayText = string.IsNullOrWhiteSpace(text) ? string.Empty : text; + int visibleChars = GetVisibleChars(label); + string separator = string.IsNullOrEmpty(marqueeSeparator) ? string.Empty : marqueeSeparator; + int offset = getOffset(); + + if (!ShouldScroll(label, displayText)) + { + marqueeTimer.Stop(); + if (pauseTimer != null) pauseTimer.Stop(); + resetOffset(); + SetLabelTextFull(label, displayText); + return; + } + + string scrollText = displayText + separator; + if (offset >= scrollText.Length) + offset = 0; + + label.Text = GetMarqueeWindow(scrollText, offset, visibleChars); + LogMessage($"{labelName}: separator='{separator}', scrollText='{scrollText}', offset={offset}"); + + if (offset >= displayText.Length) + { + marqueeTimer.Stop(); + var pause = pauseTimer; + if (pause == null) + { + pause = new System.Windows.Forms.Timer(); + pause.Tick += (s, args) => + { + pause.Stop(); + resetOffset(); + marqueeTimer.Start(); + }; + pauseTimer = pause; + } + + pause.Interval = marqueePauseTime; + pause.Start(); + return; + } + + setOffset(offset + 1); + } + private void MarqueeTimerTitle_Tick(object sender, EventArgs e) { - int visibleChars = GetVisibleChars(label4); - if (marqueeTextTitle.Length > visibleChars) - { - string separator = string.IsNullOrEmpty(marqueeSeparator) ? "" : marqueeSeparator; - string scrollText = marqueeTextTitle + separator; - string repeatedScrollText = scrollText + scrollText; - marqueeOffsetTitle = (marqueeOffsetTitle + 1) % scrollText.Length; - label4.Text = repeatedScrollText.Substring(marqueeOffsetTitle, visibleChars); - LogMessage($"MarqueeTitle: separator='{separator}', scrollText='{scrollText}', offset={marqueeOffsetTitle}"); - if (marqueeOffsetTitle == 0) - { - marqueeTimerTitle.Stop(); - if (pauseTimerTitle == null) - { - pauseTimerTitle = new System.Windows.Forms.Timer(); - pauseTimerTitle.Tick += (s, args) => { - pauseTimerTitle.Stop(); - marqueeTimerTitle.Start(); - }; - } - pauseTimerTitle.Interval = marqueePauseTime; - pauseTimerTitle.Start(); - } - } - else - { - SetLabelTextFull(label4, marqueeTextTitle); - } + UpdateMarqueeLabel(label4, marqueeTimerTitle, ref pauseTimerTitle, marqueeTextTitle, "MarqueeTitle", () => marqueeOffsetTitle, value => marqueeOffsetTitle = value, () => marqueeOffsetTitle = 0); } private void MarqueeTimerArtist_Tick(object sender, EventArgs e) { - int visibleChars = GetVisibleChars(label5); - if (marqueeTextArtist.Length > visibleChars) - { - string separator = string.IsNullOrEmpty(marqueeSeparator) ? "" : marqueeSeparator; - string scrollText = marqueeTextArtist + separator; - string repeatedScrollText = scrollText + scrollText; - marqueeOffsetArtist = (marqueeOffsetArtist + 1) % scrollText.Length; - label5.Text = repeatedScrollText.Substring(marqueeOffsetArtist, visibleChars); - LogMessage($"MarqueeArtist: separator='{separator}', scrollText='{scrollText}', offset={marqueeOffsetArtist}"); - if (marqueeOffsetArtist == 0) - { - marqueeTimerArtist.Stop(); - if (pauseTimerArtist == null) - { - pauseTimerArtist = new System.Windows.Forms.Timer(); - pauseTimerArtist.Tick += (s, args) => { - pauseTimerArtist.Stop(); - marqueeTimerArtist.Start(); - }; - } - pauseTimerArtist.Interval = marqueePauseTime; - pauseTimerArtist.Start(); - } - } - else - { - SetLabelTextFull(label5, marqueeTextArtist); - } + UpdateMarqueeLabel(label5, marqueeTimerArtist, ref pauseTimerArtist, marqueeTextArtist, "MarqueeArtist", () => marqueeOffsetArtist, value => marqueeOffsetArtist = value, () => marqueeOffsetArtist = 0); } private void MarqueeTimerAlbum_Tick(object sender, EventArgs e) { - int visibleChars = GetVisibleChars(label6); - if (marqueeTextAlbum.Length > visibleChars) - { - string separator = string.IsNullOrEmpty(marqueeSeparator) ? "" : marqueeSeparator; - string scrollText = marqueeTextAlbum + separator; - string repeatedScrollText = scrollText + scrollText; - marqueeOffsetAlbum = (marqueeOffsetAlbum + 1) % scrollText.Length; - label6.Text = repeatedScrollText.Substring(marqueeOffsetAlbum, visibleChars); - LogMessage($"MarqueeAlbum: separator='{separator}', scrollText='{scrollText}', offset={marqueeOffsetAlbum}"); - if (marqueeOffsetAlbum == 0) - { - marqueeTimerAlbum.Stop(); - if (pauseTimerAlbum == null) - { - pauseTimerAlbum = new System.Windows.Forms.Timer(); - pauseTimerAlbum.Tick += (s, args) => { - pauseTimerAlbum.Stop(); - marqueeTimerAlbum.Start(); - }; - } - pauseTimerAlbum.Interval = marqueePauseTime; - pauseTimerAlbum.Start(); - } - } - else - { - SetLabelTextFull(label6, marqueeTextAlbum); - } + UpdateMarqueeLabel(label6, marqueeTimerAlbum, ref pauseTimerAlbum, marqueeTextAlbum, "MarqueeAlbum", () => marqueeOffsetAlbum, value => marqueeOffsetAlbum = value, () => marqueeOffsetAlbum = 0); } private void ApiTimer_Tick(object sender, EventArgs e) @@ -494,16 +490,6 @@ namespace RadioDJViewer } } - private void StartMarqueeTimers() - { - marqueeOffsetTitle = 0; - marqueeOffsetArtist = 0; - marqueeOffsetAlbum = 0; - marqueeTimerTitle.Start(); - marqueeTimerArtist.Start(); - marqueeTimerAlbum.Start(); - } - private void StopMarqueeTimers() { marqueeTimerTitle.Stop();