2026-08-26 11:18:40 +08:00
|
|
|
using FairyView;
|
2026-06-26 15:00:53 +08:00
|
|
|
|
|
|
|
|
namespace StandardScene.Utils
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2026-08-26 22:49:07 +08:00
|
|
|
/// FairyView 通用 UI 小工具:浮动居中弹窗,不依赖宿主 SafeUI。
|
2026-06-26 15:00:53 +08:00
|
|
|
/// </summary>
|
2026-08-26 22:49:07 +08:00
|
|
|
public static class FairyUiHelper
|
2026-06-26 15:00:53 +08:00
|
|
|
{
|
|
|
|
|
/// <summary>
|
2026-08-26 11:18:40 +08:00
|
|
|
/// 非阻塞二次确认:用户点「确认」后在当前线程执行 <paramref name="onConfirm"/>。
|
|
|
|
|
/// 耗时逻辑请自行 <c>Task.Run</c>。
|
2026-06-26 15:00:53 +08:00
|
|
|
/// </summary>
|
2026-08-26 22:49:07 +08:00
|
|
|
public static void ConfirmThen(string message, System.Action onConfirm)
|
|
|
|
|
{
|
|
|
|
|
var dlg = CenteredDialog(GUI.DeclarePanel().ShowTitle("确认"), 380, 150);
|
|
|
|
|
dlg.Define(pb =>
|
|
|
|
|
{
|
|
|
|
|
if (pb.Closing())
|
|
|
|
|
{
|
|
|
|
|
dlg.Exit();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pb.Label(message);
|
|
|
|
|
pb.Separator();
|
|
|
|
|
if (pb.Button("确认", distinct: "fairyui-confirm-ok"))
|
|
|
|
|
{
|
|
|
|
|
dlg.Exit();
|
|
|
|
|
onConfirm?.Invoke();
|
|
|
|
|
}
|
|
|
|
|
pb.SameLine(8);
|
|
|
|
|
if (pb.Button("取消", distinct: "fairyui-confirm-cancel"))
|
|
|
|
|
dlg.Exit();
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-08-26 11:18:40 +08:00
|
|
|
|
|
|
|
|
/// <summary>非阻塞文件选择对话框。</summary>
|
|
|
|
|
public static void PickOpenFile(string label, string filter, System.Action<string> onPicked)
|
2026-06-26 15:00:53 +08:00
|
|
|
{
|
2026-08-26 22:49:07 +08:00
|
|
|
var dlg = CenteredDialog(GUI.DeclarePanel().ShowTitle("选择文件"), 420, 120);
|
2026-06-26 15:00:53 +08:00
|
|
|
dlg.Define(pb =>
|
|
|
|
|
{
|
|
|
|
|
if (pb.Closing())
|
|
|
|
|
{
|
|
|
|
|
dlg.Exit();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pb.OpenFile(label, filter, out var path))
|
|
|
|
|
{
|
|
|
|
|
dlg.Exit();
|
|
|
|
|
onPicked?.Invoke(path);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>非阻塞提示对话框。</summary>
|
|
|
|
|
public static void Alert(string title, string message)
|
|
|
|
|
{
|
2026-08-26 22:49:07 +08:00
|
|
|
var dlg = CenteredDialog(GUI.DeclarePanel().ShowTitle(title), 380, 150);
|
2026-06-26 15:00:53 +08:00
|
|
|
dlg.Define(pb =>
|
|
|
|
|
{
|
|
|
|
|
if (pb.Closing())
|
|
|
|
|
{
|
|
|
|
|
dlg.Exit();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pb.Label(message);
|
|
|
|
|
pb.Separator();
|
2026-08-26 22:49:07 +08:00
|
|
|
if (pb.Button("确定", distinct: "fairyui-alert-ok"))
|
2026-06-26 15:00:53 +08:00
|
|
|
dlg.Exit();
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-08-26 11:18:40 +08:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// FairyView <c>Table.height</c> 是 Ant Design <c>scroll.y</c> 像素;旧 CycleGUI 同参是可见行数。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static int TableHeightPx(int visibleRows) =>
|
|
|
|
|
visibleRows <= 0 ? 0 : visibleRows * 32;
|
2026-08-26 22:49:07 +08:00
|
|
|
|
|
|
|
|
static Panel CenteredDialog(Panel panel, int width, int height) =>
|
|
|
|
|
panel
|
|
|
|
|
.TopMost(true)
|
|
|
|
|
.ForceFloat()
|
|
|
|
|
.InitSize(width, height)
|
|
|
|
|
.InitPos(true, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
|
2026-06-26 15:00:53 +08:00
|
|
|
}
|
|
|
|
|
}
|