2444 lines
100 KiB
C#
Raw Normal View History

2025-04-07 16:54:10 +08:00
using System.IO;
using System.Runtime.InteropServices;
using NAudio.Wave;
using Microsoft.Ink;
using System.Text.RegularExpressions;
using DBObj;
using OverlayFormObj;
using Timer = System.Windows.Forms.Timer;
namespace DualScreenDemo
{
public partial class PrimaryForm : Form
{
#region
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
#endregion
public static PrimaryForm Instance { get; private set; }
public bool isOnOrderedSongsPage = false;
private ProgressBar progressBar;
private PictureBox pictureBox1;
private PictureBox pictureBox2;
private PictureBox pictureBox3;
private PictureBox pictureBox4;
private PictureBox pictureBox5;
private PictureBox pictureBox6;
private PictureBox pictureBoxArtistSearch;
private Button singerSearchButton;
private Bitmap singerSearchNormalBackground;
private Bitmap singerSearchActiveBackground;
private Button songSearchButton;
private Bitmap songSearchNormalBackground;
private Bitmap songSearchActiveBackground;
private Button serviceBellButton;
private Button deliciousFoodButton;
private Bitmap deliciousFoodNormalBackground;
private Bitmap deliciousFoodActiveBackground;
private Button mobileSongRequestButton;
private Button qieGeButton;
private Button musicUpButton;
private Button musicDownButton;
private Button micUpButton;
private Button micDownButton;
private Button originalSongButton;
private Button replayButton;
public Button pauseButton;
public Button playButton;
private Button muteButton;
private Button maleKeyButton;
private Button femaleKeyButton;
private Button standardKeyButton;
private Button soundEffectButton;
private Button pitchUpButton;
private Button pitchDownButton;
private Button syncScreenButton;
private Button toggleLightButton;
private PictureBox promotionsPictureBox;
private List<Image> promotions;
private List<Image> menu;
private PictureBox VodScreenPictureBox;
private Panel overlayPanel;
private Button btnPreviousPage;
private Button btnReturn;
private Button btnNextPage;
private Button btnApplause;
private Button btnSimplifiedChinese;
private Button btnTraditionalChinese;
2025-04-15 13:16:32 +08:00
private Button exitButton;
2025-04-07 16:54:10 +08:00
private static Bitmap normalStateImage;
private static Bitmap mouseOverImage;
2025-04-15 13:16:32 +08:00
private static Bitmap mouseDownImage;
2025-04-07 16:54:10 +08:00
private static Bitmap resizedNormalStateImage;
private static Bitmap resizedMouseOverImage;
private static Bitmap resizedMouseDownImage;
private static Bitmap normalStateImageNewSongAlert;
private static Bitmap mouseOverImageNewSongAlert;
private static Bitmap mouseDownImageNewSongAlert;
private static Bitmap resizedNormalStateImageForNewSongAlert;
private static Bitmap resizedMouseOverImageForNewSongAlert;
private static Bitmap resizedMouseDownImageForNewSongAlert;
private static Bitmap normalStateImageArtistQuery;
private static Bitmap mouseOverImageArtistQuery;
private static Bitmap mouseDownImageArtistQuery;
private static Bitmap resizedNormalStateImageForArtistQuery;
private static Bitmap resizedMouseOverImageForArtistQuery;
private static Bitmap resizedMouseDownImageForArtistQuery;
private static Bitmap normalStateImageSongQuery;
private static Bitmap mouseOverImageSongQuery;
private static Bitmap mouseDownImageSongQuery;
private static Bitmap resizedNormalStateImageForSongQuery;
private static Bitmap resizedMouseOverImageForSongQuery;
private static Bitmap resizedMouseDownImageForSongQuery;
private static Bitmap normalStateImageLanguageQuery;
private static Bitmap mouseOverImageLanguageQuery;
private static Bitmap mouseDownImageLanguageQuery;
private static Bitmap resizedNormalStateImageForLanguageQuery;
private static Bitmap resizedMouseOverImageForLanguageQuery;
private static Bitmap resizedMouseDownImageForLanguageQuery;
private static Bitmap normalStateImageCategoryQuery;
private static Bitmap mouseOverImageCategoryQuery;
private static Bitmap mouseDownImageCategoryQuery;
private static Bitmap resizedNormalStateImageForCategoryQuery;
private static Bitmap resizedMouseOverImageForCategoryQuery;
2025-04-15 13:16:32 +08:00
private static Bitmap resizedMouseDownImageForCategoryQuery;
2025-04-07 16:54:10 +08:00
private static Bitmap normalStateImageForPromotionsAndMenu;
private static Bitmap resizedNormalStateImageForPromotionsAndMenu;
private static Bitmap normalStateImageForSyncScreen;
private static Bitmap resizedNormalStateImageForSyncScreen;
private static Bitmap normalStateImageForSceneSoundEffects;
private static Bitmap resizedNormalStateImageForSceneSoundEffects;
private static Bitmap normalStateImageForLightControl;
private static Bitmap resizedNormalStateImageForLightControl;
public VideoPlayerForm videoPlayerForm;
public List<SongData> currentSongList;
public List<Artist> currentArtistList;
public static List<SongData> userRequestedSongs;
public static List<SongData> playedSongsHistory;
public static List<PlayState> playStates;
public static int currentSongIndexInHistory = -1;
public MultiPagePanel multiPagePanel;
private List<Label> songLabels = new List<Label>();
private int _currentPage { get; set; }= 0;
private int _totalPages { get; set; }
public int currentPage
{
get { return _currentPage; }
set { _currentPage = value; }
}
public int totalPages
{
get { return _totalPages; }
set { _totalPages = value; }
}
private void HandlePageChanged()
{
this.Invalidate(); // 重新繪製界面
}
public const int itemsPerPage = 18;
private WaveInEvent waveIn;
private WaveFileWriter waveWriter;
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
private const int PanelStartLeft = 25; // 修改為實際需要的左邊距
private const int PanelStartTop = 227; // 修改為實際需要的上邊距
private const int PanelEndLeft = 1175; // 修改為實際需要的右邊界
private const int PanelEndTop = 739; // 修改為實際需要的下邊界
private Timer lightControlTimer;
public Timer volumeUpTimer;
public Timer volumeDownTimer;
public Timer micControlTimer;
private SequenceManager sequenceManager = new SequenceManager();
private PictureBox buttonMiddle;
private PictureBox buttonTopRight;
private PictureBox buttonTopLeft;
private PictureBox buttonThanks;
private Dictionary<Control, (Point Location, bool Visible)> initialControlStates = new Dictionary<Control, (Point Location, bool Visible)>();
private Panel sendOffPanel;
2025-05-13 15:21:19 +08:00
2025-04-07 16:54:10 +08:00
private static Bitmap normalStateImageHotSong;
private static Bitmap mouseDownImageHotSong;
private static Bitmap resizedNormalStateImageForHotSong;
private static Bitmap resizedMouseDownImageForHotSong;
private PictureBox serviceBellPictureBox; // 添加为类成员变量
private Timer autoRefreshTimer;
//private Label pageNumberLabel; // 添加頁碼標籤
public PrimaryForm()
{
Instance = this;
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
// 添加 DPI 感知支持
if (Environment.OSVersion.Version.Major >= 6)
{
SetProcessDPIAware();
}
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
this.DoubleBuffered = true;
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
InitializeProgressBar();
// 初始化自动刷新Timer
autoRefreshTimer = new Timer();
autoRefreshTimer.Interval = 1000; // 1秒
autoRefreshTimer.Tick += AutoRefreshTimer_Tick;
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
// 設置窗體屬性
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
lightControlTimer = new Timer();
2025-06-03 16:52:44 +08:00
lightControlTimer.Interval = 5;
2025-04-07 16:54:10 +08:00
lightControlTimer.Tick += LightControlTimer_Tick;
volumeUpTimer = new Timer();
2025-06-03 16:52:44 +08:00
volumeUpTimer.Interval = 100;
2025-04-07 16:54:10 +08:00
volumeUpTimer.Tick += VolumeUpTimer_Tick;
volumeDownTimer = new Timer();
volumeDownTimer.Interval = 100;
volumeDownTimer.Tick += VolumeDownTimer_Tick;
micControlTimer = new Timer();
micControlTimer.Interval = 100;
micControlTimer.Tick += MicControlTimer_Tick;
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
InitializeRecording();
InitializeMediaPlayer();
LoadSongData();
2025-06-03 16:52:44 +08:00
LoadImages();
InitializeFormAndControls();
2025-04-07 16:54:10 +08:00
InitializeMultiPagePanel();
OverlayQRCodeOnImage(HttpServer.randomFolderPath);
InitializeHandWritingForSingers();
InitializeHandWritingForSongs();
InitializeSendOffPanel();
2025-06-03 16:52:44 +08:00
2025-04-07 16:54:10 +08:00
InitializePromotionsAndMenuPanel();
SaveInitialControlStates(this);
// 包廂 + port 名稱
this.Paint += PrimaryForm_Paint;
2025-05-22 13:33:48 +08:00
this.Paint += User_Paint;
2025-04-07 16:54:10 +08:00
// 註冊多頁面面板的頁碼改變事件處理
2025-06-03 16:52:44 +08:00
multiPagePanel.PageIndexChanged += HandlePageChanged;
2025-04-07 16:54:10 +08:00
// 添加 Load 事件處理
this.Load += PrimaryForm_Load;
}
2025-06-20 13:12:10 +08:00
public bool IsAppResponsive()
{
try
{
var form = this;
if (form != null)
{
bool dummy = form.InvokeRequired; // 如果 Invoke 卡死,會丟錯
return true;
}
}
catch
{
return false;
}
return true;
}
2025-04-07 16:54:10 +08:00
// 添加 DPI 感知支持
[DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
private void SaveInitialControlStates(Control parent)
{
foreach (Control control in parent.Controls)
{
initialControlStates[control] = (control.Location, control.Visible);
if (control.HasChildren)
{
SaveInitialControlStates(control);
}
}
}
private void PrimaryForm_Paint(object sender, PaintEventArgs e)
{
// 取得本機電腦的主機名稱 (hostname)
string hostName = System.Net.Dns.GetHostName();
// 顯示包廂名稱
// 取主機名稱的最後 20 個字元 (如果長度不足 20則取全部)
string displayName = "包廂" + hostName.Substring(Math.Max(0, hostName.Length - 3));
2025-04-15 10:59:03 +08:00
string totalPages = multiPagePanel.totalPages.ToString() == "0" ? "1" : multiPagePanel.totalPages.ToString();
string pageNumber = (multiPagePanel.currentPageIndex + 1).ToString() + "/" + totalPages;
// 最後確定要塗鴉的值
displayName = displayName + " " + pageNumber;
// 基準解析度(你目前的設計基準)
float baseWidth = 1920f;
float baseHeight = 1080f;
// 實際螢幕解析度
float actualWidth = Screen.PrimaryScreen.Bounds.Width;
float actualHeight = Screen.PrimaryScreen.Bounds.Height;
// 計算縮放比例
float scaleX = actualWidth / baseWidth;
float scaleY = actualHeight / baseHeight;
2025-04-07 16:54:10 +08:00
// 設定字型:
// "微軟正黑體",大小 24粗體 (Bold)
float fontSize = 24 * scaleY;
Font font = new Font("微軟正黑體", fontSize, FontStyle.Bold);
2025-04-07 16:54:10 +08:00
// 設定畫刷 (Brush)
// 使用紅色 (Red) 來繪製文字
Brush brush = new SolidBrush(Color.Red);
// 設定繪製文字的位置 (X=500, Y=30)
PointF point_PCName = new PointF(500 * scaleX, 30 * scaleY);
2025-04-07 16:54:10 +08:00
// 繪製文字:
// `DrawString(要繪製的文字, 字型, 畫刷, 位置)`
e.Graphics.DrawString(displayName, font, brush, point_PCName);
2025-04-07 16:54:10 +08:00
}
2025-05-22 13:33:48 +08:00
private void User_Paint(object sender, PaintEventArgs e)
{
if (!string.IsNullOrWhiteSpace(userPhone) && isLoggedIn)
{
string displayName = "歡迎貴賓 :" + userPhone;
float baseWidth = 1920f;
float baseHeight = 1080f;
// 實際螢幕解析度
float actualWidth = Screen.PrimaryScreen.Bounds.Width;
float actualHeight = Screen.PrimaryScreen.Bounds.Height;
// 計算縮放比例
float scaleX = actualWidth / baseWidth;
float scaleY = actualHeight / baseHeight;
2025-04-07 16:54:10 +08:00
2025-05-22 13:33:48 +08:00
// 設定字型:
// "微軟正黑體",大小 20粗體 (Bold)
float fontSize = 18 * scaleY;
Font font = new Font("微軟正黑體", fontSize, FontStyle.Bold);
// 設定畫刷 (Brush)
// 使用紅色 (Red) 來繪製文字
Brush brush = new SolidBrush(Color.Red);
// 設定繪製文字的位置 (X=800, Y=30)
PointF point_user = new PointF(800 * scaleX, 30 * scaleY);
e.Graphics.DrawString(displayName, font, brush, point_user);
}
}
2025-04-07 16:54:10 +08:00
private void buttonMiddle_Click(object sender, EventArgs e)
{
Console.WriteLine("巨");
2025-04-07 16:54:10 +08:00
sequenceManager.ProcessClick("巨");
}
private void buttonTopRight_Click(object sender, EventArgs e)
{
Console.WriteLine("級");
2025-04-07 16:54:10 +08:00
sequenceManager.ProcessClick("級");
}
private void buttonTopLeft_Click(object sender, EventArgs e)
{
Console.WriteLine("超");
2025-04-07 16:54:10 +08:00
sequenceManager.ProcessClick("超");
}
private void buttonThanks_Click(object sender, EventArgs e)
{
Console.WriteLine("星");
2025-04-07 16:54:10 +08:00
sequenceManager.ProcessClick("星");
}
public void ShowSendOffScreen()
{
sendOffPanel.BringToFront();
sendOffPanel.Visible = true;
// 確保按鈕可見並在最上層
buttonMiddle.Visible = true;
buttonTopRight.Visible = true;
buttonTopLeft.Visible = true;
buttonThanks.Visible = true;
buttonMiddle.BringToFront();
buttonTopRight.BringToFront();
buttonTopLeft.BringToFront();
buttonThanks.BringToFront();
}
// 修正螢幕初始化關鍵
2025-04-07 16:54:10 +08:00
public void HideSendOffScreen()
{
sendOffPanel.Visible = false;
foreach (Control ctrl in this.Controls)
{
ctrl.Enabled = true;
}
2025-04-07 16:54:10 +08:00
}
private void HideControlsRecursively(Control parent)
{
foreach (Control control in parent.Controls)
{
if (control is Button)
{
control.Visible = false;
}
else if (control.HasChildren)
{
HideControlsRecursively(control);
}
}
}
private void InitializeProgressBar()
{
progressBar = new ProgressBar();
progressBar.Location = new System.Drawing.Point(10, 10);
progressBar.Size = new System.Drawing.Size(300, 30);
progressBar.Minimum = 0;
progressBar.Maximum = 100;
progressBar.Value = 0;
this.Controls.Add(progressBar);
}
private void EnableDoubleBuffering(Control control)
{
if (control != null)
{
var doubleBufferedProperty = control.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (doubleBufferedProperty != null)
{
doubleBufferedProperty.SetValue(control, true, null);
}
}
}
private void InitializeRecording()
{
for (int n = 0; n < WaveIn.DeviceCount; n++)
{
var caps = WaveIn.GetCapabilities(n);
Console.WriteLine(String.Format("{0}: {1}", n, caps.ProductName));
}
waveIn = new WaveInEvent();
waveIn.DataAvailable += OnDataAvailable;
waveIn.RecordingStopped += OnRecordingStopped;
waveIn.WaveFormat = new WaveFormat(44100, 1);
}
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
if (waveWriter != null)
{
waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
waveWriter.Flush();
}
}
private void OnRecordingStopped(object sender, StoppedEventArgs e)
{
if (waveIn != null)
{
waveIn.Dispose();
waveIn = null;
}
if (waveWriter != null)
{
waveWriter.Dispose();
waveWriter = null;
}
}
private void InitializeFormAndControls()
{
this.SuspendLayout();
// 獲取螢幕尺寸
Screen screen = Screen.PrimaryScreen;
int screenWidth = screen.Bounds.Width;
int screenHeight = screen.Bounds.Height;
// 設置窗體大小
this.Size = new Size(screenWidth, screenHeight);
this.Location = new Point(0, 0);
// 調整背景圖片
string selectedTheme = ReadSelectedThemePath();
if (!string.IsNullOrEmpty(selectedTheme))
{
string backgroundImagePath = Path.Combine(Application.StartupPath, "themes\\superstar\\555009.jpg");
try
{
using (Image originalImage = Image.FromFile(backgroundImagePath))
{
this.BackgroundImage = new Bitmap(originalImage);
this.BackgroundImageLayout = ImageLayout.Stretch;
}
}
catch (Exception ex)
{
Console.WriteLine($"加載背景圖片時發生錯誤: {ex.Message}");
}
}
InitializePictureBox();
InitializeButtonsForHotSong();
InitializeButtonsForNewSong();
InitializeButtonsForSingerSearch();
InitializeButtonsForSongSearch();
InitializeButtonsForPictureBoxLanguageQuery();
InitializeButtonsForGroupPictureBox();
InitializeCategorySearchButtons();
InitializeButtonsForZhuYinSingers();
InitializeButtonsForZhuYinSongs();
InitializeButtonsForEnglishSingers();
InitializeButtonsForEnglishSongs();
InitializeButtonsForWordCountSongs();
InitializeButtonsForWordCountSingers();
InitializeButtonsForPinYinSingers();
InitializeButtonsForPinYinSongs();
InitializeButtonsForSongIDSearch();
InitializeButtonsForFavoritePictureBox();
InitializePromotionsButton();
InitializeButtonsForPictureBoxToggleLight();
InitializeButtonsForVodScreenPictureBox();
InitializeSoundEffectButtons();
InitializeSyncScreen();
InitializeButtonsForSongIDSearch();
InitializeOtherControls();
pictureBox1.BringToFront();
pictureBox2.BringToFront();
pictureBox3.BringToFront();
pictureBox4.BringToFront();
pictureBoxQRCode.BringToFront();
pictureBoxZhuYinSingers.BringToFront();
pictureBoxZhuYinSongs.BringToFront();
pictureBoxEnglishSingers.BringToFront();
pictureBoxEnglishSongs.BringToFront();
pictureBoxWordCountSongs.BringToFront();
FavoritePictureBox.BringToFront();
promotionsPictureBox.BringToFront();
pictureBoxToggleLight.BringToFront();
overlayPanel.BringToFront();
VodScreenPictureBox.BringToFront();
newSongAlertButton.BringToFront();
hotPlayButton.BringToFront();
singerSearchButton.BringToFront();
songSearchButton.BringToFront();
languageSearchButton.BringToFront();
groupSearchButton.BringToFront();
categorySearchButton.BringToFront();
serviceBellButton.BringToFront();
orderedSongsButton.BringToFront();
myFavoritesButton.BringToFront();
deliciousFoodButton.BringToFront();
promotionsButton.BringToFront();
mobileSongRequestButton.BringToFront();
qieGeButton.BringToFront();
musicUpButton.BringToFront();
musicDownButton.BringToFront();
micUpButton.BringToFront();
micDownButton.BringToFront();
originalSongButton.BringToFront();
replayButton.BringToFront();
pauseButton.BringToFront();
playButton.BringToFront();
muteButton.BringToFront();
maleKeyButton.BringToFront();
femaleKeyButton.BringToFront();
standardKeyButton.BringToFront();
soundEffectButton.BringToFront();
pitchUpButton.BringToFront();
pitchDownButton.BringToFront();
syncScreenButton.BringToFront();
toggleLightButton.BringToFront();
btnPreviousPage.BringToFront();
btnReturn.BringToFront();
btnNextPage.BringToFront();
btnApplause.BringToFront();
btnSimplifiedChinese.BringToFront();
btnTraditionalChinese.BringToFront();
exitButton.BringToFront();
this.ResumeLayout(false);
this.PerformLayout();
}
private string ReadSelectedThemePath()
{
2025-04-09 11:46:18 +08:00
string configFilePath = Path.Combine(Application.StartupPath, "txt", "theme_description.txt");
2025-04-07 16:54:10 +08:00
try
{
string[] lines = File.ReadAllLines(configFilePath);
foreach (string line in lines)
{
if (line.StartsWith("Selected Theme: "))
{
string themePath = line.Substring("Selected Theme: ".Length).Trim();
return themePath;
}
}
}
catch (Exception ex)
{
Console.WriteLine(String.Format("讀取文件時發生錯誤: {0}", ex.Message));
}
return string.Empty;
}
private void InitializePictureBox()
{
pictureBox1 = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage
};
pictureBox2 = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBox3 = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBox4 = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBox5 = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBox6 = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxZhuYinSingers = new PictureBox
{
Name = "pictureBoxZhuYinSingers",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxZhuYinSongs = new PictureBox
{
Name = "pictureBoxZhuYinSongs",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxEnglishSingers = new PictureBox
{
Name = "pictureBoxEnglishSingers",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxEnglishSongs = new PictureBox
{
Name = "pictureBoxEnglishSongs",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxArtistSearch = new PictureBox
{
Name = "pictureBoxArtistSearch",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxWordCountSongs = new PictureBox
{
Name = "pictureBoxWordCountSongs",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxWordCountSingers = new PictureBox
{
Name = "pictureBoxWordCountSingers",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxPinYinSingers = new PictureBox
{
Name = "pictureBoxPinYinSingers",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxPinYinSongs = new PictureBox
{
Name = "pictureBoxPinYinSongs",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxSongIDSearch = new PictureBox
{
Name = "pictureBoxSongIDSearch",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxHandWritingSingers = new PictureBox
{
Name = "pictureBoxHandWritingSingers",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxHandWritingSongs = new PictureBox
{
Name = "pictureBoxHandWritingSongs",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
FavoritePictureBox = new PictureBox
{
Name = "FavoritePictureBox",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
FavoritePictureBox.Paint += new PaintEventHandler(FavoritePictureBox_Paint);
promotionsPictureBox = new PictureBox
{
Name = "promotionsPictureBox",
Dock = DockStyle.Fill,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxToggleLight = new PictureBox
{
Name = "pictureBoxToggleLight",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
VodScreenPictureBox = new PictureBox
{
Name = "VodScreenPictureBox",
BackColor = Color.FromArgb(128, 0, 0, 0),
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
overlayPanel = new Panel
{
Name = "overlayPanel",
Dock = DockStyle.Fill,
BackColor = Color.FromArgb(128, 0, 0, 0),
Visible = false
};
pictureBoxQRCode = new PictureBox
{
Name = "pictureBoxQRCode",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
pictureBoxSceneSoundEffects = new PictureBox
{
Name = "pictureBoxSceneSoundEffects",
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Visible = false
};
this.Controls.Add(pictureBox1);
this.Controls.Add(pictureBox2);
this.Controls.Add(pictureBox3);
this.Controls.Add(pictureBox4);
this.Controls.Add(pictureBox5);
this.Controls.Add(pictureBox6);
this.Controls.Add(pictureBoxQRCode);
this.Controls.Add(pictureBoxZhuYinSingers);
this.Controls.Add(pictureBoxWordCountSongs);
this.Controls.Add(pictureBoxZhuYinSongs);
this.Controls.Add(pictureBoxEnglishSingers);
this.Controls.Add(pictureBoxEnglishSongs);
this.Controls.Add(pictureBoxArtistSearch);
this.Controls.Add(pictureBoxWordCountSingers);
this.Controls.Add(pictureBoxPinYinSingers);
this.Controls.Add(pictureBoxPinYinSongs);
this.Controls.Add(pictureBoxHandWritingSingers);
this.Controls.Add(pictureBoxHandWritingSongs);
this.Controls.Add(pictureBoxSongIDSearch);
this.Controls.Add(FavoritePictureBox);
this.Controls.Add(promotionsPictureBox);
this.Controls.Add(pictureBoxToggleLight);
this.Controls.Add(VodScreenPictureBox);
this.Controls.Add(overlayPanel);
this.Controls.Add(pictureBoxSceneSoundEffects);
}
private void PhoneticButton_Click(object sender, EventArgs e)
{
var button = sender as Button;
if (button != null && button.Tag != null)
{
if (inputBoxZhuYinSingers.Visible)
{
inputBoxZhuYinSingers.Text += button.Tag.ToString();
}
else if (inputBoxZhuYinSongs.Visible)
{
inputBoxZhuYinSongs.Text += button.Tag.ToString();
}
}
}
private void LightControlTimer_Tick(object sender, EventArgs e)
{
if(lightControlTimer.Tag != null)
{
SendCommandThroughSerialPort(lightControlTimer.Tag.ToString());
}
}
private void VolumeUpTimer_Tick(object sender, EventArgs e)
{
Task.Run(() =>
{
try
{
SendCommandThroughSerialPort("a2 b3 a4");
}
catch (Exception ex)
{
Console.WriteLine("Failed to send command: " + ex.Message);
}
});
}
private void VolumeDownTimer_Tick(object sender, EventArgs e)
{
Task.Run(() =>
{
try
{
SendCommandThroughSerialPort("a2 b4 a4");
}
catch (Exception ex)
{
Console.WriteLine("Failed to send command: " + ex.Message);
}
});
}
private void MicControlTimer_Tick(object sender, EventArgs e)
{
Task.Run(() =>
{
try
{
if(micControlTimer.Tag != null)
{
SendCommandThroughSerialPort(micControlTimer.Tag.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine("Failed to send command: " + ex.Message);
}
});
}
public static void SendCommandThroughSerialPort(string command)
{
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
{
try
{
byte[] commandBytes = HexStringToByteArray(command);
SerialPortManager.mySerialPort.Write(commandBytes, 0, commandBytes.Length);
}
catch (Exception ex)
{
2025-06-20 13:12:10 +08:00
Console.WriteLine("Failed to send command: " + ex.Message);
2025-04-07 16:54:10 +08:00
}
}
else
{
2025-06-20 13:12:10 +08:00
Console.WriteLine("Serial port is not open.");
2025-04-07 16:54:10 +08:00
}
}
public static byte[] HexStringToByteArray(string hex)
{
hex = hex.Replace(" ", "");
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
private void RecognizeInk(InkOverlay inkOverlay, ListBox candidateListBox)
{
if (inkOverlay.Ink.Strokes.Count > 0)
{
using (RecognizerContext context = new RecognizerContext())
{
context.Strokes = inkOverlay.Ink.Strokes;
RecognitionStatus status;
RecognitionResult result = context.Recognize(out status);
if (status == RecognitionStatus.NoError)
{
List<string> candidates = new List<string>();
foreach (RecognitionAlternate alternate in result.GetAlternatesFromSelection())
{
candidates.Add(alternate.ToString());
}
ShowCandidates(candidates, candidateListBox);
}
else
{
candidateListBox.Visible = false;
}
}
}
else
{
candidateListBox.Visible = false;
}
}
private void ShowCandidates(List<string> candidates, ListBox candidateListBox)
{
candidateListBox.Items.Clear();
foreach (var candidate in candidates)
{
candidateListBox.Items.Add(candidate);
}
candidateListBox.Visible = true;
}
private void ConfigureButton(Button button, int posX, int posY, int width, int height,
Bitmap normalStateImage, Bitmap mouseOverImage, Bitmap mouseDownImage,
EventHandler clickEventHandler)
{
ResizeAndPositionButton(button, posX, posY, width, height);
Rectangle cropArea = new Rectangle(button.Location.X, button.Location.Y, button.Size.Width, button.Size.Height);
button.BackgroundImage = normalStateImage.Clone(cropArea, normalStateImage.PixelFormat);
button.BackgroundImageLayout = ImageLayout.Stretch;
button.FlatStyle = FlatStyle.Flat;
button.FlatAppearance.BorderSize = 0;
button.FlatAppearance.MouseDownBackColor = Color.Transparent;
button.FlatAppearance.MouseOverBackColor = Color.Transparent;
button.MouseEnter += (sender, e) => button.BackgroundImage = mouseOverImage.Clone(cropArea, mouseOverImage.PixelFormat);
button.MouseLeave += (sender, e) => button.BackgroundImage = normalStateImage.Clone(cropArea, normalStateImage.PixelFormat);
button.MouseDown += (sender, e) => button.BackgroundImage = mouseDownImage.Clone(cropArea, mouseDownImage.PixelFormat);
button.MouseUp += (sender, e) => button.BackgroundImage = normalStateImage.Clone(cropArea, normalStateImage.PixelFormat);
if (clickEventHandler != null)
{
button.Click += clickEventHandler;
}
this.Controls.Add(button);
}
private void InitializeOtherControls()
{
InitializeButton(ref newSongAlertButton, ref newSongAlertNormalBackground, ref newSongAlertActiveBackground, "newSongAlertButton", 25, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_新歌快報X.png", NewSongAlertButton_Click);
InitializeButton(ref hotPlayButton, ref hotPlayNormalBackground, ref hotPlayActiveBackground, "hotPlayButton", 143, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_熱門排行-02.png", HotPlayButton_Click);
InitializeButton(ref singerSearchButton, ref singerSearchNormalBackground, ref singerSearchActiveBackground, "singerSearchButton", 261, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_歌星查詢-03.png", SingerSearchButton_Click);
InitializeButton(ref songSearchButton, ref songSearchNormalBackground, ref songSearchActiveBackground, "songSearchButton", 378, 97, 100, 99, "themes\\superstar\\ICON上方\\上方ICON_歌名查詢-04.png", SongSearchButton_Click);
InitializeButton(ref languageSearchButton, ref languageSearchNormalBackground, ref languageSearchActiveBackground, "languageSearchButton", 496, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_語別查詢-05.png", LanguageSongSelectionButton_Click);
InitializeButton(ref groupSearchButton, ref groupSearchNormalBackground, ref groupSearchActiveBackground, "groupSearchButton", 614, 97, 99, 100, "themes\\superstar\\ICON上方\\上方ICON_合唱查詢-06.png", GroupSongSelectionButton_Click);
InitializeButton(ref categorySearchButton, ref categorySearchNormalBackground, ref categorySearchActiveBackground, "categorySearchButton", 731, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_類別查詢-07.png", CategorySearchButton_Click);
serviceBellButton = new Button { Text = "" };
serviceBellButton.Name = "serviceBellButton";
ConfigureButton(serviceBellButton, 848, 96, 101, 102,
resizedNormalStateImage, resizedMouseOverImage, resizedMouseDownImage,
(sender, e) => OnServiceBellButtonClick(sender, e));
this.Controls.Add(serviceBellButton);
InitializeButton(ref orderedSongsButton, ref orderedSongsNormalBackground, ref orderedSongsActiveBackground, "orderedSongsButton", 966, 97, 100, 99, "themes\\superstar\\ICON上方\\上方ICON_已點歌曲-09.png", OrderedSongsButton_Click);
InitializeButton(ref myFavoritesButton, ref myFavoritesNormalBackground, ref myFavoritesActiveBackground, "myFavoritesButton", 1084, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_我的最愛-10.png", MyFavoritesButton_Click);
InitializeButton(ref promotionsButton, ref promotionsNormalBackground, ref promotionsActiveBackground, "promotionsButton", 1202, 97, 99, 99, "themes\\superstar\\ICON上方\\上方ICON_優惠活動-11.png", promotionsButton_Click);
InitializeButton(ref deliciousFoodButton, ref deliciousFoodNormalBackground, ref deliciousFoodActiveBackground, "deliciousFoodButton", 1320, 97, 98, 99, "themes\\superstar\\ICON上方\\上方ICON_美味菜單-12.png", DeliciousFoodButton_Click);
mobileSongRequestButton = new Button { Text = "" };
mobileSongRequestButton.Name = "mobileSongRequestButton";
ConfigureButton(mobileSongRequestButton, 1211, 669, 210, 70,
resizedNormalStateImage, resizedMouseOverImage, resizedMouseDownImage,
MobileSongRequestButton_Click);
qieGeButton = new Button{ Text = "" };
qieGeButton.Name = "qieGeButton";
ConfigureButton(qieGeButton, 28, 755, 92, 132,
resizedNormalStateImage, resizedNormalStateImage, resizedNormalStateImage,
(sender, e) => videoPlayerForm.SkipToNextSong());
this.Controls.Add(qieGeButton);
musicUpButton = new Button{ Text = "" };
musicUpButton.Name = "musicUpButton";
ResizeAndPositionButton(musicUpButton, 136, 754, 92, 58);
Rectangle musicUpButtonCropArea = new Rectangle(136, 754, 92, 58);
musicUpButton.BackgroundImage = normalStateImage.Clone(musicUpButtonCropArea, normalStateImage.PixelFormat);
musicUpButton.BackgroundImageLayout = ImageLayout.Stretch;
musicUpButton.FlatStyle = FlatStyle.Flat;
musicUpButton.FlatAppearance.BorderSize = 0;
musicUpButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowVolumeUpLabel(); volumeUpTimer.Start(); };
musicUpButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); volumeUpTimer.Stop(); };
this.Controls.Add(musicUpButton);
musicDownButton = new Button{ Text = "" };
musicDownButton.Name = "musicDownButton";
ResizeAndPositionButton(musicDownButton, 136, 827, 92, 57);
Rectangle musicDownButtonCropArea = new Rectangle(136, 827, 92, 57);
musicDownButton.BackgroundImage = normalStateImage.Clone(musicDownButtonCropArea, normalStateImage.PixelFormat);
musicDownButton.BackgroundImageLayout = ImageLayout.Stretch;
musicDownButton.FlatStyle = FlatStyle.Flat;
musicDownButton.FlatAppearance.BorderSize = 0;
musicDownButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowVolumeDownLabel(); volumeDownTimer.Start(); };
musicDownButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); volumeDownTimer.Stop(); };
this.Controls.Add(musicDownButton);
micUpButton = new Button{ Text = "" };
micUpButton.Name = "micUpButton";
ResizeAndPositionButton(micUpButton, 244, 754, 92, 57);
Rectangle micUpButtonCropArea = new Rectangle(244, 754, 92, 57);
micUpButton.BackgroundImage = normalStateImage.Clone(micUpButtonCropArea, normalStateImage.PixelFormat);
micUpButton.BackgroundImageLayout = ImageLayout.Stretch;
micUpButton.FlatStyle = FlatStyle.Flat;
micUpButton.FlatAppearance.BorderSize = 0;
micUpButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowMicUpLabel(); micControlTimer.Tag = "a2 b5 a4"; micControlTimer.Start(); };
micUpButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); micControlTimer.Stop(); };
this.Controls.Add(micUpButton);
micDownButton = new Button{ Text = "" };
micDownButton.Name = "micDownButton";
ResizeAndPositionButton(micDownButton, 244, 827, 92, 57);
Rectangle micDownButtonCropArea = new Rectangle(244, 827, 92, 57);
micDownButton.BackgroundImage = normalStateImage.Clone(micDownButtonCropArea, normalStateImage.PixelFormat);
micDownButton.BackgroundImageLayout = ImageLayout.Stretch;
micDownButton.FlatStyle = FlatStyle.Flat;
micDownButton.FlatAppearance.BorderSize = 0;
micDownButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowMicDownLabel(); micControlTimer.Tag = "a2 b6 a4"; micControlTimer.Start(); };
micDownButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); micControlTimer.Stop(); };
this.Controls.Add(micDownButton);
originalSongButton = new Button { Text = "" };
originalSongButton.Name = "originalSongButton";
ResizeAndPositionButton(originalSongButton, 353, 756, 91, 55);
Rectangle originalSongButtonCropArea = new Rectangle(353, 756, 91, 55);
originalSongButton.BackgroundImage = normalStateImage.Clone(originalSongButtonCropArea, normalStateImage.PixelFormat);
originalSongButton.BackgroundImageLayout = ImageLayout.Stretch;
originalSongButton.FlatStyle = FlatStyle.Flat;
originalSongButton.FlatAppearance.BorderSize = 0;
originalSongButton.Click += OriginalSongButton_Click;
this.Controls.Add(originalSongButton);
replayButton = new Button{ Text = "" };
replayButton.Name = "replayButton";
ResizeAndPositionButton(replayButton, 353, 828, 91, 55);
Rectangle replayButtonCropArea = new Rectangle(353, 828, 91, 55);
replayButton.BackgroundImage = normalStateImage.Clone(replayButtonCropArea, normalStateImage.PixelFormat);
replayButton.BackgroundImageLayout = ImageLayout.Stretch;
replayButton.FlatStyle = FlatStyle.Flat;
replayButton.FlatAppearance.BorderSize = 0;
replayButton.Click += ReplayButton_Click;
this.Controls.Add(replayButton);
pauseButton = new Button {
Text = "",
Name = "pauseButton"
};
ResizeAndPositionButton(pauseButton, 461, 755, 91, 56);
Rectangle pauseButtonCropArea = new Rectangle(461, 755, 91, 56);
pauseButton.BackgroundImage = normalStateImage.Clone(pauseButtonCropArea, normalStateImage.PixelFormat);
pauseButton.BackgroundImageLayout = ImageLayout.Stretch;
pauseButton.FlatStyle = FlatStyle.Flat;
pauseButton.FlatAppearance.BorderSize = 0;
pauseButton.Click += PauseButton_Click;
this.Controls.Add(pauseButton);
playButton = new Button {
Text = "",
Name = "playButton",
Visible = false
};
ResizeAndPositionButton(playButton, 461, 755, 91, 56);
Rectangle playButtonCropArea = new Rectangle(461, 755, 91, 56);
playButton.BackgroundImage = normalStateImage.Clone(playButtonCropArea, normalStateImage.PixelFormat);
playButton.BackgroundImageLayout = ImageLayout.Stretch;
playButton.FlatStyle = FlatStyle.Flat;
playButton.FlatAppearance.BorderSize = 0;
playButton.Click += PlayButton_Click;
this.Controls.Add(playButton);
muteButton = new Button{ Text = "" };
muteButton.Name = "muteButton";
ResizeAndPositionButton(muteButton, 461, 828, 91, 55);
Rectangle muteButtonCropArea = new Rectangle(461, 828, 91, 55);
muteButton.BackgroundImage = normalStateImage.Clone(muteButtonCropArea, normalStateImage.PixelFormat);
muteButton.BackgroundImageLayout = ImageLayout.Stretch;
muteButton.FlatStyle = FlatStyle.Flat;
muteButton.FlatAppearance.BorderSize = 0;
muteButton.Click += MuteUnmuteButton_Click;
this.Controls.Add(muteButton);
maleKeyButton = new Button{ Text = "" };
maleKeyButton.Name = "maleKeyButton";
ResizeAndPositionButton(maleKeyButton, 569, 755, 91, 56);
Rectangle maleKeyButtonCropArea = new Rectangle(569, 755, 91, 56);
maleKeyButton.BackgroundImage = normalStateImage.Clone(maleKeyButtonCropArea, normalStateImage.PixelFormat);
maleKeyButton.BackgroundImageLayout = ImageLayout.Stretch;
maleKeyButton.FlatStyle = FlatStyle.Flat;
maleKeyButton.Click += MaleKeyButton_Click;
maleKeyButton.FlatAppearance.BorderSize = 0;
this.Controls.Add(maleKeyButton);
femaleKeyButton = new Button{ Text = "" };
femaleKeyButton.Name = "femaleKeyButton";
ResizeAndPositionButton(femaleKeyButton, 570, 828, 90, 55);
Rectangle femaleKeyButtonCropArea = new Rectangle(570, 828, 90, 55);
femaleKeyButton.BackgroundImage = normalStateImage.Clone(femaleKeyButtonCropArea, normalStateImage.PixelFormat);
femaleKeyButton.BackgroundImageLayout = ImageLayout.Stretch;
femaleKeyButton.FlatStyle = FlatStyle.Flat;
femaleKeyButton.FlatAppearance.BorderSize = 0;
femaleKeyButton.Click += FemaleKeyButton_Click;
this.Controls.Add(femaleKeyButton);
standardKeyButton = new Button { Text = "" };
standardKeyButton.Name = "standardKeyButton";
ResizeAndPositionButton(standardKeyButton, 677, 757, 91, 56);
Rectangle standardKeyButtonCropArea = new Rectangle(677, 757, 91, 56);
standardKeyButton.BackgroundImage = normalStateImage.Clone(standardKeyButtonCropArea, normalStateImage.PixelFormat);
standardKeyButton.BackgroundImageLayout = ImageLayout.Stretch;
standardKeyButton.FlatStyle = FlatStyle.Flat;
standardKeyButton.FlatAppearance.BorderSize = 0;
standardKeyButton.Click += StandardKeyButton_Click;
this.Controls.Add(standardKeyButton);
soundEffectButton = new Button { Text = "" };
soundEffectButton.Name = "soundEffectButton";
ResizeAndPositionButton(soundEffectButton, 677, 827, 91, 56);
Rectangle soundEffectButtonCropArea = new Rectangle(677, 827, 91, 56);
soundEffectButton.BackgroundImage = normalStateImage.Clone(soundEffectButtonCropArea, normalStateImage.PixelFormat);
soundEffectButton.BackgroundImageLayout = ImageLayout.Stretch;
soundEffectButton.FlatStyle = FlatStyle.Flat;
soundEffectButton.FlatAppearance.BorderSize = 0;
soundEffectButton.Click += SoundEffectButton_Click;
this.Controls.Add(soundEffectButton);
pitchUpButton = new Button{ Text = "" };
pitchUpButton.Name = "pitchUpButton";
ResizeAndPositionButton(pitchUpButton, 786, 755, 90, 56);
Rectangle pitchUpButtonCropArea = new Rectangle(786, 755, 90, 56);
pitchUpButton.BackgroundImage = normalStateImage.Clone(pitchUpButtonCropArea, normalStateImage.PixelFormat);
pitchUpButton.BackgroundImageLayout = ImageLayout.Stretch;
pitchUpButton.FlatStyle = FlatStyle.Flat;
pitchUpButton.FlatAppearance.BorderSize = 0;
pitchUpButton.Click += PitchUpButton_Click;
this.Controls.Add(pitchUpButton);
pitchDownButton = new Button{ Text = "" };
pitchDownButton.Name = "pitchDownButton";
ResizeAndPositionButton(pitchDownButton, 786, 828, 90, 55);
Rectangle pitchDownButtonCropArea = new Rectangle(786, 828, 90, 55);
pitchDownButton.BackgroundImage = normalStateImage.Clone(pitchDownButtonCropArea, normalStateImage.PixelFormat);
pitchDownButton.BackgroundImageLayout = ImageLayout.Stretch;
pitchDownButton.FlatStyle = FlatStyle.Flat;
pitchDownButton.FlatAppearance.BorderSize = 0;
pitchDownButton.Click += PitchDownButton_Click;
this.Controls.Add(pitchDownButton);
syncScreenButton = new Button { Text = "" };
syncScreenButton.Name = "syncScreenButton";
ResizeAndPositionButton(syncScreenButton, 893, 754, 93, 133);
Rectangle syncScreenButtonCropArea = new Rectangle(893, 754, 93, 133);
syncScreenButton.BackgroundImage = normalStateImage.Clone(syncScreenButtonCropArea, normalStateImage.PixelFormat);
syncScreenButton.BackgroundImageLayout = ImageLayout.Stretch;
syncScreenButton.FlatStyle = FlatStyle.Flat;
syncScreenButton.FlatAppearance.BorderSize = 0;
syncScreenButton.Click += SyncScreenButton_Click;
this.Controls.Add(syncScreenButton);
toggleLightButton = new Button{ Text = "" };
toggleLightButton.Name = "toggleLightButton";
ResizeAndPositionButton(toggleLightButton, 1002, 756, 91, 130);
Rectangle toggleLightButtonCropArea = new Rectangle(1002, 756, 91, 130);
toggleLightButton.BackgroundImage = normalStateImage.Clone(toggleLightButtonCropArea, normalStateImage.PixelFormat);
toggleLightButton.BackgroundImageLayout = ImageLayout.Stretch;
toggleLightButton.FlatStyle = FlatStyle.Flat;
toggleLightButton.FlatAppearance.BorderSize = 0;
toggleLightButton.Click += ToggleLightButton_Click;
this.Controls.Add(toggleLightButton);
Rectangle previousPageButtonCropArea = new Rectangle(1109, 754, 93, 58);
InitializeButton(
ref btnPreviousPage,
"btnPreviousPage",
1109, 754, 93, 58,
previousPageButtonCropArea,
normalStateImage,
PreviousPageButton_Click
);
btnReturn = new Button{ Text = "" };
btnReturn.Name = "btnReturn";
ResizeAndPositionButton(btnReturn, 1218, 755, 92, 57);
Rectangle returnButtonCropArea = new Rectangle(1218, 755, 92, 57);
btnReturn.BackgroundImage = normalStateImage.Clone(returnButtonCropArea, normalStateImage.PixelFormat);
btnReturn.BackgroundImageLayout = ImageLayout.Stretch;
btnReturn.FlatStyle = FlatStyle.Flat;
btnReturn.FlatAppearance.BorderSize = 0;
btnReturn.Click += ShouYeButton_Click;
this.Controls.Add(btnReturn);
Rectangle nextPageButtonCropArea = new Rectangle(1326, 754, 92, 58);
InitializeButton(
ref btnNextPage,
"btnNextPage",
1326, 754, 92, 58,
nextPageButtonCropArea,
normalStateImage,
NextPageButton_Click
);
Rectangle applauseButtonCropArea = new Rectangle(1110, 828, 91, 55);
InitializeButton(
ref btnApplause,
"btnApplause",
1110, 828, 91, 55,
applauseButtonCropArea,
normalStateImage,
ApplauseButton_Click
);
Rectangle simplifiedChineseButtonCropArea = new Rectangle(1327, 828, 90, 55);
InitializeButton(
ref btnSimplifiedChinese,
"btnSimplifiedChinese",
1327, 828, 90, 55,
simplifiedChineseButtonCropArea,
normalStateImage,
SimplifiedChineseButton_Click
);
Rectangle traditionalChineseButtonCropArea = new Rectangle(1219, 828, 90, 55);
InitializeButton(
ref btnTraditionalChinese,
"btnTraditionalChinese",
1219, 828, 90, 55,
traditionalChineseButtonCropArea,
normalStateImage,
TraditionalChineseButton_Click
);
/* 關閉應用程式按鈕*/
2025-04-07 16:54:10 +08:00
exitButton = new Button{};
/*exitButton.Name = "exitButton";
2025-04-07 16:54:10 +08:00
ConfigureButton(exitButton, 1394, 2, 1428 - 1394, 37 - 2,
resizedNormalStateImage, resizedMouseOverImage, resizedMouseDownImage,
(sender, e) => Application.Exit());*/
2025-04-07 16:54:10 +08:00
}
private void InitializeButton(ref Button button, ref Bitmap normalBackground, ref Bitmap activeBackground, string buttonName, int x, int y, int width, int height, string imagePath, EventHandler clickEventHandler)
{
button = new Button { Text = "", Name = buttonName };
ResizeAndPositionButton(button, x, y, width, height);
Rectangle buttonCropArea = new Rectangle(x, y, width, height);
normalBackground = new Bitmap(Path.Combine(Application.StartupPath, imagePath));
activeBackground = mouseDownImage.Clone(buttonCropArea, mouseDownImage.PixelFormat);
button.BackgroundImage = normalBackground;
button.BackgroundImageLayout = ImageLayout.Stretch;
button.FlatStyle = FlatStyle.Flat;
button.FlatAppearance.BorderSize = 0;
if (clickEventHandler != null)
{
button.Click += clickEventHandler;
}
this.Controls.Add(button);
}
private void InitializeButton(
ref Button button,
string buttonName,
int x, int y,
int width, int height,
Rectangle cropArea,
Bitmap normalStateImage,
EventHandler clickEventHandler)
{
button = new Button { Text = "", Name = buttonName };
ResizeAndPositionButton(button, x, y, width, height);
button.BackgroundImage = normalStateImage.Clone(cropArea, normalStateImage.PixelFormat);
button.BackgroundImageLayout = ImageLayout.Stretch;
button.FlatStyle = FlatStyle.Flat;
button.FlatAppearance.BorderSize = 0;
if (clickEventHandler != null)
{
button.Click += clickEventHandler;
}
this.Controls.Add(button);
}
private void InitializeMultiPagePanel()
{
// 獲取螢幕尺寸
Screen screen = Screen.PrimaryScreen;
int screenWidth = screen.Bounds.Width;
int screenHeight = screen.Bounds.Height;
// 計算縮放比例
float widthRatio = screenWidth / 1440f;
float heightRatio = screenHeight / 900f;
multiPagePanel = new MultiPagePanel();
// 計算面板位置和大小
int panelX = (int)(PanelStartLeft * widthRatio);
int panelY = (int)(PanelStartTop * heightRatio);
int panelWidth = (int)((PanelEndLeft - PanelStartLeft) * widthRatio);
int panelHeight = (int)((PanelEndTop - PanelStartTop) * heightRatio);
multiPagePanel.Location = new Point(panelX, panelY);
multiPagePanel.Size = new Size(panelWidth, panelHeight);
this.Controls.Add(multiPagePanel);
multiPagePanel.BringToFront();
}
private SongData currentSelectedSong;
public void Label_Click(object sender, EventArgs e)
{
var label = sender as Label;
if (label != null && label.Tag is SongData)
{
currentSelectedSong = label.Tag as SongData;
this.DoubleBuffered = true;
this.SuspendLayout();
DrawTextOnVodScreenPictureBox(Path.Combine(Application.StartupPath, @"themes\superstar\點播介面\點播介面_有按鈕.png"), currentSelectedSong);
SetVodScreenPictureBoxAndButtonsVisibility(true);
this.ResumeLayout(true);
}
}
public static void WriteLog(string message)
{
2025-04-09 11:46:18 +08:00
string logFilePath = Path.Combine(Application.StartupPath, "txt", "logfile.txt");
2025-04-07 16:54:10 +08:00
using (StreamWriter sw = new StreamWriter(logFilePath, true))
{
sw.WriteLine(String.Format("{0}: {1}", DateTime.Now, message));
}
}
public static void PrintPlayingSongList()
{
Console.WriteLine("當前播放列表:");
foreach (var song in userRequestedSongs)
{
2025-07-08 18:13:36 +08:00
Console.WriteLine(song.name_text());
2025-04-07 16:54:10 +08:00
}
}
private void NextPageButton_Click(object sender, EventArgs e)
{
multiPagePanel.LoadNextPage();
}
private void SimplifiedChineseButton_Click(object sender, EventArgs e)
{
Console.WriteLine("切換到簡體顯示"); // 添加日誌
if (multiPagePanel != null)
{
multiPagePanel.IsSimplified = true;
btnSimplifiedChinese.Enabled = false;
btnTraditionalChinese.Enabled = true;
}
}
private void TraditionalChineseButton_Click(object sender, EventArgs e)
{
Console.WriteLine("切換到繁體顯示"); // 添加日誌
if (multiPagePanel != null)
{
multiPagePanel.IsSimplified = false;
btnSimplifiedChinese.Enabled = true;
btnTraditionalChinese.Enabled = false;
}
}
private void PreviousPageButton_Click(object sender, EventArgs e)
{
multiPagePanel.LoadPreviousPage();
}
private void LoadSongData()
{
userRequestedSongs = new List<SongData>();
playedSongsHistory = new List<SongData>();
playStates = new List<PlayState>();
2025-04-07 16:54:10 +08:00
}
private Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
using (var wrapMode = new System.Drawing.Imaging.ImageAttributes())
{
wrapMode.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
private void LoadImages()
{
string selectedThemePath = ReadSelectedThemePath();
string basePath = Path.Combine(Application.StartupPath, selectedThemePath);
int targetWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
int targetHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
normalStateImage = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\555009.jpg"));
resizedNormalStateImage = ResizeImage(normalStateImage, targetWidth, targetHeight);
mouseOverImage = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\主選單_已按.jpg"));
resizedMouseOverImage = ResizeImage(mouseOverImage, targetWidth, targetHeight);
mouseDownImage = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\主選單_已按.jpg"));
resizedMouseDownImage = ResizeImage(mouseDownImage, targetWidth, targetHeight);
normalStateImageNewSongAlert = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\新歌快報_未按.jpg"));
resizedNormalStateImageForNewSongAlert = ResizeImage(normalStateImageNewSongAlert, targetWidth, targetHeight);
mouseOverImageNewSongAlert = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\新歌快報_已按.jpg"));
resizedMouseOverImageForNewSongAlert = ResizeImage(mouseOverImageNewSongAlert, targetWidth, targetHeight);
mouseDownImageNewSongAlert = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\新歌快報_已按.jpg"));
resizedMouseDownImageForNewSongAlert = ResizeImage(mouseDownImageNewSongAlert, targetWidth, targetHeight);
normalStateImageArtistQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\3.歌星查詢_未按.jpg"));
resizedNormalStateImageForArtistQuery = ResizeImage(normalStateImageArtistQuery, targetWidth, targetHeight);
mouseOverImageArtistQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\3.歌星查詢_已按.jpg"));
resizedMouseOverImageForArtistQuery = ResizeImage(mouseOverImageArtistQuery, targetWidth, targetHeight);
mouseDownImageArtistQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\3.歌星查詢_已按.jpg"));
resizedMouseDownImageForArtistQuery = ResizeImage(mouseDownImageArtistQuery, targetWidth, targetHeight);
normalStateImageSongQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\4.歌名查詢_未按.jpg"));
resizedNormalStateImageForSongQuery = ResizeImage(normalStateImageSongQuery, targetWidth, targetHeight);
mouseOverImageSongQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\4.歌名查詢_已按.jpg"));
resizedMouseOverImageForSongQuery = ResizeImage(mouseOverImageSongQuery, targetWidth, targetHeight);
mouseDownImageSongQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\4.歌名查詢_已按.jpg"));
resizedMouseDownImageForSongQuery = ResizeImage(mouseDownImageSongQuery, targetWidth, targetHeight);
normalStateImageLanguageQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\語別查詢_未按.jpg"));
resizedNormalStateImageForLanguageQuery = ResizeImage(normalStateImageLanguageQuery, targetWidth, targetHeight);
mouseOverImageLanguageQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\語別查詢_已按.jpg"));
resizedMouseOverImageForLanguageQuery = ResizeImage(mouseOverImageLanguageQuery, targetWidth, targetHeight);
mouseDownImageLanguageQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\語別查詢_已按.jpg"));
resizedMouseDownImageForLanguageQuery = ResizeImage(mouseDownImageLanguageQuery, targetWidth, targetHeight);
normalStateImageCategoryQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\類別查詢_未按.jpg"));
resizedNormalStateImageForCategoryQuery = ResizeImage(normalStateImageCategoryQuery, targetWidth, targetHeight);
mouseOverImageCategoryQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\類別查詢_已按.jpg"));
resizedMouseOverImageForCategoryQuery = ResizeImage(mouseOverImageCategoryQuery, targetWidth, targetHeight);
mouseDownImageCategoryQuery = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\類別查詢_已按.jpg"));
resizedMouseDownImageForCategoryQuery = ResizeImage(mouseDownImageCategoryQuery, targetWidth, targetHeight);
normalStateImageForPromotionsAndMenu = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\555021.jpg"));
resizedNormalStateImageForPromotionsAndMenu = ResizeImage(normalStateImageForPromotionsAndMenu, targetWidth, targetHeight);
try
{
string imagePath = Path.Combine(Application.StartupPath, "themes\\superstar\\555019.jpg");
if (File.Exists(imagePath))
{
normalStateImageForSyncScreen = new Bitmap(imagePath);
resizedNormalStateImageForSyncScreen = ResizeImage(normalStateImageForSyncScreen, targetWidth, targetHeight);
Console.WriteLine("Image loaded successfully.");
}
else
{
Console.WriteLine("Image file does not exist: " + imagePath);
}
}
catch (Exception ex)
{
Console.WriteLine("Failed to load image: " + ex.Message);
}
normalStateImageForSceneSoundEffects = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\555022.jpg"));
resizedNormalStateImageForSceneSoundEffects = ResizeImage(normalStateImageForSceneSoundEffects, targetWidth, targetHeight);
normalStateImageHotSong = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\熱門排行_未按.jpg"));
resizedNormalStateImageForHotSong = ResizeImage(normalStateImageHotSong, targetWidth, targetHeight);
mouseDownImageHotSong = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\熱門排行_已按.jpg"));
resizedMouseDownImageForHotSong = ResizeImage(mouseDownImageHotSong, targetWidth, targetHeight);
normalStateImageForLightControl = new Bitmap(Path.Combine(Application.StartupPath, "themes\\superstar\\選單內介面_燈光控制.jpg"));
resizedNormalStateImageForLightControl = ResizeImage(normalStateImageForLightControl, targetWidth, targetHeight);
}
private Bitmap CropImage(Bitmap source, Rectangle section)
{
Bitmap bmp = new Bitmap(section.Width, section.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
}
return bmp;
}
private void DrawTextOnVodScreenPictureBox(string imagePath, SongData songData)
{
Bitmap originalImage = new Bitmap(imagePath);
VodScreenPictureBox.Image = originalImage;
2025-04-17 15:53:19 +08:00
int screenWidth = 1440;
int screenHeight = 900;
int pictureBoxWidth = (int)(938*0.8f);
int pictureBoxHeight = (int)(209*0.8f);
2025-04-07 16:54:10 +08:00
int xPosition = (screenWidth - pictureBoxWidth) / 2;
int yPosition = (screenHeight - pictureBoxHeight) / 2;
using (Graphics g = Graphics.FromImage(originalImage))
{
2025-05-21 15:42:42 +08:00
// 計算文字寬度
2025-04-07 16:54:10 +08:00
float dpiX = g.DpiX;
float points = 25;
2025-05-21 15:42:42 +08:00
float pixels = points * (dpiX / 72);
2025-04-07 16:54:10 +08:00
Font font = new Font("微軟正黑體", points, FontStyle.Bold);
2025-05-21 15:42:42 +08:00
// 根據文字長度設置字體大小
2025-07-08 18:13:36 +08:00
if (songData.getNameLength() > 18)
2025-05-21 15:42:42 +08:00
{
font = new Font("微軟正黑體", 17, FontStyle.Bold);
}
2025-07-08 18:13:36 +08:00
else if (songData.getNameLength() > 13)
2025-05-21 15:42:42 +08:00
{
font = new Font("微軟正黑體", 21, FontStyle.Bold);
}
else
{
font = new Font("微軟正黑體", 25, FontStyle.Bold);
}
2025-04-07 16:54:10 +08:00
Brush textBrush = Brushes.Black;
2025-07-08 18:13:36 +08:00
string songInfo = songData.Name ?? "未提供歌曲信息";
2025-04-07 16:54:10 +08:00
2025-06-24 10:35:01 +08:00
g.DrawString(songInfo, font, textBrush, new PointF(201, 29));
2025-04-07 16:54:10 +08:00
}
ResizeAndPositionPictureBox(VodScreenPictureBox, xPosition, yPosition, pictureBoxWidth, pictureBoxHeight);
VodScreenPictureBox.Visible = true;
}
public static void ResizeAndPositionButton(Button button, int x, int y, int width, int height)
{
// 獲取螢幕尺寸
Screen screen = Screen.PrimaryScreen;
int screenWidth = screen.Bounds.Width;
int screenHeight = screen.Bounds.Height;
// 計算縮放比例
float widthRatio = screenWidth / 1440f;
float heightRatio = screenHeight / 900f;
// 調整按鈕位置和大小
button.Location = new Point(
(int)(x * widthRatio),
(int)(y * heightRatio)
);
button.Size = new Size(
(int)(width * widthRatio),
(int)(height * heightRatio)
);
}
private static void ResizeAndPositionPictureBox(PictureBox pictureBox, int originalX, int originalY, int originalWidth, int originalHeight)
{
int screenW = Screen.PrimaryScreen.Bounds.Width;
int screenH = Screen.PrimaryScreen.Bounds.Height;
2025-04-17 15:53:19 +08:00
float widthRatio = screenW / (float)1440;
float heightRatio = screenH / (float)900;
2025-04-07 16:54:10 +08:00
pictureBox.Location = new Point(
(int)(originalX * widthRatio),
(int)(originalY * heightRatio)
);
pictureBox.Size = new Size(
(int)(originalWidth * widthRatio),
(int)(originalHeight * heightRatio)
);
}
public static void ResizeAndPositionControl(Control control, int x, int y, int width, int height)
{
// 獲取螢幕尺寸
Screen screen = Screen.PrimaryScreen;
int screenWidth = screen.Bounds.Width;
int screenHeight = screen.Bounds.Height;
// 計算縮放比例
float widthRatio = screenWidth / 1440f;
float heightRatio = screenHeight / 900f;
// 調整控件位置和大小
control.Location = new Point(
(int)(x * widthRatio),
(int)(y * heightRatio)
);
control.Size = new Size(
(int)(width * widthRatio),
(int)(height * heightRatio)
);
}
private void DeliciousFoodButton_Click(object sender, EventArgs e)
{
newSongAlertButton.BackgroundImage = newSongAlertNormalBackground;
hotPlayButton.BackgroundImage = hotPlayNormalBackground;
singerSearchButton.BackgroundImage = singerSearchNormalBackground;
songSearchButton.BackgroundImage = songSearchNormalBackground;
languageSearchButton.BackgroundImage = languageSearchNormalBackground;
groupSearchButton.BackgroundImage = groupSearchNormalBackground;
categorySearchButton.BackgroundImage = categorySearchNormalBackground;
orderedSongsButton.BackgroundImage = orderedSongsNormalBackground;
myFavoritesButton.BackgroundImage = myFavoritesNormalBackground;
promotionsButton.BackgroundImage = promotionsNormalBackground;
deliciousFoodButton.BackgroundImage = deliciousFoodActiveBackground;
isOnOrderedSongsPage = false;
SetHotSongButtonsVisibility(false);
SetNewSongButtonsVisibility(false);
SetSingerSearchButtonsVisibility(false);
SetSongSearchButtonsVisibility(false);
SetPictureBoxLanguageButtonsVisibility(false);
SetGroupButtonsVisibility(false);
SetZhuYinSingersAndButtonsVisibility(false);
SetZhuYinSongsAndButtonsVisibility(false);
SetEnglishSingersAndButtonsVisibility(false);
SetEnglishSongsAndButtonsVisibility(false);
SetPinYinSingersAndButtonsVisibility(false);
SetPinYinSongsAndButtonsVisibility(false);
SetPictureBoxCategoryAndButtonsVisibility(false);
promotionsAndMenuPanel.currentPageIndex = 0;
promotionsAndMenuPanel.LoadImages(menu);
promotionsAndMenuPanel.Visible = true;
promotionsAndMenuPanel.BringToFront();
previousPromotionButton.Visible = true;
previousPromotionButton.BringToFront();
nextPromotionButton.Visible = true;
nextPromotionButton.BringToFront();
closePromotionsButton.Visible = true;
closePromotionsButton.BringToFront();
if (pictureBoxQRCode != null)
{
pictureBoxQRCode.Visible = false;
closeQRCodeButton.Visible = false;
}
}
private void MobileSongRequestButton_Click(object sender, EventArgs e)
{
SetHotSongButtonsVisibility(false);
SetNewSongButtonsVisibility(false);
SetSingerSearchButtonsVisibility(false);
SetSongSearchButtonsVisibility(false);
SetPictureBoxLanguageButtonsVisibility(false);
SetZhuYinSingersAndButtonsVisibility(false);
SetZhuYinSongsAndButtonsVisibility(false);
SetEnglishSingersAndButtonsVisibility(false);
SetEnglishSongsAndButtonsVisibility(false);
SetPinYinSingersAndButtonsVisibility(false);
SetPinYinSongsAndButtonsVisibility(false);
SetGroupButtonsVisibility(false);
if (pictureBoxQRCode != null)
{
pictureBoxQRCode.Visible = true;
pictureBoxQRCode.BringToFront();
closeQRCodeButton.Visible = true;
closeQRCodeButton.BringToFront();
}
else
{
Console.WriteLine("pictureBoxQRCode is not initialized!");
}
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
public void OriginalSongButton_Click(object sender, EventArgs e)
{
videoPlayerForm.ToggleVocalRemoval();
}
private void ReplayButton_Click(object sender, EventArgs e)
{
videoPlayerForm.ReplayCurrentSong();
}
2025-06-20 13:12:10 +08:00
public void PauseButton_Click(object sender, EventArgs e)
2025-04-07 16:54:10 +08:00
{
videoPlayerForm.Pause();
pauseButton.Visible = false;
playButton.Visible = true;
}
2025-06-20 13:12:10 +08:00
public void PlayButton_Click(object sender, EventArgs e)
2025-04-07 16:54:10 +08:00
{
videoPlayerForm.Play();
playButton.Visible = false;
pauseButton.Visible = true;
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
/// <summary>
/// 右下角關閉按鈕事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ShouYeButton_Click(object sender, EventArgs e)
{ /*Console.WriteLine("playedSongsHistory");
foreach(var song in playedSongsHistory){
Console.WriteLine(song.ToString());
}
Console.WriteLine("userRequestedSongs");
foreach(var song in userRequestedSongs){
Console.WriteLine(song.ToString());
}*/
if( multiPagePanel.get_currentSongList() == playedSongsHistory)
return;
2025-04-07 16:54:10 +08:00
autoRefreshTimer.Stop(); // 停止自动刷新
FindFirstNonEmptyText(inputBoxZhuYinSingers
, inputBoxZhuYinSongs
, inputBoxEnglishSingers
, inputBoxEnglishSongs
, inputBoxPinYinSingers
, inputBoxPinYinSongs
, inputBoxWordCountSingers
, inputBoxWordCountSongs
, inputBoxSongIDSearch
, handwritingInputBoxForSongs
, handwritingInputBoxForSingers);
foreach (var label in songLabels)
{
this.Controls.Remove(label);
label.Dispose();
}
songLabels.Clear();
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
/// <summary>
/// 查詢空字串,將第一個不為空的字串,重新刷新
/// </summary>
/// <param name="controls"></param>
private void FindFirstNonEmptyText(params Control[] controls)
{
2025-04-14 11:55:18 +08:00
var searchActions = new Dictionary<Control, Action>
{
{ inputBoxZhuYinSingers, FindZhuYiSingers },
{ inputBoxZhuYinSongs, FindZhuYiSongs },
{ inputBoxEnglishSingers, FindEnglishSingers },
{ inputBoxEnglishSongs, FindEnglishSongs },
{ inputBoxPinYinSingers, FindPinYinSingers },
{ inputBoxPinYinSongs, FindPinYinSongs },
{ inputBoxWordCountSingers, FindWordCountSingers },
{ inputBoxWordCountSongs, FindWordCountSongs },
{ inputBoxSongIDSearch, FindNumberSongs },
{ handwritingInputBoxForSongs, FindHandwritingSongs },
{ handwritingInputBoxForSingers, FindHandwritingSingers },
};
2025-04-07 16:54:10 +08:00
foreach (var control in controls)
{
if (!string.IsNullOrEmpty(control.Text))
2025-04-14 11:55:18 +08:00
{
2025-04-07 16:54:10 +08:00
var temp = control.Text;
2025-04-14 11:55:18 +08:00
ResetinputBox(); // 清除所有輸入框
control.Text = temp; // 還原唯一有內容的那個
if (searchActions.TryGetValue(control, out var action))
{
action.Invoke(); // 執行對應的查詢方法
}
break; // 只處理第一個有文字的輸入框
2025-04-07 16:54:10 +08:00
}
}
}
2025-04-14 11:55:18 +08:00
2025-04-07 16:54:10 +08:00
/// <summary>
/// 重置所有輸入框
/// </summary>
private void ResetinputBox()
{
inputBoxZhuYinSingers?.Clear();
inputBoxZhuYinSongs?.Clear();
inputBoxEnglishSingers?.Clear();
inputBoxEnglishSongs?.Clear();
inputBoxPinYinSingers?.Clear();
inputBoxPinYinSongs?.Clear();
inputBoxWordCountSingers?.Clear();
inputBoxWordCountSongs?.Clear();
inputBoxSongIDSearch?.Clear();
handwritingInputBoxForSongs?.Clear();
handwritingInputBoxForSingers?.Clear();
2025-04-07 16:54:10 +08:00
}
2025-04-07 16:54:10 +08:00
private void MuteUnmuteButton_Click(object sender, EventArgs e)
{
SetHotSongButtonsVisibility(false);
SetNewSongButtonsVisibility(false);
SetSingerSearchButtonsVisibility(false);
SetSongSearchButtonsVisibility(false);
SetPictureBoxToggleLightAndButtonsVisibility(false);
if (videoPlayerForm.isMuted)
{
videoPlayerForm.SetVolume(videoPlayerForm.previousVolume);
videoPlayerForm.isMuted = false;
OverlayForm.MainForm.HideMuteLabel();
}
else
{
videoPlayerForm.previousVolume = videoPlayerForm.GetVolume();
videoPlayerForm.SetVolume(-10000);
videoPlayerForm.isMuted = true;
OverlayForm.MainForm.ShowMuteLabel();
}
}
private void MaleKeyButton_Click(object sender, EventArgs e)
{
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
{
byte[] commandBytesIncreasePitch1 = new byte[] { 0xA2, 0x7F, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch1, 0, commandBytesIncreasePitch1.Length);
OverlayForm.MainForm.HideAllLabels();
byte[] commandBytesDecreasePitch = new byte[] { 0xA2, 0xB2, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesDecreasePitch, 0, commandBytesDecreasePitch.Length);
OverlayForm.MainForm.HideAllLabels();
SerialPortManager.mySerialPort.Write(commandBytesDecreasePitch, 0, commandBytesDecreasePitch.Length);
OverlayForm.MainForm.HideAllLabels();
}
else
{
MessageBox.Show("串口未開啟,無法發送降調指令。");
}
OverlayForm.MainForm.ShowMaleKeyLabel();
}
private void FemaleKeyButton_Click(object sender, EventArgs e)
{
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
{
byte[] commandBytesIncreasePitch1 = new byte[] { 0xA2, 0x7F, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch1, 0, commandBytesIncreasePitch1.Length);
OverlayForm.MainForm.HideAllLabels();
byte[] commandBytesIncreasePitch = new byte[] { 0xA2, 0xB1, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch, 0, commandBytesIncreasePitch.Length);
OverlayForm.MainForm.HideAllLabels();
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch, 0, commandBytesIncreasePitch.Length);
OverlayForm.MainForm.HideAllLabels();
}
else
{
MessageBox.Show("串口未開啟,無法發送升調指令。");
}
OverlayForm.MainForm.ShowFemaleKeyLabel();
}
private void StandardKeyButton_Click(object sender, EventArgs e)
{
OverlayForm.MainForm.ShowStandardKeyLabel();
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
{
byte[] commandBytesIncreasePitch = new byte[] { 0xA2, 0x7F, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch, 0, commandBytesIncreasePitch.Length);
}
else
{
MessageBox.Show("串口未開啟,無法發送升調指令。");
}
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
private void PitchUpButton_Click(object sender, EventArgs e)
{
OverlayForm.MainForm.ShowKeyUpLabel();
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
{
byte[] commandBytesIncreasePitch = new byte[] { 0xA2, 0xB1, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch, 0, commandBytesIncreasePitch.Length);
}
else
{
MessageBox.Show("串口未開啟,無法發送升調指令。");
}
}
private void PitchDownButton_Click(object sender, EventArgs e)
{
OverlayForm.MainForm.ShowKeyDownLabel();
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
{
byte[] commandBytesDecreasePitch = new byte[] { 0xA2, 0xB2, 0xA4 };
SerialPortManager.mySerialPort.Write(commandBytesDecreasePitch, 0, commandBytesDecreasePitch.Length);
}
else
{
MessageBox.Show("串口未開啟,無法發送降調指令。");
}
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
private void ApplauseButton_Click(object sender, EventArgs e)
{
PlayApplauseSound();
}
private bool isWaiting = false;
//服務鈴事件
2025-04-07 16:54:10 +08:00
private async void OnServiceBellButtonClick(object sender, EventArgs e)
{
if (isWaiting) return;
isWaiting = true;
// 发送串口命令
SendCommandThroughSerialPort("a2 53 a4");
// 显示提示信息
OverlayForm.MainForm.HideAllLabels();
OverlayForm.MainForm.ShowServiceBell();
2025-04-07 16:54:10 +08:00
// 延迟3秒
await Task.Delay(3000);
// 隐藏提示信息
//OverlayForm.MainForm.HideServiceBellLabel();
2025-04-07 16:54:10 +08:00
isWaiting = false;
}
private void InitializeSendOffPanel()
{
sendOffPanel = new Panel
{
Dock = DockStyle.Fill,
2025-04-08 11:34:46 +08:00
//BackColor = Color.Black,
BackgroundImage = LoadSendOffImage(),
BackgroundImageLayout = ImageLayout.Stretch
2025-04-07 16:54:10 +08:00
};
// 初始化服務鈴圖標
serviceBellPictureBox = new PictureBox {
Visible = true,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
Image = LoadButtonImage("服務鈴.png"),
Cursor = System.Windows.Forms.Cursors.Hand,
};
// 添加服務鈴點擊事件
serviceBellPictureBox.Click += (sender, e) => {
if (serviceBellButton != null)
{
OnServiceBellButtonClick(sender, e);
}
};
// 使用 PictureBox 並加載小圖片
buttonMiddle = new PictureBox {
Visible = true,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
2025-04-08 11:34:46 +08:00
Image = null,//LoadButtonImage("巨.png")
2025-04-07 16:54:10 +08:00
Cursor = System.Windows.Forms.Cursors.Hand
};
buttonTopRight = new PictureBox {
Visible = true,
BackColor = Color.Transparent,
SizeMode = PictureBoxSizeMode.StretchImage,
2025-04-08 11:34:46 +08:00
Image = null, //LoadButtonImage("級.png")
2025-04-07 16:54:10 +08:00
Cursor = System.Windows.Forms.Cursors.Hand
};
buttonTopLeft = new PictureBox {
Visible = true,
2025-04-08 11:34:46 +08:00
BackColor = Color.Transparent,
2025-04-07 16:54:10 +08:00
SizeMode = PictureBoxSizeMode.StretchImage,
2025-04-08 11:34:46 +08:00
Image = null, //LoadButtonImage("超.png")
2025-04-07 16:54:10 +08:00
Cursor = System.Windows.Forms.Cursors.Hand
};
buttonThanks = new PictureBox {
Visible = true,
2025-04-08 11:34:46 +08:00
BackColor = Color.Transparent,
2025-04-07 16:54:10 +08:00
SizeMode = PictureBoxSizeMode.StretchImage,
2025-04-08 11:34:46 +08:00
Image = null, //LoadButtonImage("星.png")
2025-04-07 16:54:10 +08:00
Cursor = System.Windows.Forms.Cursors.Hand
};
2025-04-08 11:34:46 +08:00
// 設定按鈕的初始位置和大小
UpdateSendOffButtonPositions();
2025-04-07 16:54:10 +08:00
// 添加點擊事件
buttonMiddle.Click += buttonMiddle_Click;
buttonTopRight.Click += buttonTopRight_Click;
buttonTopLeft.Click += buttonTopLeft_Click;
buttonThanks.Click += buttonThanks_Click;
// 添加控件到面板
sendOffPanel.Controls.Add(serviceBellPictureBox); // 添加服務鈴
sendOffPanel.Controls.Add(buttonMiddle);
sendOffPanel.Controls.Add(buttonTopRight);
sendOffPanel.Controls.Add(buttonTopLeft);
sendOffPanel.Controls.Add(buttonThanks);
2025-04-08 11:34:46 +08:00
// 包廂名稱顯示
sendOffPanel.Paint+=SendOffPanel_Paint;
2025-04-07 16:54:10 +08:00
// 確保圖片在最上層
serviceBellPictureBox.BringToFront(); // 確保服務鈴在最上層
buttonMiddle.BringToFront();
buttonTopRight.BringToFront();
buttonTopLeft.BringToFront();
buttonThanks.BringToFront();
2025-04-08 11:34:46 +08:00
// 重新計算按鈕位置
sendOffPanel.Resize += (s, e) => {
UpdateSendOffButtonPositions();
sendOffPanel.Invalidate(); // 重新繪製面板以更新顯示
};
2025-04-07 16:54:10 +08:00
this.Controls.Add(sendOffPanel);
}
2025-04-15 13:16:32 +08:00
2025-04-08 11:34:46 +08:00
/// <summary>
/// 動態按鈕座標位置設定(依據螢幕大小)
/// </summary>
private void UpdateSendOffButtonPositions()
{ Size designSize = new Size(1920, 1080);
var panelWidth = sendOffPanel.Width;
var panelHeight = sendOffPanel.Height;
// 計算寬高的縮放比例
float scaleX = panelWidth / (float)designSize.Width;
float scaleY = panelHeight / (float)designSize.Height;
// 幫你設定的按鈕位置(以原始座標為基礎)
buttonTopLeft.Location = new Point((int)(1598 * scaleX), (int)(490 * scaleY));
buttonTopRight.Location = new Point(panelWidth - (int)(80 * scaleX), 0);
buttonMiddle.Location = new Point(0, 0);
buttonThanks.Location = new Point((int)(831 * scaleX), (int)(490 * scaleY));
// 設定按鈕縮放後的大小(原始尺寸 * 縮放比例)
buttonTopLeft.Size = new Size((int)(150 * scaleX), (int)(150 * scaleY));
buttonTopRight.Size = new Size((int)(80 * scaleX), (int)(80 * scaleY));
buttonMiddle.Size = new Size((int)(80 * scaleX), (int)(80 * scaleY));
buttonThanks.Size = new Size((int)(150 * scaleX), (int)(150 * scaleY));
// ========== 服務鈴位置與大小 ==========
serviceBellPictureBox.Location = new Point((int)(757 * scaleX), (int)(151 * scaleY));
serviceBellPictureBox.Size = new Size((int)(410 * scaleX), (int)(130 * scaleY));
}
2025-04-15 13:16:32 +08:00
2025-04-08 11:34:46 +08:00
/// <summary>
/// 送客畫面包廂名稱顯示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SendOffPanel_Paint(object sender, PaintEventArgs e)
{
Size designSize = new Size(1920, 1080);
var panelWidth = sendOffPanel.Width;
var panelHeight = sendOffPanel.Height;
2025-04-07 16:54:10 +08:00
2025-04-08 11:34:46 +08:00
// 計算寬高的縮放比例
float scaleX = panelWidth / (float)designSize.Width;
float scaleY = panelHeight / (float)designSize.Height;
float scaledFontSize = 84f * scaleY;
string hostName = System.Net.Dns.GetHostName();
string displayName = "包廂" + hostName.Substring(Math.Max(0, hostName.Length - 3));
2025-04-08 11:34:46 +08:00
using (Font font = new Font("微軟正黑體", scaledFontSize, FontStyle.Bold))
using (Brush brush = new SolidBrush(Color.Red))
{
PointF point_PCName = new PointF(820 * scaleX, 325 * scaleY);
e.Graphics.DrawString(displayName, font, brush, point_PCName);
}
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
// 添加載入按鈕圖片的方法
private Image LoadButtonImage(string imageName)
{
try
{
2025-04-11 09:50:48 +08:00
string filePath = Path.Combine(Application.StartupPath, "themes", "superstar", "ButtonImages", imageName);
2025-04-07 16:54:10 +08:00
if (File.Exists(filePath))
{
return Image.FromFile(filePath);
}
return null;
}
catch (Exception ex)
{
Console.WriteLine($"載入按鈕圖片時發生錯誤: {ex.Message}");
return null;
}
}
2025-04-15 13:16:32 +08:00
2025-04-07 16:54:10 +08:00
/// <summary>
/// 加載送客畫面圖片
/// </summary>
/// <returns></returns>
private Image LoadSendOffImage()
{
try
{
string filePath = Path.Combine(Application.StartupPath, "themes\\superstar\\VOD_送客畫面.jpg");
if (File.Exists(filePath))
{
return Image.FromFile(filePath);
}
else
{
Console.WriteLine("VOD_送客畫面.jpg 文件未找到。");
return null;
}
}
catch (Exception ex)
{
Console.WriteLine($"加載送客畫面圖片時發生錯誤: {ex.Message}");
return null;
}
}
// 添加 Form Load 事件處理方法
private void PrimaryForm_Load(object sender, EventArgs e)
{
2025-04-07 16:54:10 +08:00
if (hotPlayButton != null)
{
HotPlayButton_Click(null, EventArgs.Empty);
}
if (Program.RoomState.Equals("CLOSE"))
{
ShowSendOffScreen();
}
// 確保所有控件都已初始化完成後,再觸發熱門排行按鈕點擊
2025-04-07 16:54:10 +08:00
}
private void AutoRefreshTimer_Tick(object sender, EventArgs e)
{
if (isOnOrderedSongsPage)
{
multiPagePanel.RefreshDisplay();
}
}
private void OrderedSongsButton_Click(object sender, EventArgs e)
{
newSongAlertButton.BackgroundImage = newSongAlertNormalBackground;
hotPlayButton.BackgroundImage = hotPlayNormalBackground;
singerSearchButton.BackgroundImage = singerSearchNormalBackground;
songSearchButton.BackgroundImage = songSearchNormalBackground;
languageSearchButton.BackgroundImage = languageSearchNormalBackground;
groupSearchButton.BackgroundImage = groupSearchNormalBackground;
categorySearchButton.BackgroundImage = categorySearchNormalBackground;
orderedSongsButton.BackgroundImage = orderedSongsActiveBackground;
myFavoritesButton.BackgroundImage = myFavoritesNormalBackground;
promotionsButton.BackgroundImage = promotionsNormalBackground;
deliciousFoodButton.BackgroundImage = deliciousFoodNormalBackground;
isOnOrderedSongsPage = true;
autoRefreshTimer.Start(); // 开始自动刷新
2025-04-21 13:07:01 +08:00
// 已點歌曲錨點
2025-04-07 16:54:10 +08:00
currentSongList = playedSongsHistory;
totalPages = (int)Math.Ceiling((double)playedSongsHistory.Count / itemsPerPage);
multiPagePanel.currentPageIndex = 0;
SetHotSongButtonsVisibility(false);
SetNewSongButtonsVisibility(false);
SetSingerSearchButtonsVisibility(false);
SetSongSearchButtonsVisibility(false);
SetPictureBoxLanguageButtonsVisibility(false);
SetGroupButtonsVisibility(false);
SetZhuYinSingersAndButtonsVisibility(false);
SetZhuYinSongsAndButtonsVisibility(false);
SetEnglishSingersAndButtonsVisibility(false);
SetEnglishSongsAndButtonsVisibility(false);
// SetPictureBoxWordCountAndButtonsVisibility(false);
SetPinYinSingersAndButtonsVisibility(false);
SetPinYinSongsAndButtonsVisibility(false);
SetPictureBoxToggleLightAndButtonsVisibility(false);
SetPictureBoxSceneSoundEffectsAndButtonsVisibility(false);
if (pictureBoxQRCode != null)
{
pictureBoxQRCode.Visible = false;
closeQRCodeButton.Visible = false;
}
2025-05-22 10:24:21 +08:00
multiPagePanel.LoadPlayedSongs(playedSongsHistory, playStates);
2025-04-07 16:54:10 +08:00
}
}
}