using Herse.Models; using KaraokePlayer.Classes; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace KaraokePlayer { public partial class SongInfoForm : Form { private Timer fadeTimer; private Timer pulseTimer; private int fadeAlpha = 0; private bool isFadingIn = true; private int pulseAlpha = 255; private bool pulseDirection = false; public SongInfoForm() { InitializeComponent(); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.WindowState = FormWindowState.Normal; this.ShowInTaskbar = false; this.TopMost = true; // Enable double buffering to prevent flickering SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); // Add paint event for gradient background mainPanel.Paint += MainPanel_Paint; // Setup fade timer fadeTimer = new Timer(); fadeTimer.Interval = 20; fadeTimer.Tick += FadeTimer_Tick; // Setup pulse timer for "UP NEXT" label pulseTimer = new Timer(); pulseTimer.Interval = 50; pulseTimer.Tick += PulseTimer_Tick; // Start fade in effect StartFadeIn(); } private void StartFadeIn() { fadeAlpha = 0; isFadingIn = true; fadeTimer.Start(); pulseTimer.Start(); } private void PulseTimer_Tick(object sender, EventArgs e) { if (pulseDirection) { pulseAlpha += 5; if (pulseAlpha >= 255) { pulseAlpha = 255; pulseDirection = false; } } else { pulseAlpha -= 5; if (pulseAlpha <= 150) { pulseAlpha = 150; pulseDirection = true; } } upNextLabel.ForeColor = System.Drawing.Color.FromArgb(pulseAlpha, 255, 128, 0); } private void FadeTimer_Tick(object sender, EventArgs e) { if (isFadingIn) { fadeAlpha += 10; if (fadeAlpha >= 255) { fadeAlpha = 255; fadeTimer.Stop(); } } else { fadeAlpha -= 10; if (fadeAlpha <= 0) { fadeAlpha = 0; fadeTimer.Stop(); this.Hide(); } } // Update opacity this.Opacity = fadeAlpha / 255.0; mainPanel.Invalidate(); } private void MainPanel_Paint(object sender, PaintEventArgs e) { e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // Create gradient background using (LinearGradientBrush brush = new LinearGradientBrush( mainPanel.ClientRectangle, System.Drawing.Color.FromArgb(30, 30, 50), System.Drawing.Color.FromArgb(20, 20, 30), LinearGradientMode.Vertical)) { e.Graphics.FillRectangle(brush, mainPanel.ClientRectangle); } // Add subtle radial gradient overlay for depth using (GraphicsPath path = new GraphicsPath()) { path.AddEllipse(-300, -300, mainPanel.Width + 600, mainPanel.Height + 600); using (PathGradientBrush pgb = new PathGradientBrush(path)) { pgb.CenterColor = System.Drawing.Color.FromArgb(40, 40, 80); pgb.SurroundColors = new System.Drawing.Color[] { System.Drawing.Color.FromArgb(0, 0, 0) }; e.Graphics.FillPath(pgb, path); } } // Add subtle border glow using (Pen glowPen = new Pen(System.Drawing.Color.FromArgb(50, 100, 200), 2)) { glowPen.LineJoin = LineJoin.Round; e.Graphics.DrawRectangle(glowPen, 2, 2, mainPanel.Width - 4, mainPanel.Height - 4); } } public void Update(QueueItem queueItem) { if (queueItem?.Singer != null) { singerLabel.Text = queueItem.Singer.Name; } if (queueItem?.Song != null) { artistLabel.Text = queueItem.Song.Artist; songTitleLabel.Text = queueItem.Song.Title; } // Force a repaint to update the gradient mainPanel.Invalidate(); } protected override void OnFormClosing(FormClosingEventArgs e) { fadeTimer?.Stop(); fadeTimer?.Dispose(); pulseTimer?.Stop(); pulseTimer?.Dispose(); base.OnFormClosing(e); } } }