diff --git a/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs b/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs new file mode 100644 index 0000000..6170249 --- /dev/null +++ b/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs @@ -0,0 +1,595 @@ +using DBObj; +using System.IO; + +namespace DualScreenDemo +{ + public partial class PrimaryForm : Form{ + public class MultiPagePanel : Panel + { + private const int ItemHeight = 70; + private const int RowGap = 2; + private int itemsPerPage + { + get + { + Screen screen = Screen.PrimaryScreen; + int screenWidth = screen.Bounds.Width; + int screenHeight = screen.Bounds.Height; + if(screenWidth==1440 && screenHeight==900) + { + return 14; + } + else if(screenWidth==1024 && screenHeight==768) + { + return 12; + } + else if(screenWidth == 1920 && screenHeight == 1080) + { + return 16; + } + return 16; // 預設值 + } + } + private const float LeftColumnX = 0.03f; + private const float RightColumnX = 0.52f; + private const float SongWidth = 0.35f; + private const float ArtistWidth = 0.12f; + + private int _currentPageIndex = 0; + private bool _isSimplified = false; + public bool IsSimplified + { + get { return _isSimplified; } + set + { + if (_isSimplified != value) + { + _isSimplified = value; + RefreshDisplay(); + } + } + } + private List currentSongList = new List(); + private List currentArtistList = new List(); + private int _totalPages = 0; + private Point mouseDownLocation; // 新增字段 + private bool isDragging = false; // 新增字段 + public event Action PageIndexChanged; // 新增事件 + public int currentPageIndex + { + get { return _currentPageIndex; } + set + { + if (_currentPageIndex != value) + { + _currentPageIndex = value; + // 觸發事件,通知頁面索引已改變 + PageIndexChanged?.Invoke(); + } + } + } + public int totalPages + { + get { return _totalPages; } + set + { + if (_totalPages != value) + { + _totalPages = value; + // 觸發事件,通知頁面索引已改變 + PageIndexChanged?.Invoke(); + } + } + } + + public MultiPagePanel() + { + this.SetStyle( + ControlStyles.OptimizedDoubleBuffer | + ControlStyles.AllPaintingInWmPaint | + ControlStyles.UserPaint | + ControlStyles.ResizeRedraw, + true); + this.BackColor = Color.FromArgb(64, 0, 0, 0); + this.BorderStyle = BorderStyle.None; + + // 添加滑動事件 + this.MouseDown += MultiPagePanel_MouseDown; + this.MouseMove += MultiPagePanel_MouseMove; + this.MouseUp += MultiPagePanel_MouseUp; + } + + private void MultiPagePanel_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + mouseDownLocation = e.Location; + isDragging = true; + } + } + + private void MultiPagePanel_MouseMove(object sender, MouseEventArgs e) + { + if (isDragging) + { + int deltaX = e.X - mouseDownLocation.X; + if (Math.Abs(deltaX) > 50) // 滑動距離超過50像素才觸發 + { + if (deltaX > 0 && currentPageIndex > 0) + { + // 向右滑動,上一頁 + LoadPreviousPage(); + } + else if (deltaX < 0 && currentPageIndex < totalPages - 1) + { + // 向左滑動,下一頁 + LoadNextPage(); + } + isDragging = false; + } + } + } + private void MultiPagePanel_MouseUp(object sender, MouseEventArgs e) + { + isDragging = false; + } + public void LoadNextPage() + { + if (currentPageIndex < totalPages - 1) + { + currentPageIndex++; + // 如果歌單為0(沒有歌單),則刷新歌手列表 + if(currentSongList.Count == 0) + { + RefreshDisplayBase_Singer(); + } + else + { + RefreshDisplay(); + } + } + } + public void LoadPreviousPage() + { + if (currentPageIndex > 0) + { + currentPageIndex--; + if(currentSongList.Count == 0) + { + RefreshDisplayBase_Singer(); + } + else + { + RefreshDisplay(); + } + } + } + + public void LoadSongs(List songs, bool clearHistory = false) + { + currentSongList = songs; + currentArtistList.Clear(); + currentPageIndex = 0; + totalPages = (int)Math.Ceiling(songs.Count / (double)itemsPerPage); + + // 直接調用基礎刷新邏輯 + RefreshDisplayBase(); + } + + public void LoadSingers(List artists) + { + currentArtistList = artists; + currentSongList.Clear(); + currentPageIndex = 0; + totalPages = (int)Math.Ceiling(artists.Count / (double)itemsPerPage); + RefreshDisplayBase_Singer(); + } + + public void LoadPlayedSongs(List songs, List states) + { + currentSongList = songs; + currentArtistList.Clear(); + currentPageIndex = 0; + totalPages = (int)Math.Ceiling(songs.Count / (double)itemsPerPage); + + // 直接調用基礎刷新邏輯 + RefreshDisplayBase(); + } + + public void RefreshDisplay() + { + this.Controls.Clear(); // 清除所有 UI 元件 + RefreshDisplayBase(); // 重新建立 UI + this.Invalidate(); // 通知系統需要重新繪製 + } + + private void RefreshDisplayBase() + { + if (this.InvokeRequired) // 確保 UI 操作在主執行緒執行 + { + this.Invoke(new Action(() => RefreshDisplayBase())); + return; + } + this.SuspendLayout(); // 暫停 UI 更新,提高效能 + this.Controls.Clear(); // 清空 UI (這裡會再清除一次) + + int startIndex = currentPageIndex * itemsPerPage; + int endIndex = Math.Min(startIndex + itemsPerPage, currentSongList.Count); + + for (int i = startIndex; i < endIndex; i++) + { + CreateSongLabel(currentSongList[i], i - startIndex, startIndex); // 這行負責新增 UI + } + this.ResumeLayout(); // 恢復 UI 更新 + } + private void RefreshDisplayBase_Singer() + { + this.Controls.Clear(); + if (this.InvokeRequired) // 確保 UI 操作在主執行緒執行 + { + this.Invoke(new Action(() => RefreshDisplayBase_Singer())); + return; + } + this.SuspendLayout(); // 暫停 UI 更新,提高效能 + this.Controls.Clear(); // 清空 UI (這裡會再清除一次) + + int startIndex = currentPageIndex * itemsPerPage; + int endIndex = Math.Min(startIndex + itemsPerPage, currentArtistList.Count); + + for (int i = startIndex; i < endIndex; i++) + { + CreateSingerLabel(currentArtistList[i], i - startIndex, startIndex); // 這行負責新增 UI + } + this.ResumeLayout(); // 恢復 UI 更新 + this.Invalidate(); + } + + private void CreateSingerLabel(Artist artist, int index, int pageOffset) + { + + // 創建歌手標籤 + Label artistLabel = new Label(); + artistLabel.Text = artist.Name; + artistLabel.Tag = artist; + artistLabel.AutoSize = false; + + // 計算文字寬度 + Font normalFont = new Font("微軟正黑體", 26, FontStyle.Bold); + Font mediumFont = new Font("微軟正黑體", 20, FontStyle.Bold); + Font smallFont = new Font("微軟正黑體", 16, FontStyle.Bold); + + // 根據文字長度設置字體大小 + if (artistLabel.Text.Length > 18) + { + artistLabel.Font = smallFont; + } + else if (artistLabel.Text.Length > 13) + { + artistLabel.Font = mediumFont; + } + else + { + artistLabel.Font = normalFont; + } + Screen screen = Screen.PrimaryScreen; + int screenWidth = screen.Bounds.Width; + int screenHeight = screen.Bounds.Height; + int NumberOfItem = (screenWidth, screenHeight) switch + { + (1440, 900) => 7, + (1024, 768) => 6, + (1920, 1080) => 8, + _ => 8 // 預設值 + }; + // 計算位置 - 依照NumberOfItem來計算 + bool isLeftColumn = index < NumberOfItem; + int row = isLeftColumn ? index : index - NumberOfItem; // 如果是右边,需要减去8来计算正确的行号 + float startX = isLeftColumn ? LeftColumnX : RightColumnX; + int y = row * (ItemHeight + RowGap); + // 計算歌手標籤的位置和大小 + int singerX = (int)(this.Width * startX); + int singerWidth = (int)(this.Width * (SongWidth+ArtistWidth)); + // 字體顏色 + artistLabel.ForeColor = Color.White; + // 標籤座標設定 + artistLabel.Location = new Point(singerX, y); + artistLabel.Size = new Size(singerWidth + 20, ItemHeight); + + Panel separatorPanel = new Panel + { + Location = new Point(singerX , y + ItemHeight), + Size = new Size(singerWidth + 20, 2), + BackColor = Color.FromArgb(80, 255, 255, 255), + Name = "SeparatorPanel_" + index.ToString() + }; + // 字體調整和字體背景顏色 + artistLabel.TextAlign = ContentAlignment.TopLeft; + artistLabel.BackColor = Color.Transparent; + + // 設置滑鼠事件 + EventHandler mouseEnter = (sender, e) => { + // 變更歌手名稱為黃色 + artistLabel.ForeColor = Color.Yellow; + // 增強分隔線的亮度,使其更明顯 + separatorPanel.BackColor = Color.FromArgb(120, 255, 255, 255); + + }; + EventHandler mouseLeave = (sender, e) => { + // 還原歌手名稱為白色 + artistLabel.ForeColor = Color.White; + // 還原分隔線的亮度 + separatorPanel.BackColor = Color.FromArgb(80, 255, 255, 255); + }; + artistLabel.Click += (sender, e) => + { + string searchText = artistLabel.Text; // 取得輸入內容 + string query = $"SELECT * FROM SongLibrary WHERE `歌星 A` = '{searchText}' OR `歌星 B` = '{searchText}'"; + var searchResults = PrimaryForm.Instance.SearchSongs_Mysql(query); + // 重置分頁 + PrimaryForm.Instance.currentPage = 0; + currentSongList = searchResults; + totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); + // 更新多頁面面板的內容 + PrimaryForm.Instance.multiPagePanel.currentPageIndex = 0; + PrimaryForm.Instance.multiPagePanel.LoadSongs(currentSongList); + }; + // 添加滑鼠事件 + artistLabel.MouseEnter += mouseEnter; + artistLabel.MouseLeave += mouseLeave; + separatorPanel.MouseEnter += mouseEnter; + separatorPanel.MouseLeave += mouseLeave; + // 添加到畫面上 + this.Controls.Add(separatorPanel); + this.Controls.Add(artistLabel); + // 將歌手標籤置於最上層 + artistLabel.BringToFront(); + + } + + private void CreateSongLabel(SongData song, int index, int pageOffset) + { + // 創建歌曲標籤 + Label songLabel = new Label(); + string statusText = ""; // 狀態文字 + + bool isCurrentlyPlaying = false; // 是否正在播放 + bool hasBeenPlayed = false; // 是否已播放完成 + bool isLatestInstance = true; // 是否是最新的歌曲 + + // 僅在 "已點歌曲" 頁面顯示播放狀態 + if (PrimaryForm.Instance.isOnOrderedSongsPage) + { + // 判斷是否正在播放公播歌單 (若用戶點播歌單為空,則播放公播歌單) + bool isPlayingPublicList = userRequestedSongs.Count == 0 || + (currentSongIndexInHistory >= userRequestedSongs.Count - 1 && PrimaryForm.Instance.videoPlayerForm.IsPlayingPublicSong); + if (isPlayingPublicList) + { + // 若播放公播歌單,代表已點歌曲皆已播放完畢 + hasBeenPlayed = true; + songLabel.ForeColor = Color.Gray; + statusText = IsSimplified ? "(播毕)" : "(播畢)"; + } + else + { + // 計算已完成播放的歌曲數量 + int completedCount = 0; + // 遍歷已點歌曲歷史 + for (int i = 0; i <= currentSongIndexInHistory && i < playedSongsHistory.Count; i++) { + if (i == currentSongIndexInHistory) { + completedCount = i + 1; // 当前播放的歌曲 + break; + } + // 检查播放状态 + if (i < playStates.Count) { + if (playStates[i] == PlayState.Played || playStates[i] == PlayState.Playing) { + completedCount++; + } + // 如果是切歌状态,不增加计数 + } + } + + // 計算歌曲在歷史中的位置 + int songPosition = pageOffset + index; + // 判斷歌曲狀態 + if (songPosition < completedCount - 1) + { + // 已播放完成 + hasBeenPlayed = true; + songLabel.ForeColor = Color.Gray; + statusText = IsSimplified ? "(播毕)" : "(播畢)"; + } + else if (songPosition == completedCount - 1) + { + // 正在播放 + isCurrentlyPlaying = true; + songLabel.ForeColor = Color.LimeGreen; + statusText = IsSimplified ? "(播放中)" : "(播放中)"; + } + else + { + // 未播放 + songLabel.ForeColor = Color.White; + statusText = string.Empty; + } + } + } + else + { + // 未在 "已點歌曲" 頁面顯示白色 + songLabel.ForeColor = Color.White; + statusText = string.Empty; + } + + // 根據簡繁體設置選擇要顯示的文字 + string songText = IsSimplified ? + (!string.IsNullOrEmpty(song.SongSimplified) ? song.SongSimplified : song.Song) : + song.Song; + + string artistText = IsSimplified ? + (!string.IsNullOrEmpty(song.ArtistASimplified) ? song.ArtistASimplified : song.ArtistA) : + song.ArtistA; + + string fullText = songText + statusText; + int textLength = fullText.Length; + + // 計算文字寬度 + Font normalFont = new Font("微軟正黑體", 26, FontStyle.Bold); + Font mediumFont = new Font("微軟正黑體", 20, FontStyle.Bold); + Font smallFont = new Font("微軟正黑體", 16, FontStyle.Bold); + // 根據文字長度設置字體大小 + if (textLength > 18) + { + songLabel.Font = smallFont; + } + else if (textLength > 13) + { + songLabel.Font = mediumFont; + } + else + { + songLabel.Font = normalFont; + } + songLabel.Text = fullText; + songLabel.Tag = song; + songLabel.AutoSize = false; + // 創建歌手標籤 + Label artistLabel = new Label(); + artistLabel.Text = artistText; + artistLabel.Tag = song; + artistLabel.AutoSize = false; + Screen screen = Screen.PrimaryScreen; + int screenWidth = screen.Bounds.Width; + int screenHeight = screen.Bounds.Height; + int NumberOfItem = 0; + if(screenWidth==1440 && screenHeight==900) + { + NumberOfItem = 7; + } + else if(screenWidth==1024 && screenHeight==768) + { + NumberOfItem = 6; + } + else if(screenWidth == 1920 && screenHeight == 1080) + { + NumberOfItem = 8; + } + // 計算位置 - 依照NumberOfItem來計算 + bool isLeftColumn = index < NumberOfItem; + int row = isLeftColumn ? index : index - NumberOfItem; + float startX = isLeftColumn ? LeftColumnX : RightColumnX; + int y = row * (ItemHeight + RowGap); + // 設置位置和大小 + int songX = (int)(this.Width * startX); + int songWidth = (int)(this.Width * SongWidth); + int artistWidth = (int)(this.Width * ArtistWidth); + int artistX = songX + songWidth + 10; + // 添加人聲標籤 + if (song.HumanVoice == 1) + { + PictureBox icon = new PictureBox() + { + Image = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\其他符號_人聲\其他符號_人聲.png")), + SizeMode = PictureBoxSizeMode.Zoom, + Size = new Size(32, 32), + Location = new Point(songX + 5, y + 8) + }; + this.Controls.Add(icon); + icon.BringToFront(); + + // 有圖標時歌名右移 + songLabel.Location = new Point(songX + 42, y); + songLabel.Size = new Size(songWidth - 47, ItemHeight - 20); + } + else + { + // 沒有圖標時歌名置中 + songLabel.Location = new Point(songX, y); + songLabel.Size = new Size(songWidth - 10, ItemHeight - 20); + } + // 歌手標籤位置調整 + artistLabel.Location = new Point(artistX, y + 33); + artistLabel.Size = new Size(artistWidth - 10, ItemHeight - 35); + // 創建分隔線面板 + Panel separatorPanel = new Panel + { + Location = new Point(songX - 5, y + ItemHeight - 2), + Size = new Size(songWidth + artistWidth + 20, 2), + BackColor = Color.FromArgb(80, 255, 255, 255), + Name = "SeparatorPanel_" + index.ToString() + }; + // 設置字體樣式 + artistLabel.Font = new Font("微軟正黑體", 16, FontStyle.Bold); + artistLabel.ForeColor = Color.FromArgb(30,144,255); + songLabel.TextAlign = ContentAlignment.MiddleLeft; + artistLabel.TextAlign = ContentAlignment.MiddleRight; + // 確保背景透明 + songLabel.BackColor = Color.Transparent; + artistLabel.BackColor = Color.Transparent; + // 定義滑鼠進入 (MouseEnter) 事件的處理程序 + EventHandler mouseEnter = (sender, e) => { + // 當不在「已點歌曲」頁面,或者該歌曲不是當前正在播放的歌曲, + // 且(該歌曲未播放過或不是該歌曲的最新實例)時,改變顯示樣式 + if (!PrimaryForm.Instance.isOnOrderedSongsPage || + (!isCurrentlyPlaying && (!hasBeenPlayed || !isLatestInstance))) + { + // 當滑鼠移到歌曲上時,變更歌曲名稱為黃色 + songLabel.ForeColor = Color.Yellow; + // 變更歌手名稱為黃色 + artistLabel.ForeColor = Color.Yellow; + // 增強分隔線的亮度,使其更明顯 + separatorPanel.BackColor = Color.FromArgb(120, 255, 255, 255); + } + }; + // 定義滑鼠離開 (MouseLeave) 事件的處理程序 + EventHandler mouseLeave = (sender, e) => { + // 判斷是否處於「已點歌曲」頁面 + if (PrimaryForm.Instance.isOnOrderedSongsPage) + { + // 如果當前歌曲正在播放,則維持綠色顯示 + if (isCurrentlyPlaying) + { + songLabel.ForeColor = Color.LimeGreen; + } + // 如果該歌曲已播放完成,且是該歌曲的最新實例,則變為灰色 + else if (hasBeenPlayed && isLatestInstance) + { + songLabel.ForeColor = Color.Gray; + } + // 其他情況,則維持白色 + else + { + songLabel.ForeColor = Color.White; + } + } + else + { + // 若不在「已點歌曲」頁面,則默認為白色 + songLabel.ForeColor = Color.White; + } + // 恢復歌手名稱的顏色為預設的藍色 + artistLabel.ForeColor = Color.FromArgb(30, 144, 255); + // 恢復分隔線的顏色為半透明白色 + separatorPanel.BackColor = Color.FromArgb(80, 255, 255, 255); + }; + // 添加事件处理 + songLabel.Click += PrimaryForm.Instance.Label_Click; + artistLabel.Click += PrimaryForm.Instance.Label_Click; + songLabel.MouseEnter += mouseEnter; + songLabel.MouseLeave += mouseLeave; + artistLabel.MouseEnter += mouseEnter; + artistLabel.MouseLeave += mouseLeave; + separatorPanel.MouseEnter += mouseEnter; + separatorPanel.MouseLeave += mouseLeave; + // 按正确顺序添加控件 + this.Controls.Add(separatorPanel); + this.Controls.Add(songLabel); + this.Controls.Add(artistLabel); + // 确保控件层次正确 + songLabel.BringToFront(); + artistLabel.BringToFront(); + } + + + } + } +} diff --git a/PrimaryFormParts/PrimaryForm.SequenceManager.cs b/PrimaryFormParts/PrimaryForm.SequenceManager.cs new file mode 100644 index 0000000..a8c2da5 --- /dev/null +++ b/PrimaryFormParts/PrimaryForm.SequenceManager.cs @@ -0,0 +1,42 @@ +namespace DualScreenDemo +{ + public partial class PrimaryForm : Form{ + private class SequenceManager + { + private List correctSequence = new List { "超", "級", "巨", "星" }; + private List currentSequence = new List(); + + public void ProcessClick(string buttonName) + { + currentSequence.Add(buttonName); + + // 檢查是否點擊錯誤 + if (currentSequence.Count <= correctSequence.Count) + { + if (currentSequence[currentSequence.Count - 1] != correctSequence[currentSequence.Count - 1]) + { + // 順序錯誤,重置序列 + currentSequence.Clear(); + return; + } + } + + // 檢查是否完成正確序列 + if (currentSequence.Count == correctSequence.Count) + { + try + { + // 使用 Windows 命令關機 + System.Diagnostics.Process.Start("shutdown", "/s /t 0"); + } + catch (Exception ex) + { + MessageBox.Show($"關機失敗: {ex.Message}"); + // 如果關機失敗,退出程式 + Application.Exit(); + } + } + } + } + } +} \ No newline at end of file diff --git a/PrimaryFormParts/PrimaryForm.cs b/PrimaryFormParts/PrimaryForm.cs index f7bd6d8..64bf0af 100644 --- a/PrimaryFormParts/PrimaryForm.cs +++ b/PrimaryFormParts/PrimaryForm.cs @@ -22,48 +22,16 @@ namespace DualScreenDemo } } #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 const int offsetX = 100; - private PictureBox pictureBoxArtistSearch; - - // private Button[] numberButtonsArtistSearch; - // private Button modifyButtonArtistSearch, closeButtonArtistSearch; - //private RichTextBox inputBoxArtistSearch; - private const int offsetXArtistSearch = 100; - private const int offsetYArtistSearch = 100; - - //private PictureBox pictureBoxWordCount; - - //private Button[] numberButtonsWordCount; - // private Button modifyButtonWordCount, closeButtonWordCount; - // private RichTextBox inputBoxWordCount; - private const int offsetXWordCount = 100; - private const int offsetYWordCount = 100; - - //private PictureBox pictureBoxSongIDSearch; - - //private Button[] numberButtonsSongIDSearch; - //private Button modifyButtonSongIDSearch, closeButtonSongIDSearch; - //private RichTextBox inputBoxSongIDSearch; - private const int offsetXSongID = 100; - private const int offsetYSongID = 100; - private const int offsetXPinYin = 100; - private Button singerSearchButton; private Bitmap singerSearchNormalBackground; private Bitmap singerSearchActiveBackground; @@ -89,95 +57,70 @@ namespace DualScreenDemo 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 promotions; private List 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; - private Button exitButton; - + private Button exitButton; private static Bitmap normalStateImage; private static Bitmap mouseOverImage; - private static Bitmap mouseDownImage; - - + private static Bitmap mouseDownImage; 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; - private static Bitmap resizedMouseDownImageForCategoryQuery; - - + private static Bitmap resizedMouseDownImageForCategoryQuery; 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 currentSongList; public List currentArtistList; public List publicSongList; - public static List userRequestedSongs; public static List playedSongsHistory; public static List playStates; @@ -187,7 +130,6 @@ namespace DualScreenDemo private int _currentPage { get; set; }= 0; private int _totalPages { get; set; } - public int currentPage { get { return _currentPage; } @@ -205,15 +147,9 @@ namespace DualScreenDemo } public const int itemsPerPage = 18; - private const int RowsPerPage = 9; - private const int Columns = 2; - private WaveInEvent waveIn; private WaveFileWriter waveWriter; - - - - + private const int PanelStartLeft = 25; // 修改為實際需要的左邊距 private const int PanelStartTop = 227; // 修改為實際需要的上邊距 private const int PanelEndLeft = 1175; // 修改為實際需要的右邊界 @@ -222,8 +158,6 @@ namespace DualScreenDemo private Timer lightControlTimer; public Timer volumeUpTimer; public Timer volumeDownTimer; - private DateTime lastVolumeUpTime = DateTime.MinValue; - private DateTime lastVolumeDownTime = DateTime.MinValue; public Timer micControlTimer; private SequenceManager sequenceManager = new SequenceManager(); @@ -234,8 +168,6 @@ namespace DualScreenDemo private Dictionary initialControlStates = new Dictionary(); - private Dictionary initialControlPositions = new Dictionary(); - private Panel sendOffPanel; private static Bitmap normalStateImageHotSong; @@ -243,14 +175,6 @@ namespace DualScreenDemo private static Bitmap resizedNormalStateImageForHotSong; private static Bitmap resizedMouseDownImageForHotSong; - // 布局常量 - private const float LeftColumnX = 0.05f; // 左列起始位置(屏幕宽度的5%) - private const float RightColumnX = 0.55f; // 右列起始位置(屏幕宽度的55%) - private const float SongWidth = 0.4f; // 歌名宽度(屏幕宽度的40%) - private const float ArtistWidth = 0.1f; // 歌手名宽度(屏幕宽度的10%) - private const int ItemHeight = 64; // 每个项目的高度 - private const int RowGap = 0; // 行间距 - private PictureBox serviceBellPictureBox; // 添加为类成员变量 private Timer autoRefreshTimer; @@ -268,7 +192,6 @@ namespace DualScreenDemo this.DoubleBuffered = true; - InitializeComponent(); InitializeProgressBar(); // 初始化自动刷新Timer @@ -361,7 +284,6 @@ namespace DualScreenDemo e.Graphics.DrawString(pageNumber, font, brush, point_pageNumber); } - private void buttonMiddle_Click(object sender, EventArgs e) { sequenceManager.ProcessClick("巨"); @@ -404,11 +326,6 @@ namespace DualScreenDemo sendOffPanel.Visible = false; } - private void HideAllButtons() - { - HideControlsRecursively(this); - } - private void HideControlsRecursively(Control parent) { foreach (Control control in parent.Controls) @@ -424,23 +341,6 @@ namespace DualScreenDemo } } - private void UpdateProgress(TimeSpan currentPosition) - { - - if (progressBar.InvokeRequired) { - progressBar.Invoke(new System.Action(() => { - progressBar.Value = (int)currentPosition.TotalSeconds; - })); - } else { - progressBar.Value = (int)currentPosition.TotalSeconds; - } - } - - private void InitializeComponent() - { - - } - private void InitializeProgressBar() { @@ -546,7 +446,6 @@ namespace DualScreenDemo InitializePictureBox(); - InitializeButtonsForHotSong(); InitializeButtonsForNewSong(); InitializeButtonsForSingerSearch(); @@ -558,7 +457,6 @@ namespace DualScreenDemo InitializeButtonsForZhuYinSongs(); InitializeButtonsForEnglishSingers(); InitializeButtonsForEnglishSongs(); - //InitializeButtonsForPictureBoxArtistSearch(); InitializeButtonsForWordCountSongs(); InitializeButtonsForWordCountSingers(); InitializeButtonsForPinYinSingers(); @@ -573,7 +471,6 @@ namespace DualScreenDemo InitializeButtonsForSongIDSearch(); InitializeOtherControls(); - pictureBox1.BringToFront(); pictureBox2.BringToFront(); @@ -899,7 +796,6 @@ namespace DualScreenDemo this.Controls.Add(pictureBoxSceneSoundEffects); } - private void PhoneticButton_Click(object sender, EventArgs e) { var button = sender as Button; @@ -917,38 +813,6 @@ namespace DualScreenDemo } } - /* private void ModifyButtonArtist_Click(object sender, EventArgs e) - { - - if (inputBoxArtistSearch.Text.Length > 0) - { - - inputBoxArtistSearch.Text = inputBoxArtistSearch.Text.Substring(0, inputBoxArtistSearch.Text.Length - 1); - } - } */ - - /* private void ModifyButtonWordCount_Click(object sender, EventArgs e) - { - - if (inputBoxWordCount.Text.Length > 0) - { - - inputBoxWordCount.Text = inputBoxWordCount.Text.Substring(0, inputBoxWordCount.Text.Length - 1); - } - } */ - - private void BtnBrightnessUp1_MouseDown(object sender, MouseEventArgs e) - { - - lightControlTimer.Tag = "a2 d9 a4"; - lightControlTimer.Start(); - } - - private void BtnBrightnessUp1_MouseUp(object sender, MouseEventArgs e) - { - lightControlTimer.Stop(); - } - private void LightControlTimer_Tick(object sender, EventArgs e) { if(lightControlTimer.Tag != null) @@ -1041,12 +905,6 @@ namespace DualScreenDemo return bytes; } - private void OptionButton_Click(object sender, EventArgs e) - { - Button clickedButton = sender as Button; - MessageBox.Show(String.Format("Clicked on option: {0}", clickedButton.Text)); - - } private void RecognizeInk(InkOverlay inkOverlay, ListBox candidateListBox) { @@ -1095,11 +953,6 @@ namespace DualScreenDemo candidateListBox.Visible = true; } - private void BtnShowAll_Click(object sender, EventArgs e) - { - MessageBox.Show("Show All button clicked!"); - - } private void ConfigureButton(Button button, int posX, int posY, int width, int height, Bitmap normalStateImage, Bitmap mouseOverImage, Bitmap mouseDownImage, @@ -1515,674 +1368,6 @@ namespace DualScreenDemo this.Controls.Add(button); } -public class MultiPagePanel : Panel -{ - private const int ItemHeight = 70; - private const int RowGap = 2; - private int itemsPerPage - { - get - { - Screen screen = Screen.PrimaryScreen; - int screenWidth = screen.Bounds.Width; - int screenHeight = screen.Bounds.Height; - if(screenWidth==1440 && screenHeight==900) - { - return 14; - } - else if(screenWidth==1024 && screenHeight==768) - { - return 12; - } - else if(screenWidth == 1920 && screenHeight == 1080) - { - return 16; - } - return 16; // 預設值 - } - } - private const float LeftColumnX = 0.03f; - private const float RightColumnX = 0.52f; - private const float SongWidth = 0.35f; - private const float ArtistWidth = 0.12f; - private const int ArtistVerticalOffset = 2; - private const string MusicNoteSymbol = "♫"; - - private int _currentPageIndex = 0; - private bool _isSimplified = false; - public bool IsSimplified - { - get { return _isSimplified; } - set - { - if (_isSimplified != value) - { - _isSimplified = value; - RefreshDisplay(); - } - } - } - private List currentSongList = new List(); - private List currentArtistList = new List(); - private int _totalPages = 0; - private Point mouseDownLocation; // 新增字段 - private bool isDragging = false; // 新增字段 - public event Action PageIndexChanged; // 新增事件 - public int currentPageIndex - { - get { return _currentPageIndex; } - set - { - if (_currentPageIndex != value) - { - _currentPageIndex = value; - // 觸發事件,通知頁面索引已改變 - PageIndexChanged?.Invoke(); - } - } - } - public int totalPages - { - get { return _totalPages; } - set - { - if (_totalPages != value) - { - _totalPages = value; - // 觸發事件,通知頁面索引已改變 - PageIndexChanged?.Invoke(); - } - } - } - - public MultiPagePanel() - { - this.SetStyle( - ControlStyles.OptimizedDoubleBuffer | - ControlStyles.AllPaintingInWmPaint | - ControlStyles.UserPaint | - ControlStyles.ResizeRedraw, - true); - - this.BackColor = Color.FromArgb(64, 0, 0, 0); - this.BorderStyle = BorderStyle.None; - - // 添加滑動事件 - this.MouseDown += MultiPagePanel_MouseDown; - this.MouseMove += MultiPagePanel_MouseMove; - this.MouseUp += MultiPagePanel_MouseUp; - } - - private void MultiPagePanel_MouseDown(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Left) - { - mouseDownLocation = e.Location; - isDragging = true; - } - } - - private void MultiPagePanel_MouseMove(object sender, MouseEventArgs e) - { - if (isDragging) - { - int deltaX = e.X - mouseDownLocation.X; - if (Math.Abs(deltaX) > 50) // 滑動距離超過50像素才觸發 - { - if (deltaX > 0 && currentPageIndex > 0) - { - // 向右滑動,上一頁 - LoadPreviousPage(); - } - else if (deltaX < 0 && currentPageIndex < totalPages - 1) - { - // 向左滑動,下一頁 - LoadNextPage(); - } - isDragging = false; - } - } - } - - private void MultiPagePanel_MouseUp(object sender, MouseEventArgs e) - { - isDragging = false; - } - - public void LoadNextPage() - { - if (currentPageIndex < totalPages - 1) - { - currentPageIndex++; - // 如果歌單為0(沒有歌單),則刷新歌手列表 - if(currentSongList.Count == 0) - { - RefreshDisplayBase_Singer(); - } - else - { - RefreshDisplay(); - } - } - } - - public void LoadPreviousPage() - { - if (currentPageIndex > 0) - { - currentPageIndex--; - if(currentSongList.Count == 0) - { - RefreshDisplayBase_Singer(); - } - else - { - RefreshDisplay(); - } - } - } - - public void LoadSongs(List songs, bool clearHistory = false) - { - currentSongList = songs; - currentArtistList.Clear(); - currentPageIndex = 0; - totalPages = (int)Math.Ceiling(songs.Count / (double)itemsPerPage); - - // 直接調用基礎刷新邏輯 - RefreshDisplayBase(); - } - - public void LoadSingers(List artists) - { - currentArtistList = artists; - currentSongList.Clear(); - currentPageIndex = 0; - totalPages = (int)Math.Ceiling(artists.Count / (double)itemsPerPage); - RefreshDisplayBase_Singer(); - } - - public void LoadPlayedSongs(List songs, List states) - { - currentSongList = songs; - currentArtistList.Clear(); - currentPageIndex = 0; - totalPages = (int)Math.Ceiling(songs.Count / (double)itemsPerPage); - - // 直接調用基礎刷新邏輯 - RefreshDisplayBase(); - } - - public void RefreshDisplay() - { - this.Controls.Clear(); // 清除所有 UI 元件 - RefreshDisplayBase(); // 重新建立 UI - this.Invalidate(); // 通知系統需要重新繪製 - } - - private void RefreshDisplayBase() - { - if (this.InvokeRequired) // 確保 UI 操作在主執行緒執行 - { - this.Invoke(new Action(() => RefreshDisplayBase())); - return; - } - - this.SuspendLayout(); // 暫停 UI 更新,提高效能 - this.Controls.Clear(); // 清空 UI (這裡會再清除一次) - - int startIndex = currentPageIndex * itemsPerPage; - int endIndex = Math.Min(startIndex + itemsPerPage, currentSongList.Count); - - for (int i = startIndex; i < endIndex; i++) - { - CreateSongLabel(currentSongList[i], i - startIndex, startIndex); // 這行負責新增 UI - } - - this.ResumeLayout(); // 恢復 UI 更新 - } - - - private void RefreshDisplayBase_Singer() - { - this.Controls.Clear(); - if (this.InvokeRequired) // 確保 UI 操作在主執行緒執行 - { - this.Invoke(new Action(() => RefreshDisplayBase_Singer())); - return; - } - - this.SuspendLayout(); // 暫停 UI 更新,提高效能 - this.Controls.Clear(); // 清空 UI (這裡會再清除一次) - - int startIndex = currentPageIndex * itemsPerPage; - int endIndex = Math.Min(startIndex + itemsPerPage, currentArtistList.Count); - - for (int i = startIndex; i < endIndex; i++) - { - CreateSingerLabel(currentArtistList[i], i - startIndex, startIndex); // 這行負責新增 UI - } - - this.ResumeLayout(); // 恢復 UI 更新 - this.Invalidate(); - } - - private void CreateSingerLabel(Artist artist, int index, int pageOffset) - { - - // 創建歌手標籤 - Label artistLabel = new Label(); - artistLabel.Text = artist.Name; - artistLabel.Tag = artist; - artistLabel.AutoSize = false; - // 計算文字寬度 - - Font normalFont = new Font("微軟正黑體", 26, FontStyle.Bold); - Font mediumFont = new Font("微軟正黑體", 20, FontStyle.Bold); - Font smallFont = new Font("微軟正黑體", 16, FontStyle.Bold); - // 根據文字長度設置字體大小 - if (artistLabel.Text.Length > 18) - { - artistLabel.Font = smallFont; - } - else if (artistLabel.Text.Length > 13) - { - artistLabel.Font = mediumFont; - } - else - { - artistLabel.Font = normalFont; - } - Screen screen = Screen.PrimaryScreen; - int screenWidth = screen.Bounds.Width; - int screenHeight = screen.Bounds.Height; - int NumberOfItem = (screenWidth, screenHeight) switch - { - (1440, 900) => 7, - (1024, 768) => 6, - (1920, 1080) => 8, - _ => 8 // 預設值 - }; - // 計算位置 - 依照NumberOfItem來計算 - bool isLeftColumn = index < NumberOfItem; - int row = isLeftColumn ? index : index - NumberOfItem; // 如果是右边,需要减去8来计算正确的行号 - float startX = isLeftColumn ? LeftColumnX : RightColumnX; - int y = row * (ItemHeight + RowGap); - - // 計算歌手標籤的位置和大小 - int singerX = (int)(this.Width * startX); - int singerWidth = (int)(this.Width * (SongWidth+ArtistWidth)); - - // 字體顏色 - artistLabel.ForeColor = Color.White; - - // 標籤座標設定 - artistLabel.Location = new Point(singerX, y); - artistLabel.Size = new Size(singerWidth + 20, ItemHeight); - - - Panel separatorPanel = new Panel - { - Location = new Point(singerX , y + ItemHeight), - Size = new Size(singerWidth + 20, 2), - BackColor = Color.FromArgb(80, 255, 255, 255), - Name = "SeparatorPanel_" + index.ToString() - }; - // 字體調整和字體背景顏色 - artistLabel.TextAlign = ContentAlignment.TopLeft; - artistLabel.BackColor = Color.Transparent; - - // 設置滑鼠事件 - EventHandler mouseEnter = (sender, e) => { - // 變更歌手名稱為黃色 - artistLabel.ForeColor = Color.Yellow; - // 增強分隔線的亮度,使其更明顯 - separatorPanel.BackColor = Color.FromArgb(120, 255, 255, 255); - - }; - EventHandler mouseLeave = (sender, e) => { - // 還原歌手名稱為白色 - artistLabel.ForeColor = Color.White; - // 還原分隔線的亮度 - separatorPanel.BackColor = Color.FromArgb(80, 255, 255, 255); - }; - - artistLabel.Click += (sender, e) => - { - string searchText = artistLabel.Text; // 取得輸入內容 - string query = $"SELECT * FROM SongLibrary WHERE `歌星 A` = '{searchText}' OR `歌星 B` = '{searchText}'"; - var searchResults = PrimaryForm.Instance.SearchSongs_Mysql(query); - // 重置分頁 - PrimaryForm.Instance.currentPage = 0; - currentSongList = searchResults; - totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); - - // 更新多頁面面板的內容 - PrimaryForm.Instance.multiPagePanel.currentPageIndex = 0; - PrimaryForm.Instance.multiPagePanel.LoadSongs(currentSongList); - }; - - // 添加滑鼠事件 - artistLabel.MouseEnter += mouseEnter; - artistLabel.MouseLeave += mouseLeave; - separatorPanel.MouseEnter += mouseEnter; - separatorPanel.MouseLeave += mouseLeave; - - // 添加到畫面上 - this.Controls.Add(separatorPanel); - this.Controls.Add(artistLabel); - - // 將歌手標籤置於最上層 - artistLabel.BringToFront(); - - } - - private void CreateSongLabel(SongData song, int index, int pageOffset) - { - // 創建歌曲標籤 - Label songLabel = new Label(); - string statusText = ""; // 狀態文字 - - bool isCurrentlyPlaying = false; // 是否正在播放 - bool hasBeenPlayed = false; // 是否已播放完成 - bool isLatestInstance = true; // 是否是最新的歌曲 - - // 僅在 "已點歌曲" 頁面顯示播放狀態 - if (PrimaryForm.Instance.isOnOrderedSongsPage) - { - // 判斷是否正在播放公播歌單 (若用戶點播歌單為空,則播放公播歌單) - bool isPlayingPublicList = userRequestedSongs.Count == 0 || - (currentSongIndexInHistory >= userRequestedSongs.Count - 1 && PrimaryForm.Instance.videoPlayerForm.IsPlayingPublicSong); - - if (isPlayingPublicList) - { - // 若播放公播歌單,代表已點歌曲皆已播放完畢 - hasBeenPlayed = true; - songLabel.ForeColor = Color.Gray; - statusText = IsSimplified ? "(播毕)" : "(播畢)"; - } - else - { - // 計算已完成播放的歌曲數量 - int completedCount = 0; - // 遍歷已點歌曲歷史 - for (int i = 0; i <= currentSongIndexInHistory && i < playedSongsHistory.Count; i++) { - if (i == currentSongIndexInHistory) { - completedCount = i + 1; // 当前播放的歌曲 - break; - } - // 检查播放状态 - if (i < playStates.Count) { - if (playStates[i] == PlayState.Played || playStates[i] == PlayState.Playing) { - completedCount++; - } - // 如果是切歌状态,不增加计数 - } - } - - // 計算歌曲在歷史中的位置 - int songPosition = pageOffset + index; - - // 判斷歌曲狀態 - if (songPosition < completedCount - 1) - { - // 已播放完成 - hasBeenPlayed = true; - songLabel.ForeColor = Color.Gray; - statusText = IsSimplified ? "(播毕)" : "(播畢)"; - } - else if (songPosition == completedCount - 1) - { - // 正在播放 - isCurrentlyPlaying = true; - songLabel.ForeColor = Color.LimeGreen; - statusText = IsSimplified ? "(播放中)" : "(播放中)"; - } - else - { - // 未播放 - songLabel.ForeColor = Color.White; - statusText = string.Empty; - } - } - } - else - { - // 未在 "已點歌曲" 頁面顯示白色 - songLabel.ForeColor = Color.White; - statusText = string.Empty; - } - - // 根據簡繁體設置選擇要顯示的文字 - string songText = IsSimplified ? - (!string.IsNullOrEmpty(song.SongSimplified) ? song.SongSimplified : song.Song) : - song.Song; - - string artistText = IsSimplified ? - (!string.IsNullOrEmpty(song.ArtistASimplified) ? song.ArtistASimplified : song.ArtistA) : - song.ArtistA; - - - string fullText = songText + statusText; - int textLength = fullText.Length; - - // 計算文字寬度 - Font normalFont = new Font("微軟正黑體", 26, FontStyle.Bold); - Font mediumFont = new Font("微軟正黑體", 20, FontStyle.Bold); - Font smallFont = new Font("微軟正黑體", 16, FontStyle.Bold); - - // 根據文字長度設置字體大小 - if (textLength > 18) - { - songLabel.Font = smallFont; - } - else if (textLength > 13) - { - songLabel.Font = mediumFont; - } - else - { - songLabel.Font = normalFont; - } - - songLabel.Text = fullText; - songLabel.Tag = song; - songLabel.AutoSize = false; - - // 創建歌手標籤 - Label artistLabel = new Label(); - artistLabel.Text = artistText; - artistLabel.Tag = song; - artistLabel.AutoSize = false; - Screen screen = Screen.PrimaryScreen; - int screenWidth = screen.Bounds.Width; - int screenHeight = screen.Bounds.Height; - int NumberOfItem = 0; - if(screenWidth==1440 && screenHeight==900) - { - NumberOfItem = 7; - } - else if(screenWidth==1024 && screenHeight==768) - { - NumberOfItem = 6; - } - else if(screenWidth == 1920 && screenHeight == 1080) - { - NumberOfItem = 8; - } - - // 計算位置 - 依照NumberOfItem來計算 - bool isLeftColumn = index < NumberOfItem; - int row = isLeftColumn ? index : index - NumberOfItem; - float startX = isLeftColumn ? LeftColumnX : RightColumnX; - int y = row * (ItemHeight + RowGap); - - // 設置位置和大小 - int songX = (int)(this.Width * startX); - int songWidth = (int)(this.Width * SongWidth); - int artistWidth = (int)(this.Width * ArtistWidth); - int artistX = songX + songWidth + 10; - - // 添加人聲標籤 - if (song.HumanVoice == 1) - { - PictureBox icon = new PictureBox() - { - Image = Image.FromFile(Path.Combine(Application.StartupPath, @"themes\superstar\其他符號_人聲\其他符號_人聲.png")), - SizeMode = PictureBoxSizeMode.Zoom, - Size = new Size(32, 32), - Location = new Point(songX + 5, y + 8) - }; - this.Controls.Add(icon); - icon.BringToFront(); - - // 有圖標時歌名右移 - songLabel.Location = new Point(songX + 42, y); - songLabel.Size = new Size(songWidth - 47, ItemHeight - 20); - } - else - { - // 沒有圖標時歌名置中 - songLabel.Location = new Point(songX, y); - songLabel.Size = new Size(songWidth - 10, ItemHeight - 20); - } - - // 歌手標籤位置調整 - artistLabel.Location = new Point(artistX, y + 33); - artistLabel.Size = new Size(artistWidth - 10, ItemHeight - 35); - - // 創建分隔線面板 - Panel separatorPanel = new Panel - { - Location = new Point(songX - 5, y + ItemHeight - 2), - Size = new Size(songWidth + artistWidth + 20, 2), - BackColor = Color.FromArgb(80, 255, 255, 255), - Name = "SeparatorPanel_" + index.ToString() - }; - - // 設置字體樣式 - artistLabel.Font = new Font("微軟正黑體", 16, FontStyle.Bold); - artistLabel.ForeColor = Color.FromArgb(30,144,255); - songLabel.TextAlign = ContentAlignment.MiddleLeft; - artistLabel.TextAlign = ContentAlignment.MiddleRight; - - // 確保背景透明 - songLabel.BackColor = Color.Transparent; - artistLabel.BackColor = Color.Transparent; - - // 定義滑鼠進入 (MouseEnter) 事件的處理程序 - EventHandler mouseEnter = (sender, e) => { - // 當不在「已點歌曲」頁面,或者該歌曲不是當前正在播放的歌曲, - // 且(該歌曲未播放過或不是該歌曲的最新實例)時,改變顯示樣式 - if (!PrimaryForm.Instance.isOnOrderedSongsPage || - (!isCurrentlyPlaying && (!hasBeenPlayed || !isLatestInstance))) - { - // 當滑鼠移到歌曲上時,變更歌曲名稱為黃色 - songLabel.ForeColor = Color.Yellow; - - // 變更歌手名稱為黃色 - artistLabel.ForeColor = Color.Yellow; - - // 增強分隔線的亮度,使其更明顯 - separatorPanel.BackColor = Color.FromArgb(120, 255, 255, 255); - } - }; - - // 定義滑鼠離開 (MouseLeave) 事件的處理程序 - EventHandler mouseLeave = (sender, e) => { - // 判斷是否處於「已點歌曲」頁面 - if (PrimaryForm.Instance.isOnOrderedSongsPage) - { - // 如果當前歌曲正在播放,則維持綠色顯示 - if (isCurrentlyPlaying) - { - songLabel.ForeColor = Color.LimeGreen; - } - // 如果該歌曲已播放完成,且是該歌曲的最新實例,則變為灰色 - else if (hasBeenPlayed && isLatestInstance) - { - songLabel.ForeColor = Color.Gray; - } - // 其他情況,則維持白色 - else - { - songLabel.ForeColor = Color.White; - } - } - else - { - // 若不在「已點歌曲」頁面,則默認為白色 - songLabel.ForeColor = Color.White; - } - - // 恢復歌手名稱的顏色為預設的藍色 - artistLabel.ForeColor = Color.FromArgb(30, 144, 255); - - // 恢復分隔線的顏色為半透明白色 - separatorPanel.BackColor = Color.FromArgb(80, 255, 255, 255); - }; - - - // 添加事件处理 - songLabel.Click += PrimaryForm.Instance.Label_Click; - artistLabel.Click += PrimaryForm.Instance.Label_Click; - songLabel.MouseEnter += mouseEnter; - songLabel.MouseLeave += mouseLeave; - artistLabel.MouseEnter += mouseEnter; - artistLabel.MouseLeave += mouseLeave; - separatorPanel.MouseEnter += mouseEnter; - separatorPanel.MouseLeave += mouseLeave; - - // 按正确顺序添加控件 - this.Controls.Add(separatorPanel); - this.Controls.Add(songLabel); - this.Controls.Add(artistLabel); - - // 确保控件层次正确 - songLabel.BringToFront(); - artistLabel.BringToFront(); - } - private bool IsLatestInstanceBeforeIndex(SongData song, int currentIndex) - { - if (currentSongList == null) return true; - - // 从当前索引向前搜索,检查是否是最新实例 - for (int i = currentIndex; i >= 0; i--) - { - if (currentSongList[i].SongNumber == song.SongNumber) - { - return currentSongList[i] == song; - } - } - return true; - } - - private bool HasBeenPlayedBeforeIndex(SongData song, int checkUntil) - { - for (int i = 0; i < checkUntil; i++) - { - if (playedSongsHistory[i].SongNumber == song.SongNumber) - { - return true; - } - } - return false; - } - - private bool IsLatestInstanceInCurrentList(SongData song) - { - if (currentSongList == null) return true; - - for (int i = currentSongList.Count - 1; i >= 0; i--) - { - if (currentSongList[i].SongNumber == song.SongNumber) - { - return currentSongList[i] == song; - } - } - return true; - } - } private void InitializeMultiPagePanel() { @@ -2210,23 +1395,6 @@ public class MultiPagePanel : Panel multiPagePanel.BringToFront(); } - private void PrintControlZOrder(Panel panel) - { - Console.WriteLine(String.Format("Printing Z-Order for controls in {0}:", panel.Name)); - int index = 0; - foreach (Control control in panel.Controls) - { - - Console.WriteLine(String.Format("Control Index: {0}, Type: {1}, Location: {2}, Size: {3}, Text: {4}", - index, - control.GetType().Name, - control.Location, - control.Size, - control.Text)); - index++; - } - } - private SongData currentSelectedSong; public void Label_Click(object sender, EventArgs e) @@ -2605,35 +1773,6 @@ public class MultiPagePanel : Panel resizedNormalStateImageForLightControl = ResizeImage(normalStateImageForLightControl, targetWidth, targetHeight); } - public Bitmap MakeTransparentImage(string imagePath, Color maskColor) - { - Bitmap bmp = new Bitmap(imagePath); - - bmp.MakeTransparent(maskColor); - - return bmp; - } - - - private void ShowImageOnPictureBoxArtistSearch(string imagePath) - { - Bitmap originalImage = new Bitmap(imagePath); - - - Rectangle cropArea = new Rectangle(593, 135, 507, 508); - - - Bitmap croppedImage = CropImage(originalImage, cropArea); - - - pictureBoxArtistSearch.Image = croppedImage; - - - ResizeAndPositionPictureBox(pictureBoxArtistSearch, cropArea.X + offsetXWordCount, cropArea.Y + offsetXWordCount, cropArea.Width, cropArea.Height); - - pictureBoxArtistSearch.Visible = true; - } - private Bitmap CropImage(Bitmap source, Rectangle section) { @@ -2650,10 +1789,8 @@ public class MultiPagePanel : Panel private void DrawTextOnVodScreenPictureBox(string imagePath, SongData songData) { - Bitmap originalImage = new Bitmap(imagePath); - VodScreenPictureBox.Image = originalImage; int screenWidth = 1440; @@ -2663,7 +1800,6 @@ public class MultiPagePanel : Panel int xPosition = (screenWidth - pictureBoxWidth) / 2; int yPosition = (screenHeight - pictureBoxHeight) / 2; - using (Graphics g = Graphics.FromImage(originalImage)) { @@ -2671,20 +1807,14 @@ public class MultiPagePanel : Panel float points = 25; float pixels = points * (dpiX / 72); - Font font = new Font("微軟正黑體", points, FontStyle.Bold); Brush textBrush = Brushes.Black; - string songInfo = songData.Song ?? "未提供歌曲信息"; - g.DrawString(songInfo, font, textBrush, new PointF(201, 29)); - } - - ResizeAndPositionPictureBox(VodScreenPictureBox, xPosition, yPosition, pictureBoxWidth, pictureBoxHeight); VodScreenPictureBox.Visible = true; @@ -2712,25 +1842,6 @@ public class MultiPagePanel : Panel ); } - private static void ResizeAndPositionLabel(Label label, int originalX, int originalY, int originalWidth, int originalHeight) - { - int screenW = Screen.PrimaryScreen.Bounds.Width; - int screenH = Screen.PrimaryScreen.Bounds.Height; - - float widthRatio = screenW / (float)1440; - float heightRatio = screenH / (float)900; - - - label.Location = new Point( - (int)(originalX * widthRatio), - (int)(originalY * heightRatio) - ); - label.Size = new Size( - (int)(originalWidth * widthRatio), - (int)(originalHeight * heightRatio) - ); - } - private static void ResizeAndPositionPictureBox(PictureBox pictureBox, int originalX, int originalY, int originalWidth, int originalHeight) { int screenW = Screen.PrimaryScreen.Bounds.Width; @@ -2786,7 +1897,6 @@ public class MultiPagePanel : Panel promotionsButton.BackgroundImage = promotionsNormalBackground; deliciousFoodButton.BackgroundImage = deliciousFoodActiveBackground; isOnOrderedSongsPage = false; - SetHotSongButtonsVisibility(false); SetNewSongButtonsVisibility(false); @@ -2801,11 +1911,6 @@ public class MultiPagePanel : Panel SetPinYinSingersAndButtonsVisibility(false); SetPinYinSongsAndButtonsVisibility(false); SetPictureBoxCategoryAndButtonsVisibility(false); - - - - - promotionsAndMenuPanel.currentPageIndex = 0; @@ -2833,7 +1938,6 @@ public class MultiPagePanel : Panel private void MobileSongRequestButton_Click(object sender, EventArgs e) { - SetHotSongButtonsVisibility(false); SetNewSongButtonsVisibility(false); SetSingerSearchButtonsVisibility(false); @@ -2861,9 +1965,7 @@ public class MultiPagePanel : Panel Console.WriteLine("pictureBoxQRCode is not initialized!"); } } - - - + public void OriginalSongButton_Click(object sender, EventArgs e) { videoPlayerForm.ToggleVocalRemoval(); @@ -2877,8 +1979,6 @@ public class MultiPagePanel : Panel private void PauseButton_Click(object sender, EventArgs e) { videoPlayerForm.Pause(); - - pauseButton.Visible = false; playButton.Visible = true; } @@ -2886,11 +1986,10 @@ public class MultiPagePanel : Panel private void PlayButton_Click(object sender, EventArgs e) { videoPlayerForm.Play(); - - playButton.Visible = false; pauseButton.Visible = true; } + /// /// 右下角關閉按鈕事件 /// @@ -2899,23 +1998,6 @@ public class MultiPagePanel : Panel private void ShouYeButton_Click(object sender, EventArgs e) { autoRefreshTimer.Stop(); // 停止自动刷新 - /* - 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);*/ - - FindFirstNonEmptyText(inputBoxZhuYinSingers , inputBoxZhuYinSongs , inputBoxEnglishSingers @@ -2935,6 +2017,7 @@ public class MultiPagePanel : Panel } songLabels.Clear(); } + /// /// 查詢空字串,將第一個不為空的字串,重新刷新 /// @@ -3018,23 +2101,6 @@ public class MultiPagePanel : Panel OverlayForm.MainForm.ShowMuteLabel(); } } - - private string GetRoomNumber() - { - string roomNumberFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "RoomNumber.txt"); - try - { - - string roomNumber = File.ReadLines(roomNumberFilePath).First(); - return roomNumber; - } - catch (Exception ex) - { - MessageBox.Show(String.Format("讀取包廂號文件出錯: {0}", ex.Message)); - return null; - } - } - private void MaleKeyButton_Click(object sender, EventArgs e) { @@ -3103,8 +2169,7 @@ public class MultiPagePanel : Panel MessageBox.Show("串口未開啟,無法發送升調指令。"); } } - - + private void PitchUpButton_Click(object sender, EventArgs e) { OverlayForm.MainForm.ShowKeyUpLabel(); @@ -3140,65 +2205,12 @@ public class MultiPagePanel : Panel MessageBox.Show("串口未開啟,無法發送降調指令。"); } } - - - private void HardMuteButton_Click(object sender, EventArgs e) - { - - MessageBox.Show("硬是消音 功能開發中..."); - } - - - private void TrackCorrectionButton_Click(object sender, EventArgs e) - { - - if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen) - { - - byte[] commandBytes = new byte[] { 0xA2, 0xD5, 0xA4 }; - - - SerialPortManager.mySerialPort.Write(commandBytes, 0, commandBytes.Length); - - MessageBox.Show("音軌修正指令已發送."); - } - else - { - MessageBox.Show("Serial port is not open. Cannot send track correction command."); - } - } - - + private void ApplauseButton_Click(object sender, EventArgs e) { PlayApplauseSound(); } - - private void CheerButton_Click(object sender, EventArgs e) - { - - MessageBox.Show("歡呼 功能開發中..."); - } - - - private void MockButton_Click(object sender, EventArgs e) - { - - MessageBox.Show("嘲笑 功能開發中..."); - } - - - private void BooButton_Click(object sender, EventArgs e) - { - - MessageBox.Show("噓聲 功能開發中..."); - } - - - - - private bool isWaiting = false; private async void OnServiceBellButtonClick(object sender, EventArgs e) { @@ -3221,25 +2233,6 @@ public class MultiPagePanel : Panel isWaiting = false; } - private void SaveInitialControlPositions() - { - foreach (Control control in this.Controls) - { - initialControlPositions[control] = control.Location; - } - } - - private void RestoreInitialControlPositions() - { - foreach (Control control in this.Controls) - { - if (initialControlPositions.ContainsKey(control)) - { - control.Location = initialControlPositions[control]; - } - } - } - private void InitializeSendOffPanel() { sendOffPanel = new Panel @@ -3333,6 +2326,7 @@ public class MultiPagePanel : Panel }; this.Controls.Add(sendOffPanel); } + /// /// 動態按鈕座標位置設定(依據螢幕大小) /// @@ -3361,6 +2355,7 @@ public class MultiPagePanel : Panel serviceBellPictureBox.Location = new Point((int)(757 * scaleX), (int)(151 * scaleY)); serviceBellPictureBox.Size = new Size((int)(410 * scaleX), (int)(130 * scaleY)); } + /// /// 送客畫面包廂名稱顯示 /// @@ -3388,6 +2383,7 @@ public class MultiPagePanel : Panel e.Graphics.DrawString(displayName, font, brush, point_PCName); } } + // 添加載入按鈕圖片的方法 private Image LoadButtonImage(string imageName) { @@ -3406,6 +2402,7 @@ public class MultiPagePanel : Panel return null; } } + /// /// 加載送客畫面圖片 /// @@ -3432,45 +2429,6 @@ public class MultiPagePanel : Panel } } - // 將 SequenceManager 類保留在這裡 - private class SequenceManager - { - private List correctSequence = new List { "超", "級", "巨", "星" }; - private List currentSequence = new List(); - - public void ProcessClick(string buttonName) - { - currentSequence.Add(buttonName); - - // 檢查是否點擊錯誤 - if (currentSequence.Count <= correctSequence.Count) - { - if (currentSequence[currentSequence.Count - 1] != correctSequence[currentSequence.Count - 1]) - { - // 順序錯誤,重置序列 - currentSequence.Clear(); - return; - } - } - - // 檢查是否完成正確序列 - if (currentSequence.Count == correctSequence.Count) - { - try - { - // 使用 Windows 命令關機 - System.Diagnostics.Process.Start("shutdown", "/s /t 0"); - } - catch (Exception ex) - { - MessageBox.Show($"關機失敗: {ex.Message}"); - // 如果關機失敗,退出程式 - Application.Exit(); - } - } - } - } - // 添加 Form Load 事件處理方法 private void PrimaryForm_Load(object sender, EventArgs e) { diff --git a/SequenceManager.cs b/SequenceManager.cs deleted file mode 100644 index 5241b15..0000000 --- a/SequenceManager.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace DualScreenDemo -{ - - public class SequenceManager - { - private ClickSequenceState currentState = ClickSequenceState.Initial; - - public void ProcessClick(string position) - { - switch (currentState) - { - case ClickSequenceState.Initial: - if (position == "中間") - { - currentState = ClickSequenceState.FirstClicked; - } - break; - case ClickSequenceState.FirstClicked: - if (position == "右上") - { - currentState = ClickSequenceState.SecondClicked; - } - else - { - ResetState(); - } - break; - case ClickSequenceState.SecondClicked: - if (position == "左上") - { - currentState = ClickSequenceState.ThirdClicked; - } - else - { - ResetState(); - } - break; - case ClickSequenceState.ThirdClicked: - if (position == "謝謝") - { - currentState = ClickSequenceState.Completed; - PerformShutdown(); - } - else - { - ResetState(); - } - break; - } - } - - private void ResetState() - { - currentState = ClickSequenceState.Initial; - } - - private void PerformShutdown() - { - - System.Diagnostics.Process.Start("shutdown", "/s /t 0"); - } - } -} \ No newline at end of file