From 3ba3d328b89350df638a5b4e386704ba7e4101e0 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 5 Sep 2025 17:49:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E6=8D=95=E6=8D=89=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8D=B3=E4=BD=BF?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=AF=BC=E8=88=AA=E5=B7=A5=E5=85=B7=E4=BE=9D?= =?UTF-8?q?=E7=84=B6=E5=8F=AF=E4=BB=A5=E8=8E=B7=E5=8F=96=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E7=84=A6=E7=82=B9=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E7=82=B9=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NavisworksTransportPlugin.csproj | 1 + src/Core/PathClickToolPlugin.cs | 11 +++ src/Core/PathInputMonitor.cs | 120 +++++++++++++++++++++++++++++++ src/Core/PathPlanningManager.cs | 44 ++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 src/Core/PathInputMonitor.cs diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj index c055abd..52aeef5 100644 --- a/NavisworksTransportPlugin.csproj +++ b/NavisworksTransportPlugin.csproj @@ -98,6 +98,7 @@ + diff --git a/src/Core/PathClickToolPlugin.cs b/src/Core/PathClickToolPlugin.cs index 18c3786..80e5de4 100644 --- a/src/Core/PathClickToolPlugin.cs +++ b/src/Core/PathClickToolPlugin.cs @@ -33,6 +33,17 @@ namespace NavisworksTransport } } + /// + /// 公开方法,允许外部代码触发 MouseClicked 事件 + /// 用于 PathInputMonitor 等备用输入机制 + /// + /// 事件发送者 + /// 点击结果 + public static void TriggerMouseClicked(object sender, PickItemResult result) + { + MouseClicked?.Invoke(sender, result); + } + /// /// 重写鼠标按下事件,获取精确的点击坐标 diff --git a/src/Core/PathInputMonitor.cs b/src/Core/PathInputMonitor.cs new file mode 100644 index 0000000..713bf44 --- /dev/null +++ b/src/Core/PathInputMonitor.cs @@ -0,0 +1,120 @@ +using System; +using Autodesk.Navisworks.Api; +using Autodesk.Navisworks.Api.Plugins; +using NavisworksTransport.Core; + +namespace NavisworksTransport +{ + /// + /// 路径编辑输入监听器 + /// 作为PathClickToolPlugin的备用事件捕获机制,解决工具焦点丢失问题 + /// + [Plugin("NavisworksTransport.PathInputMonitor", "NVTX", DisplayName = "PathInputMonitor")] + public class PathInputMonitor : InputPlugin + { + /// + /// 鼠标按下事件处理 + /// 在路径编辑模式下捕获鼠标点击,即使ToolPlugin失活也能响应 + /// + public override bool MouseDown(View view, KeyModifiers modifiers, ushort button, int x, int y, double timeOffset) + { + try + { + // 只处理左键点击 + if (button != 1) return false; + + // 获取PathPlanningManager实例 + var pathManager = PathPlanningManager.GetActivePathManager(); + if (pathManager == null) return false; + + // 只在路径编辑模式下处理 + if (pathManager.PathEditState == PathEditState.AddingPoints || + pathManager.PathEditState == PathEditState.EditingPoint) + { + LogManager.WriteLog("[InputMonitor] 检测到路径编辑模式下的鼠标点击"); + + // 如果ToolPlugin未激活,自动重新激活 + if (!pathManager.IsToolPluginActive) + { + LogManager.WriteLog("[InputMonitor] ToolPlugin未激活,自动重新激活"); + pathManager.ReactivateToolPlugin(); + + // 给用户一个视觉反馈 + var uiStateManager = UIStateManager.Instance; + uiStateManager?.QueueUIUpdate(() => + { + // 这里可以添加状态栏提示或其他UI反馈 + }); + } + + // 获取精确的3D坐标 + PickItemResult itemResult = view.PickItemFromPoint(x, y); + if (itemResult != null) + { + LogManager.WriteLog($"[InputMonitor] 获取到3D坐标: ({itemResult.Point.X:F3}, {itemResult.Point.Y:F3}, {itemResult.Point.Z:F3})"); + + // 触发PathClickToolPlugin的事件,复用现有的完整处理逻辑 + // 这确保了自动路径、手动路径的所有模式都能正常工作 + PathClickToolPlugin.TriggerMouseClicked(this, itemResult); + + LogManager.WriteLog("[InputMonitor] 已触发PathClickToolPlugin事件"); + return true; // 返回true表示已处理,阻止其他处理程序 + } + else + { + LogManager.WriteLog("[InputMonitor] 未点击到有效对象"); + } + + return false; // 让其他处理程序继续处理 + } + + return false; // 不在编辑模式,不处理 + } + catch (Exception ex) + { + LogManager.WriteLog($"[InputMonitor] 处理鼠标点击异常: {ex.Message}"); + return false; + } + } + + /// + /// 鼠标移动事件(暂不处理,避免性能影响) + /// + public override bool MouseMove(View view, KeyModifiers modifiers, int x, int y, double timeOffset) + { + return false; + } + + /// + /// 键盘按下事件 + /// 可以在这里添加快捷键恢复工具的功能 + /// + public override bool KeyDown(View view, KeyModifiers modifier, ushort key, double timeOffset) + { + try + { + // 空格键快速恢复工具 + if (key == 32) // 空格键 + { + var pathManager = PathPlanningManager.GetActivePathManager(); + if (pathManager != null && + (pathManager.PathEditState == PathEditState.AddingPoints || + pathManager.PathEditState == PathEditState.EditingPoint) && + !pathManager.IsToolPluginActive) + { + LogManager.WriteLog("[InputMonitor] 用户按空格键,重新激活工具"); + pathManager.ReactivateToolPlugin(); + return true; + } + } + + return false; + } + catch (Exception ex) + { + LogManager.WriteLog($"[InputMonitor] 处理键盘事件异常: {ex.Message}"); + return false; + } + } + } +} \ No newline at end of file diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs index 5c0a243..ee3c98b 100644 --- a/src/Core/PathPlanningManager.cs +++ b/src/Core/PathPlanningManager.cs @@ -55,6 +55,11 @@ namespace NavisworksTransport private int _editingPointIndex = -1; // 正在修改的路径点索引 private PathPoint _originalPoint = null; // 修改前的原始路径点 private PathPoint _editingPreviewPoint = null; // 修改时的预览路径点 + + /// + /// ToolPlugin是否处于激活状态(供InputMonitor使用) + /// + public bool IsToolPluginActive => _isToolPluginActive; /// /// 获取当前是否在预览模式 @@ -2304,6 +2309,45 @@ namespace NavisworksTransport } } + /// + /// 重新激活ToolPlugin(供InputMonitor调用) + /// 用于在工具失活后快速恢复,不重复订阅事件 + /// + public void ReactivateToolPlugin() + { + try + { + // 只有在编辑模式且工具未激活时才重新激活 + if (!_isToolPluginActive && + (PathEditState == PathEditState.AddingPoints || + PathEditState == PathEditState.EditingPoint)) + { + LogManager.WriteLog("[ReactivateToolPlugin] 开始重新激活ToolPlugin"); + + // 调用现有的激活方法,但不重复订阅事件 + if (ActivateToolPlugin(false)) + { + LogManager.WriteLog("[ReactivateToolPlugin] ToolPlugin重新激活成功"); + RaiseStatusChanged("工具已重新激活", PathPlanningStatusType.Info); + } + else + { + LogManager.WriteLog("[ReactivateToolPlugin] ToolPlugin重新激活失败"); + RaiseErrorOccurred("无法重新激活编辑工具"); + } + } + else + { + LogManager.WriteLog($"[ReactivateToolPlugin] 跳过重新激活 - IsToolPluginActive: {_isToolPluginActive}, PathEditState: {PathEditState}"); + } + } + catch (Exception ex) + { + LogManager.WriteLog($"[ReactivateToolPlugin] 重新激活失败: {ex.Message}"); + RaiseErrorOccurred($"重新激活工具失败: {ex.Message}", ex); + } + } + /// /// 处理ToolPlugin的鼠标点击事件 ///