diff --git a/RadioDJViewer/Main.Designer.cs b/RadioDJViewer/Main.Designer.cs index a3e17da..8f4af70 100644 --- a/RadioDJViewer/Main.Designer.cs +++ b/RadioDJViewer/Main.Designer.cs @@ -74,9 +74,9 @@ this.toolStripStatusLabel2, this.toolStripStatusLabel4, this.toolStripStatusLabel3}); - this.statusStrip1.Location = new System.Drawing.Point(0, 362); + this.statusStrip1.Location = new System.Drawing.Point(0, 309); this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(612, 26); + this.statusStrip1.Size = new System.Drawing.Size(780, 26); this.statusStrip1.TabIndex = 0; this.statusStrip1.Text = "statusStrip1"; // @@ -99,7 +99,7 @@ // this.toolStripStatusLabel4.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.toolStripStatusLabel4.Name = "toolStripStatusLabel4"; - this.toolStripStatusLabel4.Size = new System.Drawing.Size(260, 21); + this.toolStripStatusLabel4.Size = new System.Drawing.Size(344, 21); this.toolStripStatusLabel4.Spring = true; this.toolStripStatusLabel4.Text = "Profile:"; this.toolStripStatusLabel4.Click += new System.EventHandler(this.toolStripStatusLabel4_Click); @@ -107,7 +107,7 @@ // toolStripStatusLabel3 // this.toolStripStatusLabel3.Name = "toolStripStatusLabel3"; - this.toolStripStatusLabel3.Size = new System.Drawing.Size(260, 21); + this.toolStripStatusLabel3.Size = new System.Drawing.Size(344, 21); this.toolStripStatusLabel3.Spring = true; this.toolStripStatusLabel3.Text = "Song Changed Updateing"; this.toolStripStatusLabel3.TextAlign = System.Drawing.ContentAlignment.MiddleRight; @@ -119,7 +119,7 @@ this.aboutToolStripMenuItem}); this.menuStrip2.Location = new System.Drawing.Point(0, 0); this.menuStrip2.Name = "menuStrip2"; - this.menuStrip2.Size = new System.Drawing.Size(612, 25); + this.menuStrip2.Size = new System.Drawing.Size(780, 25); this.menuStrip2.TabIndex = 2; this.menuStrip2.Text = "menuStrip2"; // @@ -192,7 +192,7 @@ this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.groupBox1.Location = new System.Drawing.Point(199, 37); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(390, 205); + this.groupBox1.Size = new System.Drawing.Size(569, 205); this.groupBox1.TabIndex = 4; this.groupBox1.TabStop = false; this.groupBox1.Text = "Song Info"; @@ -200,9 +200,9 @@ // time_data_label // this.time_data_label.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.time_data_label.Location = new System.Drawing.Point(97, 160); + this.time_data_label.Location = new System.Drawing.Point(101, 159); this.time_data_label.Name = "time_data_label"; - this.time_data_label.Size = new System.Drawing.Size(266, 17); + this.time_data_label.Size = new System.Drawing.Size(437, 21); this.time_data_label.TabIndex = 10; this.time_data_label.Text = "No Data"; this.time_data_label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -212,9 +212,9 @@ this.label9.AutoSize = true; this.label9.Location = new System.Drawing.Point(17, 144); this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(357, 16); + this.label9.Size = new System.Drawing.Size(539, 16); this.label9.TabIndex = 9; - this.label9.Text = "――――――――――――――――――――――――――――――――――――――――――――――――――"; + this.label9.Text = "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"; this.label9.TextAlign = System.Drawing.ContentAlignment.BottomCenter; // // time_label @@ -233,9 +233,9 @@ this.label8.AutoSize = true; this.label8.Location = new System.Drawing.Point(20, 103); this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(357, 16); + this.label8.Size = new System.Drawing.Size(539, 16); this.label8.TabIndex = 7; - this.label8.Text = "――――――――――――――――――――――――――――――――――――――――――――――――――"; + this.label8.Text = "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"; this.label8.TextAlign = System.Drawing.ContentAlignment.BottomCenter; // // label7 @@ -243,36 +243,43 @@ this.label7.AutoSize = true; this.label7.Location = new System.Drawing.Point(19, 61); this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(357, 16); + this.label7.Size = new System.Drawing.Size(539, 16); this.label7.TabIndex = 6; - this.label7.Text = "――――――――――――――――――――――――――――――――――――――――――――――――――"; + this.label7.Text = "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"; + this.label7.Click += new System.EventHandler(this.label7_Click_1); // // album_data // + this.album_data.AutoEllipsis = true; + this.album_data.AutoSize = false; this.album_data.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.album_data.Location = new System.Drawing.Point(99, 121); + this.album_data.Location = new System.Drawing.Point(100, 119); this.album_data.Name = "album_data"; - this.album_data.Size = new System.Drawing.Size(266, 17); + this.album_data.Size = new System.Drawing.Size(443, 19); this.album_data.TabIndex = 5; this.album_data.Text = "No album"; this.album_data.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // artist_data // + this.artist_data.AutoEllipsis = true; + this.artist_data.AutoSize = false; this.artist_data.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.artist_data.Location = new System.Drawing.Point(99, 76); this.artist_data.Name = "artist_data"; - this.artist_data.Size = new System.Drawing.Size(266, 17); + this.artist_data.Size = new System.Drawing.Size(433, 23); this.artist_data.TabIndex = 4; this.artist_data.Text = "No artist"; this.artist_data.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // title_data // + this.title_data.AutoEllipsis = true; + this.title_data.AutoSize = false; this.title_data.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.title_data.Location = new System.Drawing.Point(99, 33); + this.title_data.Location = new System.Drawing.Point(97, 33); this.title_data.Name = "title_data"; - this.title_data.Size = new System.Drawing.Size(266, 16); + this.title_data.Size = new System.Drawing.Size(443, 20); this.title_data.TabIndex = 3; this.title_data.Text = "No title"; this.title_data.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -309,7 +316,7 @@ // // button1 // - this.button1.Location = new System.Drawing.Point(62, 281); + this.button1.Location = new System.Drawing.Point(425, 254); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(99, 42); this.button1.TabIndex = 5; @@ -319,7 +326,7 @@ // // button2 // - this.button2.Location = new System.Drawing.Point(180, 281); + this.button2.Location = new System.Drawing.Point(577, 253); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(99, 42); this.button2.TabIndex = 6; @@ -330,7 +337,7 @@ // uicolor // this.uicolor.Image = global::RadioDJViewer.Properties.Resources.MdiWeatherNight; - this.uicolor.Location = new System.Drawing.Point(572, 327); + this.uicolor.Location = new System.Drawing.Point(740, 262); this.uicolor.Name = "uicolor"; this.uicolor.Size = new System.Drawing.Size(28, 23); this.uicolor.TabIndex = 7; @@ -347,7 +354,7 @@ // profile_drop_box // this.profile_drop_box.FormattingEnabled = true; - this.profile_drop_box.Location = new System.Drawing.Point(62, 329); + this.profile_drop_box.Location = new System.Drawing.Point(62, 268); this.profile_drop_box.Name = "profile_drop_box"; this.profile_drop_box.Size = new System.Drawing.Size(217, 21); this.profile_drop_box.TabIndex = 8; @@ -355,7 +362,7 @@ // profile_label // this.profile_label.AutoSize = true; - this.profile_label.Location = new System.Drawing.Point(12, 332); + this.profile_label.Location = new System.Drawing.Point(12, 272); this.profile_label.Name = "profile_label"; this.profile_label.Size = new System.Drawing.Size(44, 13); this.profile_label.TabIndex = 9; @@ -364,7 +371,7 @@ // // load_profile_button // - this.load_profile_button.Location = new System.Drawing.Point(285, 327); + this.load_profile_button.Location = new System.Drawing.Point(292, 267); this.load_profile_button.Name = "load_profile_button"; this.load_profile_button.Size = new System.Drawing.Size(75, 23); this.load_profile_button.TabIndex = 10; @@ -375,7 +382,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(612, 388); + this.ClientSize = new System.Drawing.Size(780, 335); this.Controls.Add(this.load_profile_button); this.Controls.Add(this.profile_label); this.Controls.Add(this.profile_drop_box); diff --git a/RadioDJViewer/Main.cs b/RadioDJViewer/Main.cs index c264ea6..8029630 100644 --- a/RadioDJViewer/Main.cs +++ b/RadioDJViewer/Main.cs @@ -34,6 +34,8 @@ namespace RadioDJViewer private string selectedFolderPath = string.Empty; private string outputFolderPath = string.Empty; private bool isConnected = false; + private bool _isDisconnecting = false; + private CancellationTokenSource _connectionCts = new CancellationTokenSource(); private string currentProfile = "Default"; private string currentSongImagePath = string.Empty; // Path to the current song image private string defaultImagePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "default.jpg"); @@ -48,23 +50,6 @@ namespace RadioDJViewer private System.Windows.Forms.Timer playbackTimer; private string lastApiXml = null; - private System.Windows.Forms.Timer marqueeTimerTitle; - private System.Windows.Forms.Timer marqueeTimerArtist; - private System.Windows.Forms.Timer marqueeTimerAlbum; - private int marqueeOffsetTitle = 0; - private int marqueeOffsetArtist = 0; - private int marqueeOffsetAlbum = 0; - private string marqueeTextTitle = ""; - private string marqueeTextArtist = ""; - private string marqueeTextAlbum = ""; - - private System.Windows.Forms.Timer pauseTimerTitle; - private System.Windows.Forms.Timer pauseTimerArtist; - private System.Windows.Forms.Timer pauseTimerAlbum; - - private int marqueeScrollSpeed = 100; // Default to Medium - private int marqueePauseTime = 6000; // Default to 6 seconds - private string marqueeSeparator = " | "; // Default separator private bool loggingEnabled = false; private string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RadioDJViewer.log"); @@ -81,23 +66,24 @@ namespace RadioDJViewer playbackTimer = new System.Windows.Forms.Timer(); playbackTimer.Interval = 250; playbackTimer.Tick += PlaybackTimer_Tick; - // Marquee timers for each label - marqueeTimerTitle = new System.Windows.Forms.Timer(); - marqueeTimerTitle.Interval = marqueeScrollSpeed; - marqueeTimerTitle.Tick += MarqueeTimerTitle_Tick; - marqueeTimerArtist = new System.Windows.Forms.Timer(); - marqueeTimerArtist.Interval = marqueeScrollSpeed; - marqueeTimerArtist.Tick += MarqueeTimerArtist_Tick; - marqueeTimerAlbum = new System.Windows.Forms.Timer(); - marqueeTimerAlbum.Interval = marqueeScrollSpeed; - marqueeTimerAlbum.Tick += MarqueeTimerAlbum_Tick; // Wire up dark mode button this.uicolor.Click += Uicolor_Click; this.load_profile_button.Click += load_profile_button_Click; PopulateProfileDropBox(); UpdateTheme(); - // Auto-load profiles if profiles.json exists - AutoLoadProfiles(); + } + + public void SetSongMetadataLabels(string title, string artist, string album) + { + if (InvokeRequired) + { + BeginInvoke((Action)(() => SetSongMetadataLabels(title, artist, album))); + return; + } + + title_data.Text = title; + artist_data.Text = artist; + album_data.Text = album; } private void EnsureDefaultImageExists() @@ -113,32 +99,6 @@ namespace RadioDJViewer } } - public void SetMarqueeScrollSpeed(string speed) - { - switch (speed) - { - case "Very Slow": marqueeScrollSpeed = 300; break; - case "Slow": marqueeScrollSpeed = 200; break; - case "Medium": marqueeScrollSpeed = 100; break; - case "Fast": marqueeScrollSpeed = 60; break; - case "Very Fast": marqueeScrollSpeed = 30; break; - default: marqueeScrollSpeed = 100; break; - } - marqueeTimerTitle.Interval = marqueeScrollSpeed; - marqueeTimerArtist.Interval = marqueeScrollSpeed; - marqueeTimerAlbum.Interval = marqueeScrollSpeed; - } - - public void SetMarqueePauseTime(int seconds) - { - marqueePauseTime = seconds * 1000; - } - - public void SetMarqueeSeparator(string separator) - { - marqueeSeparator = separator; - } - private void LogMessage(string message) { if (!loggingEnabled) return; @@ -149,117 +109,6 @@ namespace RadioDJViewer catch { } } - private int GetVisibleChars(Label label) - { - // Use the label's actual width and font to estimate visible characters - using (Graphics g = label.CreateGraphics()) - { - SizeF size = g.MeasureString("W", label.Font); - int chars = (int)(label.Width / size.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) - { - 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(title_data, marqueeTextTitle)) marqueeTimerTitle.Start(); else marqueeTimerTitle.Stop(); - if (ShouldScroll(artist_data, marqueeTextArtist)) marqueeTimerArtist.Start(); else marqueeTimerArtist.Stop(); - if (ShouldScroll(album_data, 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) - { - UpdateMarqueeLabel(title_data, marqueeTimerTitle, ref pauseTimerTitle, marqueeTextTitle, "MarqueeTitle", () => marqueeOffsetTitle, value => marqueeOffsetTitle = value, () => marqueeOffsetTitle = 0); - } - - private void MarqueeTimerArtist_Tick(object sender, EventArgs e) - { - UpdateMarqueeLabel(artist_data, marqueeTimerArtist, ref pauseTimerArtist, marqueeTextArtist, "MarqueeArtist", () => marqueeOffsetArtist, value => marqueeOffsetArtist = value, () => marqueeOffsetArtist = 0); - } - - private void MarqueeTimerAlbum_Tick(object sender, EventArgs e) - { - UpdateMarqueeLabel(album_data, marqueeTimerAlbum, ref pauseTimerAlbum, marqueeTextAlbum, "MarqueeAlbum", () => marqueeOffsetAlbum, value => marqueeOffsetAlbum = value, () => marqueeOffsetAlbum = 0); - } - private void ApiTimer_Tick(object sender, EventArgs e) { if (isConnected) @@ -270,7 +119,7 @@ namespace RadioDJViewer private async Task PollRestApi() { - if (loadedProfile == null) return; + if (loadedProfile == null || _isDisconnecting || _connectionCts.IsCancellationRequested) return; string url = loadedProfile.UrlFormat; if (!string.IsNullOrWhiteSpace(url)) { @@ -284,34 +133,24 @@ namespace RadioDJViewer } try { - var client = new System.Net.Http.HttpClient(); - var response = await client.GetAsync(url); - if (response.IsSuccessStatusCode) + using (var client = new System.Net.Http.HttpClient()) { - var xml = await response.Content.ReadAsStringAsync(); - lastApiXml = xml; - ParseAndDisplaySongInfo(xml); - } - } - catch { } - } + var response = await client.GetAsync(url); + if (_isDisconnecting || _connectionCts.IsCancellationRequested || !isConnected) + return; - private void AutoLoadProfiles() - { - string profilesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "profiles.json"); - if (File.Exists(profilesPath)) - { - var profileNames = ProfileStorage.GetProfileNames(); - if (profileNames.Count > 0) - { - // Optionally, load the first profile by default - var profile = ProfileStorage.LoadProfile(profileNames[0]); - if (profile != null) + if (response.IsSuccessStatusCode) { - LoadProfile(profile); + var xml = await response.Content.ReadAsStringAsync(); + if (_isDisconnecting || _connectionCts.IsCancellationRequested || !isConnected) + return; + + lastApiXml = xml; + ParseAndDisplaySongInfo(xml); } } } + catch { } } private async void button1_Click(object sender, EventArgs e) @@ -330,7 +169,9 @@ namespace RadioDJViewer private void button2_Click(object sender, EventArgs e) { // Disconnect + _isDisconnecting = true; isConnected = false; + try { _connectionCts.Cancel(); } catch { } apiTimer.Stop(); playbackTimer.Stop(); _playbackElapsedSeconds = 0; @@ -352,6 +193,8 @@ namespace RadioDJViewer catch { } ClearStatusMessage(); UpdateStatusBar(); + _isDisconnecting = false; + _connectionCts = new CancellationTokenSource(); } private async Task ConnectToRestApi() @@ -380,27 +223,37 @@ namespace RadioDJViewer } try { - var client = new System.Net.Http.HttpClient(); - var response = await client.GetAsync(url); - if (response.IsSuccessStatusCode) + _isDisconnecting = false; + _connectionCts = new CancellationTokenSource(); + using (var client = new System.Net.Http.HttpClient()) { - var xml = await response.Content.ReadAsStringAsync(); - ParseAndDisplaySongInfo(xml); - try + var response = await client.GetAsync(url); + if (_isDisconnecting || _connectionCts.IsCancellationRequested) + return; + + if (response.IsSuccessStatusCode) { - _currentTrackKey = $"{marqueeTextArtist}|{marqueeTextTitle}"; + var xml = await response.Content.ReadAsStringAsync(); + if (_isDisconnecting || _connectionCts.IsCancellationRequested) + return; + + ParseAndDisplaySongInfo(xml); + try + { + _currentTrackKey = $"{_previousToastArtist}|{_previousToastTitle}"; + } + catch { } + isConnected = true; + // Clear the 'Connecting...' persistent message and show connected + ClearStatusMessage(); + UpdateStatusBar(); + // Start web server immediately after API connection if profile requests it + StartWidgetServerIfEnabled(); + } + else + { + isConnected = false; } - catch { } - isConnected = true; - // Clear the 'Connecting...' persistent message and show connected - ClearStatusMessage(); - UpdateStatusBar(); - // Start web server immediately after API connection if profile requests it - StartWidgetServerIfEnabled(); - } - else - { - isConnected = false; } } catch (Exception ex) @@ -411,7 +264,6 @@ namespace RadioDJViewer UpdateStatusBar(); } - // Call this method after parsing song info, assuming image path is available from profile or API private void UpdateCurrentSongImage(string imageName) { string imagePath = string.Empty; @@ -490,13 +342,6 @@ namespace RadioDJViewer } } - private void StopMarqueeTimers() - { - marqueeTimerTitle.Stop(); - marqueeTimerArtist.Stop(); - marqueeTimerAlbum.Stop(); - } - private void PlaybackTimer_Tick(object sender, EventArgs e) { UpdatePlaybackDisplay(); @@ -577,6 +422,9 @@ namespace RadioDJViewer { try { + if (_isDisconnecting || _connectionCts.IsCancellationRequested || IsDisposed) + return; + var doc = new XmlDocument(); doc.LoadXml(xml); // Parse title, artist, album from XML (case-insensitive) @@ -588,44 +436,29 @@ namespace RadioDJViewer string elapsed = doc.SelectSingleNode("//*[translate(local-name(), 'ELAPSED', 'elapsed')='elapsed']")?.InnerText; string duration = doc.SelectSingleNode("//*[translate(local-name(), 'DURATION', 'duration')='duration']")?.InnerText; - marqueeTextTitle = !string.IsNullOrWhiteSpace(title) ? title : "No title"; - marqueeTextArtist = !string.IsNullOrWhiteSpace(artist) ? artist : "No artist"; - marqueeTextAlbum = !string.IsNullOrWhiteSpace(album) ? album : "No album"; - - // Explicitly set label text on UI thread - if (this.InvokeRequired) - { - this.BeginInvoke(new Action(() => - { - title_data.Text = marqueeTextTitle; - artist_data.Text = marqueeTextArtist; - album_data.Text = marqueeTextAlbum; - })); - } - else - { - title_data.Text = marqueeTextTitle; - artist_data.Text = marqueeTextArtist; - album_data.Text = marqueeTextAlbum; - } - - StartMarqueeTimers(); + string titleText = !string.IsNullOrWhiteSpace(title) ? title : "No title"; + string artistText = !string.IsNullOrWhiteSpace(artist) ? artist : "No artist"; + string albumText = !string.IsNullOrWhiteSpace(album) ? album : "No album"; + bool trackChanged = !string.Equals(titleText, _previousToastTitle, StringComparison.OrdinalIgnoreCase) + || !string.Equals(artistText, _previousToastArtist, StringComparison.OrdinalIgnoreCase); - UpdatePlaybackState($"{marqueeTextArtist}|{marqueeTextTitle}", elapsed, duration); + SetSongMetadataLabels(titleText, artistText, albumText); + + UpdatePlaybackState($"{artistText}|{titleText}", elapsed, duration); // Write to output files if (!string.IsNullOrEmpty(outputFolderPath)) { - File.WriteAllText(Path.Combine(outputFolderPath, "title.txt"), marqueeTextTitle); - File.WriteAllText(Path.Combine(outputFolderPath, "artist.txt"), marqueeTextArtist); - File.WriteAllText(Path.Combine(outputFolderPath, "album.txt"), marqueeTextAlbum); + File.WriteAllText(Path.Combine(outputFolderPath, "title.txt"), titleText); + File.WriteAllText(Path.Combine(outputFolderPath, "artist.txt"), artistText); + File.WriteAllText(Path.Combine(outputFolderPath, "album.txt"), albumText); } // Update in-memory cache for widget server try { - WidgetServer.CachedArtist = marqueeTextArtist ?? string.Empty; - WidgetServer.CachedTitle = marqueeTextTitle ?? string.Empty; + WidgetServer.CachedArtist = artistText ?? string.Empty; + WidgetServer.CachedTitle = titleText ?? string.Empty; byte[] imgBytes = null; // Prefer album art from main images folder @@ -675,32 +508,24 @@ namespace RadioDJViewer UpdateCurrentSongImage(null); } - HandleToastForTrackChange(title, artist); + if (trackChanged) + { +#if DEBUG + System.Diagnostics.Debug.WriteLine($"[Toast] Track change detected. newTitle='{titleText}', newArtist='{artistText}'"); +#endif + HandleToastForTrackChange(titleText, artistText); + _previousToastTitle = titleText; + _previousToastArtist = artistText; + } } catch { - marqueeTextTitle = "No title"; - marqueeTextArtist = "No artist"; - marqueeTextAlbum = "No album"; - - // Explicitly set label text on UI thread in error case - if (this.InvokeRequired) - { - this.BeginInvoke(new Action(() => - { - title_data.Text = marqueeTextTitle; - artist_data.Text = marqueeTextArtist; - album_data.Text = marqueeTextAlbum; - })); - } - else - { - title_data.Text = marqueeTextTitle; - artist_data.Text = marqueeTextArtist; - album_data.Text = marqueeTextAlbum; - } - - StartMarqueeTimers(); + if (_isDisconnecting || _connectionCts.IsCancellationRequested || IsDisposed) + return; + + SetSongMetadataLabels("No title", "No artist", "No album"); + _previousToastTitle = "No title"; + _previousToastArtist = "No artist"; playbackTimer.Stop(); _playbackElapsedSeconds = 0; _playbackDurationSeconds = 0; @@ -796,7 +621,7 @@ namespace RadioDJViewer if (widgetServer == null) { int port = loadedProfile.WebServerPort > 0 ? loadedProfile.WebServerPort : 8080; - widgetServer = new WidgetServer(port, () => marqueeTextArtist, () => marqueeTextTitle, () => this.currentSongImagePath ?? this.defaultImagePath); + widgetServer = new WidgetServer(port, () => _previousToastArtist, () => _previousToastTitle, () => this.currentSongImagePath ?? this.defaultImagePath); } widgetServer.Start(); widgetRunning = true; @@ -844,19 +669,41 @@ namespace RadioDJViewer loadedProfile = profile; int pollingRate = profile.PollingRateSeconds > 0 ? profile.PollingRateSeconds : 3; apiTimer.Interval = pollingRate * 1000; - SetMarqueeScrollSpeed(profile.MarqueeScrollSpeed ?? "Medium"); - SetMarqueePauseTime(profile.MarqueePauseTime > 0 ? profile.MarqueePauseTime : 6); - SetMarqueeSeparator(profile.MarqueeSeparator ?? " | "); - if (pauseTimerTitle != null) pauseTimerTitle.Interval = marqueePauseTime; - if (pauseTimerArtist != null) pauseTimerArtist.Interval = marqueePauseTime; - if (pauseTimerAlbum != null) pauseTimerAlbum.Interval = marqueePauseTime; - marqueeTimerTitle.Interval = marqueeScrollSpeed; - marqueeTimerArtist.Interval = marqueeScrollSpeed; - marqueeTimerAlbum.Interval = marqueeScrollSpeed; WidgetServer.CachedClockVisibility = profile.ClockVisibilityEnabled; UpdateStatusBar(); } + private void PopulateProfileDropBox() + { + profile_drop_box.Items.Clear(); + var profileNames = ProfileStorage.GetProfileNames(); + profile_drop_box.Items.AddRange(profileNames.ToArray()); + string currentProfile = GetCurrentProfileName(); + if (!string.IsNullOrEmpty(currentProfile) && profileNames.Contains(currentProfile)) + profile_drop_box.SelectedItem = currentProfile; + else if (profile_drop_box.Items.Count > 0) + profile_drop_box.SelectedIndex = 0; + } + + private void load_profile_button_Click(object sender, EventArgs e) + { + if (profile_drop_box.SelectedItem != null) + { + var profile = ProfileStorage.LoadProfile(profile_drop_box.SelectedItem.ToString()); + if (profile != null) + { + LoadProfile(profile); + UpdateStatusBar(); + MessageBox.Show($"Profile '{profile.Name}' loaded.", "Profile Loaded", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } + + public string GetCurrentProfileName() + { + return currentProfile; + } + private void Uicolor_Click(object sender, EventArgs e) { isDarkMode = !isDarkMode; @@ -913,80 +760,21 @@ namespace RadioDJViewer } } - private void label7_Click(object sender, EventArgs e) - { - } - - private void label9_Click(object sender, EventArgs e) - { - } - - public string GetCurrentProfileName() - { - return currentProfile; - } - - private void PopulateProfileDropBox() - { - profile_drop_box.Items.Clear(); - var profileNames = ProfileStorage.GetProfileNames(); - profile_drop_box.Items.AddRange(profileNames.ToArray()); - string currentProfile = GetCurrentProfileName(); - if (!string.IsNullOrEmpty(currentProfile) && profileNames.Contains(currentProfile)) - profile_drop_box.SelectedItem = currentProfile; - else if (profile_drop_box.Items.Count > 0) - profile_drop_box.SelectedIndex = 0; - } - - private void load_profile_button_Click(object sender, EventArgs e) - { - if (profile_drop_box.SelectedItem != null) - { - var profile = ProfileStorage.LoadProfile(profile_drop_box.SelectedItem.ToString()); - if (profile != null) - { - LoadProfile(profile); - UpdateStatusBar(); - MessageBox.Show($"Profile '{profile.Name}' loaded.", "Profile Loaded", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - } - } - - private string FormatTimeDisplay(string elapsedSeconds, string durationSeconds) - { - double elapsed; - double duration; - if (!TryParseSeconds(elapsedSeconds, out elapsed) || !TryParseSeconds(durationSeconds, out duration)) - { - return "No Data"; - } - - return FormatTimeDisplay(elapsed, duration); - } - private string FormatTimeDisplay(double elapsed, double duration) { - // If duration is zero or negative, show "No Data" if (duration <= 0) { return "No Data"; } - // Clamp elapsed to [0, duration] if (elapsed < 0) elapsed = 0; if (elapsed > duration) elapsed = duration; - // Convert to integers (seconds only) int elapsedInt = (int)elapsed; int durationInt = (int)duration; - - // Convert seconds to MM:SS format - string elapsedFormatted = FormatSeconds(elapsedInt); - string durationFormatted = FormatSeconds(durationInt); - - return $"{elapsedFormatted} / {durationFormatted}"; + return $"{FormatSeconds(elapsedInt)} / {FormatSeconds(durationInt)}"; } private string FormatSeconds(int seconds) @@ -1001,43 +789,6 @@ namespace RadioDJViewer return loadedProfile != null && loadedProfile.ToastNotificationsEnabled; } - private void HandleToastForTrackChange(string title, string artist) - { - string normalizedTitle = NormalizeTrackMetadata(title); - string normalizedArtist = NormalizeTrackMetadata(artist); - - if (string.Equals(normalizedTitle, _previousToastTitle, StringComparison.OrdinalIgnoreCase) && - string.Equals(normalizedArtist, _previousToastArtist, StringComparison.OrdinalIgnoreCase)) - { - return; - } - - _previousToastTitle = normalizedTitle; - _previousToastArtist = normalizedArtist; - - if (!IsToastEnabledForActiveProfile()) - return; - - if (!HasValidTrackMetadata(normalizedTitle, normalizedArtist)) - return; - - try - { - string outputImagePath = GetProfileOutputImagePath(); -#if DEBUG - System.Diagnostics.Debug.WriteLine($"[Toast] Track change accepted. title='{normalizedTitle}', artist='{normalizedArtist}', imagePath='{outputImagePath}'"); -#endif - ShowTrackChangeToast(normalizedTitle, normalizedArtist, outputImagePath); - } - catch (Exception ex) - { -#if DEBUG - System.Diagnostics.Debug.WriteLine($"[Toast] Trigger error: {ex}"); - MessageBox.Show($"Toast trigger failed: {ex.Message}", "Toast Debug", MessageBoxButtons.OK, MessageBoxIcon.Warning); -#endif - } - } - private static string NormalizeTrackMetadata(string value) { return string.IsNullOrWhiteSpace(value) ? string.Empty : value.Trim(); @@ -1080,12 +831,56 @@ namespace RadioDJViewer private void ShowTrackChangeToast(string title, string artist, string outputImagePath) { + if (IsDisposed || _isDisconnecting || !isConnected) + return; + string safeTitle = string.IsNullOrWhiteSpace(title) ? "No title" : title; string safeArtist = string.IsNullOrWhiteSpace(artist) ? "No artist" : artist; DateTime now = DateTime.Now; string attribution = $"Date: {now:MM/dd/yyyy} | Time: {now:hh:mm tt}"; ToastNotificationService.ShowTrackChangeToast(safeTitle, safeArtist, attribution, outputImagePath); } + + private void HandleToastForTrackChange(string title, string artist) + { + if (IsDisposed || _isDisconnecting || !isConnected) + return; + + string normalizedTitle = NormalizeTrackMetadata(title); + string normalizedArtist = NormalizeTrackMetadata(artist); + + if (!IsToastEnabledForActiveProfile()) + return; + + if (!HasValidTrackMetadata(normalizedTitle, normalizedArtist)) + return; + + try + { + string outputImagePath = GetProfileOutputImagePath(); + System.Diagnostics.Debug.WriteLine($"[Toast] Firing toast. title='{normalizedTitle}', artist='{normalizedArtist}', imagePath='{outputImagePath}'"); + ShowTrackChangeToast(normalizedTitle, normalizedArtist, outputImagePath); + } + catch (Exception ex) + { +#if DEBUG + System.Diagnostics.Debug.WriteLine($"[Toast] Trigger error: {ex}"); + MessageBox.Show($"Toast trigger failed: {ex.Message}", "Toast Debug", MessageBoxButtons.OK, MessageBoxIcon.Warning); +#endif + } + } + + private void label9_Click(object sender, EventArgs e) + { + } + + private void label7_Click(object sender, EventArgs e) + { + } + + private void label7_Click_1(object sender, EventArgs e) + { + } } internal static class ToastNotificationService diff --git a/RadioDJViewer/Properties/AssemblyInfo.cs b/RadioDJViewer/Properties/AssemblyInfo.cs index b1230ae..cdee07a 100644 --- a/RadioDJViewer/Properties/AssemblyInfo.cs +++ b/RadioDJViewer/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("1.14.2")] -[assembly: AssemblyFileVersion("1.14.2")] +[assembly: AssemblyVersion("1.14.3")] +[assembly: AssemblyFileVersion("1.14.3")] diff --git a/RadioDJViewer/radiodj-restapi-template.Designer.cs b/RadioDJViewer/radiodj-restapi-template.Designer.cs index 3919b4e..45728b0 100644 --- a/RadioDJViewer/radiodj-restapi-template.Designer.cs +++ b/RadioDJViewer/radiodj-restapi-template.Designer.cs @@ -54,7 +54,7 @@ this.button6 = new System.Windows.Forms.Button(); this.label6 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label(); - this.textBox7 = new System.Windows.Forms.TextBox(); + this.polling_rate_textbox = new System.Windows.Forms.TextBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.toast_box_group_box = new System.Windows.Forms.GroupBox(); this.toast_check_box_enable = new System.Windows.Forms.CheckBox(); @@ -66,13 +66,6 @@ this.web_server_port_label = new System.Windows.Forms.Label(); this.web_server_label = new System.Windows.Forms.Label(); this.web_server_checkbox = new System.Windows.Forms.CheckBox(); - this.label13 = new System.Windows.Forms.Label(); - this.comboBoxScrollSpeed = new System.Windows.Forms.ComboBox(); - this.textBoxPauseTime = new System.Windows.Forms.TextBox(); - this.separatingcharacterformatbox = new System.Windows.Forms.TextBox(); - this.textBox9 = new System.Windows.Forms.TextBox(); - this.label9 = new System.Windows.Forms.Label(); - this.label8 = new System.Windows.Forms.Label(); this.label12 = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.groupBox3.SuspendLayout(); @@ -110,7 +103,7 @@ // // ok_button_master // - this.ok_button_master.Location = new System.Drawing.Point(54, 729); + this.ok_button_master.Location = new System.Drawing.Point(54, 684); this.ok_button_master.Name = "ok_button_master"; this.ok_button_master.Size = new System.Drawing.Size(157, 23); this.ok_button_master.TabIndex = 1; @@ -119,7 +112,7 @@ // // button2 // - this.button2.Location = new System.Drawing.Point(302, 729); + this.button2.Location = new System.Drawing.Point(301, 684); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(157, 23); this.button2.TabIndex = 2; @@ -193,7 +186,7 @@ // // button3 // - this.button3.Location = new System.Drawing.Point(62, 587); + this.button3.Location = new System.Drawing.Point(66, 537); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(120, 30); this.button3.TabIndex = 8; @@ -202,7 +195,7 @@ // // button4 // - this.button4.Location = new System.Drawing.Point(309, 587); + this.button4.Location = new System.Drawing.Point(279, 537); this.button4.Name = "button4"; this.button4.Size = new System.Drawing.Size(120, 30); this.button4.TabIndex = 9; @@ -215,9 +208,9 @@ this.groupBox3.Controls.Add(this.labelOutputFolderPath); this.groupBox3.Controls.Add(this.textBox5); this.groupBox3.Controls.Add(this.label10); - this.groupBox3.Location = new System.Drawing.Point(22, 413); + this.groupBox3.Location = new System.Drawing.Point(26, 368); this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(482, 115); + this.groupBox3.Size = new System.Drawing.Size(476, 115); this.groupBox3.TabIndex = 12; this.groupBox3.TabStop = false; this.groupBox3.Text = "Output Setting"; @@ -274,17 +267,17 @@ // // button6 // - this.button6.Location = new System.Drawing.Point(23, 269); + this.button6.Location = new System.Drawing.Point(91, 234); this.button6.Name = "button6"; this.button6.Size = new System.Drawing.Size(140, 23); this.button6.TabIndex = 18; - this.button6.Text = "Select Main Image Folder"; + this.button6.Text = "Main Image Folder"; this.button6.UseVisualStyleBackColor = true; // // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(169, 274); + this.label6.Location = new System.Drawing.Point(306, 239); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(93, 13); this.label6.TabIndex = 19; @@ -299,27 +292,20 @@ this.label7.TabIndex = 20; this.label7.Text = "Polling Rate (in seconds)"; // - // textBox7 + // polling_rate_textbox // - this.textBox7.Location = new System.Drawing.Point(150, 208); - this.textBox7.Name = "textBox7"; - this.textBox7.Size = new System.Drawing.Size(63, 20); - this.textBox7.TabIndex = 21; + this.polling_rate_textbox.Location = new System.Drawing.Point(150, 208); + this.polling_rate_textbox.Name = "polling_rate_textbox"; + this.polling_rate_textbox.Size = new System.Drawing.Size(49, 20); + this.polling_rate_textbox.TabIndex = 21; // // groupBox2 // this.groupBox2.Controls.Add(this.toast_box_group_box); this.groupBox2.Controls.Add(this.web_server_settings_groupbox); - this.groupBox2.Controls.Add(this.label13); - this.groupBox2.Controls.Add(this.comboBoxScrollSpeed); - this.groupBox2.Controls.Add(this.textBoxPauseTime); - this.groupBox2.Controls.Add(this.separatingcharacterformatbox); this.groupBox2.Controls.Add(this.textBox6); this.groupBox2.Controls.Add(this.label11); - this.groupBox2.Controls.Add(this.textBox9); - this.groupBox2.Controls.Add(this.label9); - this.groupBox2.Controls.Add(this.label8); - this.groupBox2.Controls.Add(this.textBox7); + this.groupBox2.Controls.Add(this.polling_rate_textbox); this.groupBox2.Controls.Add(this.label7); this.groupBox2.Controls.Add(this.label6); this.groupBox2.Controls.Add(this.button6); @@ -336,7 +322,7 @@ this.groupBox2.Controls.Add(this.comboBox1); this.groupBox2.Location = new System.Drawing.Point(12, 100); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(519, 623); + this.groupBox2.Size = new System.Drawing.Size(519, 578); this.groupBox2.TabIndex = 3; this.groupBox2.TabStop = false; this.groupBox2.Text = "Profiles"; @@ -345,7 +331,7 @@ // this.toast_box_group_box.Controls.Add(this.toast_check_box_enable); this.toast_box_group_box.Controls.Add(this.toast_label); - this.toast_box_group_box.Location = new System.Drawing.Point(118, 534); + this.toast_box_group_box.Location = new System.Drawing.Point(120, 489); this.toast_box_group_box.Name = "toast_box_group_box"; this.toast_box_group_box.Size = new System.Drawing.Size(248, 42); this.toast_box_group_box.TabIndex = 4; @@ -379,9 +365,9 @@ this.web_server_settings_groupbox.Controls.Add(this.web_server_port_label); this.web_server_settings_groupbox.Controls.Add(this.web_server_label); this.web_server_settings_groupbox.Controls.Add(this.web_server_checkbox); - this.web_server_settings_groupbox.Location = new System.Drawing.Point(31, 308); + this.web_server_settings_groupbox.Location = new System.Drawing.Point(26, 263); this.web_server_settings_groupbox.Name = "web_server_settings_groupbox"; - this.web_server_settings_groupbox.Size = new System.Drawing.Size(471, 99); + this.web_server_settings_groupbox.Size = new System.Drawing.Size(476, 99); this.web_server_settings_groupbox.TabIndex = 35; this.web_server_settings_groupbox.TabStop = false; this.web_server_settings_groupbox.Text = "Web Server Settings"; @@ -440,70 +426,6 @@ this.web_server_checkbox.Text = "Enabled"; this.web_server_checkbox.UseVisualStyleBackColor = true; // - // label13 - // - this.label13.AutoSize = true; - this.label13.Location = new System.Drawing.Point(20, 240); - this.label13.Name = "label13"; - this.label13.Size = new System.Drawing.Size(142, 13); - this.label13.TabIndex = 32; - this.label13.Text = "Separating Character Format"; - // - // comboBoxScrollSpeed - // - this.comboBoxScrollSpeed.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxScrollSpeed.FormattingEnabled = true; - this.comboBoxScrollSpeed.Items.AddRange(new object[] { - "Very Slow", - "Slow", - "Medium", - "Fast", - "Very Fast"}); - this.comboBoxScrollSpeed.Location = new System.Drawing.Point(382, 207); - this.comboBoxScrollSpeed.Name = "comboBoxScrollSpeed"; - this.comboBoxScrollSpeed.Size = new System.Drawing.Size(97, 21); - this.comboBoxScrollSpeed.TabIndex = 29; - // - // textBoxPauseTime - // - this.textBoxPauseTime.Location = new System.Drawing.Point(382, 237); - this.textBoxPauseTime.Name = "textBoxPauseTime"; - this.textBoxPauseTime.Size = new System.Drawing.Size(97, 20); - this.textBoxPauseTime.TabIndex = 30; - // - // separatingcharacterformatbox - // - this.separatingcharacterformatbox.Location = new System.Drawing.Point(164, 237); - this.separatingcharacterformatbox.Name = "separatingcharacterformatbox"; - this.separatingcharacterformatbox.Size = new System.Drawing.Size(49, 20); - this.separatingcharacterformatbox.TabIndex = 31; - // - // textBox9 - // - this.textBox9.Location = new System.Drawing.Point(382, 237); - this.textBox9.Name = "textBox9"; - this.textBox9.Size = new System.Drawing.Size(97, 20); - this.textBox9.TabIndex = 25; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(239, 240); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(119, 13); - this.label9.TabIndex = 24; - this.label9.Text = "Pause time (in seconds)"; - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(239, 211); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(127, 13); - this.label8.TabIndex = 22; - this.label8.Text = "Scroll Speed (in Main UI)"; - this.label8.Click += new System.EventHandler(this.label8_Click); - // // label12 // this.label12.AutoSize = true; @@ -517,7 +439,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(542, 764); + this.ClientSize = new System.Drawing.Size(542, 716); this.Controls.Add(this.groupBox2); this.Controls.Add(this.button2); this.Controls.Add(this.ok_button_master); @@ -566,18 +488,11 @@ private System.Windows.Forms.Button button6; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label7; - private System.Windows.Forms.TextBox textBox7; + private System.Windows.Forms.TextBox polling_rate_textbox; private System.Windows.Forms.GroupBox groupBox2; - private System.Windows.Forms.Label label8; - private System.Windows.Forms.TextBox textBox9; - private System.Windows.Forms.Label label9; private System.Windows.Forms.ComboBox comboBox2; private System.Windows.Forms.TextBox textBox8; private System.Windows.Forms.Label label12; - private System.Windows.Forms.ComboBox comboBoxScrollSpeed; - private System.Windows.Forms.TextBox textBoxPauseTime; - private System.Windows.Forms.TextBox separatingcharacterformatbox; - private System.Windows.Forms.Label label13; private System.Windows.Forms.GroupBox web_server_settings_groupbox; private System.Windows.Forms.Label web_server_label; private System.Windows.Forms.CheckBox web_server_checkbox; diff --git a/RadioDJViewer/radiodj-restapi-template.cs b/RadioDJViewer/radiodj-restapi-template.cs index f0b12f9..c760578 100644 --- a/RadioDJViewer/radiodj-restapi-template.cs +++ b/RadioDJViewer/radiodj-restapi-template.cs @@ -20,15 +20,6 @@ namespace RadioDJViewer { InitializeComponent(); textBox4.UseSystemPasswordChar = true; // Obscure password field - comboBoxScrollSpeed.Items.Clear(); - comboBoxScrollSpeed.Items.AddRange(new object[] { - "Very Slow", - "Slow", - "Medium", - "Fast", - "Very Fast" - }); - comboBoxScrollSpeed.SelectedItem = "Medium"; this.buttonSelectOutputFolder.Click += ButtonSelectOutputFolder_Click; this.button6.Click += ButtonSelectMainImagesFolder_Click; this.button3.Click += button3_Click; @@ -74,10 +65,7 @@ namespace RadioDJViewer textBox5.Text = profile.OutputImageName; textBox1.Text = profile.UrlFormat; // Default polling rate to 3 if missing or zero - textBox7.Text = (profile.PollingRateSeconds > 0 ? profile.PollingRateSeconds : 3).ToString(); - comboBoxScrollSpeed.SelectedItem = profile.MarqueeScrollSpeed ?? "Medium"; - textBoxPauseTime.Text = profile.MarqueePauseTime > 0 ? profile.MarqueePauseTime.ToString() : "6"; - separatingcharacterformatbox.Text = profile.MarqueeSeparator ?? " | "; + polling_rate_textbox.Text = (profile.PollingRateSeconds > 0 ? profile.PollingRateSeconds : 3).ToString(); // Web server settings try { @@ -125,7 +113,7 @@ namespace RadioDJViewer return; } int pollingRate = 3; - int.TryParse(textBox7.Text, out pollingRate); + int.TryParse(polling_rate_textbox.Text, out pollingRate); var profile = new Profile { Name = textBox6.Text, @@ -137,9 +125,9 @@ namespace RadioDJViewer OutputImageName = textBox5.Text, UrlFormat = textBox1.Text, PollingRateSeconds = pollingRate, - MarqueeScrollSpeed = comboBoxScrollSpeed.SelectedItem?.ToString() ?? "Medium", - MarqueePauseTime = int.TryParse(textBoxPauseTime.Text, out int pt) ? pt : 6, - MarqueeSeparator = separatingcharacterformatbox.Text, + MarqueeScrollSpeed = "Medium", + MarqueePauseTime = 6, + MarqueeSeparator = " | ", // Web server settings WebServerEnabled = web_server_checkbox.Checked, WebServerPort = int.TryParse(web_server_port_textbox.Text, out int wp) ? wp : 8080,