Add a custom ribbon tab for logistics tools

This commit is contained in:
tian 2026-04-11 23:17:21 +08:00
parent 7e1931fd37
commit 970d3465f4
6 changed files with 146 additions and 0 deletions

View File

@ -165,6 +165,7 @@
<Compile Include="src\Commands\SetLogisticsAttributeCommand.cs" /> <Compile Include="src\Commands\SetLogisticsAttributeCommand.cs" />
<Compile Include="src\Commands\StartAnimationCommand.cs" /> <Compile Include="src\Commands\StartAnimationCommand.cs" />
<Compile Include="src\Commands\GenerateCollisionReportCommand.cs" /> <Compile Include="src\Commands\GenerateCollisionReportCommand.cs" />
<Compile Include="src\Commands\TransportRibbonHandler.cs" />
<Compile Include="src\Commands\VoxelGridSDFTestCommand.cs" /> <Compile Include="src\Commands\VoxelGridSDFTestCommand.cs" />
<Compile Include="src\Commands\VoxelPathFindingTestCommand.cs" /> <Compile Include="src\Commands\VoxelPathFindingTestCommand.cs" />
<!-- Core - Animation System --> <!-- Core - Animation System -->
@ -522,6 +523,18 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>resources\TransportPlugin.name.txt</Link> <Link>resources\TransportPlugin.name.txt</Link>
</None> </None>
<None Include="resources\TransportRibbon.xaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>TransportRibbon.xaml</Link>
</None>
<None Include="resources\TransportRibbon_16.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>TransportRibbon_16.png</Link>
</None>
<None Include="resources\TransportRibbon_32.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>TransportRibbon_32.png</Link>
</None>
<!-- Unit Cube NWC Model File --> <!-- Unit Cube NWC Model File -->
<None Include="resources\unit_cube.nwc"> <None Include="resources\unit_cube.nwc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

View File

@ -16,6 +16,11 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command ^
" 'System.Data.SQLite.dll'," ^ " 'System.Data.SQLite.dll'," ^
" 'Tomlyn.dll'" ^ " 'Tomlyn.dll'" ^
");" ^ ");" ^
"$deployRootFiles = @(" ^
" 'TransportRibbon.xaml'," ^
" 'TransportRibbon_16.png'," ^
" 'TransportRibbon_32.png'" ^
");" ^
"$stalePluginFiles = @(" ^ "$stalePluginFiles = @(" ^
" 'Autodesk.Navisworks.Api.dll'," ^ " 'Autodesk.Navisworks.Api.dll'," ^
" 'NavisworksTransport.UnitTests.dll'," ^ " 'NavisworksTransport.UnitTests.dll'," ^
@ -63,6 +68,17 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command ^
" if (-not (Test-Path $sourceDll)) { throw ('Deployment source file missing: ' + $sourceDll) }" ^ " if (-not (Test-Path $sourceDll)) { throw ('Deployment source file missing: ' + $sourceDll) }" ^
" Copy-Item $sourceDll $targetDir -Force;" ^ " Copy-Item $sourceDll $targetDir -Force;" ^
"}" ^ "}" ^
"foreach ($rootFileName in $deployRootFiles) {" ^
" $sourceRootFile = Join-Path $buildDir $rootFileName;" ^
" if (Test-Path $sourceRootFile) {" ^
" Copy-Item $sourceRootFile $targetDir -Force;" ^
" foreach ($locale in @('en-US','zh-CN')) {" ^
" $localeDir = Join-Path $targetDir $locale;" ^
" New-Item -ItemType Directory -Force -Path $localeDir | Out-Null;" ^
" Copy-Item $sourceRootFile $localeDir -Force;" ^
" }" ^
" }" ^
"}" ^
"if (Test-Path (Join-Path $buildDir 'resources')) {" ^ "if (Test-Path (Join-Path $buildDir 'resources')) {" ^
" New-Item -ItemType Directory -Force -Path (Join-Path $targetDir 'resources') | Out-Null;" ^ " New-Item -ItemType Directory -Force -Path (Join-Path $targetDir 'resources') | Out-Null;" ^
" Copy-Item (Join-Path $buildDir 'resources\\*') (Join-Path $targetDir 'resources') -Recurse -Force;" ^ " Copy-Item (Join-Path $buildDir 'resources\\*') (Join-Path $targetDir 'resources') -Recurse -Force;" ^
@ -70,6 +86,10 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"" ^ "" ^
"$sourceFiles = @();" ^ "$sourceFiles = @();" ^
"foreach ($dllName in $deployDllNames) { $sourceFiles += Get-Item (Join-Path $buildDir $dllName) }" ^ "foreach ($dllName in $deployDllNames) { $sourceFiles += Get-Item (Join-Path $buildDir $dllName) }" ^
"foreach ($rootFileName in $deployRootFiles) {" ^
" $sourceRootFile = Join-Path $buildDir $rootFileName;" ^
" if (Test-Path $sourceRootFile) { $sourceFiles += Get-Item $sourceRootFile }" ^
"}" ^
"if (Test-Path (Join-Path $buildDir 'resources')) {" ^ "if (Test-Path (Join-Path $buildDir 'resources')) {" ^
" $sourceFiles += Get-ChildItem (Join-Path $buildDir 'resources') -File;" ^ " $sourceFiles += Get-ChildItem (Join-Path $buildDir 'resources') -File;" ^
"}" ^ "}" ^
@ -82,6 +102,17 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command ^
" throw ('Deployment verification failed for ' + $sourceFile.Name + ': source=' + $sourceFile.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff') + ' (' + $sourceFile.Length + '), target=' + $targetInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff') + ' (' + $targetInfo.Length + ')');" ^ " throw ('Deployment verification failed for ' + $sourceFile.Name + ': source=' + $sourceFile.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff') + ' (' + $sourceFile.Length + '), target=' + $targetInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff') + ' (' + $targetInfo.Length + ')');" ^
" }" ^ " }" ^
" Write-Host ('Verified ' + $sourceFile.Name + ': ' + $targetInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff'));" ^ " Write-Host ('Verified ' + $sourceFile.Name + ': ' + $targetInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff'));" ^
" if ($deployRootFiles -contains $sourceFile.Name) {" ^
" foreach ($locale in @('en-US','zh-CN')) {" ^
" $localeTargetFile = Join-Path (Join-Path $targetDir $locale) $sourceFile.Name;" ^
" if (-not (Test-Path $localeTargetFile)) { throw ('Deployment verification failed: missing locale target file ' + $localeTargetFile) }" ^
" $localeTargetInfo = Get-Item $localeTargetFile;" ^
" if ($sourceFile.Length -ne $localeTargetInfo.Length -or $sourceFile.LastWriteTime -ne $localeTargetInfo.LastWriteTime) {" ^
" throw ('Deployment verification failed for locale copy ' + $localeTargetFile);" ^
" }" ^
" Write-Host ('Verified ' + $locale + '\\' + $sourceFile.Name + ': ' + $localeTargetInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss.fff'));" ^
" }" ^
" }" ^
"}" ^ "}" ^
"" ^ "" ^
"Write-Host 'Plugin deployed successfully!';" "Write-Host 'Plugin deployed successfully!';"

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RibbonControl
xmlns="clr-namespace:Autodesk.Windows;assembly=AdWindows"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Autodesk.Navisworks.Gui.Roamer.AIRLook;assembly=navisworks.gui.roamer">
<RibbonTab x:Uid="RibbonTab_Transport" Id="ID_TransportTab" Title="物流路径规划" KeyTip="WL">
<RibbonPanel x:Uid="RibbonPanel_TransportMain">
<RibbonPanelSource x:Uid="RibbonPanelSource_TransportMain" Title="物流路径规划" KeyTip="G">
<local:NWRibbonButton
x:Uid="RibbonButton_OpenLogisticsPanel"
Id="OpenLogisticsPanel"
Orientation="Vertical"
Size="Large"
ShowText="True"
Text="物流路径&#xA;规划"
ToolTip="打开物流路径规划面板"
Image="TransportRibbon_16.png"
LargeImage="TransportRibbon_32.png"
KeyTip="P" />
</RibbonPanelSource>
</RibbonPanel>
</RibbonTab>
</RibbonControl>

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,79 @@
using System;
using Autodesk.Navisworks.Api.Plugins;
using NavisworksTransport.Utils;
namespace NavisworksTransport.Commands
{
[Plugin("TransportRibbonHandler", "NavisworksTransport",
DisplayName = "物流路径规划工具栏",
ToolTip = "物流路径规划工具栏命令")]
[RibbonLayout("TransportRibbon.xaml")]
[RibbonTab("ID_TransportTab", DisplayName = "物流路径规划")]
[Command("OpenLogisticsPanel",
DisplayName = "物流路径规划",
ToolTip = "打开物流路径规划面板",
LoadForCanExecute = true)]
public class TransportRibbonHandler : CommandHandlerPlugin
{
private const string MainDockPanePluginKey = "NavisworksTransport.Main.Tian";
private const string OpenLogisticsPanelCommandId = "OpenLogisticsPanel";
private const string TransportRibbonTabId = "ID_TransportTab";
public override int ExecuteCommand(string commandId, params string[] parameters)
{
try
{
if (!string.Equals(commandId, OpenLogisticsPanelCommandId, StringComparison.OrdinalIgnoreCase))
{
LogManager.Warning($"[Ribbon] 未知命令: {commandId}");
return 1;
}
var pluginRecord = Autodesk.Navisworks.Api.Application.Plugins.FindPlugin(MainDockPanePluginKey) as DockPanePluginRecord;
if (pluginRecord == null)
{
throw new InvalidOperationException($"未找到物流路径规划面板插件: {MainDockPanePluginKey}");
}
var dockPane = pluginRecord.LoadPlugin() as DockPanePlugin;
if (dockPane == null)
{
throw new InvalidOperationException("物流路径规划面板加载失败");
}
dockPane.Visible = true;
dockPane.ActivatePane();
LogManager.Info("[Ribbon] 已通过正式工具栏打开物流路径规划面板");
return 0;
}
catch (Exception ex)
{
LogManager.Error($"[Ribbon] 执行命令失败: {ex.Message}", ex);
return 1;
}
}
public override CommandState CanExecuteCommand(string commandId)
{
if (string.Equals(commandId, OpenLogisticsPanelCommandId, StringComparison.OrdinalIgnoreCase))
{
return new CommandState
{
IsEnabled = true,
IsVisible = true
};
}
return new CommandState
{
IsEnabled = false,
IsVisible = false
};
}
public override bool CanExecuteRibbonTab(string ribbonTabId)
{
return string.Equals(ribbonTabId, TransportRibbonTabId, StringComparison.OrdinalIgnoreCase);
}
}
}