superstar_v2/PrimaryFormParts/SongSearch/PrimaryForm.SongSearch.WordCountSearch.cs
2025-04-11 15:44:47 +08:00

859 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.IO;
using System.Drawing.Imaging;
using IniParser;
using IniParser.Model;
using System.Text;
namespace DualScreenDemo
{
public partial class PrimaryForm
{
private PictureBox pictureBoxWordCountSongs;
private Button[] numberWordCountButtonsForSongs;
private Button modifyButtonWordCountSongs;
private Button clearButtonWordCountSongs;
private Button closeButtonWordCountSongs;
//private string[] numberWordCountSymbols;
//private (int X, int Y, int Width, int Height)[] numberWordCountButtonCoords;
//private Dictionary<string, (string normal, string mouseDown, string mouseOver)> numberWordCountButtonImages;
//private (int X, int Y, int Width, int Height) modifyButtonWordCountCoords;
//private (int X, int Y, int Width, int Height) clearButtonWordCountCoords;
//private (int X, int Y, int Width, int Height) closeButtonWordCountCoords;
private RichTextBox inputBoxWordCountSongs;
//private (int X, int Y, int Width, int Height) inputBoxWordCountCoords;
//private string inputBoxWordCountFontName;
//private float inputBoxWordCountFontSize;
//private FontStyle inputBoxWordCountFontStyle;
//private Color inputBoxWordCountForeColor;
/// <summary>
/// <para> 點擊「注音歌手搜尋」按鈕時執行的事件處理函式。</para>
/// <para>此函式負責更新按鈕的背景圖片、載入對應的歌手圖片,並切換相關 UI 控件的可見性。</para>
/// </summary>
/// <param name="sender">觸發事件的物件(通常是按鈕本身)。</param>
/// <param name="e">事件參數。</param>
private void WordCountSearchSongsButton_Click(object sender, EventArgs e)
{
// 設定按鈕背景,將「注音搜尋」設為啟動狀態,其餘按鈕恢復為正常狀態
zhuyinSearchSongButton.BackgroundImage = zhuyinSearchSongNormalBackground;
englishSearchSongButton.BackgroundImage = englishSearchSongNormalBackground;
pinyinSearchSongButton.BackgroundImage = pinyinSearchSongNormalBackground;
wordCountSearchSongButton.BackgroundImage = wordCountSearchSongActiveBackground;
handWritingSearchSongButton.BackgroundImage = handWritingSearchSongNormalBackground;
numberSearchSongButton.BackgroundImage = numberSearchSongNormalBackground;
// 載入設定檔,取得圖片路徑資訊
var configData = LoadConfigDataforWordCountSongs();
// 取得「注音歌手圖片」的完整路徑
string imagePath = Path.Combine(Application.StartupPath, configData["ImagePaths"]["WordCountSongs"]);
// 在 PictureBox 中顯示對應的「注音歌手」圖片
ShowImageOnPictureBoxWordCountSongs(Path.Combine(Application.StartupPath, imagePath));
// 鍵盤UI介面顯示設定
SetWordCountSongsAndButtonsVisibility(true);
SetEnglishSongsAndButtonsVisibility(false);
SetPinYinSongsAndButtonsVisibility(false);
SetHandWritingForSongsAndButtonsVisibility(false);
SetSongIDSearchAndButtonsVisibility(false);
SetZhuYinSongsAndButtonsVisibility(false);
SetWordCountSongsAndButtonsVisibility(true); // 顯示字數搜尋相關控件
// 顯示「注音歌手搜尋」的圖片框
ResetinputBox();
pictureBoxWordCountSongs.Visible = true;
}
/// <summary>
/// <para>從 config.ini 設定檔中載入注音符號NumberWordCount Symbols。</para>
/// <para>讀取 ini 檔的 [NumberWordCountSymbols] 區塊並將「Symbols」欄位的值解析為陣列。</para>
/// </summary>
/*private void LoadNumberWordCountSymbolsFromConfig()
{
// 建立 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);
}
// 取得 [NumberWordCountSymbols] 區塊中的 "Symbols" 欄位內容
string symbols = data["NumberWordCountSymbols"]["Symbols"];
// 將符號字串以逗號分隔,轉換為字串陣列
numberWordCountSymbols = symbols.Split(',');
}*/
/// <summary>
/// 從設定檔 (config.ini) 載入 INI 設定數據。
/// </summary>
/// <returns>回傳解析後的 INI 設定數據 (IniData)。</returns>
private IniData LoadConfigDataforWordCountSongs()
{
var parser = new FileIniDataParser();
string iniFilePath = "config.ini";
// 使用 UTF-8 讀取 INI 檔案並解析內容
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
{
return parser.ReadData(reader);
}
}
/// <summary>
/// 從 INI 設定數據中讀取注音符號 (NumberWordCount Symbols)。
/// </summary>
/// <param name="data">已解析的 INI 設定數據。</param>
/// <returns>回傳包含注音符號的字串陣列。</returns>
/*private string[] LoadNumberWordCountSymbols(IniData data)
{
// 從 INI 檔案的 [NumberWordCountSymbols] 區塊取得 Symbols 欄位值
string symbols = data["NumberWordCountSymbols"]["Symbols"];
// 以逗號分隔字串並轉換為字串陣列
return symbols.Split(',');
}*/
/// <summary>
/// 從 INI 設定數據中載入按鈕座標資料。
/// </summary>
/// <param name="data">已解析的 INI 設定數據。</param>
/// <param name="section">設定檔中按鈕座標所屬的區塊名稱。</param>
/// <param name="buttonCount">按鈕數量。</param>
/// <returns>回傳包含按鈕座標的陣列,每個元素是由 (X, Y, Width, Height) 組成的元組。</returns>
private (int X, int Y, int Width, int Height)[] LoadButtonCoordinatesForWordCountSongs(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(',');
// 將座標資料轉換為 (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();
}
/// <summary>
/// 從 INI 設定數據中載入按鈕圖片檔案路徑資料 (包含正常、點擊、滑鼠移過圖片)。
/// </summary>
/// <param name="data">已解析的 INI 設定數據。</param>
/// <param name="section">設定檔中按鈕圖片設定所屬的區塊名稱。</param>
/// <param name="buttonCount">按鈕數量。</param>
/// <returns>回傳一個字典,鍵是按鈕名稱,值是包含正常、點擊和滑鼠移過狀態的元組。</returns>
private Dictionary<string, (string normal, string mouseDown, string mouseOver)> LoadButtonImagesForWordCountSongs(IniData data, string section, int buttonCount)
{
var buttonImages = new Dictionary<string, (string normal, string mouseDown, string mouseOver)>();
// 迴圈讀取每個按鈕的圖片設定
for (int i = 0; i < 10; i++)
{
// 讀取按鈕的三種圖片狀態:正常、點擊、滑鼠移過
buttonImages[$"button{i}"] = (
data[section][$"button{i}_normal"], // 正常狀態圖片路徑
data[section][$"button{i}_mouseDown"], // 點擊狀態圖片路徑
data[section][$"button{i}_mouseOver"] // 滑鼠移過狀態圖片路徑
);
}
// 回傳包含所有按鈕圖片路徑資料的字典
return buttonImages;
}
/// <summary>
/// 從 INI 設定數據中載入特定按鈕的座標資料。
/// </summary>
/// <param name="data">已解析的 INI 設定數據。</param>
/// <param name="section">設定檔中按鈕座標所屬的區塊名稱。</param>
/// <param name="buttonKey">指定按鈕的鍵名 (如 "button1")。</param>
/// <returns>回傳包含按鈕座標的元組 (X, Y, Width, Height)。</returns>
private (int X, int Y, int Width, int Height) LoadSpecialButtonCoordinatesForWordCountSongs(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]));
}
/// <summary>
/// 從 INI 設定數據中載入按鈕的圖片資料 (包含正常、點擊、滑鼠移過圖片)。
/// </summary>
/// <param name="data">已解析的 INI 設定數據。</param>
/// <param name="section">設定檔中按鈕圖片設定所屬的區塊名稱。</param>
/// <returns>回傳包含按鈕三種狀態圖片路徑的元組 (normal, mouseDown, mouseOver)。</returns>
private (string normal, string mouseDown, string mouseOver) LoadButtonImagesForWordCountSongs(IniData data, string section)
{
// 讀取按鈕三種狀態的圖片路徑
return (
data[section]["normal"], // 正常狀態圖片路徑
data[section]["mouseDown"], // 點擊狀態圖片路徑
data[section]["mouseOver"] // 滑鼠移過狀態圖片路徑
);
}
/// <summary>
/// 初始化並設置語音按鈕的相關資料,包括符號、座標與圖片等。
/// </summary>
private void InitializeNumberWordCountSongsButtons()
{
// 載入配置資料
var data = LoadConfigDataforWordCountSongs();
// 載入語音符號(如拼音、注音符號等)
numberWordCountSymbols = LoadNumberWordCountSymbols(data);
// 載入按鈕座標資料
numberWordCountButtonCoords = LoadButtonCoordinatesForWordCountSongs(data, "NumberWordCountButtonCoordinates", 10);
// 載入按鈕圖片資料
numberWordCountButtonImages = LoadButtonImagesForWordCountSongs(data, "NumberWordCountButtonImages", 10);
// 初始化語音按鈕陣列,總共有 10 個按鈕
numberWordCountButtonsForSongs = new Button[10];
// 設置每個語音按鈕
for (int i = 0; i < 10; i++)
{
// 根據按鈕索引讀取其圖片資料
var buttonImages = numberWordCountButtonImages[$"button{i}"];
// 創建並初始化語音按鈕,設定其背景圖片
CreateNumberWordCountSongsButton(i, buttonImages.normal, buttonImages.mouseDown, buttonImages.mouseOver);
}
}
/// <summary>
/// 創建一個語音按鈕,並為其設置圖片、座標、事件等屬性。
/// </summary>
/// <param name="index">按鈕的索引,用來獲取對應的語音符號、座標和圖片資料。</param>
/// <param name="normalImagePath">正常狀態下的圖片路徑。</param>
/// <param name="mouseDownImagePath">點擊狀態下的圖片路徑。</param>
/// <param name="mouseOverImagePath">滑鼠移過狀態下的圖片路徑。</param>
private void CreateNumberWordCountSongsButton(int index, string normalImagePath, string mouseDownImagePath, string mouseOverImagePath)
{
try
{
// 創建語音按鈕並設置其屬性
numberWordCountButtonsForSongs[index] = new Button
{
Name = $"numberWordCountButton_{numberWordCountSymbols[index]}", // 按鈕名稱設為語音符號名稱
BackgroundImage = Image.FromFile(Path.Combine(Application.StartupPath, normalImagePath)), // 設定背景圖片
BackgroundImageLayout = ImageLayout.Stretch, // 設定圖片拉伸樣式
FlatStyle = FlatStyle.Flat, // 設定為平面風格
FlatAppearance = { BorderSize = 0 } // 設定無邊框
};
// 調整按鈕大小並設置位置
ResizeAndPositionButton(numberWordCountButtonsForSongs[index], numberWordCountButtonCoords[index].X, numberWordCountButtonCoords[index].Y,
numberWordCountButtonCoords[index].Width, numberWordCountButtonCoords[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));
// 設置滑鼠事件:點擊、進入、離開等,改變按鈕的背景圖片
numberWordCountButtonsForSongs[index].MouseDown += (s, e) => numberWordCountButtonsForSongs[index].BackgroundImage = mouseDownImage;
numberWordCountButtonsForSongs[index].MouseUp += (s, e) => numberWordCountButtonsForSongs[index].BackgroundImage = normalImage;
numberWordCountButtonsForSongs[index].MouseEnter += (s, e) => numberWordCountButtonsForSongs[index].BackgroundImage = mouseOverImage;
numberWordCountButtonsForSongs[index].MouseLeave += (s, e) => numberWordCountButtonsForSongs[index].BackgroundImage = normalImage;
// 設置點擊事件處理方法
numberWordCountButtonsForSongs[index].Click += NumberWordCountSongsButton_Click;
// 設置按鈕的 Tag 屬性為對應的語音符號
numberWordCountButtonsForSongs[index].Tag = numberWordCountSymbols[index];
// 將按鈕添加到表單的控制項集合中
this.Controls.Add(numberWordCountButtonsForSongs[index]);
}
catch (Exception ex)
{
// 捕捉錯誤並輸出錯誤訊息
Console.WriteLine($"Error creating button at index {index}: {ex.Message}");
}
}
/// <summary>
/// 初始化所有與注音歌手相關的按鈕,包括語音符號按鈕、特殊按鈕及輸入框。
/// </summary>
private void InitializeButtonsForWordCountSongs()
{
// 從配置檔案加載注音符號並初始化按鈕
LoadNumberWordCountSymbolsFromConfig();
// 初始化所有語音按鈕
InitializeNumberWordCountSongsButtons();
// 初始化注音歌手的特殊按鈕(例如音量、搜尋等)
InitializeSpecialButtonsForWordCountSongs();
// 初始化注音歌手的輸入框
InitializeInputBoxWordCountSongs();
}
/// <summary>
/// 移除圖像周圍的白色邊框,將邊框的像素透明化。
/// </summary>
/// <param name="imagePath">待處理的圖像文件路徑。</param>
/// <returns>處理後的圖像,其中白色邊框已被去除並替換為透明。</returns>
private Image RemoveWhiteBorderForWordCountSongs(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); // 從圖像數據中複製像素數據到 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]; // 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; // 透明
}
}
}
// 將修改後的像素數據重新複製回位圖數據
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// 解鎖圖像數據
bmp.UnlockBits(bmpData);
// 返回處理後的圖像
return bmp;
}
/// <summary>
/// 初始化與注音歌手相關的特殊按鈕,包括修改、清除和關閉按鈕。
/// </summary>
private void InitializeSpecialButtonsForWordCountSongs()
{
// 初始化修改按鈕
InitializeModifyButtonWordCountSongs();
// 初始化清除按鈕
InitializeClearButtonWordCountSongs();
// 初始化關閉按鈕
InitializeCloseButtonWordCountSongs();
}
/// <summary>
/// 初始化「修改」按鈕,設定按鈕的坐標、圖片和點擊事件。
/// </summary>
private void InitializeModifyButtonWordCountSongs()
{
// 加載配置數據
var data = LoadConfigDataforWordCountSongs();
// 讀取按鈕坐標
modifyButtonWordCountCoords = LoadSpecialButtonCoordinatesForWordCountSongs(data, "SpecialButtonCoordinates", "modifyButtonWordCountSongs");
// 加載按鈕圖片(正常、鼠標懸停、鼠標按下)
var buttonImages = LoadButtonImagesForWordCountSongs(data, "ModifyButtonImagesWordCount");
// 創建「修改」按鈕,並設置坐標、圖片及點擊事件
modifyButtonWordCountSongs = CreateSpecialButtonForWordCountSongs(
"btnModifyWordCountSongs", // 按鈕名稱
modifyButtonWordCountCoords, // 按鈕坐標
buttonImages.normal, // 正常狀態圖片
buttonImages.mouseOver, // 鼠標懸停圖片
buttonImages.mouseDown, // 鼠標按下圖片
ModifyButtonWordCountSongs_Click // 按鈕點擊事件
);
}
/// <summary>
/// 處理「修改」按鈕的點擊事件,該事件會刪除輸入框中的最後一個字符。
/// </summary>
/// <param name="sender">觸發事件的對象</param>
/// <param name="e">事件參數</param>
private void ModifyButtonWordCountSongs_Click(object sender, EventArgs e)
{
// 如果輸入框不為空,且包含輸入內容,則刪除最後一個字符
if (this.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0)
{
inputBoxWordCountSongs.Text = inputBoxWordCountSongs.Text.Substring(0, inputBoxWordCountSongs.Text.Length - 1);
}
}
/// <summary>
/// 初始化「清除」按鈕,設定按鈕的坐標、圖片和點擊事件。
/// </summary>
private void InitializeClearButtonWordCountSongs()
{
// 加載配置數據
var data = LoadConfigDataforWordCountSongs();
// 讀取按鈕坐標
clearButtonWordCountCoords = LoadSpecialButtonCoordinatesForWordCountSongs(data, "SpecialButtonCoordinates", "clearButtonWordCountSongs");
// 加載按鈕圖片(正常、鼠標懸停、鼠標按下)
var buttonImages = LoadButtonImagesForWordCountSongs(data, "ClearButtonImagesWordCount");
// 創建「清除」按鈕,並設置坐標、圖片及點擊事件
clearButtonWordCountSongs = CreateSpecialButtonForWordCountSongs(
"btnClearWordCountSongs", // 按鈕名稱
clearButtonWordCountCoords, // 按鈕坐標
buttonImages.normal, // 正常狀態圖片
buttonImages.mouseOver, // 鼠標懸停圖片
buttonImages.mouseDown, // 鼠標按下圖片
ClearButtonWordCountSongs_Click // 按鈕點擊事件
);
}
/// <summary>
/// 處理「清除」按鈕的點擊事件,該事件會清空輸入框中的所有文本。
/// </summary>
/// <param name="sender">觸發事件的對象</param>
/// <param name="e">事件參數</param>
private void ClearButtonWordCountSongs_Click(object sender, EventArgs e)
{
// 如果輸入框不為空,則清空該框的文本內容
if (this.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0)
{
inputBoxWordCountSongs.Text = "";
}
}
/// <summary>
/// 初始化「關閉」按鈕,設定按鈕的坐標、圖片和點擊事件。
/// </summary>
private void InitializeCloseButtonWordCountSongs()
{
// 加載配置數據
var data = LoadConfigDataforWordCountSongs();
// 讀取按鈕坐標
closeButtonWordCountCoords = LoadSpecialButtonCoordinatesForWordCountSongs(data, "SpecialButtonCoordinates", "closeButtonWordCountSongs");
// 加載按鈕圖片(正常、鼠標懸停、鼠標按下)
var buttonImages = LoadButtonImagesForWordCountSongs(data, "CloseButtonImagesWordCount");
// 創建「關閉」按鈕,並設置坐標、圖片及點擊事件
closeButtonWordCountSongs = CreateSpecialButtonForWordCountSongs(
"btnCloseWordCountSongs", // 按鈕名稱
closeButtonWordCountCoords, // 按鈕坐標
buttonImages.normal, // 正常狀態圖片
buttonImages.mouseOver, // 鼠標懸停圖片
buttonImages.mouseDown, // 鼠標按下圖片
CloseButtonWordCountSongs_Click // 按鈕點擊事件
);
}
/// <summary>
/// 「關閉」按鈕的點擊事件處理方法。
/// 隱藏 WordCount 歌手圖片框以及與其相關的按鈕。
/// </summary>
/// <param name="sender">觸發事件的對象,這裡是關閉按鈕。</param>
/// <param name="e">事件參數。</param>
private void CloseButtonWordCountSongs_Click(object sender, EventArgs e)
{
// 隱藏 WordCount 歌手圖片框
pictureBoxWordCountSongs.Visible = false;
// 關閉背景圖式
wordCountSearchSongButton.BackgroundImage = wordCountSearchSongNormalBackground;
// 隱藏與 WordCount 歌手相關的所有按鈕
SetWordCountSongsAndButtonsVisibility(false);
// 錨點 歌曲查詢改版
FindWordCountSongs();
}
/// <summary>
/// 查詢歌曲(字數查詢),連接資料庫並執行 SQL 查詢。
/// </summary>
private void FindWordCountSongs(){
string searchText = inputBoxWordCountSongs.Text;
// 在這裡添加搜尋歌曲的邏輯
// 例如:根據輸入框的內容搜尋歌曲
string query;
if (int.TryParse(searchText, out int length))
{
query = $"SELECT * FROM SongLibrary WHERE CHAR_LENGTH(歌曲名稱) = {length} ";
}
else
{
// 處理輸入錯誤,例如顯示提示訊息
//MessageBox.Show("請輸入正確的數字!");
query = string.Empty; // 清空查詢
return;
}
var searchResults = SearchSongs_Mysql(query);
// 重置分頁
currentPage = 0;
currentSongList = searchResults;
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
// 更新多頁面面板的內容
multiPagePanel.currentPageIndex = 0;
multiPagePanel.LoadSongs(currentSongList);
}
/// <summary>
/// 創建一個特殊的按鈕,並設定其顯示屬性、事件處理和位置。
/// </summary>
/// <param name="name">按鈕的名稱。</param>
/// <param name="coords">按鈕的坐標和大小,包含 X, Y, 寬度和高度。</param>
/// <param name="normalImagePath">按鈕正常狀態下的背景圖片路徑。</param>
/// <param name="mouseOverImagePath">鼠標懸停時按鈕的背景圖片路徑。</param>
/// <param name="mouseDownImagePath">鼠標點擊時按鈕的背景圖片路徑。</param>
/// <param name="clickEventHandler">按鈕的點擊事件處理程序。</param>
/// <returns>創建並返回的按鈕對象。</returns>
private Button CreateSpecialButtonForWordCountSongs(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,
FlatStyle = FlatStyle.Flat,
FlatAppearance = { BorderSize = 0, MouseDownBackColor = Color.Transparent, MouseOverBackColor = Color.Transparent },
BackgroundImageLayout = ImageLayout.Stretch,
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;
}
/// <summary>
/// 初始化 WordCount 歌手的輸入框,並設定其屬性與事件處理程序。
/// </summary>
private void InitializeInputBoxWordCountSongs()
{
try
{
// 加載輸入框配置
LoadInputBoxConfigForWordCountSongs();
// 創建一個 RichTextBox 控件來作為輸入框
inputBoxWordCountSongs = new RichTextBox
{
Name = "inputBoxWordCountSongs",
ForeColor = inputBoxWordCountForeColor, // 設定文字顏色
Font = new Font(inputBoxWordCountFontName, inputBoxWordCountFontSize, inputBoxWordCountFontStyle), // 設定字體樣式
ScrollBars = RichTextBoxScrollBars.None // 不顯示滾動條
};
// 調整和定位輸入框的位置及大小
ResizeAndPositionControl(inputBoxWordCountSongs, inputBoxWordCountCoords.X, inputBoxWordCountCoords.Y, inputBoxWordCountCoords.Width, inputBoxWordCountCoords.Height);
// 將輸入框加入到窗體的控件集合中
this.Controls.Add(inputBoxWordCountSongs);
}
catch (Exception ex)
{
// 如果初始化過程中出現錯誤,則在控制台輸出錯誤信息
Console.WriteLine("Error initializing inputBoxWordCountSongs: " + ex.Message);
}
}
/// <summary>
/// 從配置文件 `config.ini` 中加載輸入框的設置,包括位置、大小、字體等屬性。
/// </summary>
private void LoadInputBoxConfigForWordCountSongs()
{
try
{
// 創建 INI 解析器
var parser = new FileIniDataParser();
string iniFilePath = "config.ini"; // 配置文件的路徑
IniData data;
// 打開並讀取配置文件
using (var reader = new StreamReader(iniFilePath, Encoding.UTF8))
{
data = parser.ReadData(reader);
}
// 從配置中加載輸入框的坐標和大小
inputBoxWordCountCoords = (
int.Parse(data["InputBoxWordCountSongs"]["X"]), // 輸入框的 X 坐標
int.Parse(data["InputBoxWordCountSongs"]["Y"]), // 輸入框的 Y 坐標
int.Parse(data["InputBoxWordCountSongs"]["Width"]), // 輸入框的寬度
int.Parse(data["InputBoxWordCountSongs"]["Height"]) // 輸入框的高度
);
// 從配置中加載字體屬性
inputBoxWordCountFontName = data["InputBoxWordCountSongs"]["FontName"]; // 字體名稱
inputBoxWordCountFontSize = float.Parse(data["InputBoxWordCountSongs"]["FontSize"]); // 字體大小
inputBoxWordCountFontStyle = (FontStyle)Enum.Parse(typeof(FontStyle), data["InputBoxWordCountSongs"]["FontStyle"]); // 字體樣式
inputBoxWordCountForeColor = Color.FromName(data["InputBoxWordCountSongs"]["ForeColor"]); // 字體顏色
}
catch (Exception ex)
{
// 若發生錯誤,顯示錯誤信息
Console.WriteLine("Error loading inputBox configuration: " + ex.Message);
}
}
/// <summary>
/// 存儲 `pictureBoxWordCountSongs` 控制項的坐標和大小設置。
/// </summary>
/// <remarks>
/// 這個元組包含了 `X`、`Y` 坐標以及 `Width`、`Height` 大小,用於配置 `pictureBoxWordCountSongs` 的位置和大小。
/// </remarks>
private (int X, int Y, int Width, int Height) pictureBoxWordCountSongCoords;
/// <summary>
/// 從配置檔案中讀取 `PictureBoxWordCountSongs` 控制項的坐標和大小設置。
/// </summary>
private void LoadPictureBoxWordCountSongCoordsFromConfig()
{
var parser = new FileIniDataParser();
IniData data = parser.ReadFile("config.ini");
var coords = data["PictureBoxWordCountSongs"];
pictureBoxWordCountSongCoords = (
int.Parse(coords["X"]),
int.Parse(coords["Y"]),
int.Parse(coords["Width"]),
int.Parse(coords["Height"])
);
}
/// <summary>
/// 顯示圖片並根據配置文件設置顯示區域的大小和位置。
/// </summary>
/// <param name="imagePath">圖片的路徑。</param>
private void ShowImageOnPictureBoxWordCountSongs(string imagePath)
{
// 讀取配置文件中的顯示區域設置
LoadPictureBoxWordCountSongCoordsFromConfig();
// 加載原始圖片
Bitmap originalImage = new Bitmap(imagePath);
// 創建顯示區域,根據配置文件中的坐標和大小設置
Rectangle displayArea = new Rectangle(pictureBoxWordCountSongCoords.X, pictureBoxWordCountSongCoords.Y, pictureBoxWordCountSongCoords.Width, pictureBoxWordCountSongCoords.Height);
// 設置圖片到 PictureBox
pictureBoxWordCountSongs.Image = originalImage;
// 調整 PictureBox 大小和位置
ResizeAndPositionPictureBox(pictureBoxWordCountSongs, displayArea.X, displayArea.Y, displayArea.Width, displayArea.Height);
// 顯示圖片
pictureBoxWordCountSongs.Visible = true;
}
/// <summary>
/// 設置注音歌手相關控制項(包括圖片框、按鈕和輸入框)的顯示或隱藏狀態。
/// </summary>
/// <param name="isVisible">指定控件是否可見。True 為顯示False 為隱藏。</param>
private void SetWordCountSongsAndButtonsVisibility(bool isVisible)
{
// 定義一個動作來處理控制項的顯示或隱藏
System.Action action = () =>
{
try
{
// 暫停控制項佈局的重新排版,提高效率
SuspendLayout();
// 檢查並設置圖片框的可見性
if (pictureBoxWordCountSongs == null)
{
Console.WriteLine("pictureBoxWordCountSongs is null");
}
else
{
pictureBoxWordCountSongs.Visible = isVisible;
if (isVisible) pictureBoxWordCountSongs.BringToFront(); // 如果顯示,將其置於最前
}
// 檢查並設置拼音按鈕的可見性
if (numberWordCountButtonsForSongs == null)
{
Console.WriteLine("numberWordCountButtonsForSongs is null");
}
else
{
foreach (var button in numberWordCountButtonsForSongs)
{
if (button == null)
{
Console.WriteLine("One of the numberWordCountButtonsForSongs is null");
}
else
{
button.Visible = isVisible;
if (isVisible) button.BringToFront(); // 如果顯示,將其置於最前
}
}
}
// 檢查並設置修改按鈕的可見性
if (modifyButtonWordCountSongs == null)
{
Console.WriteLine("modifyButtonWordCountSongs is null");
}
else
{
modifyButtonWordCountSongs.Visible = isVisible;
if (isVisible) modifyButtonWordCountSongs.BringToFront(); // 如果顯示,將其置於最前
}
// 檢查並設置清除按鈕的可見性
if (clearButtonWordCountSongs == null)
{
Console.WriteLine("clearButtonWordCountSongs is null");
}
else
{
clearButtonWordCountSongs.Visible = isVisible;
if (isVisible) clearButtonWordCountSongs.BringToFront(); // 如果顯示,將其置於最前
}
// 檢查並設置關閉按鈕的可見性
if (closeButtonWordCountSongs == null)
{
Console.WriteLine("closeButtonWordCountSongs is null");
}
else
{
closeButtonWordCountSongs.Visible = isVisible;
if (isVisible) closeButtonWordCountSongs.BringToFront(); // 如果顯示,將其置於最前
}
// 檢查並設置輸入框的可見性
if (inputBoxWordCountSongs == null)
{
Console.WriteLine("inputBoxWordCountSongs is null");
}
else
{
inputBoxWordCountSongs.Visible = isVisible;
if (isVisible) inputBoxWordCountSongs.BringToFront(); // 如果顯示,將其置於最前
}
// 恢復控制項的佈局重新排版
ResumeLayout();
PerformLayout();
// 刷新所有控制項的顯示
pictureBoxWordCountSongs?.Refresh();
if (numberWordCountButtonsForSongs != null)
{
foreach (var button in numberWordCountButtonsForSongs)
{
button?.Refresh(); // 刷新每個按鈕
}
}
modifyButtonWordCountSongs?.Refresh();
clearButtonWordCountSongs?.Refresh();
closeButtonWordCountSongs?.Refresh();
inputBoxWordCountSongs?.Refresh();
}
catch (Exception ex)
{
Console.WriteLine("Error in SetWordCountSongsAndButtonsVisibility: " + ex.Message);
}
};
// 檢查是否需要在主執行緒外執行
if (this.InvokeRequired)
{
this.Invoke(action); // 如果需要,透過主執行緒執行
}
else
{
action(); // 否則直接執行
}
}
private void NumberWordCountSongsButton_Click(object sender, EventArgs e)
{
var button = sender as Button;
if (button != null && button.Tag != null)
{
if (inputBoxWordCountSongs.Visible)
{
inputBoxWordCountSongs.Text += button.Tag.ToString();
}
}
}
}
}