From d545c0d8c4f241383b6c1de042c9928f9a91a463 Mon Sep 17 00:00:00 2001 From: jasonchenwork Date: Mon, 14 Jul 2025 18:08:12 +0800 Subject: [PATCH] =?UTF-8?q?superstar=201.2.1=2020250714=20=E6=AD=8C?= =?UTF-8?q?=E5=BA=AB=E5=88=97=E8=A1=A8=20=E9=87=8D=E6=96=B0=E8=AA=BF?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CommandHandler.cs | 87 +-- DBObj/Artist.cs | 6 +- DBObj/Song.cs | 26 + DBObj/SongData.cs | 137 ++--- DBObj/SongList.cs | 97 +++ HttpServer.cs | 141 ++--- OverlayFormObj/OverlayForm.Labels.cs | 37 -- OverlayFormObj/OverlayForm.cs | 497 +++++---------- PlayState.cs | 10 +- PrimaryFormParts/PrimaryForm.Favorite.cs | 9 +- .../PrimaryForm.MultiPagePanel.cs | 133 +--- PrimaryFormParts/PrimaryForm.SyncScreen.cs | 41 +- PrimaryFormParts/PrimaryForm.VodScreen.cs | 43 +- PrimaryFormParts/PrimaryForm.cs | 47 +- .../PrimaryForm.SongSearch.PinyinSearch.cs | 3 +- Program.cs | 92 +-- PublicSongChecker.cs | 25 +- SongChecker.cs | 127 ---- TCPServer.cs | 22 +- VideoPlayerForm.cs | 574 ++---------------- 20 files changed, 542 insertions(+), 1612 deletions(-) create mode 100644 DBObj/Song.cs create mode 100644 DBObj/SongList.cs delete mode 100644 SongChecker.cs diff --git a/CommandHandler.cs b/CommandHandler.cs index 605f39d..26bfb7b 100644 --- a/CommandHandler.cs +++ b/CommandHandler.cs @@ -25,8 +25,9 @@ namespace DualScreenDemo /// /// 遙控器接收資料 /// - public async Task ProcessData(string indata) - { AddToHistory(indata); + public Task ProcessData(string indata) + { + AddToHistory(indata); // 遙控器測試 // Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 遙控器: {indata}"); switch (indata) @@ -190,7 +191,8 @@ namespace DualScreenDemo } break; } - + + return Task.CompletedTask; } private void SafeInvokeAction(string commandKey, Action action) { @@ -243,18 +245,11 @@ namespace DualScreenDemo private static void SkipToNextSong() { if (PrimaryForm.Instance.InvokeRequired) - { - PrimaryForm.Instance.Invoke(new System.Action(() => PrimaryForm.Instance.videoPlayerForm.SkipToNextSong())); - } + PrimaryForm.Instance.Invoke(new System.Action(() => PrimaryForm.Instance.videoPlayerForm.PlayNextSong())); else - { - PrimaryForm.Instance.videoPlayerForm.SkipToNextSong(); - } - - OverlayForm.MainForm.Invoke(new System.Action(() => - { - OverlayForm.MainForm.ShowStandardLabel(); - })); + PrimaryForm.Instance.videoPlayerForm.PlayNextSong(); + + OverlayForm.MainForm.Invoke(new System.Action(() => { OverlayForm.MainForm.ShowStandardLabel(); } ) ); } @@ -352,7 +347,7 @@ namespace DualScreenDemo { ClearDisplay(); OverlayForm.MainForm.displayLabel.Text = String.Format("已點歌曲:{0}", song); - OverlayForm.MainForm.AddSongToPlaylist(song); + SongList.Add(song); OverlayForm.MainForm.nextSongLabel.Visible = false; OverlayForm.displayTimer.Start(); } @@ -382,7 +377,7 @@ namespace DualScreenDemo { ClearDisplay(); OverlayForm.MainForm.displayLabel.Text = String.Format("{0}", song); - OverlayForm.MainForm.AddSongToPlaylist(song); + SongList.Add(song); OverlayForm.MainForm.nextSongLabel.Visible = false; OverlayForm.displayTimer.Start(); } @@ -409,12 +404,12 @@ namespace DualScreenDemo } private string check_control(string old){ foreach(string item in _indataHistory) - { - if(item == "A261A4") - old += "#"; - else if(item == "A262A4") - old += "*"; - } + { + if(item == "A261A4") + old += "#"; + else if(item == "A262A4") + old += "*"; + } return old; } @@ -458,7 +453,7 @@ namespace DualScreenDemo { ClearDisplay(); OverlayForm.MainForm.displayLabel.Text = String.Format("插播歌曲{0}", song); - OverlayForm.MainForm.InsertSongToPlaylist(song); + SongList.Insert(song); OverlayForm.MainForm.nextSongLabel.Visible = false; OverlayForm.displayTimer.Start(); } @@ -592,7 +587,8 @@ namespace DualScreenDemo ClearDisplay(); // 設定歌曲總數為已播放歌曲的數量 - OverlayForm.MainForm.totalSongs = PrimaryForm.playedSongsHistory.Count; + List historySongs = SongList.GetHistory(); + OverlayForm.MainForm.totalSongs = historySongs.Count; // 若無任何播放紀錄,直接顯示訊息並返回,不執行後續動作 if (OverlayForm.MainForm.totalSongs == 0) @@ -609,45 +605,8 @@ namespace DualScreenDemo int endIndex = Math.Min(startIndex + OverlayForm.MainForm.songsPerPage, OverlayForm.MainForm.totalSongs); // 準備要傳給 UpdateHistoryLabel 的兩個清單:歌曲資料與播放狀態 - List historySongs = new List(); - List playStates = new List(); + // 錨點 遙控器 - // 從播放紀錄中取出當前頁面應顯示的歌曲與狀態 - int completedCount = PrimaryForm.currentSongIndexInHistory; - // 判斷是否正在播放公播歌單 (若用戶點播歌單為空,則播放公播歌單) - bool isPlayingPublicList = PrimaryForm.userRequestedSongs.Count == 0 || - (PrimaryForm.currentSongIndexInHistory >= PrimaryForm.userRequestedSongs.Count - 1 ); - if (isPlayingPublicList) - { - for (int i = startIndex; i < endIndex; i++) - { - historySongs.Add(PrimaryForm.playedSongsHistory[i]); // 加入歌曲 - playStates.Add(PlayState.Played); - } - } - else - { - for (int i = startIndex; i < endIndex; i++) - { - - historySongs.Add(PrimaryForm.playedSongsHistory[i]); // 加入歌曲 - if (i < completedCount) - { - playStates.Add(PlayState.Played); - } - else if (i == completedCount) - { - playStates.Add(PlayState.Playing); - } - else - { - playStates.Add(PlayState.NotPlayed); - } - } - } - - - // 安全更新 UI:若非 UI 執行緒則使用 Invoke 切換 if (OverlayForm.MainForm.InvokeRequired) @@ -655,7 +614,7 @@ namespace DualScreenDemo OverlayForm.MainForm.Invoke(new System.Action(() => { // 更新主畫面的歷史播放顯示區 - OverlayForm.MainForm.UpdateHistoryLabel(historySongs, playStates, OverlayForm.MainForm.currentPage, totalPages); + OverlayForm.MainForm.UpdateHistoryLabel(historySongs, OverlayForm.MainForm.currentPage, totalPages); // 隱藏下一首提示 OverlayForm.MainForm.nextSongLabel.Visible = false; @@ -664,7 +623,7 @@ namespace DualScreenDemo else { // 若已在 UI 執行緒,直接操作 - OverlayForm.MainForm.UpdateHistoryLabel(historySongs, playStates, OverlayForm.MainForm.currentPage, totalPages); + OverlayForm.MainForm.UpdateHistoryLabel(historySongs, OverlayForm.MainForm.currentPage, totalPages); OverlayForm.MainForm.nextSongLabel.Visible = false; } diff --git a/DBObj/Artist.cs b/DBObj/Artist.cs index 8a5138c..bc7f5f9 100644 --- a/DBObj/Artist.cs +++ b/DBObj/Artist.cs @@ -3,8 +3,8 @@ namespace DBObj // artist OOP test public class Artist { - public string Name { get; set; } - public string NameSimplified{get;set;} + public string Name ; + public string NameSimplified ; //public string Phonetic { get; set; } //public string Category { get; set; } //public int Strokes { get; set; } @@ -14,6 +14,8 @@ namespace DBObj Name = name; NameSimplified=nameSimplified; } + public string getName(bool IsSimplified=false) { return IsSimplified ? NameSimplified : Name; } + public string getName() {return Name;} public override string ToString() { diff --git a/DBObj/Song.cs b/DBObj/Song.cs new file mode 100644 index 0000000..507666e --- /dev/null +++ b/DBObj/Song.cs @@ -0,0 +1,26 @@ +namespace DBObj +{ + // song OOP test + public class Song + { + private string Number; + private string Name; + private string Name_Simplified; + private string FileName; + private int HumanVoice; + + + public Song(string num,string name,string name_s,string filename,int humanVoice) { + Number=num; + Name=name; + Name_Simplified=name_s; + FileName=filename; + HumanVoice =humanVoice; + } + public string getNumber() {return Number;} + public string getName(bool IsSimplified) {return IsSimplified ? Name_Simplified : Name;} + public string getName() { return Name;} + public string getFileName() { return FileName;} + public int getHumanVoice() { return HumanVoice;} + } +} \ No newline at end of file diff --git a/DBObj/SongData.cs b/DBObj/SongData.cs index 606fbdb..c8eb7b3 100644 --- a/DBObj/SongData.cs +++ b/DBObj/SongData.cs @@ -1,109 +1,62 @@ using DualScreenDemo; using System; using System.IO; +using System.Windows.Markup; namespace DBObj { public class SongData { - public string Number { get; set; } - public string Name { get; set; } - public string Artist_A { get; set; } - private string Artist_B { get; set; } - public string FileName { get; set; } - public string Artist_A_Simplified { get; set; } - public string Artist_B_Simplified { get; set; } - public string Name_Simplified { get; set; } - public int HumanVoice { get; set; } + private Song basic; + private Artist A ; + private Artist B ; public bool isPublicSong { get; set; } public PlayState state; - - /* - public SongData(string songNumber, string category, string song, double plays, string artistA, string artistB, string artistACategory, string artistBCategory, DateTime addedTime, string songFilePathHost1, string songFilePathHost2, string phoneticNotation, string pinyinNotation, string artistAPhonetic, string artistBPhonetic, string artistASimplified, string artistBSimplified, string songSimplified, string songGenre, string artistAPinyin, string artistBPinyin, int humanVoice) - { - SongNumber = songNumber; - // Category = category; - Song = song; - // Plays = plays; - ArtistA = artistA; - ArtistB = artistB; - //ArtistACategory = artistACategory; - //ArtistBCategory = artistBCategory; - //AddedTime = addedTime; - SongFilePathHost1 = songFilePathHost1; - SongFilePathHost2 = songFilePathHost2; - //PhoneticNotation = phoneticNotation; - //PinyinNotation = pinyinNotation; - //ArtistAPhonetic = artistAPhonetic; - //ArtistBPhonetic = artistBPhonetic; - ArtistASimplified = artistASimplified; - ArtistBSimplified = artistBSimplified; - SongSimplified = songSimplified; - //SongGenre = songGenre; - //ArtistAPinyin = artistAPinyin; - //ArtistBPinyin = artistBPinyin; - HumanVoice = humanVoice; - } - - */ public SongData(string songNumber, string song, string filename, int humanVoice, bool isPublic) { - Number = songNumber; - Name = song; - FileName = filename; - HumanVoice = humanVoice; + basic=new(songNumber,song,"",filename,humanVoice); isPublicSong = isPublic; } public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice) { - Number = songNumber; - Name = song; - Artist_A = artistA; - Artist_B = artistB; - FileName = filename; - Artist_A_Simplified = artistASimplified; - Artist_B_Simplified = artistBSimplified; - Name_Simplified = songSimplified; - HumanVoice = humanVoice; + basic=new(songNumber,song,songSimplified,filename,humanVoice); + A= new Artist(artistA, artistASimplified); + if(artistB!=null){ + B= new Artist(artistB, artistBSimplified); + } isPublicSong = false; } - public string getName(bool IsSimplified=false) - { - return IsSimplified ? Name_Simplified : Name; - } - public int getNameLength() - { - return Name.Length; - } + public string getNumber() {return basic.getNumber();} + public string getName(bool IsSimplified=false) { return basic.getName(IsSimplified); } + public string getName() { return basic.getName();} + public string getArtist_A(bool IsSimplified) { return A.getName(IsSimplified); } + public string getArtist_A() { return A.getName();} + public string getArtist_B(bool IsSimplified) { return B.getName(IsSimplified); } + public string getArtist_B() { return B.getName();} + public int getNameLength() { return basic.getName().Length; } + public string getFileName() {return basic.getFileName();} public string next_artist_text() { - return !string.IsNullOrWhiteSpace(Artist_B) - ? String.Format("下一首:{0} {1} {2}", Artist_A, Artist_B, Name) - : String.Format("下一首:{0} {1}", Artist_A, Name); + return B!=null + ? String.Format("下一首:{0} {1} {2}", A.getName(false), B.getName(false), basic.getName(false)) + : String.Format("下一首:{0} {1}", A.getName(false), basic.getName(false)); } public string artist_text() { - return !string.IsNullOrWhiteSpace(Artist_B) - ? $"{Artist_A} - {Artist_B}" - : Artist_A; + return B!=null + ? $"{A.getName(false)} - {B.getName(false)}" + : A.getName(false); } public string name_text() { - return !string.IsNullOrWhiteSpace(Artist_B) - ? String.Format("{0} - {1} - {2}", Artist_A, Artist_B, Name) - : String.Format("{0} - {1}", Artist_A, Name); - } - public string getArtist_A(bool IsSimplified) - { - return IsSimplified ? Artist_A_Simplified : Artist_A; - } - public string getArtist_B(bool IsSimplified) - { - return IsSimplified ? Artist_B_Simplified : Artist_B; + return B!=null + ? String.Format("{0} - {1} - {2}", A.getName(false), B.getName(false), basic.getName(false)) + : String.Format("{0} - {1}", A.getName(false), basic.getName(false)); } + public string getFile() { - return FindExistingPath(FileName); + return FindExistingPath(basic.getFileName()); } private string FindExistingPath(string filename) { @@ -115,6 +68,28 @@ namespace DBObj } return null; // 找不到就回原本的 filename,不加路徑 } + public Color GetStateColor(){ + Color c = Color.White; + if (state == PlayState.Played){ + c = Color.Gray;//Color.FromArgb(200, 75, 125); // 播畢顏色:紫紅色 + }else if (state == PlayState.Playing){ + c = Color.LimeGreen; + }else if (state == PlayState.InsertPlayback){ + c = Color.Gold; + } + return c; + } + public string GetStateTxt(bool IsSimplified){ + string txt = string.Empty; + if (state == PlayState.Played) { + txt = IsSimplified ? "(播毕)" : "(播畢)"; + } else if (state == PlayState.Playing) { + txt = IsSimplified ? "(播放中)" : "(播放中)"; + } else if (state == PlayState.InsertPlayback) { + txt = IsSimplified ? "(插播)" : "(插播)"; + } + return txt; + } public void SetState(PlayState s) => state = s; public PlayState GetState() @@ -122,13 +97,13 @@ namespace DBObj return state; } - + public int getHumanVoice() { return basic.getHumanVoice(); } public override string ToString() { - return !string.IsNullOrWhiteSpace(Artist_B) - ? String.Format("{0} - {1} - {2}", Artist_A, Artist_B, Name) - : String.Format("{0} - {1}", Artist_A, Name); + return B!=null + ? String.Format("{0} - {1} - {2} - {3}", state, A.getName(), B.getName(), basic.getName()) + : String.Format("{0} - {1} - {2}", state, A.getName(), basic.getName()); } } } \ No newline at end of file diff --git a/DBObj/SongList.cs b/DBObj/SongList.cs new file mode 100644 index 0000000..a010134 --- /dev/null +++ b/DBObj/SongList.cs @@ -0,0 +1,97 @@ +using DualScreenDemo; +using System; +using System.IO; +using System.Windows.Navigation; +namespace DBObj +{ + public class SongList + { + public static SongData welcome ; + public static SongData close ; + private static SongData publicPlaying=null; + private static List publicSong = new(); + private static SongData playing=null; + private static List not_played = new List(); + private static List played = new List(); + public static List PublicSong() => publicSong; + + public static SongData Current() + { + Console.WriteLine(not_played.Count + " Current " + playing); + return (playing ==null) ? publicPlaying : playing; + } + public static SongData Next() + { + if (playing != null) + { + playing.SetState(PlayState.Played); + played.Add(playing); + playing = null; + } + if (not_played.Count <= 0) + return NextPublicSong(); + else + return NextUserSong(); + } + private static SongData NextUserSong() + { + playing = not_played[0]; + not_played.RemoveAt(0); + playing.SetState(PlayState.Playing); + UpdateNextSongLabel(); + return playing; + } + private static SongData NextPublicSong() + { + publicPlaying = publicSong[0]; + publicSong.RemoveAt(0); + publicSong.Add(publicPlaying); + return publicPlaying; + } + + public static List GetHistory() + { + List History = [.. played]; + if (playing != null) History.Add(playing); + History.AddRange(not_played); + return History; + } + + public static void Add(SongData song) + { + not_played.Add(song); + // PrimaryForm.Instance.AddSongCount(songData.Number); + chkCut(); + } + public static void Insert(SongData song) + { + song.SetState(PlayState.InsertPlayback); + not_played.Insert(0, song); + chkCut(); + } + private static void chkCut() + { + if (playing == null) + { + if (PrimaryForm.Instance.InvokeRequired) + PrimaryForm.Instance.Invoke(new System.Action(() => PrimaryForm.Instance.videoPlayerForm.PlayNextSong())); + else + PrimaryForm.Instance.videoPlayerForm.PlayNextSong(); + } else { + UpdateNextSongLabel(); + } + } + + public static void UpdateNextSongLabel() + { + VideoPlayerForm.overlayForm.UpdateNextSongLabel( + (not_played.Count > 0) ? not_played[0].next_artist_text() : "目前沒有下一首,請踴躍點歌!!!" + ); + } + public static void clearSong() + { + not_played.Clear(); + played.Clear(); + } + } +} diff --git a/HttpServer.cs b/HttpServer.cs index 40e95b5..e6f1b99 100644 --- a/HttpServer.cs +++ b/HttpServer.cs @@ -592,16 +592,9 @@ namespace DualScreenDemo case "cut": // 执行切歌操作 if (PrimaryForm.Instance.InvokeRequired) - { - PrimaryForm.Instance.Invoke(new System.Action(() => - { - PrimaryForm.Instance.videoPlayerForm.SkipToNextSong(); - })); - } + PrimaryForm.Instance.Invoke(new System.Action(() => { PrimaryForm.Instance.videoPlayerForm.PlayNextSong();})); else - { - PrimaryForm.Instance.videoPlayerForm.SkipToNextSong(); - } + PrimaryForm.Instance.videoPlayerForm.PlayNextSong(); break; case "lower_key": // 执行降调操作 @@ -691,6 +684,7 @@ namespace DualScreenDemo } private static async Task HandleOrderSongListRequest(HttpListenerContext context) { + string jsonResponse = "{\"status\": \"error\", \"message\": \"An error occurred\"}"; try { // 读取请求的内容 @@ -701,94 +695,38 @@ namespace DualScreenDemo } Console.WriteLine("Received order song request: " + requestBody); - // 检查 playedSongsHistory 是否存在且不为空 - if (PrimaryForm.playedSongsHistory != null && PrimaryForm.playedSongsHistory.Count > 0) + var response = new { status = "info", message = "No songs in the played history" }; + + // 创建响应数据 + /* + response = new { - Console.WriteLine("Played Songs History Count: " + PrimaryForm.playedSongsHistory.Count); - foreach (var song in PrimaryForm.playedSongsHistory) - { - Console.WriteLine($"Song: {song.Name}, ArtistA: {song.Artist_A}"); - } - - // 根据播放历史确定每首歌的播放状态 - var playStates = DeterminePlayStates(PrimaryForm.playedSongsHistory); - - // 创建响应数据 - var response = new - { - playingSongList = PrimaryForm.playedSongsHistory - .Select((song, index) => CreateSongResponse(song, playStates[index])) // 使用新的播放状态 - .ToList(), - // 生成播放历史 - currentSongIndexInHistory = PrimaryForm.currentSongIndexInHistory - }; - - string jsonResponse = JsonConvert.SerializeObject(response); - Console.WriteLine("Serialized JSON Response: " + jsonResponse); - - context.Response.ContentType = "application/json"; - context.Response.StatusCode = (int)HttpStatusCode.OK; - await SendResponseAsync(context, jsonResponse); - } - else - { - // 如果播放历史为空,回传一条消息 - var response = new { status = "info", message = "No songs in the played history" }; - string jsonResponse = JsonConvert.SerializeObject(response); - Console.WriteLine("Sending empty response: " + jsonResponse); - - context.Response.ContentType = "application/json"; - context.Response.StatusCode = (int)HttpStatusCode.OK; - await SendResponseAsync(context, jsonResponse); - } + playingSongList = PrimaryForm.playedSongsHistory + .Select((song, index) => new + { + song.Name, + song.Artist_A, + song.FileName, + State = song.GetState() == PlayState.Playing ? "播放中" : "播放完畢" + }) + .ToList(), + // 生成播放历史 + currentSongIndexInHistory = PrimaryForm.currentSongIndexInHistory + }; + */ + jsonResponse = JsonConvert.SerializeObject(response); + context.Response.StatusCode = (int)HttpStatusCode.OK; + } catch (Exception ex) { Console.WriteLine("Error handling order song request: " + ex.Message); - context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - await SendResponseAsync(context, "{\"status\": \"error\", \"message\": \"An error occurred\"}"); + } - } - - // 确定每首歌的播放状态 - private static List DeterminePlayStates(List playedSongsHistory) - { - var playStates = new List(); - bool foundPlaying = false; // 标记是否已找到正在播放的歌曲 - - for (int i = 0; i < playedSongsHistory.Count; i++) - { - // 这里可以根据您的业务逻辑来确定每首歌的播放状态 - if (i == PrimaryForm.currentSongIndexInHistory) - { - playStates.Add(PlayState.Playing); - foundPlaying = true; // 找到正在播放的歌曲 - } - else if (foundPlaying) - { - playStates.Add(null); // 找到播放中的歌曲后,后面的状态设置为 null - } - else - { - playStates.Add(PlayState.NotPlayed); // 未播放状态 - } - } - - return playStates; - } - - // 用于创建歌曲响应对象,包括播放状态 - private static object CreateSongResponse(SongData song, PlayState? playState) - { - return new - { - song.Name, - song.Artist_A, - song.FileName, - PlayState = playState.HasValue ? (playState.Value == PlayState.Playing ? "播放中" : "播放完畢") : null // 如果状态为 null,不返回状态信息 - }; + context.Response.ContentType = "application/json"; + await SendResponseAsync(context, jsonResponse); } // 生成播放状态 @@ -810,9 +748,9 @@ namespace DualScreenDemo if (song != null) { - Console.WriteLine($"Ordering Song: {song.Name} by {song.Artist_A}"); + Console.WriteLine($"Ordering Song: {song.getName()} by {song.getArtist_A()}"); // 这里可以添加处理逻辑,例如将歌曲加入到播放列表或数据库中 - OverlayForm.MainForm.AddSongToPlaylist(song); + SongList.Add(song); var response = new { status = "success", message = "Song ordered successfully" }; string jsonResponse = JsonConvert.SerializeObject(response); @@ -849,10 +787,9 @@ namespace DualScreenDemo if (song != null) { - Console.WriteLine($"Inserting Song: {song.Name} by {song.Artist_A}"); + Console.WriteLine($"Inserting Song: {song.getName()} by {song.getArtist_A()}"); // 这里可以添加插播歌曲的处理逻辑 - OverlayForm.MainForm.InsertSongToPlaylist(song); - + SongList.Insert(song); var response = new { status = "success", message = "Song inserted successfully" }; string jsonResponse = JsonConvert.SerializeObject(response); await SendResponseAsync(context, jsonResponse); @@ -1114,14 +1051,14 @@ namespace DualScreenDemo favoriteSongList = searchResults .Select(song => new { - song.Name, - song.Artist_A, - song.Number, - song.Artist_A_Simplified, - song.Artist_B_Simplified, - song.Name_Simplified, - song.HumanVoice, - song.FileName + Name = song.getName(), + ArtistA =song.getArtist_A(), + Number = song.getNumber(), + //song.getArtist_A(true), + //song.getArtist_B(true), + //song.getName(true), + HumanVoice =song.getHumanVoice(), + FileName = song.getFileName() }) .ToList(), status = "success", diff --git a/OverlayFormObj/OverlayForm.Labels.cs b/OverlayFormObj/OverlayForm.Labels.cs index e4fc136..44565f7 100644 --- a/OverlayFormObj/OverlayForm.Labels.cs +++ b/OverlayFormObj/OverlayForm.Labels.cs @@ -601,43 +601,6 @@ namespace OverlayFormObj -public void UpdateNextSongLabelFromPlaylist( SongData currentPlayingSong) -{ - // 获取播放列表 - List currentPlaylist = VideoPlayerForm.playingSongList ; - - if (currentPlaylist == null || currentPlaylist.Count == 0) - { - nextSongLabel.Text = "目前沒有下一首,請踴躍點歌!!!"; - nextSongLabel.Visible = true; - return; - } - - // 找到当前歌曲的索引 - int currentSongIndex = currentPlaylist.IndexOf(currentPlayingSong); - - if (currentSongIndex == -1 || currentSongIndex + 1 >= currentPlaylist.Count) - { - nextSongLabel.Text = "目前沒有下一首,請踴躍點歌!!!"; - } - else - { - SongData nextSong = currentPlaylist[currentSongIndex + 1]; - if (!string.IsNullOrEmpty(nextSong.Artist_A)) - { - nextSongLabel.Text = nextSong.next_artist_text(); - } - else - { - nextSongLabel.Text = ""; - } - } - - nextSongLabel.Visible = !string.IsNullOrEmpty(nextSongLabel.Text); // 僅在有內容時顯示標籤 -} - - - // 更新 nextSongLabel 標籤的文本 public void UpdateNextSongLabel(string text) { diff --git a/OverlayFormObj/OverlayForm.cs b/OverlayFormObj/OverlayForm.cs index 15ff234..ae59124 100644 --- a/OverlayFormObj/OverlayForm.cs +++ b/OverlayFormObj/OverlayForm.cs @@ -132,159 +132,159 @@ namespace OverlayFormObj }; } -private void AddCenteredPicture(Bitmap bitmap, int y) -{ - int x = (this.Width - bitmap.Width) / 2; - AddPicture(bitmap, x, y); -} -private void AddPicture(Bitmap bitmap, int x, int y) -{ - PictureBox pictureBox = new PictureBox - { - Image = bitmap, - Size = bitmap.Size, - BackColor = Color.Transparent, - Location = new Point(x, y) - }; - this.Controls.Add(pictureBox); - pictureBox.BringToFront(); -} -private Bitmap GenerateTextImage(string text, Font font, Color textColor, Color backgroundColor) -{ - SizeF textSize; - using (Bitmap tempBitmap = new Bitmap(1, 1)) - using (Graphics tempGraphics = Graphics.FromImage(tempBitmap)) - { - textSize = tempGraphics.MeasureString(text, font); - } - - // 創建一個稍大的位圖尺寸,以容納描邊 - int padding = 4; // 描邊寬度 - Bitmap bitmap = new Bitmap((int)textSize.Width + padding * 2, (int)textSize.Height + padding * 2); - - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - graphics.Clear(backgroundColor); - graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - - // 先繪製黑色描邊 - using (Brush outlineBrush = new SolidBrush(Color.Black)) + private void AddCenteredPicture(Bitmap bitmap, int y) { - for (int x = -2; x <= 2; x++) + int x = (this.Width - bitmap.Width) / 2; + AddPicture(bitmap, x, y); + } + private void AddPicture(Bitmap bitmap, int x, int y) + { + PictureBox pictureBox = new PictureBox { - for (int y = -2; y <= 2; y++) + Image = bitmap, + Size = bitmap.Size, + BackColor = Color.Transparent, + Location = new Point(x, y) + }; + this.Controls.Add(pictureBox); + pictureBox.BringToFront(); + } + private Bitmap GenerateTextImage(string text, Font font, Color textColor, Color backgroundColor) + { + SizeF textSize; + using (Bitmap tempBitmap = new Bitmap(1, 1)) + using (Graphics tempGraphics = Graphics.FromImage(tempBitmap)) + { + textSize = tempGraphics.MeasureString(text, font); + } + + // 創建一個稍大的位圖尺寸,以容納描邊 + int padding = 4; // 描邊寬度 + Bitmap bitmap = new Bitmap((int)textSize.Width + padding * 2, (int)textSize.Height + padding * 2); + + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + graphics.Clear(backgroundColor); + graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + // 先繪製黑色描邊 + using (Brush outlineBrush = new SolidBrush(Color.Black)) { - if (x != 0 || y != 0) + for (int x = -2; x <= 2; x++) { - graphics.DrawString(text, font, outlineBrush, - new PointF(padding + x, padding + y)); + for (int y = -2; y <= 2; y++) + { + if (x != 0 || y != 0) + { + graphics.DrawString(text, font, outlineBrush, + new PointF(padding + x, padding + y)); + } + } } } + + // 繪製中心文字 + using (Brush textBrush = new SolidBrush(textColor)) + { + graphics.DrawString(text, font, textBrush, + new PointF(padding, padding)); + } } + + // 修剪圖片邊緣空白 + return TrimBitmap(bitmap); } - // 繪製中心文字 - using (Brush textBrush = new SolidBrush(textColor)) + private Bitmap TrimBitmap(Bitmap source) { - graphics.DrawString(text, font, textBrush, - new PointF(padding, padding)); - } - } + Rectangle rect = FindContentBounds(source); - // 修剪圖片邊緣空白 - return TrimBitmap(bitmap); -} + if (rect.Width == 0 || rect.Height == 0) + return source; // 防止圖片完全空白時崩潰 -private Bitmap TrimBitmap(Bitmap source) -{ - Rectangle rect = FindContentBounds(source); - - if (rect.Width == 0 || rect.Height == 0) - return source; // 防止圖片完全空白時崩潰 - - Bitmap trimmedBitmap = new Bitmap(rect.Width, rect.Height); - using (Graphics g = Graphics.FromImage(trimmedBitmap)) - { - g.DrawImage(source, 0, 0, rect, GraphicsUnit.Pixel); - } - - return trimmedBitmap; -} - -private Rectangle FindContentBounds(Bitmap bmp) -{ - int width = bmp.Width; - int height = bmp.Height; - - int top = 0, left = 0, bottom = height - 1, right = width - 1; - - bool found = false; - - // 找到頂邊界 - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - if (bmp.GetPixel(x, y).A > 0) + Bitmap trimmedBitmap = new Bitmap(rect.Width, rect.Height); + using (Graphics g = Graphics.FromImage(trimmedBitmap)) { - top = y; - found = true; - break; + g.DrawImage(source, 0, 0, rect, GraphicsUnit.Pixel); } - } - if (found) break; - } - found = false; - // 找到底邊界 - for (int y = height - 1; y >= 0; y--) - { - for (int x = 0; x < width; x++) + return trimmedBitmap; + } + + private Rectangle FindContentBounds(Bitmap bmp) { - if (bmp.GetPixel(x, y).A > 0) - { - bottom = y; - found = true; - break; - } - } - if (found) break; - } + int width = bmp.Width; + int height = bmp.Height; - found = false; - // 找到左邊界 - for (int x = 0; x < width; x++) - { - for (int y = 0; y < height; y++) - { - if (bmp.GetPixel(x, y).A > 0) - { - left = x; - found = true; - break; - } - } - if (found) break; - } + int top = 0, left = 0, bottom = height - 1, right = width - 1; - found = false; - // 找到右邊界 - for (int x = width - 1; x >= 0; x--) - { - for (int y = 0; y < height; y++) - { - if (bmp.GetPixel(x, y).A > 0) - { - right = x; - found = true; - break; - } - } - if (found) break; - } + bool found = false; - return Rectangle.FromLTRB(left, top, right + 1, bottom + 1); -} + // 找到頂邊界 + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + if (bmp.GetPixel(x, y).A > 0) + { + top = y; + found = true; + break; + } + } + if (found) break; + } + + found = false; + // 找到底邊界 + for (int y = height - 1; y >= 0; y--) + { + for (int x = 0; x < width; x++) + { + if (bmp.GetPixel(x, y).A > 0) + { + bottom = y; + found = true; + break; + } + } + if (found) break; + } + + found = false; + // 找到左邊界 + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + if (bmp.GetPixel(x, y).A > 0) + { + left = x; + found = true; + break; + } + } + if (found) break; + } + + found = false; + // 找到右邊界 + for (int x = width - 1; x >= 0; x--) + { + for (int y = 0; y < height; y++) + { + if (bmp.GetPixel(x, y).A > 0) + { + right = x; + found = true; + break; + } + } + if (found) break; + } + + return Rectangle.FromLTRB(left, top, right + 1, bottom + 1); + } @@ -356,7 +356,6 @@ private Rectangle FindContentBounds(Bitmap bmp) secondLineTimer = new System.Windows.Forms.Timer(); secondLineTimer.Interval = 100; secondLineTimer.Tick += SecondLineTimer_Tick; - try { @@ -370,12 +369,6 @@ private Rectangle FindContentBounds(Bitmap bmp) Console.WriteLine("Error reading marquee text from file: " + ex.Message); marqueeText = "這是跑馬燈文字示例 - 歡迎使用MediaPlayerForm!"; } - - - - - - this.DoubleBuffered = true; } @@ -1004,13 +997,8 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e) if (songIndex >= 0 && songIndex < totalSongs) { selectedSong = LanguageSongList[songIndex]; - Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Name + " " + selectedSong.FileName); - - - // DisplayActionWithSong(currentPage, songIndex, "點播"); - - - AddSongToPlaylist(selectedSong); + Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].getName() + " " + selectedSong.getFileName()); + SongList.Add(selectedSong); } else { @@ -1036,13 +1024,8 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e) if (songIndex < totalSongs) { selectedSong = LanguageSongList[songIndex]; - Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Name + " " + selectedSong.FileName ); - - - // DisplayActionWithSong(currentPage, songIndex, "插播"); - - - InsertSongToPlaylist(selectedSong); + Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].getName() + " " + selectedSong.getFileName() ); + SongList.Insert(selectedSong); } else { @@ -1120,7 +1103,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e) if (songIndex < totalSongs) { selectedSong = LanguageSongList[songIndex]; - Console.WriteLine("Adding song to playlist C: " + LanguageSongList[songIndex].Name + " " + selectedSong.FileName); + Console.WriteLine("Adding song to playlist C: " + LanguageSongList[songIndex].getName() + " " + selectedSong.getFileName()); DisplaySongsWithArrows(currentPage, songIndex); @@ -1200,7 +1183,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e) } } } - public void UpdateHistoryLabel(List historySongs, List playStates, int currentPage, int totalPages) + public void UpdateHistoryLabel(List historySongs, int currentPage, int totalPages) { // 移除畫面上所有現有的 PictureBox(用於刷新內容) @@ -1227,37 +1210,15 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e) int rightMargin = this.Width - 100; // 逐一繪製歷史歌曲列表 + for (int i = 0; i < historySongs.Count; i++) { - var song = historySongs[i]; // 歌曲資料 - var state = playStates[i]; // 對應的播放狀態 - - string status; // 播放狀態文字(如「播放中」) - Color textColor; // 對應的顏色 - - // 根據播放狀態決定狀態文字與顏色 - switch (state) - { - case PlayState.Played: - status = "(播畢)"; - textColor = Color.FromArgb(200, 75, 125); // 播畢顏色:紫紅色 - break; - case PlayState.Playing: - status = "(播放中)"; - textColor = Color.LimeGreen; // 播放中顏色:亮綠 - break; - case PlayState.NotPlayed: - status = ""; - textColor = Color.White; // 尚未播放:白色 - break; - default: - status = ""; - textColor = Color.White; - break; - } + var song = historySongs[i]; // 歌曲資料 + string status=song.GetStateTxt(false); // 播放狀態文字(如「播放中」) + Color textColor=song.GetStateColor(); // 對應的顏色 // 建立顯示的歌曲文字,例如 "1. 我的歌" - string songText = $"{i + 1}. {song.Name}"; + string songText = $"{i + 1}. {song.getName()}"; Font songFont = new Font("Microsoft JhengHei", 50, FontStyle.Bold); // 將歌名轉成圖片 @@ -1526,100 +1487,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 ClearDisplay(); DisplaySongs(currentPage); } - // 歌庫路徑調整 - public void AddSongToPlaylist(SongData songData) - { - try - { - // 之後還要設計成本地的資料夾位置 - string pathToPlay = songData.getFile(); - if (!string.IsNullOrEmpty(pathToPlay)) - { - bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0; - - PrimaryForm.userRequestedSongs.Add(songData); - PrimaryForm.playedSongsHistory.Add(songData); - PrimaryForm.playStates.Add(wasEmpty ? PlayState.Playing : PlayState.NotPlayed); - // 刷新頁面 - - if (PrimaryForm.Instance.multiPagePanel.get_currentSongList() == PrimaryForm.playedSongsHistory) - PrimaryForm.Instance.multiPagePanel.LoadSongs(PrimaryForm.Instance.currentSongList); - if (wasEmpty) - { - VideoPlayerForm.Instance.SetPlayingSongList(PrimaryForm.userRequestedSongs); - PrimaryForm.currentSongIndexInHistory += 1; - } - VideoPlayerForm.Instance.UpdateNextSongFromPlaylist(); - PrimaryForm.PrintPlayingSongList(); - - // 點播次數+1 - PrimaryForm.Instance.AddSongCount(songData.Number); - } - } - catch (Exception ex) - { - Console.WriteLine("Error occurred: " + ex.Message); - } - } - - - - public void InsertSongToPlaylist(SongData songData) - { - try - { - // 從 songData 中取得兩個可能的檔案路徑(主機1與主機2) - var pathToPlay = songData.getFile(); - - // 檢查兩個主機上的檔案是否皆不存在 - if (!string.IsNullOrEmpty(pathToPlay)) - { - // 若其中一個存在,就用第一個存在的那個檔案 - - Console.WriteLine("path to play" + pathToPlay); - - // 檢查目前使用者歌單是否為空 - bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0; - - if (wasEmpty) - { - // 若是空的,代表是第一首歌,直接加入並設為正在播放 - PrimaryForm.userRequestedSongs.Add(songData); // 加入播放清單 - VideoPlayerForm.Instance.SetPlayingSongList(PrimaryForm.userRequestedSongs); // 傳給播放器 - PrimaryForm.playedSongsHistory.Add(songData); // 加入播放歷史 - PrimaryForm.playStates.Add(PlayState.Playing); // 設定狀態為正在播放 - PrimaryForm.currentSongIndexInHistory += 1; // 歷史索引 +1 - } - else if (PrimaryForm.userRequestedSongs.Count == 1) - { - // 若清單中已有一首,插入新歌在 index 1 (即目前播放之後的位置) - PrimaryForm.userRequestedSongs.Insert(1, songData); - PrimaryForm.playedSongsHistory.Insert(PrimaryForm.currentSongIndexInHistory + 1, songData); - PrimaryForm.playStates.Insert(PrimaryForm.currentSongIndexInHistory + 1, PlayState.NotPlayed); // 尚未播放 - } - else - { - // 若清單中超過一首,同樣插入在 index 1,也是在當前歌曲之後的位置 - PrimaryForm.userRequestedSongs.Insert(1, songData); - PrimaryForm.playedSongsHistory.Insert(PrimaryForm.currentSongIndexInHistory + 1, songData); - PrimaryForm.playStates.Insert(PrimaryForm.currentSongIndexInHistory + 1, PlayState.NotPlayed); - } - - // 更新下一首即將播放的資訊(畫面或播放器邏輯用) - VideoPlayerForm.Instance.UpdateNextSongFromPlaylist(); - - // 印出目前播放清單資訊到畫面或 console - PrimaryForm.PrintPlayingSongList(); - } - } - catch (Exception ex) - { - // 捕捉所有例外並印出錯誤訊息(避免整個流程當掉) - Console.WriteLine("Error occurred: " + ex.Message); - } - } - - + // 測試 public int currentPage = 1; public int songsPerPage = 5; @@ -1681,7 +1549,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 for (int i = startIndex; i < endIndex; i++) { - string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}"; + string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName(false)}"; string artistText = LanguageSongList[i].artist_text(); maxSongLength = Math.Max(maxSongLength, songText.Length); @@ -1701,7 +1569,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 // 計算行高 for (int i = startIndex; i < endIndex; i++) { - string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}"; + string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName(false)}"; string artistText = LanguageSongList[i].artist_text(); Font songFont = new Font("Microsoft JhengHei", songFontSize, FontStyle.Bold); @@ -1718,7 +1586,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 { int songNumber = i - startIndex + 1; - string songText = $"{songNumber}. {LanguageSongList[i].Name}"; + string songText = $"{songNumber}. {LanguageSongList[i].getName(false)}"; string artistText = LanguageSongList[i].artist_text(); Font songFont = new Font("Microsoft JhengHei", songFontSize, FontStyle.Bold); @@ -1791,7 +1659,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 int maxArtistLength = 0; for (int i = startIndex; i < endIndex; i++) { - string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}"; + string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName()}"; string artistText = LanguageSongList[i].artist_text(); maxSongLength = Math.Max(maxSongLength, songText.Length); @@ -1807,7 +1675,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 int rowHeight = 0; for (int i = startIndex; i < endIndex; i++) { - string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}"; + string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName(false)}"; string artistText = LanguageSongList[i].artist_text(); Font tempSongFont = new Font("Microsoft JhengHei", songFontSize, FontStyle.Bold); @@ -1824,7 +1692,7 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 { int songNumber = i - startIndex + 1; - string songText = $"{songNumber}. {LanguageSongList[i].Name}"; + string songText = $"{songNumber}. {LanguageSongList[i].getName(false)}"; string artistText = LanguageSongList[i].artist_text(); // 設定顏色,選中的索引顯示為亮綠色 @@ -1847,67 +1715,6 @@ private void DisplayArtists(List artists, int page)//歌星點進去後 } } - - - public void DisplayActionWithSong(int page, int songIndex, string actionType) - { - // try - // { - // if (LanguageSongList == null || LanguageSongList.Count == 0) - // { - // Console.WriteLine("Error: LanguageSongList is null or empty."); - // return; - // } - - // SongData song = LanguageSongList[songIndex]; - - // this.Controls.OfType().ToList().ForEach(p => this.Controls.Remove(p)); - - // int songsPerColumn = 5; - // int startIndex = (page - 1) * songsPerPage; - // int endIndex = Math.Min(startIndex + songsPerPage, LanguageSongList.Count); - - // int totalPages = (int)Math.Ceiling((double)LanguageSongList.Count / songsPerPage); - - // string headerText = $"{actionType}: {song.ArtistA} - {song.Song} ({page} / {totalPages})"; - // Font headerFont = new Font("Microsoft JhengHei", 40, FontStyle.Bold); - // Color headerColor = actionType == "點播" ? Color.LimeGreen : Color.Yellow; - // Bitmap headerBitmap = GenerateTextImage(headerText, headerFont, headerColor, Color.Transparent); - // AddCenteredPicture(headerBitmap, 150); - - // int startY = 250; - // int verticalSpacing = 10; - // int leftColumnX = 200; - // int rightColumnX = this.Width / 2 + 150; - - // for (int i = startIndex; i < endIndex; i++) - // { - // int songNumber = i - startIndex + 1; - // string songText = $"{songNumber}. {LanguageSongList[i].Song}"; - // string artistText = !string.IsNullOrWhiteSpace(LanguageSongList[i].ArtistB) - // ? $"{LanguageSongList[i].ArtistA} - {LanguageSongList[i].ArtistB}" - // : LanguageSongList[i].ArtistA; - - // Font songFont = new Font("Microsoft JhengHei", 40, FontStyle.Bold); - // Bitmap songBitmap = GenerateTextImage(songText, songFont, Color.White, Color.Transparent); - - // Font artistFont = new Font("Microsoft JhengHei", 30, FontStyle.Bold); - // Bitmap artistBitmap = GenerateTextImage(artistText, artistFont, Color.White, Color.Transparent); - - // int x = (i - startIndex) < songsPerColumn ? leftColumnX : rightColumnX; - // int y = startY + ((i - startIndex) % songsPerColumn) * (songBitmap.Height + verticalSpacing); - - // AddPicture(songBitmap, x, y); - // AddPicture(artistBitmap, x + songBitmap.Width + 20, y); - // } - // } - // catch (Exception ex) - // { - // Console.WriteLine($"Error in DisplayActionWithSong: {ex.Message}"); - // Console.WriteLine(ex.StackTrace); - // } - } - public void NextPage() { diff --git a/PlayState.cs b/PlayState.cs index 64675e7..d3f3480 100644 --- a/PlayState.cs +++ b/PlayState.cs @@ -3,9 +3,11 @@ namespace DualScreenDemo public enum PlayState { - Playing, - Played, - NotPlayed, - Skipped + NotPlayed, // 未播放 + Playing, // 正在播放 + Played, // 已播放 + InsertPlayback, // 插入播放 + NoFile, // 沒有文件 + Skipped // 已跳過 } } \ No newline at end of file diff --git a/PrimaryFormParts/PrimaryForm.Favorite.cs b/PrimaryFormParts/PrimaryForm.Favorite.cs index 248d69c..2c69042 100644 --- a/PrimaryFormParts/PrimaryForm.Favorite.cs +++ b/PrimaryFormParts/PrimaryForm.Favorite.cs @@ -221,11 +221,10 @@ namespace DualScreenDemo var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql()); // 重置分頁 currentPage = 0; - currentSongList = searchResults; totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); // 更新多頁面面板的內容 multiPagePanel.currentPageIndex = 0; - multiPagePanel.LoadSongs(currentSongList); + multiPagePanel.LoadSongs(searchResults); ToggleFavoritePictureBoxButtonsVisibility(); } @@ -257,11 +256,10 @@ namespace DualScreenDemo var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql()); // 重置分頁 currentPage = 0; - currentSongList = searchResults; totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); // 更新多頁面面板的內容 multiPagePanel.currentPageIndex = 0; - multiPagePanel.LoadSongs(currentSongList); + multiPagePanel.LoadSongs(searchResults); ToggleFavoritePictureBoxButtonsVisibility(); } @@ -274,11 +272,10 @@ namespace DualScreenDemo var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql()); // 重置分頁 currentPage = 0; - currentSongList = searchResults; totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); // 更新多頁面面板的內容 multiPagePanel.currentPageIndex = 0; - multiPagePanel.LoadSongs(currentSongList); + multiPagePanel.LoadSongs(searchResults); ToggleFavoritePictureBoxButtonsVisibility(); } diff --git a/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs b/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs index e764d2d..a19d16f 100644 --- a/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs +++ b/PrimaryFormParts/PrimaryForm.MultiPagePanel.cs @@ -194,7 +194,7 @@ namespace DualScreenDemo RefreshDisplayBase_Singer(); } - public void LoadPlayedSongs(List songs, List states) + public void LoadPlayedSongs(List songs) { _isShowingSinger = false; currentSongList = songs; @@ -376,76 +376,20 @@ namespace DualScreenDemo { // 創建歌曲標籤 Label songLabel = new Label(); - string statusText = ""; // 狀態文字 - - bool isCurrentlyPlaying = false; // 是否正在播放 - bool hasBeenPlayed = false; // 是否已播放完成 - bool isLatestInstance = true; // 是否是最新的歌曲 - - // 僅在 "已點歌曲" 頁面顯示播放狀態 + string statusText; + Color color; if (PrimaryForm.Instance.isOnOrderedSongsPage) { - // 判斷是否正在播放公播歌單 (若用戶點播歌單為空,則播放公播歌單) - bool isPlayingPublicList = userRequestedSongs.Count == 0 || - (currentSongIndexInHistory >= userRequestedSongs.Count - 1 ); - if (isPlayingPublicList) - { - // 若播放公播歌單,代表已點歌曲皆已播放完畢 - hasBeenPlayed = true; - songLabel.ForeColor = Color.Gray; - statusText = IsSimplified ? "(播毕)" : "(播畢)"; - } - else - { - // 計算已完成播放的歌曲數量 - int completedCount = currentSongIndexInHistory; - //Console.WriteLine("currentSongIndexInHistory:" + currentSongIndexInHistory); - // 遍歷已點歌曲歷史 - /*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) - { - // 已播放完成 - hasBeenPlayed = true; - songLabel.ForeColor = Color.Gray; - statusText = IsSimplified ? "(播毕)" : "(播畢)"; - } - else if (songPosition == completedCount) - { - // 正在播放 - isCurrentlyPlaying = true; - songLabel.ForeColor = Color.LimeGreen; - statusText = IsSimplified ? "(播放中)" : "(播放中)"; - } - else - { - // 未播放 - songLabel.ForeColor = Color.White; - statusText = string.Empty; - } - } + statusText = song.GetStateTxt(IsSimplified); // 狀態文字 + color = song.GetStateColor(); } else { - // 未在 "已點歌曲" 頁面顯示白色 - songLabel.ForeColor = Color.White; + color = Color.White; statusText = string.Empty; } + songLabel.ForeColor = color; // 根據簡繁體設置選擇要顯示的文字 string songText = song.getName(IsSimplified); @@ -507,7 +451,7 @@ namespace DualScreenDemo int artistWidth = (int)(this.Width * ArtistWidth); int artistX = songX + songWidth + 10; // 添加人聲標籤 - if (song.HumanVoice == 1) + if (song.getHumanVoice() == 1) { PictureBox icon = new PictureBox() { @@ -542,20 +486,12 @@ namespace DualScreenDemo }; // 根據文字長度設置字體大小 + int fold = 14; if (artistText.Length > 6) - { - artistLabel.Font = new Font("微軟正黑體", 10, FontStyle.Bold); - } - else if (artistText.Length > 3) - { - artistLabel.Font = new Font("微軟正黑體", 12, FontStyle.Bold); - } - else - { - artistLabel.Font = new Font("微軟正黑體", 14, FontStyle.Bold); - } - - //artistLabel.Font = new Font("微軟正黑體", 16, FontStyle.Bold); + fold = 10; + else if (artistText.Length > 3) + fold = 12; + artistLabel.Font = new Font("微軟正黑體", fold, FontStyle.Bold); artistLabel.ForeColor = Color.FromArgb(30,144,255); songLabel.TextAlign = ContentAlignment.MiddleLeft; @@ -565,48 +501,15 @@ namespace DualScreenDemo 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); - } + 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; - } - // 恢復歌手名稱的顏色為預設的藍色 + songLabel.ForeColor = color; artistLabel.ForeColor = Color.FromArgb(30, 144, 255); - // 恢復分隔線的顏色為半透明白色 separatorPanel.BackColor = Color.FromArgb(80, 255, 255, 255); }; // 添加事件处理 diff --git a/PrimaryFormParts/PrimaryForm.SyncScreen.cs b/PrimaryFormParts/PrimaryForm.SyncScreen.cs index 525bb1a..4b02883 100644 --- a/PrimaryFormParts/PrimaryForm.SyncScreen.cs +++ b/PrimaryFormParts/PrimaryForm.SyncScreen.cs @@ -34,67 +34,30 @@ namespace DualScreenDemo this.syncCloseButton = new System.Windows.Forms.Button(); this.SuspendLayout(); - - - - - ResizeAndPositionControl(this.primaryScreenPanel, 0, 0, 1440, 900); this.primaryScreenPanel.TabIndex = 0; this.primaryScreenPanel.BorderStyle = BorderStyle.FixedSingle; this.primaryScreenPanel.BackColor = System.Drawing.Color.Black; - - // 同步畫面 服務鈴 ConfigureButton(this.syncServiceBellButton, 1240, 17, 161, 161, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, //(sender, e) => SendCommandThroughSerialPort("a2 53 a4")); (sender,e)=>OnServiceBellButtonClick(sender,e)); - - - - - ConfigureButton(this.syncCutSongButton, 1218, 195, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, (sender, e) => videoPlayerForm.SkipToNextSong()); - - - - + + ConfigureButton(this.syncCutSongButton, 1218, 195, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, (sender, e) => videoPlayerForm.PlayNextSong()); ConfigureButton(this.syncReplayButton, 1218, 265, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, ReplayButton_Click); - - - // 有人聲入口位置 ConfigureButton(this.syncOriginalSongButton, 1218, 335, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, (sender,e) => videoPlayerForm.ToggleVocalRemoval()); - - - - ConfigureButton(this.syncMuteButton, 1218, 406, 205, 55, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, MuteUnmuteButton_Click); - - - - ConfigureButton(this.syncPauseButton, 1218, 475, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, SyncPauseButton_Click); ConfigureButton(this.syncPlayButton, 1218, 475, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, SyncPlayButton_Click); - - - - ConfigureButton(this.syncVolumeUpButton, 1218, 546, 205, 55, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, null); this.syncVolumeUpButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowVolumeUpLabel(); volumeUpTimer.Start(); }; this.syncVolumeUpButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); volumeUpTimer.Stop(); }; - - - - ConfigureButton(this.syncVolumeDownButton, 1218, 616, 205, 55, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, null); this.syncVolumeDownButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowVolumeDownLabel(); volumeDownTimer.Start(); }; this.syncVolumeDownButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); volumeDownTimer.Stop(); }; - - - - ConfigureButton(this.syncMicUpButton, 1218, 686, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, null); this.syncMicUpButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowMicUpLabel(); micControlTimer.Tag = "a2 b5 a4"; micControlTimer.Start(); }; this.syncMicUpButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); micControlTimer.Stop(); }; diff --git a/PrimaryFormParts/PrimaryForm.VodScreen.cs b/PrimaryFormParts/PrimaryForm.VodScreen.cs index f90b528..21ca280 100644 --- a/PrimaryFormParts/PrimaryForm.VodScreen.cs +++ b/PrimaryFormParts/PrimaryForm.VodScreen.cs @@ -1,6 +1,6 @@ using System.IO; using DBObj; -using OverlayFormObj; + namespace DualScreenDemo { public partial class PrimaryForm @@ -114,26 +114,21 @@ namespace DualScreenDemo this.Controls.Add(favoriteButton); this.Controls.Add(vodScreenCloseButton); } - - - private async void VodButton_Click(object sender, EventArgs e) + private void VodButton_Click(object sender, EventArgs e) { SetVodScreenPictureBoxAndButtonsVisibility(false); - await Task.Delay(1000); - OverlayForm.MainForm.AddSongToPlaylist(currentSelectedSong); - + SongList.Add(currentSelectedSong); } private void InsertButton_Click(object sender, EventArgs e) { SetVodScreenPictureBoxAndButtonsVisibility(false); - OverlayForm.MainForm.InsertSongToPlaylist(currentSelectedSong); - + SongList.Insert(currentSelectedSong); } private void AlbumButton_Click(object sender, EventArgs e) { - string name = currentSelectedSong.Artist_A; + string name = currentSelectedSong.getArtist_A(false); string query = $"SELECT * FROM song_library_cache WHERE artistA = '{name}' ORDER BY add_date DESC;"; var selectedSongs = SearchSongs_Mysql(query); /*var selectedSongs = allSongs.Where(song => song.ArtistA == currentSelectedSong.ArtistA) @@ -146,24 +141,21 @@ namespace DualScreenDemo private void FavoriteButton_Click(object sender, EventArgs e) { - Console.WriteLine("Favorite Button Clicked"); - InsertNewFavoriteSong(currentSelectedSong.Number); + InsertNewFavoriteSong(currentSelectedSong.getNumber()); var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql()); // 重置分頁 currentPage = 0; - currentSongList = searchResults; totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage); // 更新多頁面面板的內容 multiPagePanel.currentPageIndex = 0; - multiPagePanel.LoadSongs(currentSongList); + multiPagePanel.LoadSongs(searchResults); SetVodScreenPictureBoxAndButtonsVisibility(false); } private void VodScreenCloseButton_Click(object sender, EventArgs e) { - SetVodScreenPictureBoxAndButtonsVisibility(false); } @@ -171,38 +163,23 @@ namespace DualScreenDemo private void SetVodScreenPictureBoxAndButtonsVisibility(bool isVisible) { - overlayPanel.Visible = isVisible; VodScreenPictureBox.Visible = isVisible; - - vodButton.Visible = isVisible; insertButton.Visible = isVisible; albumButton.Visible = isVisible; favoriteButton.Visible = isVisible; vodScreenCloseButton.Visible = isVisible; - - - - if (isVisible) - { - - if (isLoggedIn) - { + if (isVisible){ + if (isLoggedIn){ favoriteButton.Enabled = true; favoriteButton.Controls.Remove(disabledPanel); - } - else - { + } else { favoriteButton.Enabled = false; } - - overlayPanel.BringToFront(); VodScreenPictureBox.BringToFront(); - - vodButton.BringToFront(); insertButton.BringToFront(); albumButton.BringToFront(); diff --git a/PrimaryFormParts/PrimaryForm.cs b/PrimaryFormParts/PrimaryForm.cs index b496c65..b711100 100644 --- a/PrimaryFormParts/PrimaryForm.cs +++ b/PrimaryFormParts/PrimaryForm.cs @@ -118,12 +118,7 @@ namespace DualScreenDemo private static Bitmap normalStateImageForLightControl; private static Bitmap resizedNormalStateImageForLightControl; public VideoPlayerForm videoPlayerForm; - public List currentSongList; public List currentArtistList; - public static List userRequestedSongs; - public static List playedSongsHistory; - public static List playStates; - public static int currentSongIndexInHistory = -1; public MultiPagePanel multiPagePanel; private List