diff --git a/PrimaryFormParts/SingerSearch/PrimaryForm.SingerSearch.BopomofoSearch.cs b/PrimaryFormParts/SingerSearch/PrimaryForm.SingerSearch.BopomofoSearch.cs
index 3bdda57..4af8bd6 100644
--- a/PrimaryFormParts/SingerSearch/PrimaryForm.SingerSearch.BopomofoSearch.cs
+++ b/PrimaryFormParts/SingerSearch/PrimaryForm.SingerSearch.BopomofoSearch.cs
@@ -36,296 +36,503 @@ namespace DualScreenDemo
private FontStyle inputBoxFontStyle;
private Color inputBoxForeColor;
+ ///
+ /// 點擊「注音歌手搜尋」按鈕時執行的事件處理函式。
+ /// 此函式負責更新按鈕的背景圖片、載入對應的歌手圖片,並切換相關 UI 控件的可見性。
+ ///
+ /// 觸發事件的物件(通常是按鈕本身)。
+ /// 事件參數。
private void ZhuyinSearchSingersButton_Click(object sender, EventArgs e)
{
+ // 設定按鈕背景,將「注音搜尋」設為啟動狀態,其餘按鈕恢復為正常狀態
zhuyinSearchButton.BackgroundImage = zhuyinSearchActiveBackground;
englishSearchButton.BackgroundImage = englishSearchNormalBackground;
pinyinSearchButton.BackgroundImage = pinyinSearchNormalBackground;
wordCountSearchButton.BackgroundImage = wordCountSearchNormalBackground;
handWritingSearchButton.BackgroundImage = handWritingSearchNormalBackground;
-
+ // 載入設定檔,取得圖片路徑資訊
var configData = LoadConfigData();
+
+ // 取得「注音歌手圖片」的完整路徑
string imagePath = Path.Combine(Application.StartupPath, configData["ImagePaths"]["ZhuYinSingers"]);
+ // 在 PictureBox 中顯示對應的「注音歌手」圖片
ShowImageOnPictureBoxZhuYinSingers(Path.Combine(Application.StartupPath, imagePath));
+
+ // 設定不同搜尋模式的 UI 控件可見性
+ SetEnglishSingersAndButtonsVisibility(false); // 隱藏英文字母搜尋相關控件
+ SetPinYinSingersAndButtonsVisibility(false); // 隱藏拼音搜尋相關控件
+ SetHandWritingForSingersAndButtonsVisibility(false); // 隱藏手寫搜尋相關控件
+ SetZhuYinSingersAndButtonsVisibility(true); // 顯示注音搜尋相關控件
+ SetPictureBoxArtistSearchAndButtonsVisibility(false); // 隱藏其他搜尋模式的圖片框
-
-
- SetEnglishSingersAndButtonsVisibility(false);
- SetPinYinSingersAndButtonsVisibility(false);
- SetHandWritingForSingersAndButtonsVisibility(false);
- SetZhuYinSingersAndButtonsVisibility(true);
- SetPictureBoxArtistSearchAndButtonsVisibility(false);
+ // 顯示「注音歌手搜尋」的圖片框
pictureBoxZhuYinSingers.Visible = true;
}
+
+ ///
+ /// 從 config.ini 設定檔中載入注音符號(Phonetic Symbols)。
+ /// 讀取 ini 檔的 [PhoneticSymbols] 區塊,並將「Symbols」欄位的值解析為陣列。
+ ///
private void LoadPhoneticSymbolsFromConfig()
{
+ // 建立 INI 檔案解析器
var parser = new FileIniDataParser();
+
+ // 設定檔路徑
string iniFilePath = "config.ini";
-
IniData data;
+
+ // 以 UTF-8 編碼開啟並讀取 INI 檔案
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
{
+ // 解析 INI 檔內容
data = parser.ReadData(reader);
}
+ // 取得 [PhoneticSymbols] 區塊中的 "Symbols" 欄位內容
string symbols = data["PhoneticSymbols"]["Symbols"];
+
+ // 將符號字串以逗號分隔,轉換為字串陣列
phoneticSymbols = symbols.Split(',');
}
+
+ ///
+ /// 從設定檔 (config.ini) 載入 INI 設定數據。
+ ///
+ /// 回傳解析後的 INI 設定數據 (IniData)。
private IniData LoadConfigData()
{
var parser = new FileIniDataParser();
string iniFilePath = "config.ini";
+ // 使用 UTF-8 讀取 INI 檔案並解析內容
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
{
return parser.ReadData(reader);
}
}
+ ///
+ /// 從 INI 設定數據中讀取注音符號 (Phonetic Symbols)。
+ ///
+ /// 已解析的 INI 設定數據。
+ /// 回傳包含注音符號的字串陣列。
private string[] LoadPhoneticSymbols(IniData data)
{
+ // 從 INI 檔案的 [PhoneticSymbols] 區塊取得 Symbols 欄位值
string symbols = data["PhoneticSymbols"]["Symbols"];
+
+ // 以逗號分隔字串並轉換為字串陣列
return symbols.Split(',');
}
+
+ ///
+ /// 從 INI 設定數據中載入按鈕座標資料。
+ ///
+ /// 已解析的 INI 設定數據。
+ /// 設定檔中按鈕座標所屬的區塊名稱。
+ /// 按鈕數量。
+ /// 回傳包含按鈕座標的陣列,每個元素是由 (X, Y, Width, Height) 組成的元組。
private (int X, int Y, int Width, int Height)[] LoadButtonCoordinates(IniData data, string section, int buttonCount)
{
var buttonList = new List<(int X, int Y, int Width, int Height)>();
+ // 迴圈讀取每個按鈕的座標設定
for (int i = 1; i <= buttonCount; i++)
{
+ // 取得按鈕座標的字串 (格式: X,Y,Width,Height)
var coordString = data[section][$"button{i}"];
var coords = coordString.Split(',');
- buttonList.Add((int.Parse(coords[0]), int.Parse(coords[1]), int.Parse(coords[2]), int.Parse(coords[3])));
+
+ // 將座標資料轉換為 (X, Y, Width, Height) 元組並加入清單
+ buttonList.Add((
+ int.Parse(coords[0]), // X 座標
+ int.Parse(coords[1]), // Y 座標
+ int.Parse(coords[2]), // 寬度
+ int.Parse(coords[3]) // 高度
+ ));
}
+ // 回傳所有按鈕座標的陣列
return buttonList.ToArray();
}
+ ///
+ /// 從 INI 設定數據中載入按鈕圖片檔案路徑資料 (包含正常、點擊、滑鼠移過圖片)。
+ ///
+ /// 已解析的 INI 設定數據。
+ /// 設定檔中按鈕圖片設定所屬的區塊名稱。
+ /// 按鈕數量。
+ /// 回傳一個字典,鍵是按鈕名稱,值是包含正常、點擊和滑鼠移過狀態的元組。
private Dictionary LoadButtonImages(IniData data, string section, int buttonCount)
{
var buttonImages = new Dictionary();
+ // 迴圈讀取每個按鈕的圖片設定
for (int i = 0; i < 35; i++)
{
+ // 讀取按鈕的三種圖片狀態:正常、點擊、滑鼠移過
buttonImages[$"button{i}"] = (
- data[section][$"button{i}_normal"],
- data[section][$"button{i}_mouseDown"],
- data[section][$"button{i}_mouseOver"]
+ data[section][$"button{i}_normal"], // 正常狀態圖片路徑
+ data[section][$"button{i}_mouseDown"], // 點擊狀態圖片路徑
+ data[section][$"button{i}_mouseOver"] // 滑鼠移過狀態圖片路徑
);
}
+ // 回傳包含所有按鈕圖片路徑資料的字典
return buttonImages;
}
+
+ ///
+ /// 從 INI 設定數據中載入特定按鈕的座標資料。
+ ///
+ /// 已解析的 INI 設定數據。
+ /// 設定檔中按鈕座標所屬的區塊名稱。
+ /// 指定按鈕的鍵名 (如 "button1")。
+ /// 回傳包含按鈕座標的元組 (X, Y, Width, Height)。
private (int X, int Y, int Width, int Height) LoadSpecialButtonCoordinates(IniData data, string section, string buttonKey)
{
+ // 取得按鈕座標的字串 (格式: X,Y,Width,Height)
var coords = data[section][buttonKey].Split(',');
+
+ // 解析座標字串並回傳 (X, Y, Width, Height) 元組
return (int.Parse(coords[0]), int.Parse(coords[1]), int.Parse(coords[2]), int.Parse(coords[3]));
}
+ ///
+ /// 從 INI 設定數據中載入按鈕的圖片資料 (包含正常、點擊、滑鼠移過圖片)。
+ ///
+ /// 已解析的 INI 設定數據。
+ /// 設定檔中按鈕圖片設定所屬的區塊名稱。
+ /// 回傳包含按鈕三種狀態圖片路徑的元組 (normal, mouseDown, mouseOver)。
private (string normal, string mouseDown, string mouseOver) LoadButtonImages(IniData data, string section)
{
+ // 讀取按鈕三種狀態的圖片路徑
return (
- data[section]["normal"],
- data[section]["mouseDown"],
- data[section]["mouseOver"]
+ data[section]["normal"], // 正常狀態圖片路徑
+ data[section]["mouseDown"], // 點擊狀態圖片路徑
+ data[section]["mouseOver"] // 滑鼠移過狀態圖片路徑
);
}
+
+ ///
+ /// 初始化並設置語音按鈕的相關資料,包括符號、座標與圖片等。
+ ///
private void InitializePhoneticButtons()
{
+ // 載入配置資料
var data = LoadConfigData();
+ // 載入語音符號(如拼音、注音符號等)
phoneticSymbols = LoadPhoneticSymbols(data);
+
+ // 載入按鈕座標資料
phoneticButtonCoords = LoadButtonCoordinates(data, "PhoneticButtonCoordinates", 35);
+
+ // 載入按鈕圖片資料
phoneticButtonImages = LoadButtonImages(data, "PhoneticButtonImages", 35);
+ // 初始化語音按鈕陣列,總共有 35 個按鈕
phoneticButtonsForSingers = new Button[35];
+
+ // 設置每個語音按鈕
for (int i = 0; i < 35; i++)
{
+ // 根據按鈕索引讀取其圖片資料
var buttonImages = phoneticButtonImages[$"button{i}"];
+
+ // 創建並初始化語音按鈕,設定其背景圖片
CreatePhoneticButton(i, buttonImages.normal, buttonImages.mouseDown, buttonImages.mouseOver);
}
}
+
+ ///
+ /// 創建一個語音按鈕,並為其設置圖片、座標、事件等屬性。
+ ///
+ /// 按鈕的索引,用來獲取對應的語音符號、座標和圖片資料。
+ /// 正常狀態下的圖片路徑。
+ /// 點擊狀態下的圖片路徑。
+ /// 滑鼠移過狀態下的圖片路徑。
private void CreatePhoneticButton(int index, string normalImagePath, string mouseDownImagePath, string mouseOverImagePath)
{
try
{
-
-
+ // 創建語音按鈕並設置其屬性
phoneticButtonsForSingers[index] = new Button
{
- Name = $"phoneticButton_{phoneticSymbols[index]}",
- BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)),
- BackgroundImageLayout = ImageLayout.Stretch,
- FlatStyle = FlatStyle.Flat,
- FlatAppearance = { BorderSize = 0 }
+ Name = $"phoneticButton_{phoneticSymbols[index]}", // 按鈕名稱設為語音符號名稱
+ BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)), // 設定背景圖片
+ BackgroundImageLayout = ImageLayout.Stretch, // 設定圖片拉伸樣式
+ FlatStyle = FlatStyle.Flat, // 設定為平面風格
+ FlatAppearance = { BorderSize = 0 } // 設定無邊框
};
+ // 調整按鈕大小並設置位置
ResizeAndPositionButton(phoneticButtonsForSingers[index], phoneticButtonCoords[index].X, phoneticButtonCoords[index].Y,
phoneticButtonCoords[index].Width, phoneticButtonCoords[index].Height);
+ // 從檔案中讀取正常、點擊和滑鼠懸停狀態的圖片
Image normalImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath));
Image mouseDownImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseDownImagePath));
Image mouseOverImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseOverImagePath));
+ // 設置滑鼠事件:點擊、進入、離開等,改變按鈕的背景圖片
phoneticButtonsForSingers[index].MouseDown += (s, e) => phoneticButtonsForSingers[index].BackgroundImage = mouseDownImage;
phoneticButtonsForSingers[index].MouseUp += (s, e) => phoneticButtonsForSingers[index].BackgroundImage = normalImage;
phoneticButtonsForSingers[index].MouseEnter += (s, e) => phoneticButtonsForSingers[index].BackgroundImage = mouseOverImage;
phoneticButtonsForSingers[index].MouseLeave += (s, e) => phoneticButtonsForSingers[index].BackgroundImage = normalImage;
+
+ // 設置點擊事件處理方法
phoneticButtonsForSingers[index].Click += PhoneticButton_Click;
+
+ // 設置按鈕的 Tag 屬性為對應的語音符號
phoneticButtonsForSingers[index].Tag = phoneticSymbols[index];
+ // 將按鈕添加到表單的控制項集合中
this.Controls.Add(phoneticButtonsForSingers[index]);
-
-
}
catch (Exception ex)
{
+ // 捕捉錯誤並輸出錯誤訊息
Console.WriteLine($"Error creating button at index {index}: {ex.Message}");
}
}
+
+ ///
+ /// 初始化所有與注音歌手相關的按鈕,包括語音符號按鈕、特殊按鈕及輸入框。
+ ///
private void InitializeButtonsForZhuYinSingers()
{
+ // 從配置檔案加載注音符號並初始化按鈕
LoadPhoneticSymbolsFromConfig();
+
+ // 初始化所有語音按鈕
InitializePhoneticButtons();
+
+ // 初始化注音歌手的特殊按鈕(例如音量、搜尋等)
InitializeSpecialButtonsForZhuYinSingers();
+
+ // 初始化注音歌手的輸入框
InitializeInputBoxZhuYinSingers();
}
+
+ ///
+ /// 移除圖像周圍的白色邊框,將邊框的像素透明化。
+ ///
+ /// 待處理的圖像文件路徑。
+ /// 處理後的圖像,其中白色邊框已被去除並替換為透明。
private Image RemoveWhiteBorder(string imagePath)
{
+ // 創建一個 Bitmap 物件來加載圖像
Bitmap bmp = new Bitmap(imagePath);
-
+ // 定義圖像的矩形區域,這是我們將要操作的區域
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+
+ // 鎖定圖像的位圖數據,以便進行直接修改
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
- 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);
+ 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 陣列
+ // 遍歷每個像素點,檢查是否為白色邊框
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
- 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];
+ 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 分量(透明度)
-
+ // 如果當前像素在圖像邊緣且為白色 (255, 255, 255),則將其設為透明
if ((x < 5 || x > bmp.Width - 5 || y < 5 || y > bmp.Height - 5) && r == 255 && g == 255 && b == 255)
{
+ // 將白色像素的 RGB 設置為 255, 255, 255 且 alpha 設為 0 (透明)
rgbValues[position] = 255;
rgbValues[position + 1] = 255;
rgbValues[position + 2] = 255;
- rgbValues[position + 3] = 0;
+ rgbValues[position + 3] = 0; // 透明
}
}
}
+ // 將修改後的像素數據重新複製回位圖數據
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
+
+ // 解鎖圖像數據
bmp.UnlockBits(bmpData);
+ // 返回處理後的圖像
return bmp;
}
+
+ ///
+ /// 初始化與注音歌手相關的特殊按鈕,包括修改、清除和關閉按鈕。
+ ///
private void InitializeSpecialButtonsForZhuYinSingers()
{
-
+ // 初始化修改按鈕
InitializeModifyButtonZhuYinSingers();
-
+ // 初始化清除按鈕
InitializeClearButtonZhuYinSingers();
-
+ // 初始化關閉按鈕
InitializeCloseButtonZhuYinSingers();
}
+
+ ///
+ /// 初始化「修改」按鈕,設定按鈕的坐標、圖片和點擊事件。
+ ///
private void InitializeModifyButtonZhuYinSingers()
{
+ // 加載配置數據
var data = LoadConfigData();
+
+ // 讀取按鈕坐標
modifyButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "modifyButtonZhuYinSingers");
+
+ // 加載按鈕圖片(正常、鼠標懸停、鼠標按下)
var buttonImages = LoadButtonImages(data, "ModifyButtonImagesZhuYin");
+ // 創建「修改」按鈕,並設置坐標、圖片及點擊事件
modifyButtonZhuYinSingers = CreateSpecialButton(
- "btnModifyZhuYinSingers",
- modifyButtonZhuYinCoords,
- buttonImages.normal,
- buttonImages.mouseOver,
- buttonImages.mouseDown,
- ModifyButtonZhuYinSingers_Click
+ "btnModifyZhuYinSingers", // 按鈕名稱
+ modifyButtonZhuYinCoords, // 按鈕坐標
+ buttonImages.normal, // 正常狀態圖片
+ buttonImages.mouseOver, // 鼠標懸停圖片
+ buttonImages.mouseDown, // 鼠標按下圖片
+ ModifyButtonZhuYinSingers_Click // 按鈕點擊事件
);
}
+ ///
+ /// 處理「修改」按鈕的點擊事件,該事件會刪除輸入框中的最後一個字符。
+ ///
+ /// 觸發事件的對象
+ /// 事件參數
private void ModifyButtonZhuYinSingers_Click(object sender, EventArgs e)
{
-
+ // 如果輸入框不為空,且包含輸入內容,則刪除最後一個字符
if (this.Controls.Contains(inputBoxZhuYinSingers) && inputBoxZhuYinSingers.Text.Length > 0)
{
inputBoxZhuYinSingers.Text = inputBoxZhuYinSingers.Text.Substring(0, inputBoxZhuYinSingers.Text.Length - 1);
}
}
+
+ ///
+ /// 初始化「清除」按鈕,設定按鈕的坐標、圖片和點擊事件。
+ ///
private void InitializeClearButtonZhuYinSingers()
{
+ // 加載配置數據
var data = LoadConfigData();
+
+ // 讀取按鈕坐標
clearButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "clearButtonZhuYinSingers");
+
+ // 加載按鈕圖片(正常、鼠標懸停、鼠標按下)
var buttonImages = LoadButtonImages(data, "ClearButtonImagesZhuYin");
+ // 創建「清除」按鈕,並設置坐標、圖片及點擊事件
clearButtonZhuYinSingers = CreateSpecialButton(
- "btnClearZhuYinSingers",
- clearButtonZhuYinCoords,
- buttonImages.normal,
- buttonImages.mouseOver,
- buttonImages.mouseDown,
- ClearButtonZhuYinSingers_Click
+ "btnClearZhuYinSingers", // 按鈕名稱
+ clearButtonZhuYinCoords, // 按鈕坐標
+ buttonImages.normal, // 正常狀態圖片
+ buttonImages.mouseOver, // 鼠標懸停圖片
+ buttonImages.mouseDown, // 鼠標按下圖片
+ ClearButtonZhuYinSingers_Click // 按鈕點擊事件
);
}
+ ///
+ /// 處理「清除」按鈕的點擊事件,該事件會清空輸入框中的所有文本。
+ ///
+ /// 觸發事件的對象
+ /// 事件參數
private void ClearButtonZhuYinSingers_Click(object sender, EventArgs e)
- {
+ {
+ // 如果輸入框不為空,則清空該框的文本內容
if (this.Controls.Contains(inputBoxZhuYinSingers) && inputBoxZhuYinSingers.Text.Length > 0)
{
inputBoxZhuYinSingers.Text = "";
}
}
+
+ ///
+ /// 初始化「關閉」按鈕,設定按鈕的坐標、圖片和點擊事件。
+ ///
private void InitializeCloseButtonZhuYinSingers()
{
+ // 加載配置數據
var data = LoadConfigData();
+
+ // 讀取按鈕坐標
closeButtonZhuYinCoords = LoadSpecialButtonCoordinates(data, "SpecialButtonCoordinates", "closeButtonZhuYinSingers");
+
+ // 加載按鈕圖片(正常、鼠標懸停、鼠標按下)
var buttonImages = LoadButtonImages(data, "CloseButtonImagesZhuYin");
+ // 創建「關閉」按鈕,並設置坐標、圖片及點擊事件
closeButtonZhuYinSingers = CreateSpecialButton(
- "btnCloseZhuYinSingers",
- closeButtonZhuYinCoords,
- buttonImages.normal,
- buttonImages.mouseOver,
- buttonImages.mouseDown,
- CloseButtonZhuYinSingers_Click
+ "btnCloseZhuYinSingers", // 按鈕名稱
+ closeButtonZhuYinCoords, // 按鈕坐標
+ buttonImages.normal, // 正常狀態圖片
+ buttonImages.mouseOver, // 鼠標懸停圖片
+ buttonImages.mouseDown, // 鼠標按下圖片
+ CloseButtonZhuYinSingers_Click // 按鈕點擊事件
);
}
+
+ ///
+ /// 「關閉」按鈕的點擊事件處理方法。
+ /// 隱藏 ZhuYin 歌手圖片框以及與其相關的按鈕。
+ ///
+ /// 觸發事件的對象,這裡是關閉按鈕。
+ /// 事件參數。
private void CloseButtonZhuYinSingers_Click(object sender, EventArgs e)
{
+ // 隱藏 ZhuYin 歌手圖片框
pictureBoxZhuYinSingers.Visible = false;
+
+ // 隱藏與 ZhuYin 歌手相關的所有按鈕
SetZhuYinSingersAndButtonsVisibility(false);
}
+
+ ///
+ /// 創建一個特殊的按鈕,並設定其顯示屬性、事件處理和位置。
+ ///
+ /// 按鈕的名稱。
+ /// 按鈕的坐標和大小,包含 X, Y, 寬度和高度。
+ /// 按鈕正常狀態下的背景圖片路徑。
+ /// 鼠標懸停時按鈕的背景圖片路徑。
+ /// 鼠標點擊時按鈕的背景圖片路徑。
+ /// 按鈕的點擊事件處理程序。
+ /// 創建並返回的按鈕對象。
private Button CreateSpecialButton(string name, (int X, int Y, int Width, int Height) coords, string normalImagePath, string mouseOverImagePath, string mouseDownImagePath, EventHandler clickEventHandler)
{
+ // 創建按鈕並設定基本屬性
var button = new Button
{
Name = name,
@@ -335,94 +542,131 @@ namespace DualScreenDemo
BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath))
};
+ // 設定按鈕的大小和位置
ResizeAndPositionButton(button, coords.X, coords.Y, coords.Width, coords.Height);
+ // 設定鼠標事件:進入、離開、按下、放開
button.MouseEnter += (sender, e) => button.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseOverImagePath));
button.MouseLeave += (sender, e) => button.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath));
button.MouseDown += (sender, e) => button.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, mouseDownImagePath));
button.MouseUp += (sender, e) => button.BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath));
+ // 註冊點擊事件處理
button.Click += clickEventHandler;
+
+ // 將按鈕添加到控件集合中
this.Controls.Add(button);
return button;
}
+
+ ///
+ /// 初始化 ZhuYin 歌手的輸入框,並設定其屬性與事件處理程序。
+ ///
private void InitializeInputBoxZhuYinSingers()
{
try
{
+ // 加載輸入框配置
LoadInputBoxConfig();
+ // 創建一個 RichTextBox 控件來作為輸入框
inputBoxZhuYinSingers = new RichTextBox
{
Name = "inputBoxZhuYinSingers",
- ForeColor = inputBoxForeColor,
- Font = new Font(inputBoxFontName, inputBoxFontSize, inputBoxFontStyle),
- ScrollBars = RichTextBoxScrollBars.None
+ ForeColor = inputBoxForeColor, // 設定文字顏色
+ Font = new Font(inputBoxFontName, inputBoxFontSize, inputBoxFontStyle), // 設定字體樣式
+ ScrollBars = RichTextBoxScrollBars.None // 不顯示滾動條
};
+ // 調整和定位輸入框的位置及大小
ResizeAndPositionControl(inputBoxZhuYinSingers, inputBoxZhuYinCoords.X, inputBoxZhuYinCoords.Y, inputBoxZhuYinCoords.Width, inputBoxZhuYinCoords.Height);
+ // 設定文本變更事件,當輸入框內容改變時觸發
inputBoxZhuYinSingers.TextChanged += (sender, e) =>
{
string searchText = inputBoxZhuYinSingers.Text;
+
+ // 根據輸入文本來篩選符合條件的歌曲
var relatedSongs = allSongs
.Where(song => (song.ArtistAPhonetic?.StartsWith(searchText, StringComparison.OrdinalIgnoreCase) ?? false) ||
- (song.ArtistBPhonetic?.StartsWith(searchText, StringComparison.OrdinalIgnoreCase) ?? false))
+ (song.ArtistBPhonetic?.StartsWith(searchText, StringComparison.OrdinalIgnoreCase) ?? false))
.ToList();
+ // 更新當前頁面及歌單
currentPage = 0;
currentSongList = relatedSongs;
totalPages = (int)Math.Ceiling((double)relatedSongs.Count / itemsPerPage);
+ // 重新載入歌單並顯示頁面
multiPagePanel.currentPageIndex = 0;
multiPagePanel.LoadSongs(relatedSongs);
};
+ // 將輸入框加入到窗體的控件集合中
this.Controls.Add(inputBoxZhuYinSingers);
}
catch (Exception ex)
{
+ // 如果初始化過程中出現錯誤,則在控制台輸出錯誤信息
Console.WriteLine("Error initializing inputBoxZhuYinSingers: " + ex.Message);
}
}
+
+ ///
+ /// 從配置文件 `config.ini` 中加載輸入框的設置,包括位置、大小、字體等屬性。
+ ///
private void LoadInputBoxConfig()
{
try
{
+ // 創建 INI 解析器
var parser = new FileIniDataParser();
- string iniFilePath = "config.ini";
+ string iniFilePath = "config.ini"; // 配置文件的路徑
IniData data;
+ // 打開並讀取配置文件
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
{
data = parser.ReadData(reader);
}
+ // 從配置中加載輸入框的坐標和大小
inputBoxZhuYinCoords = (
- int.Parse(data["InputBoxZhuYinSingers"]["X"]),
- int.Parse(data["InputBoxZhuYinSingers"]["Y"]),
- int.Parse(data["InputBoxZhuYinSingers"]["Width"]),
- int.Parse(data["InputBoxZhuYinSingers"]["Height"])
+ int.Parse(data["InputBoxZhuYinSingers"]["X"]), // 輸入框的 X 坐標
+ int.Parse(data["InputBoxZhuYinSingers"]["Y"]), // 輸入框的 Y 坐標
+ int.Parse(data["InputBoxZhuYinSingers"]["Width"]), // 輸入框的寬度
+ int.Parse(data["InputBoxZhuYinSingers"]["Height"]) // 輸入框的高度
);
- inputBoxFontName = data["InputBoxZhuYinSingers"]["FontName"];
- inputBoxFontSize = float.Parse(data["InputBoxZhuYinSingers"]["FontSize"]);
- inputBoxFontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), data["InputBoxZhuYinSingers"]["FontStyle"]);
- inputBoxForeColor = Color.FromName(data["InputBoxZhuYinSingers"]["ForeColor"]);
+ // 從配置中加載字體屬性
+ inputBoxFontName = data["InputBoxZhuYinSingers"]["FontName"]; // 字體名稱
+ inputBoxFontSize = float.Parse(data["InputBoxZhuYinSingers"]["FontSize"]); // 字體大小
+ inputBoxFontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), data["InputBoxZhuYinSingers"]["FontStyle"]); // 字體樣式
+ inputBoxForeColor = Color.FromName(data["InputBoxZhuYinSingers"]["ForeColor"]); // 字體顏色
-
}
catch (Exception ex)
{
+ // 若發生錯誤,顯示錯誤信息
Console.WriteLine("Error loading inputBox configuration: " + ex.Message);
}
}
+
+ ///
+ /// 存儲 `pictureBoxZhuYinSingers` 控制項的坐標和大小設置。
+ ///
+ ///
+ /// 這個元組包含了 `X`、`Y` 坐標以及 `Width`、`Height` 大小,用於配置 `pictureBoxZhuYinSingers` 的位置和大小。
+ ///
private (int X, int Y, int Width, int Height) pictureBoxZhuYinSingerCoords;
+ ///
+ /// 從配置檔案中讀取 `PictureBoxZhuYinSingers` 控制項的坐標和大小設置。
+ ///
private void LoadPictureBoxZhuYinSingerCoordsFromConfig()
{
var parser = new FileIniDataParser();
@@ -437,34 +681,48 @@ namespace DualScreenDemo
);
}
+
+ ///
+ /// 顯示圖片並根據配置文件設置顯示區域的大小和位置。
+ ///
+ /// 圖片的路徑。
private void ShowImageOnPictureBoxZhuYinSingers(string imagePath)
{
-
+ // 讀取配置文件中的顯示區域設置
LoadPictureBoxZhuYinSingerCoordsFromConfig();
-
+ // 加載原始圖片
Bitmap originalImage = new Bitmap(imagePath);
-
+ // 創建顯示區域,根據配置文件中的坐標和大小設置
Rectangle displayArea = new Rectangle(pictureBoxZhuYinSingerCoords.X, pictureBoxZhuYinSingerCoords.Y, pictureBoxZhuYinSingerCoords.Width, pictureBoxZhuYinSingerCoords.Height);
-
+ // 設置圖片到 PictureBox
pictureBoxZhuYinSingers.Image = originalImage;
-
+ // 調整 PictureBox 大小和位置
ResizeAndPositionPictureBox(pictureBoxZhuYinSingers, displayArea.X, displayArea.Y, displayArea.Width, displayArea.Height);
+ // 顯示圖片
pictureBoxZhuYinSingers.Visible = true;
}
+
+ ///
+ /// 設置注音歌手相關控制項(包括圖片框、按鈕和輸入框)的顯示或隱藏狀態。
+ ///
+ /// 指定控件是否可見。True 為顯示,False 為隱藏。
private void SetZhuYinSingersAndButtonsVisibility(bool isVisible)
{
+ // 定義一個動作來處理控制項的顯示或隱藏
System.Action action = () =>
{
try
{
+ // 暫停控制項佈局的重新排版,提高效率
SuspendLayout();
+ // 檢查並設置圖片框的可見性
if (pictureBoxZhuYinSingers == null)
{
Console.WriteLine("pictureBoxZhuYinSingers is null");
@@ -472,9 +730,10 @@ namespace DualScreenDemo
else
{
pictureBoxZhuYinSingers.Visible = isVisible;
- if (isVisible) pictureBoxZhuYinSingers.BringToFront();
+ if (isVisible) pictureBoxZhuYinSingers.BringToFront(); // 如果顯示,將其置於最前
}
+ // 檢查並設置拼音按鈕的可見性
if (phoneticButtonsForSingers == null)
{
Console.WriteLine("phoneticButtonsForSingers is null");
@@ -490,11 +749,12 @@ namespace DualScreenDemo
else
{
button.Visible = isVisible;
- if (isVisible) button.BringToFront();
+ if (isVisible) button.BringToFront(); // 如果顯示,將其置於最前
}
}
}
+ // 檢查並設置修改按鈕的可見性
if (modifyButtonZhuYinSingers == null)
{
Console.WriteLine("modifyButtonZhuYinSingers is null");
@@ -502,9 +762,10 @@ namespace DualScreenDemo
else
{
modifyButtonZhuYinSingers.Visible = isVisible;
- if (isVisible) modifyButtonZhuYinSingers.BringToFront();
+ if (isVisible) modifyButtonZhuYinSingers.BringToFront(); // 如果顯示,將其置於最前
}
+ // 檢查並設置清除按鈕的可見性
if (clearButtonZhuYinSingers == null)
{
Console.WriteLine("clearButtonZhuYinSingers is null");
@@ -512,9 +773,10 @@ namespace DualScreenDemo
else
{
clearButtonZhuYinSingers.Visible = isVisible;
- if (isVisible) clearButtonZhuYinSingers.BringToFront();
+ if (isVisible) clearButtonZhuYinSingers.BringToFront(); // 如果顯示,將其置於最前
}
+ // 檢查並設置關閉按鈕的可見性
if (closeButtonZhuYinSingers == null)
{
Console.WriteLine("closeButtonZhuYinSingers is null");
@@ -522,9 +784,10 @@ namespace DualScreenDemo
else
{
closeButtonZhuYinSingers.Visible = isVisible;
- if (isVisible) closeButtonZhuYinSingers.BringToFront();
+ if (isVisible) closeButtonZhuYinSingers.BringToFront(); // 如果顯示,將其置於最前
}
+ // 檢查並設置輸入框的可見性
if (inputBoxZhuYinSingers == null)
{
Console.WriteLine("inputBoxZhuYinSingers is null");
@@ -532,19 +795,20 @@ namespace DualScreenDemo
else
{
inputBoxZhuYinSingers.Visible = isVisible;
- if (isVisible) inputBoxZhuYinSingers.BringToFront();
+ if (isVisible) inputBoxZhuYinSingers.BringToFront(); // 如果顯示,將其置於最前
}
+ // 恢復控制項的佈局重新排版
ResumeLayout();
PerformLayout();
-
+ // 刷新所有控制項的顯示
pictureBoxZhuYinSingers?.Refresh();
if (phoneticButtonsForSingers != null)
{
foreach (var button in phoneticButtonsForSingers)
{
- button?.Refresh();
+ button?.Refresh(); // 刷新每個按鈕
}
}
modifyButtonZhuYinSingers?.Refresh();
@@ -558,14 +822,16 @@ namespace DualScreenDemo
}
};
+ // 檢查是否需要在主執行緒外執行
if (this.InvokeRequired)
{
- this.Invoke(action);
+ this.Invoke(action); // 如果需要,透過主執行緒執行
}
else
{
- action();
+ action(); // 否則直接執行
}
}
+
}
}
\ No newline at end of file