2025-04-15 13:16:32 +08:00
|
|
|
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;
|
2025-04-23 13:55:11 +08:00
|
|
|
if(currentArtistList != null && currentArtistList.Count > 0)
|
|
|
|
RefreshDisplayBase_Singer();
|
|
|
|
else
|
|
|
|
RefreshDisplay();
|
2025-04-15 13:16:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-05-22 10:24:21 +08:00
|
|
|
private bool _isShowingSinger = true;
|
2025-04-15 13:16:32 +08:00
|
|
|
private List<SongData> currentSongList = new List<SongData>();
|
2025-05-08 10:09:14 +08:00
|
|
|
public List<SongData> get_currentSongList(){
|
|
|
|
return currentSongList;
|
|
|
|
}
|
2025-04-15 13:16:32 +08:00
|
|
|
private List<Artist> currentArtistList = new List<Artist>();
|
|
|
|
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;
|
2025-06-18 13:44:01 +08:00
|
|
|
if (Math.Abs(deltaX) > 20) // 滑動距離超過50像素才觸發
|
2025-04-15 13:16:32 +08:00
|
|
|
{
|
|
|
|
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(沒有歌單),則刷新歌手列表
|
2025-05-22 10:24:21 +08:00
|
|
|
if(_isShowingSinger)
|
2025-04-15 13:16:32 +08:00
|
|
|
{
|
|
|
|
RefreshDisplayBase_Singer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RefreshDisplay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public void LoadPreviousPage()
|
|
|
|
{
|
|
|
|
if (currentPageIndex > 0)
|
|
|
|
{
|
|
|
|
currentPageIndex--;
|
|
|
|
if(currentSongList.Count == 0)
|
|
|
|
{
|
|
|
|
RefreshDisplayBase_Singer();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RefreshDisplay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void LoadSongs(List<SongData> songs, bool clearHistory = false)
|
|
|
|
{
|
2025-05-22 10:24:21 +08:00
|
|
|
_isShowingSinger = false;
|
2025-04-15 13:16:32 +08:00
|
|
|
currentSongList = songs;
|
|
|
|
currentArtistList.Clear();
|
|
|
|
currentPageIndex = 0;
|
|
|
|
totalPages = (int)Math.Ceiling(songs.Count / (double)itemsPerPage);
|
|
|
|
|
|
|
|
// 直接調用基礎刷新邏輯
|
|
|
|
RefreshDisplayBase();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void LoadSingers(List<Artist> artists)
|
|
|
|
{
|
2025-05-22 10:24:21 +08:00
|
|
|
_isShowingSinger = true;
|
2025-04-15 13:16:32 +08:00
|
|
|
currentArtistList = artists;
|
2025-05-22 10:24:21 +08:00
|
|
|
// currentSongList.Clear();
|
2025-04-15 13:16:32 +08:00
|
|
|
currentPageIndex = 0;
|
|
|
|
totalPages = (int)Math.Ceiling(artists.Count / (double)itemsPerPage);
|
|
|
|
RefreshDisplayBase_Singer();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void LoadPlayedSongs(List<SongData> songs, List<PlayState> states)
|
|
|
|
{
|
2025-05-22 10:24:21 +08:00
|
|
|
_isShowingSinger = false;
|
2025-04-15 13:16:32 +08:00
|
|
|
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();
|
2025-04-23 13:55:11 +08:00
|
|
|
string artistText = IsSimplified ?
|
|
|
|
(!string.IsNullOrEmpty(artist.NameSimplified) ? artist.NameSimplified : artist.Name) :
|
|
|
|
artist.Name;
|
|
|
|
artistLabel.Text = artistText;
|
2025-04-15 13:16:32 +08:00
|
|
|
artistLabel.Tag = artist;
|
|
|
|
artistLabel.AutoSize = false;
|
|
|
|
|
|
|
|
// 計算文字寬度
|
2025-05-21 15:42:42 +08:00
|
|
|
Font normalFont = new Font("微軟正黑體", 24, FontStyle.Bold);
|
|
|
|
Font mediumFont = new Font("微軟正黑體", 18, FontStyle.Bold);
|
|
|
|
Font smallFont = new Font("微軟正黑體", 14, FontStyle.Bold);
|
2025-04-15 13:16:32 +08:00
|
|
|
|
|
|
|
// 根據文字長度設置字體大小
|
|
|
|
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; // 取得輸入內容
|
2025-04-18 15:48:41 +08:00
|
|
|
// 歌星 轉 歌曲
|
2025-04-23 13:55:11 +08:00
|
|
|
string query = IsSimplified ?
|
|
|
|
(
|
|
|
|
!string.IsNullOrEmpty(artist.NameSimplified)?
|
|
|
|
$"SELECT * FROM song_library_cache WHERE artistA_simplified = '{searchText}' OR artistB_simplified = '{searchText}'"
|
|
|
|
: $"SELECT * FROM song_library_cache WHERE artistA = '{searchText}' OR artistB = '{searchText}'"
|
|
|
|
)
|
|
|
|
: $"SELECT * FROM song_library_cache WHERE artistA = '{searchText}' OR artistB = '{searchText}'"
|
|
|
|
;
|
|
|
|
//string query = $"SELECT * FROM song_library_cache WHERE artistA ='{searchText}' OR artistB='{searchText}' ";
|
2025-04-15 13:16:32 +08:00
|
|
|
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;
|
2025-05-14 16:25:24 +08:00
|
|
|
statusText = IsSimplified ? "(播毕)" : "(播畢)";
|
2025-04-15 13:16:32 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 計算已完成播放的歌曲數量
|
2025-05-08 10:09:14 +08:00
|
|
|
int completedCount = currentSongIndexInHistory;
|
2025-05-14 16:25:24 +08:00
|
|
|
//Console.WriteLine("currentSongIndexInHistory:" + currentSongIndexInHistory);
|
2025-04-15 13:16:32 +08:00
|
|
|
// 遍歷已點歌曲歷史
|
2025-05-08 10:09:14 +08:00
|
|
|
/*for (int i = 0; i <= currentSongIndexInHistory && i < playedSongsHistory.Count; i++) {
|
2025-04-15 13:16:32 +08:00
|
|
|
if (i == currentSongIndexInHistory) {
|
|
|
|
completedCount = i + 1; // 当前播放的歌曲
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// 检查播放状态
|
|
|
|
if (i < playStates.Count) {
|
|
|
|
if (playStates[i] == PlayState.Played || playStates[i] == PlayState.Playing) {
|
|
|
|
completedCount++;
|
|
|
|
}
|
|
|
|
// 如果是切歌状态,不增加计数
|
|
|
|
}
|
2025-05-08 10:09:14 +08:00
|
|
|
}*/
|
2025-04-15 13:16:32 +08:00
|
|
|
// 計算歌曲在歷史中的位置
|
|
|
|
int songPosition = pageOffset + index;
|
|
|
|
// 判斷歌曲狀態
|
2025-05-08 10:09:14 +08:00
|
|
|
if (songPosition < completedCount)
|
2025-04-15 13:16:32 +08:00
|
|
|
{
|
|
|
|
// 已播放完成
|
|
|
|
hasBeenPlayed = true;
|
|
|
|
songLabel.ForeColor = Color.Gray;
|
2025-05-14 16:25:24 +08:00
|
|
|
statusText = IsSimplified ? "(播毕)" : "(播畢)";
|
2025-04-15 13:16:32 +08:00
|
|
|
}
|
2025-05-08 10:09:14 +08:00
|
|
|
else if (songPosition == completedCount)
|
2025-04-15 13:16:32 +08:00
|
|
|
{
|
|
|
|
// 正在播放
|
|
|
|
isCurrentlyPlaying = true;
|
|
|
|
songLabel.ForeColor = Color.LimeGreen;
|
2025-05-14 16:25:24 +08:00
|
|
|
statusText = IsSimplified ? "(播放中)" : "(播放中)";
|
2025-04-15 13:16:32 +08:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
|
2025-04-22 15:25:58 +08:00
|
|
|
// 歌手名稱設置點
|
2025-04-15 13:16:32 +08:00
|
|
|
string artistText = IsSimplified ?
|
|
|
|
(!string.IsNullOrEmpty(song.ArtistASimplified) ? song.ArtistASimplified : song.ArtistA) :
|
|
|
|
song.ArtistA;
|
|
|
|
|
|
|
|
string fullText = songText + statusText;
|
|
|
|
int textLength = fullText.Length;
|
|
|
|
|
|
|
|
// 計算文字寬度
|
2025-05-21 15:50:41 +08:00
|
|
|
Font normalFont = new Font("微軟正黑體", 20, FontStyle.Bold);
|
|
|
|
Font mediumFont = new Font("微軟正黑體", 14, FontStyle.Bold);
|
2025-05-21 15:42:42 +08:00
|
|
|
Font smallFont = new Font("微軟正黑體", 12, FontStyle.Bold);
|
2025-04-15 13:16:32 +08:00
|
|
|
// 根據文字長度設置字體大小
|
|
|
|
if (textLength > 18)
|
|
|
|
{
|
|
|
|
songLabel.Font = smallFont;
|
|
|
|
}
|
2025-05-21 15:50:41 +08:00
|
|
|
else if (textLength > 8)
|
2025-04-15 13:16:32 +08:00
|
|
|
{
|
|
|
|
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()
|
|
|
|
};
|
2025-05-21 15:42:42 +08:00
|
|
|
|
|
|
|
// 根據文字長度設置字體大小
|
|
|
|
if (artistText.Length > 6)
|
|
|
|
{
|
2025-05-21 15:50:41 +08:00
|
|
|
artistLabel.Font = new Font("微軟正黑體", 10, FontStyle.Bold);
|
2025-05-21 15:42:42 +08:00
|
|
|
}
|
2025-05-21 15:50:41 +08:00
|
|
|
else if (artistText.Length > 3)
|
2025-05-21 15:42:42 +08:00
|
|
|
{
|
2025-05-21 15:50:41 +08:00
|
|
|
artistLabel.Font = new Font("微軟正黑體", 12, FontStyle.Bold);
|
2025-05-21 15:42:42 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2025-05-21 15:50:41 +08:00
|
|
|
artistLabel.Font = new Font("微軟正黑體", 14, FontStyle.Bold);
|
2025-05-21 15:42:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//artistLabel.Font = new Font("微軟正黑體", 16, FontStyle.Bold);
|
|
|
|
|
2025-04-15 13:16:32 +08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|