superstar_v2/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.WordCountSearch.cs

378 lines
17 KiB
C#
Raw Normal View History

2025-04-07 16:54:10 +08:00
using System.IO;
using System.Drawing.Imaging;
2025-04-08 15:51:48 +08:00
2025-04-07 16:54:10 +08:00
namespace DualScreenDemo
{
public partial class PrimaryForm
{
private PictureBox pictureBoxWordCountSongs;
private Button[] numberWordCountButtonsForSongs;
private Button modifyButtonWordCountSongs;
private Button clearButtonWordCountSongs;
private Button closeButtonWordCountSongs;
2025-08-06 10:47:43 +08:00
private Button enterButtonWordCountSongs;
2025-04-07 16:54:10 +08:00
private RichTextBox inputBoxWordCountSongs;
2025-04-11 16:19:56 +08:00
// 初始化所有與注音歌手相關的按鈕,包括語音符號按鈕、特殊按鈕及輸入框。
private void InitializeButtonsForWordCountSongs()
2025-04-07 16:54:10 +08:00
{
// 初始化所有語音按鈕
InitializeNumberWordCountSongsButtons(pictureBoxWordCountSongs,NumberWordCountSongsButton_Click);
// 初始化注音歌手的輸入框
InitializeInputBoxWordCountSongs();
// 初始化下排功能按鈕
InitializeSongWordButton();
2025-04-07 16:54:10 +08:00
}
/// 初始化並設置語音按鈕的相關資料,包括符號、座標與圖片等。
private void InitializeNumberWordCountSongsButtons(Control control, EventHandler handler)
2025-04-07 16:54:10 +08:00
{
// 初始化語音按鈕陣列,總共有 10 個按鈕
numberWordCountButtonsForSongs = new Button[10];
// 設置上排數字按鈕
int x = 10;
for (int i = 0; i < 5; i++)
2025-04-07 16:54:10 +08:00
{
CreateNumBtnWordCountButton(i, x, 120, control, handler);
x += 82;
}
// 設置下排數字按鈕
x = 10;
for (int i = 5; i < 10; i++)
{
CreateNumBtnWordCountButton(i, x, 197, control, handler);
x += 82;
2025-04-07 16:54:10 +08:00
}
}
private void CreateNumBtnWordCountButton(int index, int x, int y,Control control,EventHandler handler)
2025-04-07 16:54:10 +08:00
{
try
{
// 加載配置數據
var data = LoadBtnConfigData();
2025-04-07 16:54:10 +08:00
// 創建語音按鈕並設置其屬性
numberWordCountButtonsForSongs[index] = new Button
{
Name = $"numberWordCountButton_{numberWordCountSymbols[index]}", // 按鈕名稱設為語音符號名稱
};
ConfigureButton(numberWordCountButtonsForSongs[index], x, y, 72, 67,
new Bitmap(Path.Combine(serverPath, data["NumberWordCountButtonImages"][$"button{index}_normal"])),
new Bitmap(Path.Combine(serverPath, data["NumberWordCountButtonImages"][$"button{index}_mouseOver"])),
new Bitmap(Path.Combine(serverPath, data["NumberWordCountButtonImages"][$"button{index}_mouseDown"])),
handler);
2025-04-07 16:54:10 +08:00
// 設置按鈕的 Tag 屬性為對應的語音符號
numberWordCountButtonsForSongs[index].Tag = numberWordCountSymbols[index];
// 將按鈕添加到表單的控制項集合中
control.Controls.Add(numberWordCountButtonsForSongs[index]);
2025-04-07 16:54:10 +08:00
}
catch (Exception ex)
{
Console.WriteLine($"Error creating button at index {index}: {ex.Message}");
}
}
/// 初始化下排按鈕,設定按鈕的坐標、圖片和點擊事件。
private void InitializeSongWordButton()
{
// 加載配置數據
var data = LoadBtnConfigData();
// 初始化「清除」按鈕
clearButtonWordCountSongs = new Button { Name = "btnClearWordCountSongs" };
ConfigureButton(clearButtonWordCountSongs, 55, 274, 72, 67,
new Bitmap(Path.Combine(serverPath, data["ClearButtonImagesWordCount"]["normal"])),
new Bitmap(Path.Combine(serverPath, data["ClearButtonImagesWordCount"]["mouseOver"])),
new Bitmap(Path.Combine(serverPath, data["ClearButtonImagesWordCount"]["mouseDown"])),
ClearButtonWordCountSongs_Click);
pictureBoxWordCountSongs.Controls.Add(clearButtonWordCountSongs);
// 初始化「重填」按鈕
modifyButtonWordCountSongs = new Button { Name = "btnModifyWordCountSongs" };
ConfigureButton(modifyButtonWordCountSongs, 136, 274, 72, 67,
new Bitmap(Path.Combine(serverPath, data["ModifyButtonImagesWordCount"]["normal"])),
new Bitmap(Path.Combine(serverPath, data["ModifyButtonImagesWordCount"]["mouseOver"])),
new Bitmap(Path.Combine(serverPath, data["ModifyButtonImagesWordCount"]["mouseDown"])),
ModifyButtonWordCountSongs_Click);
pictureBoxWordCountSongs.Controls.Add(modifyButtonWordCountSongs);
// 初始化「確認」按鈕
enterButtonWordCountSongs = new Button { Name = "btnEnterWordCountSongs" };
ConfigureButton(enterButtonWordCountSongs, 217, 274, 72, 67,
new Bitmap(Path.Combine(serverPath, data["EnterButtonImagesWordCount"]["normal"])),
new Bitmap(Path.Combine(serverPath, data["EnterButtonImagesWordCount"]["mouseOver"])),
new Bitmap(Path.Combine(serverPath, data["EnterButtonImagesWordCount"]["mouseDown"])),
(sender, e) => FindWordCountSongs());
pictureBoxWordCountSongs.Controls.Add(enterButtonWordCountSongs);
// 初始化「關閉」按鈕
closeButtonWordCountSongs = new Button { Name = "btnCloseWordCountSongs" };
ConfigureButton(closeButtonWordCountSongs, 298, 274, 72, 67,
new Bitmap(Path.Combine(serverPath, data["CloseButtonImagesWordCount"]["normal"])),
new Bitmap(Path.Combine(serverPath, data["CloseButtonImagesWordCount"]["mouseOver"])),
new Bitmap(Path.Combine(serverPath, data["CloseButtonImagesWordCount"]["mouseDown"])),
CloseButtonWordCountSongs_Click);
pictureBoxWordCountSongs.Controls.Add(closeButtonWordCountSongs);
}
2025-04-07 16:54:10 +08:00
// 初始化 WordCount 歌手輸入框,並設定其屬性與事件處理程序。
private void InitializeInputBoxWordCountSongs()
2025-04-07 16:54:10 +08:00
{
try
{
// 創建一個 RichTextBox 控件來作為輸入框
inputBoxWordCountSongs = new RichTextBox
{
Name = "inputBoxWordCountSongs",
ForeColor = Color.Black, // 設定文字顏色
Font = new Font("Times New Roman", 26, FontStyle.Regular), // 設定字體樣式
ScrollBars = RichTextBoxScrollBars.None // 不顯示滾動條
};
// 調整和定位輸入框的位置及大小
ResizeAndPositionControl(inputBoxWordCountSongs, 10, 55, 400, 60);
// 將輸入框加入到窗體的控件集合中
pictureBoxWordCountSongs.Controls.Add(inputBoxWordCountSongs);
}
catch (Exception ex)
{
Console.WriteLine("Error initializing inputBoxWordCountSongs: " + ex.Message);
}
2025-04-07 16:54:10 +08:00
}
// 顯示圖片並根據配置文件設置顯示區域的大小和位置。
// <param name="imagePath">圖片的路徑。</param>
private void ShowImageOnPictureBoxWordCountSongs(string imagePath)
2025-04-07 16:54:10 +08:00
{
// 加載原始圖片
Bitmap originalImage = new Bitmap(imagePath);
2025-04-07 16:54:10 +08:00
// 設置圖片到 PictureBox
pictureBoxWordCountSongs.Image = originalImage;
2025-04-07 16:54:10 +08:00
// 調整 PictureBox 大小和位置
ResizeAndPositionPictureBox(pictureBoxWordCountSongs, 778, 366, 420, 350);
2025-04-07 16:54:10 +08:00
// 顯示圖片
pictureBoxWordCountSongs.Visible = true;
}
// 設置注音歌手相關控制項(包括圖片框、按鈕和輸入框)的顯示或隱藏狀態。
// <param name="isVisible">指定控件是否可見。True 為顯示False 為隱藏。</param>
private void SetWordCountSongsAndButtonsVisibility(bool isVisible)
{
// 定義一個動作來處理控制項的顯示或隱藏
System.Action action = () =>
2025-04-07 16:54:10 +08:00
{
try
2025-04-07 16:54:10 +08:00
{
// 暫停控制項佈局的重新排版,提高效率
SuspendLayout();
if (isVisible) SetUIVisible(pictureBoxWordCountSongs);
else CloseUI(pictureBoxWordCountSongs);
2025-04-07 16:54:10 +08:00
}
catch (Exception ex)
{
Console.WriteLine("Error in SetWordCountSongsAndButtonsVisibility: " + ex.Message);
}
};
2025-04-07 16:54:10 +08:00
// 檢查是否需要在主執行緒外執行
if (this.InvokeRequired)
{
this.Invoke(action); // 如果需要,透過主執行緒執行
}
else
{
action(); // 否則直接執行
}
2025-04-07 16:54:10 +08:00
}
#region
2025-04-07 16:54:10 +08:00
/// <summary>
/// <para> 點擊「注音歌手搜尋」按鈕時執行的事件處理函式。</para>
/// <para>此函式負責更新按鈕的背景圖片、載入對應的歌手圖片,並切換相關 UI 控件的可見性。</para>
2025-04-07 16:54:10 +08:00
/// </summary>
/// <param name="sender">觸發事件的物件(通常是按鈕本身)。</param>
/// <param name="e">事件參數。</param>
private void WordCountSearchSongsButton_Click(object sender, EventArgs e)
2025-04-07 16:54:10 +08:00
{
// 設定按鈕背景,將「注音搜尋」設為啟動狀態,其餘按鈕恢復為正常狀態
zhuyinSearchSongButton.BackgroundImage = zhuyinSearchSongNormalBackground;
englishSearchSongButton.BackgroundImage = englishSearchSongNormalBackground;
pinyinSearchSongButton.BackgroundImage = pinyinSearchSongNormalBackground;
wordCountSearchSongButton.BackgroundImage = wordCountSearchSongActiveBackground;
handWritingSearchSongButton.BackgroundImage = handWritingSearchSongNormalBackground;
numberSearchSongButton.BackgroundImage = numberSearchSongNormalBackground;
2025-04-07 16:54:10 +08:00
// 載入設定檔,取得圖片路徑資訊
var configData = LoadBtnConfigData();
2025-04-07 16:54:10 +08:00
// 取得「注音歌手圖片」的完整路徑
string imagePath = Path.Combine(serverPath, configData["ImagePaths"]["WordCountSongs"]);
2025-08-06 10:47:43 +08:00
// 在 PictureBox 中顯示對應的「注音歌手」圖片
ShowImageOnPictureBoxWordCountSongs(Path.Combine(serverPath, imagePath));
2025-04-07 16:54:10 +08:00
// 鍵盤UI介面顯示設定
SetWordCountSongsAndButtonsVisibility(true);
SetEnglishSongsAndButtonsVisibility(false);
SetPinYinSongsAndButtonsVisibility(false);
SetHandWritingForSongsAndButtonsVisibility(false);
SetSongIDSearchAndButtonsVisibility(false);
SetZhuYinSongsAndButtonsVisibility(false);
SetHandWritingForSongsAndButtonsVisibility(false);
2025-04-07 16:54:10 +08:00
SetWordCountSongsAndButtonsVisibility(true); // 顯示字數搜尋相關控件
// 顯示「注音歌手搜尋」的圖片框
ResetinputBox();
pictureBoxWordCountSongs.Visible = true;
2025-04-07 16:54:10 +08:00
}
/// <summary>
/// 處理「修改」按鈕的點擊事件,該事件會刪除輸入框中的最後一個字符。
/// </summary>
private void ModifyButtonWordCountSongs_Click(object sender, EventArgs e)
{
// 如果輸入框不為空,且包含輸入內容,則刪除最後一個字符
if (pictureBoxWordCountSongs.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0)
2025-04-07 16:54:10 +08:00
{
inputBoxWordCountSongs.Text = inputBoxWordCountSongs.Text.Substring(0, inputBoxWordCountSongs.Text.Length - 1);
}
}
/// <summary>
/// 處理「清除」按鈕的點擊事件,該事件會清空輸入框中的所有文本。
/// </summary>
private void ClearButtonWordCountSongs_Click(object sender, EventArgs e)
{
// 如果輸入框不為空,則清空該框的文本內容
if (pictureBoxWordCountSongs.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0)
2025-04-07 16:54:10 +08:00
{
inputBoxWordCountSongs.Text = "";
}
}
/// <summary>
/// 「關閉」按鈕的點擊事件處理方法。
/// 隱藏 WordCount 歌手圖片框以及與其相關的按鈕。
/// </summary>
private void CloseButtonWordCountSongs_Click(object sender, EventArgs e)
{
// 隱藏 WordCount 歌手圖片框
pictureBoxWordCountSongs.Visible = false;
// 關閉背景圖式
wordCountSearchSongButton.BackgroundImage = wordCountSearchSongNormalBackground;
// 隱藏與 WordCount 歌手相關的所有按鈕
SetWordCountSongsAndButtonsVisibility(false);
2025-08-06 10:47:43 +08:00
}
private void NumberWordCountSongsButton_Click(object sender, EventArgs e)
2025-08-06 10:47:43 +08:00
{
var button = sender as Button;
if (button != null && button.Tag != null)
{
2025-08-06 10:47:43 +08:00
if (inputBoxWordCountSongs.Visible)
{
inputBoxWordCountSongs.Text += button.Tag.ToString();
}
}
}
/// 查詢歌曲(字數查詢)
private void FindWordCountSongs()
{
2025-04-09 17:50:44 +08:00
string searchText = inputBoxWordCountSongs.Text;
2025-04-08 15:51:48 +08:00
// 在這裡添加搜尋歌曲的邏輯
// 例如:根據輸入框的內容搜尋歌曲
2025-04-09 17:50:44 +08:00
string query;
2025-04-08 15:51:48 +08:00
if (int.TryParse(searchText, out int length))
{
query = $"SELECT * FROM song_library_cache WHERE CHAR_LENGTH(song_name) = {length} order by 'song_name' DESC ;";
2025-04-08 15:51:48 +08:00
}
else
{
// 處理輸入錯誤,例如顯示提示訊息
//MessageBox.Show("請輸入正確的數字!");
2025-04-09 17:50:44 +08:00
query = string.Empty; // 清空查詢
2025-04-08 15:51:48 +08:00
return;
}
var searchResults = SearchSongs_Mysql(query);
2025-04-08 15:51:48 +08:00
// 重置分頁
currentPage = 0;
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
// 更新多頁面面板的內容
multiPagePanel.currentPageIndex = 0;
multiPagePanel.LoadSongs(searchResults);
2025-04-07 16:54:10 +08:00
}
#endregion
2025-04-07 16:54:10 +08:00
#region
2025-04-07 16:54:10 +08:00
/// <summary>
/// 移除圖像周圍的白色邊框,將邊框的像素透明化。
2025-04-07 16:54:10 +08:00
/// </summary>
/// <param name="imagePath">待處理的圖像文件路徑。</param>
/// <returns>處理後的圖像,其中白色邊框已被去除並替換為透明。</returns>
private Image RemoveWhiteBorderForWordCountSongs(string imagePath)
2025-04-07 16:54:10 +08:00
{
// 創建一個 Bitmap 物件來加載圖像
Bitmap bmp = new Bitmap(imagePath);
2025-04-07 16:54:10 +08:00
// 定義圖像的矩形區域,這是我們將要操作的區域
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
2025-04-07 16:54:10 +08:00
// 鎖定圖像的位圖數據,以便進行直接修改
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
2025-04-07 16:54:10 +08:00
IntPtr ptr = bmpData.Scan0; // 獲取位圖數據的起始位置
int bytes = Math.Abs(bmpData.Stride) * bmp.Height; // 計算圖像的總字節數
byte[] rgbValues = new byte[bytes]; // 用來存儲圖像的像素數據
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); // 從圖像數據中複製像素數據到 rgbValues 陣列
2025-04-07 16:54:10 +08:00
// 遍歷每個像素點,檢查是否為白色邊框
for (int y = 0; y < bmp.Height; y++)
2025-04-07 16:54:10 +08:00
{
for (int x = 0; x < bmp.Width; x++)
2025-04-07 16:54:10 +08:00
{
int position = (y * bmpData.Stride) + (x * 4); // 計算當前像素的位址
byte b = rgbValues[position]; // 藍色分量
byte g = rgbValues[position + 1]; // 綠色分量
byte r = rgbValues[position + 2]; // 紅色分量
byte a = rgbValues[position + 3]; // alpha 分量(透明度)
2025-04-07 16:54:10 +08:00
// 如果當前像素在圖像邊緣且為白色 (255, 255, 255),則將其設為透明
if ((x < 5 || x > bmp.Width - 5 || y < 5 || y > bmp.Height - 5) && r == 255 && g == 255 && b == 255)
2025-08-06 10:47:43 +08:00
{
// 將白色像素的 RGB 設置為 255, 255, 255 且 alpha 設為 0 (透明)
rgbValues[position] = 255;
rgbValues[position + 1] = 255;
rgbValues[position + 2] = 255;
rgbValues[position + 3] = 0; // 透明
2025-08-06 10:47:43 +08:00
}
}
}
2025-08-06 10:47:43 +08:00
// 將修改後的像素數據重新複製回位圖數據
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
2025-04-07 16:54:10 +08:00
// 解鎖圖像數據
bmp.UnlockBits(bmpData);
2025-04-07 16:54:10 +08:00
// 返回處理後的圖像
return bmp;
2025-04-07 16:54:10 +08:00
}
#endregion
2025-04-07 16:54:10 +08:00
}
}