378 lines
17 KiB
C#
378 lines
17 KiB
C#
using System.IO;
|
||
using System.Drawing.Imaging;
|
||
|
||
namespace DualScreenDemo
|
||
{
|
||
public partial class PrimaryForm
|
||
{
|
||
private PictureBox pictureBoxWordCountSongs;
|
||
private Button[] numberWordCountButtonsForSongs;
|
||
private Button modifyButtonWordCountSongs;
|
||
private Button clearButtonWordCountSongs;
|
||
private Button closeButtonWordCountSongs;
|
||
private Button enterButtonWordCountSongs;
|
||
private RichTextBox inputBoxWordCountSongs;
|
||
|
||
|
||
// 初始化所有與注音歌手相關的按鈕,包括語音符號按鈕、特殊按鈕及輸入框。
|
||
private void InitializeButtonsForWordCountSongs()
|
||
{
|
||
// 初始化所有語音按鈕
|
||
InitializeNumberWordCountSongsButtons(pictureBoxWordCountSongs,NumberWordCountSongsButton_Click);
|
||
// 初始化注音歌手的輸入框
|
||
InitializeInputBoxWordCountSongs();
|
||
// 初始化下排功能按鈕
|
||
InitializeSongWordButton();
|
||
}
|
||
|
||
/// 初始化並設置語音按鈕的相關資料,包括符號、座標與圖片等。
|
||
private void InitializeNumberWordCountSongsButtons(Control control, EventHandler handler)
|
||
{
|
||
// 初始化語音按鈕陣列,總共有 10 個按鈕
|
||
numberWordCountButtonsForSongs = new Button[10];
|
||
|
||
// 設置上排數字按鈕
|
||
int x = 10;
|
||
for (int i = 0; i < 5; i++)
|
||
{
|
||
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;
|
||
}
|
||
}
|
||
|
||
private void CreateNumBtnWordCountButton(int index, int x, int y,Control control,EventHandler handler)
|
||
{
|
||
try
|
||
{
|
||
// 加載配置數據
|
||
var data = LoadBtnConfigData();
|
||
// 創建語音按鈕並設置其屬性
|
||
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);
|
||
|
||
// 設置按鈕的 Tag 屬性為對應的語音符號
|
||
numberWordCountButtonsForSongs[index].Tag = numberWordCountSymbols[index];
|
||
|
||
// 將按鈕添加到表單的控制項集合中
|
||
control.Controls.Add(numberWordCountButtonsForSongs[index]);
|
||
}
|
||
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);
|
||
}
|
||
|
||
// 初始化 WordCount 歌手輸入框,並設定其屬性與事件處理程序。
|
||
private void InitializeInputBoxWordCountSongs()
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
|
||
|
||
// 顯示圖片並根據配置文件設置顯示區域的大小和位置。
|
||
// <param name="imagePath">圖片的路徑。</param>
|
||
private void ShowImageOnPictureBoxWordCountSongs(string imagePath)
|
||
{
|
||
// 加載原始圖片
|
||
Bitmap originalImage = new Bitmap(imagePath);
|
||
|
||
// 設置圖片到 PictureBox
|
||
pictureBoxWordCountSongs.Image = originalImage;
|
||
|
||
// 調整 PictureBox 大小和位置
|
||
ResizeAndPositionPictureBox(pictureBoxWordCountSongs, 778, 366, 420, 350);
|
||
|
||
// 顯示圖片
|
||
pictureBoxWordCountSongs.Visible = true;
|
||
}
|
||
|
||
// 設置注音歌手相關控制項(包括圖片框、按鈕和輸入框)的顯示或隱藏狀態。
|
||
// <param name="isVisible">指定控件是否可見。True 為顯示,False 為隱藏。</param>
|
||
private void SetWordCountSongsAndButtonsVisibility(bool isVisible)
|
||
{
|
||
// 定義一個動作來處理控制項的顯示或隱藏
|
||
System.Action action = () =>
|
||
{
|
||
try
|
||
{
|
||
// 暫停控制項佈局的重新排版,提高效率
|
||
SuspendLayout();
|
||
if (isVisible) SetUIVisible(pictureBoxWordCountSongs);
|
||
else CloseUI(pictureBoxWordCountSongs);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine("Error in SetWordCountSongsAndButtonsVisibility: " + ex.Message);
|
||
}
|
||
};
|
||
|
||
// 檢查是否需要在主執行緒外執行
|
||
if (this.InvokeRequired)
|
||
{
|
||
this.Invoke(action); // 如果需要,透過主執行緒執行
|
||
}
|
||
else
|
||
{
|
||
action(); // 否則直接執行
|
||
}
|
||
}
|
||
|
||
#region 按鈕點擊事件
|
||
|
||
/// <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 = LoadBtnConfigData();
|
||
|
||
// 取得「注音歌手圖片」的完整路徑
|
||
string imagePath = Path.Combine(serverPath, configData["ImagePaths"]["WordCountSongs"]);
|
||
|
||
// 在 PictureBox 中顯示對應的「注音歌手」圖片
|
||
ShowImageOnPictureBoxWordCountSongs(Path.Combine(serverPath, imagePath));
|
||
|
||
// 鍵盤UI介面顯示設定
|
||
SetWordCountSongsAndButtonsVisibility(true);
|
||
SetEnglishSongsAndButtonsVisibility(false);
|
||
SetPinYinSongsAndButtonsVisibility(false);
|
||
SetHandWritingForSongsAndButtonsVisibility(false);
|
||
SetSongIDSearchAndButtonsVisibility(false);
|
||
SetZhuYinSongsAndButtonsVisibility(false);
|
||
SetHandWritingForSongsAndButtonsVisibility(false);
|
||
|
||
SetWordCountSongsAndButtonsVisibility(true); // 顯示字數搜尋相關控件
|
||
// 顯示「注音歌手搜尋」的圖片框
|
||
ResetinputBox();
|
||
pictureBoxWordCountSongs.Visible = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 處理「修改」按鈕的點擊事件,該事件會刪除輸入框中的最後一個字符。
|
||
/// </summary>
|
||
private void ModifyButtonWordCountSongs_Click(object sender, EventArgs e)
|
||
{
|
||
// 如果輸入框不為空,且包含輸入內容,則刪除最後一個字符
|
||
if (pictureBoxWordCountSongs.Controls.Contains(inputBoxWordCountSongs) && inputBoxWordCountSongs.Text.Length > 0)
|
||
{
|
||
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)
|
||
{
|
||
inputBoxWordCountSongs.Text = "";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 「關閉」按鈕的點擊事件處理方法。
|
||
/// 隱藏 WordCount 歌手圖片框以及與其相關的按鈕。
|
||
/// </summary>
|
||
private void CloseButtonWordCountSongs_Click(object sender, EventArgs e)
|
||
{
|
||
// 隱藏 WordCount 歌手圖片框
|
||
pictureBoxWordCountSongs.Visible = false;
|
||
// 關閉背景圖式
|
||
wordCountSearchSongButton.BackgroundImage = wordCountSearchSongNormalBackground;
|
||
// 隱藏與 WordCount 歌手相關的所有按鈕
|
||
SetWordCountSongsAndButtonsVisibility(false);
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 查詢歌曲(字數查詢)
|
||
private void FindWordCountSongs()
|
||
{
|
||
string searchText = inputBoxWordCountSongs.Text;
|
||
// 在這裡添加搜尋歌曲的邏輯
|
||
// 例如:根據輸入框的內容搜尋歌曲
|
||
string query;
|
||
if (int.TryParse(searchText, out int length))
|
||
{
|
||
query = $"SELECT * FROM song_library_cache WHERE CHAR_LENGTH(song_name) = {length} order by 'song_name' DESC ;";
|
||
}
|
||
else
|
||
{
|
||
// 處理輸入錯誤,例如顯示提示訊息
|
||
//MessageBox.Show("請輸入正確的數字!");
|
||
query = string.Empty; // 清空查詢
|
||
return;
|
||
}
|
||
var searchResults = SearchSongs_Mysql(query);
|
||
// 重置分頁
|
||
currentPage = 0;
|
||
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
|
||
// 更新多頁面面板的內容
|
||
multiPagePanel.currentPageIndex = 0;
|
||
multiPagePanel.LoadSongs(searchResults);
|
||
}
|
||
#endregion
|
||
|
||
#region 移除圖像周圍的白色邊框
|
||
/// <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;
|
||
}
|
||
#endregion
|
||
}
|
||
} |