refactor: SimpleLite 迁移到 Simple3,插件窗体改用 FairyView ForceFloat
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,30 +1,24 @@
|
||||
using CycleGUI;
|
||||
using FairyView;
|
||||
using Simple3;
|
||||
|
||||
namespace StandardScene.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// CycleGUI 通用 UI 小工具:把多个界面都会用到的轻量对话框收敛到一处,避免各处各写一套(不造重复轮子)。
|
||||
/// <para>注意:同一 <c>Panel.Define</c> 内所有控件的 label 文本必须唯一(含 <c>pb.Table</c> 列头),
|
||||
/// 否则 ImGui 会抛 <c>Duplicated id</c>。编辑区 label 建议加 ASCII 序号前缀(如 <c>1. IP</c>),
|
||||
/// 且勿与表格列头同名。</para>
|
||||
/// CycleGUI 通用 UI 小工具:统一委托 SafeUI 居中弹窗,避免自建 Panel 缺 Docking.None 跑到左上角。
|
||||
/// </summary>
|
||||
public static class CycleUiHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 非阻塞二次确认对话框:用户点「确认」后,在<b>当前(渲染)线程</b>同步执行 <paramref name="onConfirm"/>。
|
||||
/// 若 <paramref name="onConfirm"/> 含文件 IO / 锁等耗时操作,调用方应自行用 <c>Task.Run</c> 包裹,
|
||||
/// 避免阻塞渲染线程导致界面卡死。
|
||||
/// 非阻塞二次确认:用户点「确认」后在当前线程执行 <paramref name="onConfirm"/>。
|
||||
/// 耗时逻辑请自行 <c>Task.Run</c>。
|
||||
/// </summary>
|
||||
public static void ConfirmThen(string message, System.Action onConfirm)
|
||||
public static void ConfirmThen(string message, System.Action onConfirm) =>
|
||||
SafeUI.ConfirmThen(message, onConfirm);
|
||||
|
||||
/// <summary>非阻塞文件选择对话框。</summary>
|
||||
public static void PickOpenFile(string label, string filter, System.Action<string> onPicked)
|
||||
{
|
||||
// 不用 Modal:CycleGUI 原生「模态弹窗 + 标题栏关闭X」存在 BeginPopupModal/EndPopup 配对 bug
|
||||
//(X 关闭时 BeginPopupModal 返回 false 仍调用 EndPopup → ImGui 断言 "Calling End() too many times!" 崩溃)。
|
||||
// 改为置顶非模态:用 Begin/End 路径,X 关闭干净,效果等同点「取消」。
|
||||
var dlg = GUI.DeclarePanel()
|
||||
.ShowTitle("确认")
|
||||
.TopMost(true)
|
||||
.InitSize(380, 150)
|
||||
.InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
|
||||
var dlg = SafeUI.ApplyCenteredFloating(GUI.DeclarePanel().ShowTitle("选择文件"), 420, 120);
|
||||
dlg.Define(pb =>
|
||||
{
|
||||
if (pb.Closing())
|
||||
@@ -33,30 +27,6 @@ namespace StandardScene.Utils
|
||||
return;
|
||||
}
|
||||
|
||||
pb.Label(message);
|
||||
pb.Separator();
|
||||
if (pb.Button("确认", distinct: "cycleui-confirm-ok"))
|
||||
{
|
||||
dlg.Exit();
|
||||
onConfirm();
|
||||
}
|
||||
pb.SameLine(8);
|
||||
if (pb.Button("取消", distinct: "cycleui-confirm-cancel"))
|
||||
dlg.Exit();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>非阻塞文件选择对话框,替代 WinForms <c>OpenFileDialog</c>。</summary>
|
||||
public static void PickOpenFile(string label, string filter, System.Action<string> onPicked)
|
||||
{
|
||||
var dlg = GUI.DeclarePanel()
|
||||
.ShowTitle("选择文件")
|
||||
.TopMost(true)
|
||||
.InitSize(420, 120)
|
||||
.InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
|
||||
dlg.Define(pb =>
|
||||
{
|
||||
if (pb.Closing()) { dlg.Exit(); return; }
|
||||
if (pb.OpenFile(label, filter, out var path))
|
||||
{
|
||||
dlg.Exit();
|
||||
@@ -68,11 +38,7 @@ namespace StandardScene.Utils
|
||||
/// <summary>非阻塞提示对话框。</summary>
|
||||
public static void Alert(string title, string message)
|
||||
{
|
||||
var dlg = GUI.DeclarePanel()
|
||||
.ShowTitle(title)
|
||||
.TopMost(true)
|
||||
.InitSize(380, 150)
|
||||
.InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
|
||||
var dlg = SafeUI.ApplyCenteredFloating(GUI.DeclarePanel().ShowTitle(title), 380, 150);
|
||||
dlg.Define(pb =>
|
||||
{
|
||||
if (pb.Closing())
|
||||
@@ -87,5 +53,11 @@ namespace StandardScene.Utils
|
||||
dlg.Exit();
|
||||
});
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user