ModelingDebug/ModeSwitch.cs

169 lines
5.1 KiB
C#
Raw Permalink 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.Text;
namespace Debug;
public class ModeSwitch
{
public event Action<int>? Enter;
private readonly string[] str = ["退出"];
private int mode = 0;
private string title;
private string message;
public ModeSwitch(string title, string[] a, Action<int> Enter) : this(title, a, Enter, string.Empty)
{
}
public ModeSwitch(string title, string[] a, Action<int> Enter, string message)
{
this.Enter = Enter;
str = a;
this.title = title;
this.message = message;
Run();
}
private void Run()
{
Console.Clear();
PrintCentered("<--- " + title + " --->");
int windowWidth = Console.WindowWidth;
for (int i = 0; i < str.Length; i++)
{
// string paddedString = str[i].PadLeft((windowWidth + str[i].Length) / 2).PadRight(windowWidth);
// Console.WriteLine(paddedString);
PrintCentered($"{str[i]}");
}
// 判断message是不是为空
for (int i = 0; i < windowWidth; i++)
{
Console.Write('-');
}
Console.WriteLine();
PrintCentered("按W/S或↑/↓选择或数字键选择按Enter确定,按Esc退出");
if (message != string.Empty)
{
Console.Write(message);
}
do
{
var A1 = CalculateActualLength($"{mode}.{str[mode]}");
Console.SetCursorPosition(windowWidth / 2 - A1, mode + 1);
Console.Write("<<");
Console.SetCursorPosition(windowWidth / 2 + A1 - 2, mode + 1);
Console.Write(">>");
var key = Console.ReadKey(true);
Console.SetCursorPosition(windowWidth / 2 - A1, mode + 1);
Console.Write(" ");
Console.SetCursorPosition(windowWidth / 2 + A1 - 2, mode + 1);
Console.Write(" ");
// Console.Write(key.Key);
if (key.Key >= ConsoleKey.D1 && key.Key <= ConsoleKey.D9)
{
int v1 = int.Parse(key.KeyChar.ToString());
if (v1 >= 1 && v1 <= str.Length)
mode = v1 - 1;
}
else if (key.Key == ConsoleKey.Escape)
{
IsEnd();
return;
}
else
switch (key.Key)
{
case ConsoleKey.UpArrow:
case ConsoleKey.W:
mode--;
break;
case ConsoleKey.S:
case ConsoleKey.DownArrow:
mode++;
break;
case ConsoleKey.Enter:
Enter?.Invoke(mode);
return;
default:
break;
}
mode = int.Max(0, int.Min(str.Length - 1, mode));
} while (true);
}
/// <summary>
/// 确实是否退出
/// </summary>
private void IsEnd()
{
Console.Clear();
Console.WriteLine("再次按ESC退出,按回车键继续");
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Escape)
{
Console.Clear();
Environment.Exit(0);
}
else if (key.Key == ConsoleKey.Enter)
{
Run();
}
}
private static int CalculateActualLength(string text)
{
Encoding encoding = Encoding.UTF8;
int length = 0;
foreach (char c in text)
{
byte[] bytes = encoding.GetBytes(c.ToString());
if (bytes.Length > 1) // 汉字或宽字符
length += 2;
else
length += 1;
}
return length;
}
public static void New(string title, string[] a, Action<int> Enter, string message)
{
_ = new ModeSwitch(title, a, Enter, message);
}
public static void New(string title, string[] a, Action<int> Enter)
{
_ = new ModeSwitch(title, a, Enter);
}
static void PrintCentered(string text)
{
// 获取控制台窗口的宽度
int consoleWidth = Console.WindowWidth;
// 计算文本的宽度,对于多字节字符(如中文),可能需要特殊处理
int textLength = GetTextDisplayLength(text);
// 计算左右两侧应该填充的空格数
int padding = (consoleWidth - textLength) / 2;
if (padding > 0)
{
// 打印左侧空格
Console.Write(new string(' ', padding));
}
// 打印文本
Console.WriteLine(text);
}
static int GetTextDisplayLength(string text)
{
// 默认每个字符占一个位置包括ASCII字符和非ASCII字符如中文
// return text.Length;
// * 如果需要更精确地计算字符宽度(例如考虑全角半角字符的区别),可以使用以下代码:
int length = 0;
foreach (char c in text)
{
// 假设所有非ASCII字符都是双宽度字符
length += char.IsHighSurrogate(c) || char.IsLowSurrogate(c) || c > 127 ? 2 : 1;
}
return length;
}
}