diff --git a/Doc/ARCHITECTURE.md b/Doc/ARCHITECTURE.md index b1226fa..65dbcee 100644 --- a/Doc/ARCHITECTURE.md +++ b/Doc/ARCHITECTURE.md @@ -240,7 +240,7 @@ public sealed class MagneticSceneProfile : NavigationProfileBase | `Coders/` | 导航无关的通用轨迹编码器 | `CommonTrackCoders`, `LidarAreaSwitchCoder` | | `Model/` | 任务、地图、配置数据模型 | `TaskModel`, `LoopTask`, `Map`, `ChargingSetting` | | `TCP/` | 异步 TCP 客户端 | `AsyncTcpClient` | -| `Utils/` | JSON、Modbus、WebAPI、CycleGUI 辅助 | `WebAPIHelper`, `CycleUiHelper`, `CarRemoteHelper` | +| `Utils/` | JSON、Modbus、WebAPI、FairyView UI 辅助 | `WebAPIHelper`, `FairyUiHelper`, `CarRemoteHelper` | | `CommonTools/` | 原子文件写入、雪花 ID | `AtomicFileUpdateHelper`, `SnowflakeIdGenerator` | | 根目录 | 全局工具与 HTTP 入口 | `Commons.cs`, `WebApi.cs`, `Heuristic.cs`, `LadderLogic.cs` | diff --git a/StandardScene.Core/CarTypes/DummyCar.cs b/StandardScene.Core/CarTypes/DummyCar.cs index 918f213..c2b56c7 100644 --- a/StandardScene.Core/CarTypes/DummyCar.cs +++ b/StandardScene.Core/CarTypes/DummyCar.cs @@ -509,7 +509,7 @@ namespace AMRScene1 { Task.Run(() => { - CycleUiHelper.Alert("提示", "go?"); + FairyUiHelper.Alert("提示", "go?"); go(); }); }); @@ -599,7 +599,7 @@ namespace AMRScene1 string tag = InputBox.ResultValue; if (tag.Contains(":")) { - CycleUiHelper.Alert("提示", "需要切换英文输入法输入:"); + FairyUiHelper.Alert("提示", "需要切换英文输入法输入:"); return; } if (!string.IsNullOrEmpty(tag) && tag.Contains(":")) diff --git a/StandardScene.Core/Chained/AbstractLoopMission.cs b/StandardScene.Core/Chained/AbstractLoopMission.cs index f7eadf9..749a675 100644 --- a/StandardScene.Core/Chained/AbstractLoopMission.cs +++ b/StandardScene.Core/Chained/AbstractLoopMission.cs @@ -2172,7 +2172,7 @@ namespace StandardScene.Chained } [MethodMember(Name = "停止环线", Description = "停止环线")] - public void Stop() + public override void Stop() { StopAll(); } @@ -2182,7 +2182,7 @@ namespace StandardScene.Chained ConfirmMessage = "确认将所有已初始化的正常 AGV 一键上线?")] public void OnlineAllCars() { - // 确认由 MethodMember.ConfirmMessage + ObjectEditorParity/SafeUI 居中弹出,此处勿再套 CycleUiHelper。 + // 确认由 MethodMember.ConfirmMessage + ObjectEditorParity/SafeUI 居中弹出,此处勿再套 FairyUiHelper。 Task.Run(OnlineAllCarsCore); } @@ -2208,7 +2208,7 @@ namespace StandardScene.Chained ConfirmMessage = "确认停止环线调度并结束所有 AGV 的环线任务?")] public void StopAllCarTasks() { - // 确认由 MethodMember.ConfirmMessage + ObjectEditorParity/SafeUI 居中弹出,此处勿再套 CycleUiHelper。 + // 确认由 MethodMember.ConfirmMessage + ObjectEditorParity/SafeUI 居中弹出,此处勿再套 FairyUiHelper。 Task.Run(StopAllCarTasksCore); } diff --git a/StandardScene.Core/Chained/DeliveryViewer.cs b/StandardScene.Core/Chained/DeliveryViewer.cs index ab80c89..d7a0912 100644 --- a/StandardScene.Core/Chained/DeliveryViewer.cs +++ b/StandardScene.Core/Chained/DeliveryViewer.cs @@ -137,10 +137,10 @@ namespace StandardScene.Chained new[] { "取消任务", "重发任务", "换车重发任务" }); var taskCode = dd.Id; // 业务操作含文件 IO 与锁竞争,统一用 Task.Run 放后台执行,绝不阻塞渲染线程(否则界面卡死)。 - if (op == 0) CycleUiHelper.ConfirmThen($"是否结束任务 {taskCode}?", () => Task.Run(() => CancelDelivery(taskCode))); - else if (op == 1) CycleUiHelper.ConfirmThen($"是否重发任务 {taskCode}?", () => Task.Run(() => ResendDelivery(taskCode))); - else if (op == 2) CycleUiHelper.ConfirmThen($"是否换车重发任务 {taskCode}?", () => Task.Run(() => ChangeCarResendDelivery(taskCode))); - }, height: CycleUiHelper.TableHeightPx(18), enableSearch: true); + if (op == 0) FairyUiHelper.ConfirmThen($"是否结束任务 {taskCode}?", () => Task.Run(() => CancelDelivery(taskCode))); + else if (op == 1) FairyUiHelper.ConfirmThen($"是否重发任务 {taskCode}?", () => Task.Run(() => ResendDelivery(taskCode))); + else if (op == 2) FairyUiHelper.ConfirmThen($"是否换车重发任务 {taskCode}?", () => Task.Run(() => ChangeCarResendDelivery(taskCode))); + }, height: FairyUiHelper.TableHeightPx(18), enableSearch: true); if (!string.IsNullOrEmpty(_status)) { diff --git a/StandardScene.Core/Chained/LoopViewer.cs b/StandardScene.Core/Chained/LoopViewer.cs index 1e290e0..746e2e9 100644 --- a/StandardScene.Core/Chained/LoopViewer.cs +++ b/StandardScene.Core/Chained/LoopViewer.cs @@ -19,7 +19,7 @@ namespace LoopViewerApp /// 勾选多行后「删除选中」可批量删除(保留原 ListView 多选删除能力);每行「编辑」按钮打开编辑对话框。 /// 文件写入放后台线程,绝不阻塞渲染线程(避免界面卡死)。 /// - /// 沿用 DeliveryViewer 的同套模式(单实例面板、pb.TableCycleUiHelper.ConfirmThen),不另造轮子。 + /// 沿用 DeliveryViewer 的同套模式(单实例面板、pb.TableFairyUiHelper.ConfirmThen),不另造轮子。 /// 保留可实例化 + 以兼容既有调用 new LoopViewer().Show()。 /// public class LoopViewer @@ -116,7 +116,7 @@ namespace LoopViewerApp if (row.ButtonGroup(new[] { "编辑" }, new[] { "编辑该任务" }) == 0) OpenEditDialog(t); - }, height: CycleUiHelper.TableHeightPx(18), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(18), enableSearch: true); if (!string.IsNullOrEmpty(_status)) { @@ -146,7 +146,7 @@ namespace LoopViewerApp prompt = $"确认删除所选 {_selected.Count} 个任务?"; // 删除仅做内存列表增删(极快,可在渲染线程执行);真正的文件写入在 SaveTasks 内部放后台线程。 - CycleUiHelper.ConfirmThen(prompt, DeleteSelected); + FairyUiHelper.ConfirmThen(prompt, DeleteSelected); } private void DeleteSelected() diff --git a/StandardScene.Core/Chained/TransportMission.cs b/StandardScene.Core/Chained/TransportMission.cs index bea9a86..42bca74 100644 --- a/StandardScene.Core/Chained/TransportMission.cs +++ b/StandardScene.Core/Chained/TransportMission.cs @@ -373,7 +373,7 @@ namespace StandardScene.Chained { if (_simRunning) { - CycleUiHelper.Alert("提示", "模拟下发搬运任务已在运行中。"); + FairyUiHelper.Alert("提示", "模拟下发搬运任务已在运行中。"); return; } @@ -461,7 +461,7 @@ namespace StandardScene.Chained { G.pushStatus("选择小车"); var selected = SimpleMonitor.selected.ToArray(); - if (selected.Length == 0) { CycleUiHelper.Alert("提示", "请先选择需要控制的小车!"); return; } + if (selected.Length == 0) { FairyUiHelper.Alert("提示", "请先选择需要控制的小车!"); return; } var obj = selected[0]; if (obj is Car car) { @@ -485,7 +485,7 @@ namespace StandardScene.Chained } else { - CycleUiHelper.Alert("提示", "请选择需要控制的小车!"); + FairyUiHelper.Alert("提示", "请选择需要控制的小车!"); } } catch @@ -512,7 +512,7 @@ namespace StandardScene.Chained { G.pushStatus("选择小车"); var selected = SimpleMonitor.selected.ToArray(); - if (selected.Length == 0) { CycleUiHelper.Alert("提示", "请先选择需要控制的小车!"); return; } + if (selected.Length == 0) { FairyUiHelper.Alert("提示", "请先选择需要控制的小车!"); return; } var obj = selected[0]; if (obj is Car car) { @@ -537,7 +537,7 @@ namespace StandardScene.Chained } else { - CycleUiHelper.Alert("提示", "请选择需要控制的小车!"); + FairyUiHelper.Alert("提示", "请选择需要控制的小车!"); } } catch diff --git a/StandardScene.Core/Charge/AlarmConfigManagementForm.cs b/StandardScene.Core/Charge/AlarmConfigManagementForm.cs index 9f9497e..ec66908 100644 --- a/StandardScene.Core/Charge/AlarmConfigManagementForm.cs +++ b/StandardScene.Core/Charge/AlarmConfigManagementForm.cs @@ -124,7 +124,7 @@ namespace StandardScene.Charge if (row.ButtonGroup(new[] { "编辑" }, new[] { "编辑该报警配置" }) == 0) OpenEditDialog(alarm); - }, height: CycleUiHelper.TableHeightPx(16), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(16), enableSearch: true); if (!string.IsNullOrEmpty(_status)) { @@ -231,7 +231,7 @@ namespace StandardScene.Charge if (success) { - CycleUiHelper.Alert("成功", "保存成功!"); + FairyUiHelper.Alert("成功", "保存成功!"); LoadAlarms(); _status = isAdd ? "已新增报警配置" : $"已保存报警配置 [{draft.AlarmCode}]"; dlg.Exit(); @@ -250,13 +250,13 @@ namespace StandardScene.Charge if (pb.Button("删除", distinct: "alarm-edit-delete")) { var toDelete = draft; - CycleUiHelper.ConfirmThen( + FairyUiHelper.ConfirmThen( $"确定要删除报警配置 [{toDelete.AlarmCode}] {toDelete.AlarmContent} 吗?", () => { if (DataService.DeleteAlarmConfig(toDelete.AlarmId, out string errorMessage)) { - CycleUiHelper.Alert("成功", "删除成功!"); + FairyUiHelper.Alert("成功", "删除成功!"); LoadAlarms(); _status = $"已删除报警配置 [{toDelete.AlarmCode}]"; dlg.Exit(); @@ -265,7 +265,7 @@ namespace StandardScene.Charge } else { - CycleUiHelper.Alert("错误", $"删除失败: {errorMessage}"); + FairyUiHelper.Alert("错误", $"删除失败: {errorMessage}"); } }); } @@ -289,7 +289,7 @@ namespace StandardScene.Charge catch (Exception ex) { _allAlarms = new List(); - CycleUiHelper.Alert("错误", $"加载数据失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"加载数据失败: {ex.Message}"); } } diff --git a/StandardScene.Core/Charge/ChargeStationHelper.cs b/StandardScene.Core/Charge/ChargeStationHelper.cs index 264edf1..f7a75d2 100644 --- a/StandardScene.Core/Charge/ChargeStationHelper.cs +++ b/StandardScene.Core/Charge/ChargeStationHelper.cs @@ -282,7 +282,7 @@ namespace StandardScene.Charge if (stations.Count == 0) { - CycleUiHelper.Alert("提示", "没有符合条件的充电桩"); + FairyUiHelper.Alert("提示", "没有符合条件的充电桩"); onSelected?.Invoke(null); return; } diff --git a/StandardScene.Core/Charge/ChargeStationManagementForm.cs b/StandardScene.Core/Charge/ChargeStationManagementForm.cs index 06f91cb..02bff89 100644 --- a/StandardScene.Core/Charge/ChargeStationManagementForm.cs +++ b/StandardScene.Core/Charge/ChargeStationManagementForm.cs @@ -129,7 +129,7 @@ namespace StandardScene.Charge var op = row.ButtonGroup(new[] { "编辑", "删除" }, new[] { "编辑充电桩", "删除充电桩" }); if (op == 0) OpenEditDialog(s); else if (op == 1) ConfirmDelete(s); - }, height: CycleUiHelper.TableHeightPx(16), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(16), enableSearch: true); if (!string.IsNullOrEmpty(_status)) { @@ -290,7 +290,7 @@ namespace StandardScene.Charge _lastFlush = DateTime.MinValue; _status = "保存成功"; - CycleUiHelper.Alert("提示", "保存成功"); + FairyUiHelper.Alert("提示", "保存成功"); dlg.Exit(); _editDialog = null; _panel?.Repaint(); @@ -341,11 +341,11 @@ namespace StandardScene.Charge private void ConfirmDelete(ChargeStation station) { - CycleUiHelper.ConfirmThen($"确定删除充电桩 [{station.StationId}] {station.Name}?", () => + FairyUiHelper.ConfirmThen($"确定删除充电桩 [{station.StationId}] {station.Name}?", () => { if (!DataService.DeleteStation(station.StationId, out var err)) { - CycleUiHelper.Alert("错误", $"删除失败: {err}"); + FairyUiHelper.Alert("错误", $"删除失败: {err}"); return; } var site = SimpleLib.GetSite(station.SiteId ?? 0); @@ -384,9 +384,9 @@ namespace StandardScene.Charge { File.WriteAllText(path, Newtonsoft.Json.JsonConvert.SerializeObject(stations, Newtonsoft.Json.Formatting.Indented)); } - CycleUiHelper.Alert("提示", "导出成功"); + FairyUiHelper.Alert("提示", "导出成功"); } - catch (Exception ex) { CycleUiHelper.Alert("错误", $"导出失败: {ex.Message}"); } + catch (Exception ex) { FairyUiHelper.Alert("错误", $"导出失败: {ex.Message}"); } } private void ApplyRowColor(PanelBuilder.Row row, ChargeStation s) diff --git a/StandardScene.Core/Charge/ChargeStrategyConfigForm.cs b/StandardScene.Core/Charge/ChargeStrategyConfigForm.cs index c95be19..f76a8bc 100644 --- a/StandardScene.Core/Charge/ChargeStrategyConfigForm.cs +++ b/StandardScene.Core/Charge/ChargeStrategyConfigForm.cs @@ -135,7 +135,7 @@ namespace StandardScene.Charge } catch (Exception ex) { - CycleUiHelper.Alert("错误", $"加载配置失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"加载配置失败: {ex.Message}"); _status = "配置加载失败"; return false; } @@ -220,7 +220,7 @@ namespace StandardScene.Charge if (!ValidateSocRanges(out var socError)) { - CycleUiHelper.Alert("验证失败", socError); + FairyUiHelper.Alert("验证失败", socError); _status = "配置保存失败"; _panel?.Repaint(); return; @@ -230,7 +230,7 @@ namespace StandardScene.Charge { ConfigService.SaveConfig(_config); _status = "配置保存成功"; - CycleUiHelper.Alert("成功", "充电策略配置保存成功!"); + FairyUiHelper.Alert("成功", "充电策略配置保存成功!"); if (closeAfterSave) { _panel?.Exit(); @@ -243,7 +243,7 @@ namespace StandardScene.Charge } catch (Exception ex) { - CycleUiHelper.Alert("错误", $"保存配置失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"保存配置失败: {ex.Message}"); _status = "配置保存失败"; _panel?.Repaint(); } @@ -251,7 +251,7 @@ namespace StandardScene.Charge private void RestoreDefaults() { - CycleUiHelper.ConfirmThen("确定要恢复默认配置吗?当前配置将被覆盖。", () => + FairyUiHelper.ConfirmThen("确定要恢复默认配置吗?当前配置将被覆盖。", () => { _config = ChargeStrategyConfig.CreateDefault(); ApplyConfigToUi(_config); diff --git a/StandardScene.Core/Charge/CommunicationMonitorForm.cs b/StandardScene.Core/Charge/CommunicationMonitorForm.cs index 1faffbd..5c1f073 100644 --- a/StandardScene.Core/Charge/CommunicationMonitorForm.cs +++ b/StandardScene.Core/Charge/CommunicationMonitorForm.cs @@ -117,7 +117,7 @@ namespace StandardScene.Charge pb.SameLine(8); if (pb.Button("清空", distinct: "comm-clear")) { - CycleUiHelper.ConfirmThen("确定要清空所有报文记录吗?", () => + FairyUiHelper.ConfirmThen("确定要清空所有报文记录吗?", () => { MessageService.Clear(); lock (PendingLock) @@ -164,7 +164,7 @@ namespace StandardScene.Charge _selectedRowIndex = i; _parsedText = BuildParsedText(msg); } - }, height: CycleUiHelper.TableHeightPx(20), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(20), enableSearch: true); pb.SeparatorText("报文解析"); pb.SelectableText(null, _parsedText ?? "", copyButton: true); diff --git a/StandardScene.Core/Charge/StandardChargeMission.cs b/StandardScene.Core/Charge/StandardChargeMission.cs index 2338de0..949217e 100644 --- a/StandardScene.Core/Charge/StandardChargeMission.cs +++ b/StandardScene.Core/Charge/StandardChargeMission.cs @@ -278,7 +278,7 @@ namespace StandardScene.Charge // 防止重复启动 if (myStarted) { - CycleUiHelper.Alert("提示", "充电进程已启动,不可重复启动"); + FairyUiHelper.Alert("提示", "充电进程已启动,不可重复启动"); return; } status.status = "已启动"; @@ -671,7 +671,7 @@ namespace StandardScene.Charge /// 停止所有相关线程 /// [MethodMember(Name = "关闭进程", Description = "关闭充电进程")] - public void Stop() + public override void Stop() { try { diff --git a/StandardScene.Core/Commons.cs b/StandardScene.Core/Commons.cs index 126f362..c7969fd 100644 --- a/StandardScene.Core/Commons.cs +++ b/StandardScene.Core/Commons.cs @@ -39,7 +39,7 @@ namespace StandardScene var cars = string.Join(",", loopingCar.Select(p => $"{p.id}")); var msg = $"小车:{cars}间发生死锁" + $"请及时人工介入处理!!!!"; - CycleUiHelper.Alert("死锁提醒", msg); + FairyUiHelper.Alert("死锁提醒", msg); } catch { } }; diff --git a/StandardScene.Core/ExtendDevice/ButtonBox/ButtonBoxManager.cs b/StandardScene.Core/ExtendDevice/ButtonBox/ButtonBoxManager.cs index 7c408a3..4228ef9 100644 --- a/StandardScene.Core/ExtendDevice/ButtonBox/ButtonBoxManager.cs +++ b/StandardScene.Core/ExtendDevice/ButtonBox/ButtonBoxManager.cs @@ -95,7 +95,7 @@ namespace StandardScene.ExtendDevice.ButtonBox LoadBoxFields(b); ClearButtonFields(); } - }, height: CycleUiHelper.TableHeightPx(8), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(8), enableSearch: true); pb.SeparatorText("按钮盒编辑"); var (ip, _) = pb.TextInput("1. IP", _boxIp, alwaysReturnString: true); @@ -130,7 +130,7 @@ namespace StandardScene.ExtendDevice.ButtonBox _selectedBtnIdx = i; LoadButtonFields(btn); } - }, height: CycleUiHelper.TableHeightPx(6), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(6), enableSearch: true); pb.SeparatorText("按钮编辑"); var (bIdx, _) = pb.TextInput("5. 按钮编码", _btnIndex, alwaysReturnString: true); @@ -264,9 +264,9 @@ namespace StandardScene.ExtendDevice.ButtonBox private void AddBox() { if (!TryParseBoxInput(out var index, out var ip, out var port, out var type, false, out var err)) - { CycleUiHelper.Alert("错误", err); return; } - if (_boxes.Any(b => b.Index == index)) { CycleUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } - if (_boxes.Any(b => b.Ip == ip)) { CycleUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } + { FairyUiHelper.Alert("错误", err); return; } + if (_boxes.Any(b => b.Index == index)) { FairyUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } + if (_boxes.Any(b => b.Ip == ip)) { FairyUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } var box = new ButtonBoxModel { Index = index, Ip = ip, Port = port, Type = type }; _boxes.Add(box); @@ -279,23 +279,23 @@ namespace StandardScene.ExtendDevice.ButtonBox private void SaveBox() { var cur = GetSelectedBox(); - if (cur == null) { CycleUiHelper.Alert("提示", "请先选择按钮盒"); return; } + if (cur == null) { FairyUiHelper.Alert("提示", "请先选择按钮盒"); return; } if (!TryParseBoxInput(out var index, out var ip, out var port, out var type, true, out var err)) - { CycleUiHelper.Alert("错误", err); return; } - if (_boxes.Any(b => b.Index == index && b != cur)) { CycleUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } - if (_boxes.Any(b => b.Ip == ip && b != cur)) { CycleUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } + { FairyUiHelper.Alert("错误", err); return; } + if (_boxes.Any(b => b.Index == index && b != cur)) { FairyUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } + if (_boxes.Any(b => b.Ip == ip && b != cur)) { FairyUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } cur.Index = index; cur.Ip = ip; cur.Port = port; cur.Type = type; SaveData(); - CycleUiHelper.Alert("提示", "保存成功"); + FairyUiHelper.Alert("提示", "保存成功"); _panel?.Repaint(); } private void ConfirmDeleteBox() { var cur = GetSelectedBox(); - if (cur == null) { CycleUiHelper.Alert("提示", "请选择要删除的按钮盒"); return; } - CycleUiHelper.ConfirmThen($"删除编码为 {cur.Index} 的按钮盒?", () => + if (cur == null) { FairyUiHelper.Alert("提示", "请选择要删除的按钮盒"); return; } + FairyUiHelper.ConfirmThen($"删除编码为 {cur.Index} 的按钮盒?", () => { _boxes.Remove(cur); _selectedBoxIdx = -1; @@ -311,10 +311,10 @@ namespace StandardScene.ExtendDevice.ButtonBox private void AddButton() { var box = GetSelectedBox(); - if (box == null) { CycleUiHelper.Alert("提示", "请先选择按钮盒"); return; } + if (box == null) { FairyUiHelper.Alert("提示", "请先选择按钮盒"); return; } if (!TryParseButtonInput(out var index, out var delay, out var err)) - { CycleUiHelper.Alert("错误", err); return; } - if (box.Buttons.Any(b => b.Index == index)) { CycleUiHelper.Alert("错误", $"按钮编码 {index} 已存在"); return; } + { FairyUiHelper.Alert("错误", err); return; } + if (box.Buttons.Any(b => b.Index == index)) { FairyUiHelper.Alert("错误", $"按钮编码 {index} 已存在"); return; } box.Buttons.Add(new ButtonModel { @@ -335,10 +335,10 @@ namespace StandardScene.ExtendDevice.ButtonBox { var box = GetSelectedBox(); var btn = GetSelectedButton(); - if (box == null || btn == null) { CycleUiHelper.Alert("提示", "请先选择按钮"); return; } + if (box == null || btn == null) { FairyUiHelper.Alert("提示", "请先选择按钮"); return; } if (!TryParseButtonInput(out var index, out var delay, out var err)) - { CycleUiHelper.Alert("错误", err); return; } - if (box.Buttons.Any(b => b.Index == index && b != btn)) { CycleUiHelper.Alert("错误", $"按钮编码 {index} 已存在"); return; } + { FairyUiHelper.Alert("错误", err); return; } + if (box.Buttons.Any(b => b.Index == index && b != btn)) { FairyUiHelper.Alert("错误", $"按钮编码 {index} 已存在"); return; } btn.Index = index; btn.TriggerMission = _triggerMission.Trim(); @@ -347,7 +347,7 @@ namespace StandardScene.ExtendDevice.ButtonBox btn.TriggerState = _triggerStateNames[_triggerStateIdx]; btn.TriggerDelay = delay; SaveData(); - CycleUiHelper.Alert("提示", "保存成功"); + FairyUiHelper.Alert("提示", "保存成功"); _panel?.Repaint(); } @@ -355,8 +355,8 @@ namespace StandardScene.ExtendDevice.ButtonBox { var box = GetSelectedBox(); var btn = GetSelectedButton(); - if (box == null || btn == null) { CycleUiHelper.Alert("提示", "请选择要删除的按钮"); return; } - CycleUiHelper.ConfirmThen($"删除编码为 {btn.Index} 的按钮?", () => + if (box == null || btn == null) { FairyUiHelper.Alert("提示", "请选择要删除的按钮"); return; } + FairyUiHelper.ConfirmThen($"删除编码为 {btn.Index} 的按钮?", () => { box.Buttons.Remove(btn); _selectedBtnIdx = -1; diff --git a/StandardScene.Core/ExtendDevice/ButtonBox/ButtonMission.cs b/StandardScene.Core/ExtendDevice/ButtonBox/ButtonMission.cs index 8ab3c32..34ecb1e 100644 --- a/StandardScene.Core/ExtendDevice/ButtonBox/ButtonMission.cs +++ b/StandardScene.Core/ExtendDevice/ButtonBox/ButtonMission.cs @@ -112,7 +112,7 @@ namespace StandardScene.ExtendDevice.ButtonBox /// [MethodMember(Name = "停止进程")] [I18N.DocumentTranslation(Name = "Stop Mission", locale = "en")] - public void Stop() + public override void Stop() { StopInternalAsync().GetAwaiter().GetResult(); status.status = "/"; @@ -768,7 +768,7 @@ namespace StandardScene.ExtendDevice.ButtonBox public static void OpenViewer() { try { ButtonBoxManager.Open(); } - catch (Exception ex) { CycleUiHelper.Alert("错误", $"打开按钮盒管理界面失败: {ex.Message}"); } + catch (Exception ex) { FairyUiHelper.Alert("错误", $"打开按钮盒管理界面失败: {ex.Message}"); } } } } diff --git a/StandardScene.Core/ExtendDevice/Door/DoorManager.cs b/StandardScene.Core/ExtendDevice/Door/DoorManager.cs index 7e27c81..9062a93 100644 --- a/StandardScene.Core/ExtendDevice/Door/DoorManager.cs +++ b/StandardScene.Core/ExtendDevice/Door/DoorManager.cs @@ -93,7 +93,7 @@ namespace StandardScene.ExtendDevice.Door LoadControllerFields(c); ClearDoorFields(); } - }, height: CycleUiHelper.TableHeightPx(8), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(8), enableSearch: true); pb.SeparatorText("控制器编辑"); var (ip, _) = pb.TextInput("1. IP", _ctrlIp, alwaysReturnString: true); @@ -127,7 +127,7 @@ namespace StandardScene.ExtendDevice.Door _selectedDoorIdx = i; LoadDoorFields(d); } - }, height: CycleUiHelper.TableHeightPx(6), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(6), enableSearch: true); pb.SeparatorText("门编辑"); var (dIdx, _) = pb.TextInput("5. 门编码", _doorIndex, alwaysReturnString: true); @@ -256,11 +256,11 @@ namespace StandardScene.ExtendDevice.Door { if (!TryParseControllerInput(out var index, out var ip, out var port, out var type, false, out var err)) { - CycleUiHelper.Alert("错误", err); + FairyUiHelper.Alert("错误", err); return; } - if (_controllers.Any(c => c.Index == index)) { CycleUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } - if (_controllers.Any(c => c.Ip == ip)) { CycleUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } + if (_controllers.Any(c => c.Index == index)) { FairyUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } + if (_controllers.Any(c => c.Ip == ip)) { FairyUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } var c = new DoorControllerModel { Index = index, Ip = ip, Port = port, Type = type }; _controllers.Add(c); @@ -273,14 +273,14 @@ namespace StandardScene.ExtendDevice.Door private void SaveController() { var cur = GetSelectedController(); - if (cur == null) { CycleUiHelper.Alert("提示", "请先选择要保存的门控制器"); return; } + if (cur == null) { FairyUiHelper.Alert("提示", "请先选择要保存的门控制器"); return; } if (!TryParseControllerInput(out var index, out var ip, out var port, out var type, true, out var err)) { - CycleUiHelper.Alert("错误", err); + FairyUiHelper.Alert("错误", err); return; } - if (_controllers.Any(c => c.Index == index && c != cur)) { CycleUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } - if (_controllers.Any(c => c.Ip == ip && c != cur)) { CycleUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } + if (_controllers.Any(c => c.Index == index && c != cur)) { FairyUiHelper.Alert("错误", $"编码 {index} 已存在"); return; } + if (_controllers.Any(c => c.Ip == ip && c != cur)) { FairyUiHelper.Alert("错误", $"IP {ip} 已存在"); return; } cur.Index = index; cur.Ip = ip; @@ -288,15 +288,15 @@ namespace StandardScene.ExtendDevice.Door cur.Type = type; SaveData(); _status = "门控制器已保存"; - CycleUiHelper.Alert("提示", "保存成功"); + FairyUiHelper.Alert("提示", "保存成功"); _panel?.Repaint(); } private void ConfirmDeleteController() { var cur = GetSelectedController(); - if (cur == null) { CycleUiHelper.Alert("提示", "请选择要删除的门控制器"); return; } - CycleUiHelper.ConfirmThen($"删除编码为 {cur.Index} 的门控制器?", () => + if (cur == null) { FairyUiHelper.Alert("提示", "请选择要删除的门控制器"); return; } + FairyUiHelper.ConfirmThen($"删除编码为 {cur.Index} 的门控制器?", () => { _controllers.Remove(cur); _selectedCtrlIdx = -1; @@ -312,13 +312,13 @@ namespace StandardScene.ExtendDevice.Door private void AddDoor() { var ctrl = GetSelectedController(); - if (ctrl == null) { CycleUiHelper.Alert("提示", "请先选择门控制器"); return; } + if (ctrl == null) { FairyUiHelper.Alert("提示", "请先选择门控制器"); return; } if (!TryParseDoorInput(out var index, out var cAddr, out var oAddr, false, out var err)) { - CycleUiHelper.Alert("错误", err); + FairyUiHelper.Alert("错误", err); return; } - if (ctrl.Doors.Any(d => d.Index == index)) { CycleUiHelper.Alert("错误", $"门编码 {index} 已存在"); return; } + if (ctrl.Doors.Any(d => d.Index == index)) { FairyUiHelper.Alert("错误", $"门编码 {index} 已存在"); return; } var door = new DoorModel { @@ -338,13 +338,13 @@ namespace StandardScene.ExtendDevice.Door { var ctrl = GetSelectedController(); var door = GetSelectedDoor(); - if (ctrl == null || door == null) { CycleUiHelper.Alert("提示", "请先选择要保存的门"); return; } + if (ctrl == null || door == null) { FairyUiHelper.Alert("提示", "请先选择要保存的门"); return; } if (!TryParseDoorInput(out var index, out var cAddr, out var oAddr, true, out var err)) { - CycleUiHelper.Alert("错误", err); + FairyUiHelper.Alert("错误", err); return; } - if (ctrl.Doors.Any(d => d.Index == index && d != door)) { CycleUiHelper.Alert("错误", $"门编码 {index} 已存在"); return; } + if (ctrl.Doors.Any(d => d.Index == index && d != door)) { FairyUiHelper.Alert("错误", $"门编码 {index} 已存在"); return; } door.Index = index; door.ControlAddress = cAddr; @@ -352,7 +352,7 @@ namespace StandardScene.ExtendDevice.Door door.NoControl = _doorNoControl; SaveData(); _status = "门已保存"; - CycleUiHelper.Alert("提示", "保存成功"); + FairyUiHelper.Alert("提示", "保存成功"); _panel?.Repaint(); } @@ -360,8 +360,8 @@ namespace StandardScene.ExtendDevice.Door { var ctrl = GetSelectedController(); var door = GetSelectedDoor(); - if (ctrl == null || door == null) { CycleUiHelper.Alert("提示", "请选择要删除的门"); return; } - CycleUiHelper.ConfirmThen($"删除编码为 {door.Index} 的门?", () => + if (ctrl == null || door == null) { FairyUiHelper.Alert("提示", "请选择要删除的门"); return; } + FairyUiHelper.ConfirmThen($"删除编码为 {door.Index} 的门?", () => { ctrl.Doors.Remove(door); _selectedDoorIdx = -1; diff --git a/StandardScene.Core/ExtendDevice/Door/DoorMission.cs b/StandardScene.Core/ExtendDevice/Door/DoorMission.cs index dbf1827..b4a5d51 100644 --- a/StandardScene.Core/ExtendDevice/Door/DoorMission.cs +++ b/StandardScene.Core/ExtendDevice/Door/DoorMission.cs @@ -141,7 +141,7 @@ namespace StandardScene.ExtendDevice.Door /// [MethodMember(Name = "停止进程")] [I18N.DocumentTranslation(Name = "Stop Mission", locale = "en")] - public void Stop() + public override void Stop() { StopInternalAsync().GetAwaiter().GetResult(); status.status = "/"; @@ -1017,7 +1017,7 @@ namespace StandardScene.ExtendDevice.Door } catch (Exception ex) { - CycleUiHelper.Alert("错误", $"打开门控监控界面失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"打开门控监控界面失败: {ex.Message}"); } } } diff --git a/StandardScene.Core/ExtendDevice/Door/DoorMonitor.cs b/StandardScene.Core/ExtendDevice/Door/DoorMonitor.cs index e7bfa1c..2a97336 100644 --- a/StandardScene.Core/ExtendDevice/Door/DoorMonitor.cs +++ b/StandardScene.Core/ExtendDevice/Door/DoorMonitor.cs @@ -90,7 +90,7 @@ namespace StandardScene.ExtendDevice.Door LabelCell(row, door, FormatCars(door)); LabelCell(row, door, door.ControlAddress.ToString()); LabelCell(row, door, door.OpenStatusAddress.ToString()); - }, height: CycleUiHelper.TableHeightPx(18), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(18), enableSearch: true); pb.Separator(); pb.Label("手动控制"); @@ -161,7 +161,7 @@ namespace StandardScene.ExtendDevice.Door { if (!_selectedDoor.HasValue) { - CycleUiHelper.Alert("提示", "请先选择要控制的门"); + FairyUiHelper.Alert("提示", "请先选择要控制的门"); return; } @@ -170,17 +170,17 @@ namespace StandardScene.ExtendDevice.Door var mission = GetMission(); if (mission == null) { - CycleUiHelper.Alert("错误", "未找到门控进程"); + FairyUiHelper.Alert("错误", "未找到门控进程"); return; } var (controllerIndex, doorIndex) = _selectedDoor.Value; mission.SetManualDoorControl(controllerIndex, doorIndex, true); - CycleUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已设置手动打开(10秒)"); + FairyUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已设置手动打开(10秒)"); } catch (Exception ex) { - CycleUiHelper.Alert("错误", $"设置门打开目标失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"设置门打开目标失败: {ex.Message}"); } } @@ -188,7 +188,7 @@ namespace StandardScene.ExtendDevice.Door { if (!_selectedDoor.HasValue) { - CycleUiHelper.Alert("提示", "请先选择要控制的门"); + FairyUiHelper.Alert("提示", "请先选择要控制的门"); return; } @@ -197,7 +197,7 @@ namespace StandardScene.ExtendDevice.Door var mission = GetMission(); if (mission == null) { - CycleUiHelper.Alert("错误", "未找到门控进程"); + FairyUiHelper.Alert("错误", "未找到门控进程"); return; } @@ -205,15 +205,15 @@ namespace StandardScene.ExtendDevice.Door var success = mission.SetManualDoorControl(controllerIndex, doorIndex, false); if (!success) { - CycleUiHelper.Alert("提示", "门存在车辆占用,禁止手动关闭。"); + FairyUiHelper.Alert("提示", "门存在车辆占用,禁止手动关闭。"); return; } - CycleUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已设置手动关闭(10秒)"); + FairyUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已设置手动关闭(10秒)"); } catch (Exception ex) { - CycleUiHelper.Alert("错误", $"设置门关闭目标失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"设置门关闭目标失败: {ex.Message}"); } } @@ -221,7 +221,7 @@ namespace StandardScene.ExtendDevice.Door { if (!_selectedDoor.HasValue) { - CycleUiHelper.Alert("提示", "请先选择要清空占用的门"); + FairyUiHelper.Alert("提示", "请先选择要清空占用的门"); return; } @@ -230,17 +230,17 @@ namespace StandardScene.ExtendDevice.Door var mission = GetMission(); if (mission == null) { - CycleUiHelper.Alert("错误", "未找到门控进程"); + FairyUiHelper.Alert("错误", "未找到门控进程"); return; } var (controllerIndex, doorIndex) = _selectedDoor.Value; mission.ClearCarsInArea(controllerIndex, doorIndex); - CycleUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已清空占用"); + FairyUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已清空占用"); } catch (Exception ex) { - CycleUiHelper.Alert("错误", $"清空占用失败: {ex.Message}"); + FairyUiHelper.Alert("错误", $"清空占用失败: {ex.Message}"); } } } diff --git a/StandardScene.Core/InterLock/AbstractInterlockMission.cs b/StandardScene.Core/InterLock/AbstractInterlockMission.cs index 7beb517..85e861b 100644 --- a/StandardScene.Core/InterLock/AbstractInterlockMission.cs +++ b/StandardScene.Core/InterLock/AbstractInterlockMission.cs @@ -297,7 +297,7 @@ namespace StandardScene.InterLock var vv = await Startup.UI.Input("请输入true/false", title, "true"); if (vv == null || !bool.TryParse(vv, out var allow)) { - CycleUiHelper.Alert("错误", "输入错误"); + FairyUiHelper.Alert("错误", "输入错误"); return; } lock (sync) toManipulate[site.id] = allow; diff --git a/StandardScene.Core/InterLock/TrafficInterlockViewer.cs b/StandardScene.Core/InterLock/TrafficInterlockViewer.cs index 737794e..7877df6 100644 --- a/StandardScene.Core/InterLock/TrafficInterlockViewer.cs +++ b/StandardScene.Core/InterLock/TrafficInterlockViewer.cs @@ -18,7 +18,7 @@ namespace LoopViewerApp /// 勾选多行后「删除选中」可批量删除;每行「编辑」按钮加载下方编辑区。 /// 文件写入放后台线程,绝不阻塞渲染线程。 /// - /// 沿用 LoopViewer / DeliveryViewer 同套模式(单实例面板、pb.TableCycleUiHelper.ConfirmThen)。 + /// 沿用 LoopViewer / DeliveryViewer 同套模式(单实例面板、pb.TableFairyUiHelper.ConfirmThen)。 /// 保留可实例化 + 以兼容既有调用 new TrafficInterlockViewer().Show()。 /// public class TrafficInterlockViewer @@ -133,7 +133,7 @@ namespace LoopViewerApp _editingAreaId = areaId; LoadAreaToFields(a); } - }, height: CycleUiHelper.TableHeightPx(14), enableSearch: true); + }, height: FairyUiHelper.TableHeightPx(14), enableSearch: true); pb.Separator(); pb.Label("数据新增/编辑(点击表格行「编辑」可在此查看并修改该行数据)"); @@ -188,7 +188,7 @@ namespace LoopViewerApp ? "确定要删除选中的区域吗?" : $"确定要删除所选 {_selected.Count} 个区域吗?"; - CycleUiHelper.ConfirmThen(prompt, DeleteSelected); + FairyUiHelper.ConfirmThen(prompt, DeleteSelected); } private void DeleteSelected() diff --git a/StandardScene.Core/Utils/CycleUiHelper.cs b/StandardScene.Core/Utils/FairyUiHelper.cs similarity index 55% rename from StandardScene.Core/Utils/CycleUiHelper.cs rename to StandardScene.Core/Utils/FairyUiHelper.cs index 7d40eb3..3abb616 100644 --- a/StandardScene.Core/Utils/CycleUiHelper.cs +++ b/StandardScene.Core/Utils/FairyUiHelper.cs @@ -1,24 +1,44 @@ using FairyView; -using Simple3; namespace StandardScene.Utils { /// - /// CycleGUI 通用 UI 小工具:统一委托 SafeUI 居中弹窗,避免自建 Panel 缺 Docking.None 跑到左上角。 + /// FairyView 通用 UI 小工具:浮动居中弹窗,不依赖宿主 SafeUI。 /// - public static class CycleUiHelper + public static class FairyUiHelper { /// /// 非阻塞二次确认:用户点「确认」后在当前线程执行 。 /// 耗时逻辑请自行 Task.Run。 /// - public static void ConfirmThen(string message, System.Action onConfirm) => - SafeUI.ConfirmThen(message, onConfirm); + 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(); + }); + } /// 非阻塞文件选择对话框。 public static void PickOpenFile(string label, string filter, System.Action onPicked) { - var dlg = SafeUI.ApplyCenteredFloating(GUI.DeclarePanel().ShowTitle("选择文件"), 420, 120); + var dlg = CenteredDialog(GUI.DeclarePanel().ShowTitle("选择文件"), 420, 120); dlg.Define(pb => { if (pb.Closing()) @@ -38,7 +58,7 @@ namespace StandardScene.Utils /// 非阻塞提示对话框。 public static void Alert(string title, string message) { - var dlg = SafeUI.ApplyCenteredFloating(GUI.DeclarePanel().ShowTitle(title), 380, 150); + var dlg = CenteredDialog(GUI.DeclarePanel().ShowTitle(title), 380, 150); dlg.Define(pb => { if (pb.Closing()) @@ -49,7 +69,7 @@ namespace StandardScene.Utils pb.Label(message); pb.Separator(); - if (pb.Button("确定", distinct: "cycleui-alert-ok")) + if (pb.Button("确定", distinct: "fairyui-alert-ok")) dlg.Exit(); }); } @@ -59,5 +79,12 @@ namespace StandardScene.Utils /// public static int TableHeightPx(int visibleRows) => visibleRows <= 0 ? 0 : visibleRows * 32; + + 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); } } diff --git a/StandardScene.QrLidar/Cad/SyncQrMap.cs b/StandardScene.QrLidar/Cad/SyncQrMap.cs index fa6da5b..c964134 100644 --- a/StandardScene.QrLidar/Cad/SyncQrMap.cs +++ b/StandardScene.QrLidar/Cad/SyncQrMap.cs @@ -30,7 +30,7 @@ namespace StandardScene.QrLidar.Cad var tagTh = tagSite.fields.TryGetValue("th", out var field) ? float.Parse(field) : 0f; if (ApiController.QrMap.ContainsKey(tag)) { - CycleUiHelper.Alert("错误", $@"存在重复码值:{tag} 站点id为:{tagSite.id}"); + FairyUiHelper.Alert("错误", $@"存在重复码值:{tag} 站点id为:{tagSite.id}"); return; } diff --git a/StandardScene.QrLidar/CarTypes/Kiva.cs b/StandardScene.QrLidar/CarTypes/Kiva.cs index eedf00d..920599d 100644 --- a/StandardScene.QrLidar/CarTypes/Kiva.cs +++ b/StandardScene.QrLidar/CarTypes/Kiva.cs @@ -298,7 +298,7 @@ namespace StandardScene.CarTypes RequiresPlatformConfirm = true, ConfirmMessage = "确定强制结束该车上的作业并下线?")] [I18N.DocumentTranslation(Name = "Force Stop new", Description = "Stop car & reset clumsy", locale = "en")] - public new async void ForceStop() + public override void ForceStop() { try { @@ -327,7 +327,7 @@ namespace StandardScene.CarTypes } catch (Exception ex) { - CycleUiHelper.Alert("错误", + FairyUiHelper.Alert("错误", $@"未能立即强制结束小车{name}({id}),原因:{ExceptionFormatter.FormatEx(ex)}"); } })