#调整页面布局,新增操作 Tab; 图像算子改为Tab页选择;

This commit is contained in:
zhengxuan.zhang
2026-04-30 13:56:35 +08:00
parent 822d31665d
commit fd9784ecb6
14 changed files with 434 additions and 284 deletions
+1
View File
@@ -63,3 +63,4 @@ ExternalLibraries/Models/
XplorePlane/Tests/ XplorePlane/Tests/
ExternalLibraries/Telerik/ ExternalLibraries/Telerik/
build_out.txt build_out.txt
XplorePlane/data/
@@ -1705,10 +1705,7 @@
"Telerik.UI.for.Wpf.NetCore.Xaml": "2024.1.408" "Telerik.UI.for.Wpf.NetCore.Xaml": "2024.1.408"
}, },
"runtime": { "runtime": {
"XP.Common.dll": { "XP.Common.dll": {}
"assemblyVersion": "1.4.16.1",
"fileVersion": "1.4.16.1"
}
}, },
"resources": { "resources": {
"en-US/XP.Common.resources.dll": { "en-US/XP.Common.resources.dll": {
@@ -10,7 +10,9 @@ using Moq;
using XP.Common.Logging.Interfaces; using XP.Common.Logging.Interfaces;
using XplorePlane.Models; using XplorePlane.Models;
using XplorePlane.Services.Cnc; using XplorePlane.Services.Cnc;
using XplorePlane.Services;
using XplorePlane.Services.InspectionResults; using XplorePlane.Services.InspectionResults;
using XplorePlane.Services.MainViewport;
using Xunit; using Xunit;
namespace XplorePlane.Tests.Services namespace XplorePlane.Tests.Services
@@ -175,6 +177,9 @@ internal sealed class SynchronousProgress<T> : IProgress<T>
{ {
var mockStore = new Mock<IInspectionResultStore>(); var mockStore = new Mock<IInspectionResultStore>();
var mockLogger = new Mock<ILoggerService>(); var mockLogger = new Mock<ILoggerService>();
var mockMainViewportService = new Mock<IMainViewportService>();
var mockPipelineExecutionService = new Mock<IPipelineExecutionService>();
var mockImageProcessingService = new Mock<IImageProcessingService>();
mockLogger.Setup(l => l.ForModule<CncExecutionService>()).Returns(mockLogger.Object); mockLogger.Setup(l => l.ForModule<CncExecutionService>()).Returns(mockLogger.Object);
mockStore.Setup(s => s.BeginRunAsync( mockStore.Setup(s => s.BeginRunAsync(
@@ -195,7 +200,12 @@ internal sealed class SynchronousProgress<T> : IProgress<T>
It.IsAny<DateTime?>())) It.IsAny<DateTime?>()))
.Returns(Task.CompletedTask); .Returns(Task.CompletedTask);
var service = new CncExecutionService(mockStore.Object, mockLogger.Object); var service = new CncExecutionService(
mockStore.Object,
mockLogger.Object,
mockMainViewportService.Object,
mockPipelineExecutionService.Object,
mockImageProcessingService.Object);
return (service, mockStore, mockLogger); return (service, mockStore, mockLogger);
} }
+1 -1
View File
@@ -369,7 +369,7 @@ namespace XplorePlane
// 注册图像处理服务与视图 // 注册图像处理服务与视图
containerRegistry.RegisterSingleton<IImageProcessingService, ImageProcessingService>(); containerRegistry.RegisterSingleton<IImageProcessingService, ImageProcessingService>();
containerRegistry.Register<ImageProcessingViewModel>(); containerRegistry.Register<ImageProcessingViewModel>();
containerRegistry.RegisterForNavigation<ImageProcessingPanelView>();
// 注册流水线服务(单例,共享 IImageProcessingService // 注册流水线服务(单例,共享 IImageProcessingService
containerRegistry.RegisterSingleton<IPipelineExecutionService, PipelineExecutionService>(); containerRegistry.RegisterSingleton<IPipelineExecutionService, PipelineExecutionService>();
+21 -52
View File
@@ -6,7 +6,6 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using XP.Common.GeneralForm.Views;
using XP.Common.Logging.Interfaces; using XP.Common.Logging.Interfaces;
using XplorePlane.Models; using XplorePlane.Models;
using XplorePlane.Services.InspectionResults; using XplorePlane.Services.InspectionResults;
@@ -42,7 +41,7 @@ namespace XplorePlane.Services.Cnc
public async Task ExecuteAsync(CncProgram program, IProgress<CncNodeExecutionProgress> progress, CancellationToken cancellationToken) public async Task ExecuteAsync(CncProgram program, IProgress<CncNodeExecutionProgress> progress, CancellationToken cancellationToken)
{ {
// Pre-cancellation check do NOT call BeginRunAsync if already cancelled // Pre-cancellation check - do NOT call BeginRunAsync if already cancelled
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
return; return;
@@ -150,7 +149,10 @@ namespace XplorePlane.Services.Cnc
{ {
_logger.ForModule<CncExecutionService>().Error(ex, _logger.ForModule<CncExecutionService>().Error(ex,
"Unexpected error executing node '{0}' (Id={1})", node.Name, node.Id); "Unexpected error executing node '{0}' (Id={1})", node.Name, node.Id);
nodeSucceeded = false; if (cancellationToken.IsCancellationRequested)
cancelled = true;
else
nodeSucceeded = false;
} }
if (cancelled) if (cancelled)
@@ -160,7 +162,7 @@ namespace XplorePlane.Services.Cnc
} }
// InspectionModuleNode 完成时携带结果图像,供 ViewModel 缓存到节点上 // InspectionModuleNode 完成时携带结果图像,供 ViewModel 缓存到节点上
var nodeResultImage = (node is InspectionModuleNode) ? lastResultImage : null; var nodeResultImage = node is InspectionModuleNode ? lastResultImage : null;
var finalState = nodeSucceeded ? NodeExecutionState.Succeeded : NodeExecutionState.Failed; var finalState = nodeSucceeded ? NodeExecutionState.Succeeded : NodeExecutionState.Failed;
progress?.Report(new CncNodeExecutionProgress(node.Id, finalState, nodeResultImage)); progress?.Report(new CncNodeExecutionProgress(node.Id, finalState, nodeResultImage));
@@ -168,7 +170,7 @@ namespace XplorePlane.Services.Cnc
allSucceeded = false; allSucceeded = false;
} }
endLoop: endLoop:
bool? overallPass = cancelled ? null : (bool?)allSucceeded; bool? overallPass = cancelled ? null : (bool?)allSucceeded;
@@ -211,10 +213,8 @@ namespace XplorePlane.Services.Cnc
}; };
} }
// 构建资产列表
var assets = new System.Collections.Generic.List<InspectionAssetWriteRequest>(); var assets = new System.Collections.Generic.List<InspectionAssetWriteRequest>();
// input.bmp — 当前源图像
if (sourceImage != null) if (sourceImage != null)
{ {
assets.Add(new InspectionAssetWriteRequest assets.Add(new InspectionAssetWriteRequest
@@ -227,7 +227,6 @@ namespace XplorePlane.Services.Cnc
}); });
} }
// result_overlay.bmp — 执行流水线后的结果图像
BitmapSource resultImage = null; BitmapSource resultImage = null;
if (_pipelineExecutionService != null && inspectionNode.Pipeline?.Nodes?.Count > 0 && sourceImage != null) if (_pipelineExecutionService != null && inspectionNode.Pipeline?.Nodes?.Count > 0 && sourceImage != null)
{ {
@@ -248,8 +247,6 @@ namespace XplorePlane.Services.Cnc
Height = resultImage.PixelHeight Height = resultImage.PixelHeight
}); });
nodeResult.Status = InspectionNodeStatus.Succeeded; nodeResult.Status = InspectionNodeStatus.Succeeded;
// 执行完立即更新主视口
_mainViewportService?.SetManualImage(resultImage, $"CNC节点:{inspectionNode.Name}"); _mainViewportService?.SetManualImage(resultImage, $"CNC节点:{inspectionNode.Name}");
} }
} }
@@ -265,21 +262,20 @@ namespace XplorePlane.Services.Cnc
return resultImage; return resultImage;
} }
private System.Collections.Generic.IEnumerable<ViewModels.PipelineNodeViewModel> BuildPipelineNodeViewModels(PipelineModel pipeline) private System.Collections.Generic.IEnumerable<PipelineNodeViewModel> BuildPipelineNodeViewModels(PipelineModel pipeline)
{ {
var nodes = new System.Collections.Generic.List<ViewModels.PipelineNodeViewModel>(); var nodes = new System.Collections.Generic.List<PipelineNodeViewModel>();
if (pipeline?.Nodes == null) return nodes; if (pipeline?.Nodes == null) return nodes;
foreach (var nodeModel in pipeline.Nodes.OrderBy(n => n.Order)) foreach (var nodeModel in pipeline.Nodes.OrderBy(n => n.Order))
{ {
var displayName = _imageProcessingService?.GetProcessorDisplayName(nodeModel.OperatorKey) ?? nodeModel.OperatorKey; var displayName = _imageProcessingService?.GetProcessorDisplayName(nodeModel.OperatorKey) ?? nodeModel.OperatorKey;
var vm = new ViewModels.PipelineNodeViewModel(nodeModel.OperatorKey, displayName, string.Empty) var vm = new PipelineNodeViewModel(nodeModel.OperatorKey, displayName, string.Empty)
{ {
Order = nodeModel.Order, Order = nodeModel.Order,
IsEnabled = nodeModel.IsEnabled IsEnabled = nodeModel.IsEnabled
}; };
// 加载参数定义并恢复保存的值
if (_imageProcessingService != null) if (_imageProcessingService != null)
{ {
var paramDefs = _imageProcessingService.GetProcessorParameters(nodeModel.OperatorKey); var paramDefs = _imageProcessingService.GetProcessorParameters(nodeModel.OperatorKey);
@@ -287,7 +283,7 @@ namespace XplorePlane.Services.Cnc
{ {
foreach (var def in paramDefs) foreach (var def in paramDefs)
{ {
var paramVm = new ViewModels.ProcessorParameterVM(def); var paramVm = new ProcessorParameterVM(def);
if (nodeModel.Parameters != null && nodeModel.Parameters.TryGetValue(def.Name, out var saved)) if (nodeModel.Parameters != null && nodeModel.Parameters.TryGetValue(def.Name, out var saved))
paramVm.Value = ConvertSavedValue(saved, def.ValueType); paramVm.Value = ConvertSavedValue(saved, def.ValueType);
vm.Parameters.Add(paramVm); vm.Parameters.Add(paramVm);
@@ -300,19 +296,16 @@ namespace XplorePlane.Services.Cnc
return nodes; return nodes;
} }
/// <summary>
/// 将 JSON 反序列化后的 JsonElement 转换为参数所需的实际类型。
/// </summary>
private static object ConvertSavedValue(object savedValue, Type targetType) private static object ConvertSavedValue(object savedValue, Type targetType)
{ {
if (savedValue is not System.Text.Json.JsonElement jsonElement) if (savedValue is not JsonElement jsonElement)
return savedValue; return savedValue;
try try
{ {
if (targetType == typeof(int)) return jsonElement.GetInt32(); if (targetType == typeof(int)) return jsonElement.GetInt32();
if (targetType == typeof(double)) return jsonElement.GetDouble(); if (targetType == typeof(double)) return jsonElement.GetDouble();
if (targetType == typeof(bool)) return jsonElement.GetBoolean(); if (targetType == typeof(bool)) return jsonElement.GetBoolean();
if (targetType == typeof(string)) return jsonElement.GetString() ?? string.Empty; if (targetType == typeof(string)) return jsonElement.GetString() ?? string.Empty;
return jsonElement.ToString(); return jsonElement.ToString();
} }
@@ -338,40 +331,16 @@ namespace XplorePlane.Services.Cnc
return; return;
const int tickMs = 50; const int tickMs = 50;
ProgressWindow progressWindow = null;
await Application.Current.Dispatcher.InvokeAsync(() => int elapsed = 0;
while (elapsed < totalMs)
{ {
progressWindow = new ProgressWindow( cancellationToken.ThrowIfCancellationRequested();
title: "延时等待",
message: $"节点:{waitNode.Name} 等待 {totalMs / 1000.0:F1} 秒",
isCancelable: false);
progressWindow.Owner = Application.Current.MainWindow;
progressWindow.Show();
});
try int remaining = totalMs - elapsed;
{ int delay = Math.Min(tickMs, remaining);
int elapsed = 0; await Task.Delay(delay, cancellationToken);
while (elapsed < totalMs) elapsed += delay;
{
cancellationToken.ThrowIfCancellationRequested();
int remaining = totalMs - elapsed;
int delay = Math.Min(tickMs, remaining);
await Task.Delay(delay, cancellationToken);
elapsed += delay;
double pct = Math.Min(100.0 * elapsed / totalMs, 100.0);
double remainSec = Math.Max(0, (totalMs - elapsed) / 1000.0);
string msg = $"节点:{waitNode.Name} 剩余 {remainSec:F1} 秒";
progressWindow?.UpdateProgress(msg, pct);
}
}
finally
{
progressWindow?.Close();
} }
} }
} }
+2 -2
View File
@@ -23,7 +23,7 @@ namespace XplorePlane.ViewModels
{ {
public class MainViewModel : BindableBase public class MainViewModel : BindableBase
{ {
private const double CncEditorHostWidth = 502d; private const double CncEditorHostWidth = 402d;
private readonly ILoggerService _logger; private readonly ILoggerService _logger;
private readonly IContainerProvider _containerProvider; private readonly IContainerProvider _containerProvider;
@@ -203,7 +203,7 @@ namespace XplorePlane.ViewModels
ClearCommand = new DelegateCommand(OnClear); ClearCommand = new DelegateCommand(OnClear);
EditPropertiesCommand = new DelegateCommand(OnEditProperties); EditPropertiesCommand = new DelegateCommand(OnEditProperties);
OpenImageProcessingCommand = new DelegateCommand(() => ShowWindow(new Views.ImageProcessingWindow(), "图像处理"));
LoadImageCommand = new DelegateCommand(ExecuteLoadImage); LoadImageCommand = new DelegateCommand(ExecuteLoadImage);
OpenPipelineEditorCommand = new DelegateCommand(() => ShowWindow(new Views.PipelineEditorWindow(), "流水线编辑器")); OpenPipelineEditorCommand = new DelegateCommand(() => ShowWindow(new Views.PipelineEditorWindow(), "流水线编辑器"));
OpenCncEditorCommand = new DelegateCommand(ExecuteOpenCncEditor); OpenCncEditorCommand = new DelegateCommand(ExecuteOpenCncEditor);
+3 -3
View File
@@ -10,7 +10,7 @@
xmlns:views="clr-namespace:XplorePlane.Views" xmlns:views="clr-namespace:XplorePlane.Views"
xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc" xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc"
d:DesignHeight="760" d:DesignHeight="760"
d:DesignWidth="502" d:DesignWidth="402"
prism:ViewModelLocator.AutoWireViewModel="True" prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"> mc:Ignorable="d">
@@ -99,8 +99,8 @@
</UserControl.Resources> </UserControl.Resources>
<Border <Border
Width="502" Width="402"
MinWidth="502" MinWidth="402"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Background="{StaticResource PanelBg}" Background="{StaticResource PanelBg}"
BorderBrush="{StaticResource PanelBorder}" BorderBrush="{StaticResource PanelBorder}"
@@ -4,22 +4,29 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/" xmlns:prism="http://prismlibrary.com/"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
prism:ViewModelLocator.AutoWireViewModel="True" prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="280"> d:DesignHeight="600"
d:DesignWidth="500">
<UserControl.Resources> <UserControl.Resources>
<SolidColorBrush x:Key="PanelBg" Color="White" /> <SolidColorBrush x:Key="PanelBg" Color="White" />
<SolidColorBrush x:Key="PanelBorder" Color="#cdcbcb" /> <SolidColorBrush x:Key="PanelBorder" Color="#cdcbcb" />
<SolidColorBrush x:Key="CategoryBg" Color="#F5F7FA" />
<SolidColorBrush x:Key="HoverBg" Color="#E8F0FE" /> <SolidColorBrush x:Key="HoverBg" Color="#E8F0FE" />
<FontFamily x:Key="CsdFont">Microsoft YaHei UI</FontFamily> <FontFamily x:Key="CsdFont">Microsoft YaHei UI</FontFamily>
<Style x:Key="OperatorToolboxTabItemStyle" TargetType="TabItem">
<Setter Property="Padding" Value="10,5" />
<Setter Property="Margin" Value="0,0,4,0" />
<Setter Property="FontFamily" Value="{StaticResource CsdFont}" />
<Setter Property="FontSize" Value="11" />
</Style>
</UserControl.Resources> </UserControl.Resources>
<Border Background="{StaticResource PanelBg}" <Border Background="{StaticResource PanelBg}"
BorderBrush="{StaticResource PanelBorder}" BorderBrush="{StaticResource PanelBorder}"
BorderThickness="1" CornerRadius="4"> BorderThickness="1"
CornerRadius="4">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@@ -27,14 +34,24 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- 标题(支持无边框窗口拖拽) --> <Border x:Name="TitleBar"
<Border x:Name="TitleBar" Grid.Row="0" Background="#0060A0" Padding="10,8"> Grid.Row="0"
Background="#0060A0"
Padding="10,8">
<Grid> <Grid>
<TextBlock Text="🧰 算子工具箱" FontFamily="{StaticResource CsdFont}" <TextBlock Text="算子工具箱"
FontWeight="Bold" FontSize="13" Foreground="White" FontFamily="{StaticResource CsdFont}"
FontWeight="Bold"
FontSize="13"
Foreground="White"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<Button x:Name="CloseBtn" HorizontalAlignment="Right" VerticalAlignment="Center" <Button x:Name="CloseBtn"
Content="✕" FontSize="12" Foreground="White" Cursor="Hand" HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="×"
FontSize="12"
Foreground="White"
Cursor="Hand"
Visibility="Collapsed" Visibility="Collapsed"
ToolTip="关闭"> ToolTip="关闭">
<Button.Style> <Button.Style>
@@ -46,7 +63,8 @@
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Button"> <ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
CornerRadius="3" Padding="{TemplateBinding Padding}"> CornerRadius="3"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" <ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</Border> </Border>
@@ -64,76 +82,61 @@
</Grid> </Grid>
</Border> </Border>
<!-- 搜索框 --> <Border Grid.Row="1"
<Border Grid.Row="1" Padding="8,6" BorderBrush="{StaticResource PanelBorder}" Padding="8,6"
BorderBrush="{StaticResource PanelBorder}"
BorderThickness="0,0,0,1"> BorderThickness="0,0,0,1">
<TextBox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" <TextBox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
FontFamily="{StaticResource CsdFont}" FontSize="11" FontFamily="{StaticResource CsdFont}"
Padding="6,4" BorderBrush="#cdcbcb" BorderThickness="1" FontSize="11"
ToolTip="输入关键字搜索算子"> Padding="6,4"
<TextBox.Style> BorderBrush="#cdcbcb"
<Style TargetType="TextBox"> BorderThickness="1"
<Style.Triggers> ToolTip="输入关键字搜索算子" />
<Trigger Property="Text" Value="">
<Setter Property="Background">
<Setter.Value>
<VisualBrush AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<TextBlock Text="🔍 搜索算子..." Foreground="#aaa"
FontFamily="Microsoft YaHei UI" FontSize="11"
Margin="4,0,0,0" />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Border> </Border>
<!-- 分组算子列表 --> <Grid Grid.Row="2">
<ScrollViewer x:Name="ToolboxListBox" Grid.Row="2" VerticalScrollBarVisibility="Auto"> <TabControl x:Name="ToolboxListBox"
<ItemsControl ItemsSource="{Binding FilteredGroups}"> Margin="8"
<ItemsControl.ItemTemplate> ItemContainerStyle="{StaticResource OperatorToolboxTabItemStyle}"
ItemsSource="{Binding FilteredGroups}">
<TabControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Margin="0,0,0,2"> <StackPanel Orientation="Horizontal">
<!-- 分类标题 --> <TextBlock Text="{Binding CategoryIcon}"
<Border Background="{StaticResource CategoryBg}" VerticalAlignment="Center" />
BorderBrush="{StaticResource PanelBorder}" <TextBlock Text="{Binding CategoryName}"
BorderThickness="0,0,0,1" Margin="5,0,0,0"
Padding="10,6"> VerticalAlignment="Center" />
<StackPanel Orientation="Horizontal"> </StackPanel>
<TextBlock Text="{Binding CategoryIcon}" FontSize="13" </DataTemplate>
VerticalAlignment="Center" Margin="0,0,6,0" /> </TabControl.ItemTemplate>
<TextBlock Text="{Binding CategoryName}" <TabControl.ContentTemplate>
FontFamily="Microsoft YaHei UI" <DataTemplate>
FontWeight="SemiBold" FontSize="12" <ScrollViewer VerticalScrollBarVisibility="Auto">
Foreground="#333" VerticalAlignment="Center" />
</StackPanel>
</Border>
<!-- 分类下的算子 -->
<ItemsControl ItemsSource="{Binding Operators}"> <ItemsControl ItemsSource="{Binding Operators}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<Border Padding="12,5,8,5" Cursor="Hand" <Border Padding="12,6,8,6"
Cursor="Hand"
Background="Transparent" Background="Transparent"
BorderBrush="Transparent" BorderBrush="#ECECEC"
BorderThickness="0,0,0,1"> BorderThickness="0,0,0,1">
<Border.Style> <Border.Style>
<Style TargetType="Border"> <Style TargetType="Border">
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E8F0FE" /> <Setter Property="Background" Value="{StaticResource HoverBg}" />
</Trigger> </Trigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Border.Style> </Border.Style>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Border Width="26" Height="26" <Border Width="28"
Height="28"
Background="#EEF2FF" Background="#EEF2FF"
CornerRadius="4" Margin="0,0,8,0"> CornerRadius="4"
Margin="0,0,8,0">
<TextBlock Text="{Binding IconPath}" <TextBlock Text="{Binding IconPath}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -154,11 +157,35 @@
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
</StackPanel> </ScrollViewer>
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </TabControl.ContentTemplate>
</ItemsControl> </TabControl>
</ScrollViewer>
<Border Margin="8"
Padding="18"
Background="#FAFAFA"
BorderBrush="#E6E6E6"
BorderThickness="1"
CornerRadius="6">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ToolboxListBox, Path=HasItems}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="没有匹配的算子"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{StaticResource CsdFont}"
FontSize="12"
Foreground="#666666" />
</Border>
</Grid>
</Grid> </Grid>
</Border> </Border>
</UserControl> </UserControl>
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:XplorePlane.Views" xmlns:views="clr-namespace:XplorePlane.Views"
Title="算子工具箱" Title="算子工具箱"
Width="260" Height="500" Width="560" Height="560"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
ShowInTaskbar="False" ShowInTaskbar="False"
WindowStyle="None" WindowStyle="None"
@@ -1,11 +1,12 @@
<UserControl <UserControl
x:Class="XplorePlane.Views.PipelineEditorView" x:Class="XplorePlane.Views.PipelineEditorView"
x:Name="RootControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="700" d:DesignHeight="700"
d:DesignWidth="350" d:DesignWidth="300"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
@@ -16,7 +17,7 @@
<SolidColorBrush x:Key="DisabledNodeBg" Color="#F3F3F3" /> <SolidColorBrush x:Key="DisabledNodeBg" Color="#F3F3F3" />
<SolidColorBrush x:Key="DisabledNodeLine" Color="#B9B9B9" /> <SolidColorBrush x:Key="DisabledNodeLine" Color="#B9B9B9" />
<SolidColorBrush x:Key="DisabledNodeText" Color="#8A8A8A" /> <SolidColorBrush x:Key="DisabledNodeText" Color="#8A8A8A" />
<FontFamily x:Key="CsdFont">Microsoft YaHei UI</FontFamily> <FontFamily x:Key="UiFont">Microsoft YaHei UI</FontFamily>
<Style x:Key="PipelineNodeItemStyle" TargetType="ListBoxItem"> <Style x:Key="PipelineNodeItemStyle" TargetType="ListBoxItem">
<Setter Property="Padding" Value="0" /> <Setter Property="Padding" Value="0" />
@@ -36,16 +37,24 @@
</Style> </Style>
<Style x:Key="ToolbarBtn" TargetType="Button"> <Style x:Key="ToolbarBtn" TargetType="Button">
<Setter Property="Width" Value="52" />
<Setter Property="Height" Value="28" /> <Setter Property="Height" Value="28" />
<Setter Property="MinWidth" Value="52" />
<Setter Property="Margin" Value="2,0" /> <Setter Property="Margin" Value="2,0" />
<Setter Property="Padding" Value="8,0" />
<Setter Property="Background" Value="Transparent" /> <Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="#CDCBCB" /> <Setter Property="BorderBrush" Value="#CDCBCB" />
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="1" />
<Setter Property="FontFamily" Value="Microsoft YaHei UI" /> <Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" /> <Setter Property="FontSize" Value="11" />
<Setter Property="Cursor" Value="Hand" /> <Setter Property="Cursor" Value="Hand" />
</Style> </Style>
<Style x:Key="OperatorPickerTabItemStyle" TargetType="TabItem">
<Setter Property="Padding" Value="12,6" />
<Setter Property="Margin" Value="0,0,4,0" />
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
</Style>
</UserControl.Resources> </UserControl.Resources>
<Border <Border
@@ -59,7 +68,6 @@
<RowDefinition Height="4*" MinHeight="180" /> <RowDefinition Height="4*" MinHeight="180" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="2*" MinHeight="80" /> <RowDefinition Height="2*" MinHeight="80" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Border <Border
@@ -73,37 +81,38 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel <StackPanel
Grid.Row="0" Grid.Row="0"
Orientation="Horizontal"> Orientation="Horizontal">
<Button <Button
Command="{Binding NewPipelineCommand}" Command="{Binding NewPipelineCommand}"
Content="新建" Content="新建"
Style="{StaticResource ToolbarBtn}" Style="{StaticResource ToolbarBtn}"
ToolTip="新建流水线" /> ToolTip="新建流水线" />
<Button <Button
Command="{Binding SavePipelineCommand}" Command="{Binding SavePipelineCommand}"
Content="保存" Content="保存"
Style="{StaticResource ToolbarBtn}" Style="{StaticResource ToolbarBtn}"
ToolTip="保存当前流水线" /> ToolTip="保存当前流水线" />
<Button <Button
Width="60" Width="64"
Command="{Binding SaveAsPipelineCommand}" Command="{Binding SaveAsPipelineCommand}"
Content="另存为" Content="另存为"
Style="{StaticResource ToolbarBtn}" Style="{StaticResource ToolbarBtn}"
ToolTip="另存当前流水线" /> ToolTip="另存当前流水线" />
<Button <Button
Width="52" Command="{Binding LoadPipelineCommand}"
Command="{Binding LoadPipelineCommand}" Content="加载"
Content="加载" Style="{StaticResource ToolbarBtn}"
Style="{StaticResource ToolbarBtn}" ToolTip="加载流水线" />
ToolTip="加载流水线" />
</StackPanel> </StackPanel>
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"
Margin="2,4,2,0" Margin="2,4,2,0"
VerticalAlignment="Center" VerticalAlignment="Center"
FontFamily="{StaticResource CsdFont}" FontFamily="{StaticResource UiFont}"
FontSize="11" FontSize="11"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="#333333" Foreground="#333333"
@@ -182,13 +191,13 @@
<StackPanel Grid.Column="1" Margin="6,0,0,0" VerticalAlignment="Center"> <StackPanel Grid.Column="1" Margin="6,0,0,0" VerticalAlignment="Center">
<TextBlock <TextBlock
x:Name="NodeTitle" x:Name="NodeTitle"
FontFamily="Microsoft YaHei UI" FontFamily="{StaticResource UiFont}"
FontSize="12" FontSize="12"
Text="{Binding DisplayName}" /> Text="{Binding DisplayName}" />
<TextBlock <TextBlock
x:Name="NodeState" x:Name="NodeState"
Margin="0,2,0,0" Margin="0,2,0,0"
FontFamily="Microsoft YaHei UI" FontFamily="{StaticResource UiFont}"
FontSize="10" FontSize="10"
Foreground="#6E6E6E" Foreground="#6E6E6E"
Text="已启用" /> Text="已启用" />
@@ -240,7 +249,7 @@
<StackPanel Margin="8,6"> <StackPanel Margin="8,6">
<TextBlock <TextBlock
Margin="0,0,0,4" Margin="0,0,0,4"
FontFamily="{StaticResource CsdFont}" FontFamily="{StaticResource UiFont}"
FontSize="11" FontSize="11"
FontWeight="Bold" FontWeight="Bold"
Foreground="#555" Foreground="#555"
@@ -263,25 +272,25 @@
<ColumnDefinition Width="100" /> <ColumnDefinition Width="100" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
FontFamily="Microsoft YaHei UI" FontFamily="{StaticResource UiFont}"
FontSize="11" FontSize="11"
Text="{Binding DisplayName}" Text="{Binding DisplayName}"
TextTrimming="CharacterEllipsis" /> TextTrimming="CharacterEllipsis" />
<TextBox <TextBox
x:Name="TextValueEditor"
Grid.Column="1" Grid.Column="1"
Padding="4,2" Padding="4,2"
BorderBrush="#CDCBCB" BorderBrush="#CDCBCB"
BorderThickness="1" BorderThickness="1"
FontFamily="Microsoft YaHei UI" FontFamily="{StaticResource UiFont}"
FontSize="11" FontSize="11"
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"> Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Style> <TextBox.Style>
<Style TargetType="TextBox"> <Style TargetType="TextBox">
<Setter Property="BorderBrush" Value="#CDCBCB" />
<Setter Property="Background" Value="White" /> <Setter Property="Background" Value="White" />
<Setter Property="Visibility" Value="Visible" /> <Setter Property="Visibility" Value="Visible" />
<Style.Triggers> <Style.Triggers>
@@ -295,13 +304,14 @@
</Style> </Style>
</TextBox.Style> </TextBox.Style>
</TextBox> </TextBox>
<ComboBox <ComboBox
Grid.Column="1" Grid.Column="1"
MinHeight="24" MinHeight="24"
Padding="4,1" Padding="4,1"
BorderBrush="#CDCBCB" BorderBrush="#CDCBCB"
BorderThickness="1" BorderThickness="1"
FontFamily="Microsoft YaHei UI" FontFamily="{StaticResource UiFont}"
FontSize="11" FontSize="11"
ItemsSource="{Binding Options}" ItemsSource="{Binding Options}"
SelectedItem="{Binding SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> SelectedItem="{Binding SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
@@ -316,10 +326,11 @@
</Style> </Style>
</ComboBox.Style> </ComboBox.Style>
</ComboBox> </ComboBox>
<CheckBox <CheckBox
Grid.Column="1" Grid.Column="1"
VerticalAlignment="Center" VerticalAlignment="Center"
FontFamily="Microsoft YaHei UI" FontFamily="{StaticResource UiFont}"
FontSize="11" FontSize="11"
IsChecked="{Binding BoolValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> IsChecked="{Binding BoolValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style> <CheckBox.Style>
@@ -340,41 +351,188 @@
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>
<Border <Grid
Grid.Row="4" x:Name="OperatorPickerOverlay"
Height="24" Grid.RowSpan="4"
Padding="6,0" Background="#66000000"
BorderThickness="0,1,0,0"> Panel.ZIndex="10"
<Border.Style> Visibility="Collapsed"
<Style TargetType="Border"> MouseDown="OnOperatorPickerBackdropMouseDown">
<Setter Property="Background" Value="#F5F5F5" /> <Border
<Setter Property="BorderBrush" Value="{StaticResource PanelBorder}" /> Width="560"
<Style.Triggers> MaxHeight="560"
<DataTrigger Binding="{Binding IsStatusError}" Value="True"> Background="White"
<Setter Property="Background" Value="#FFF1F1" /> BorderBrush="#CFCFCF"
<Setter Property="BorderBrush" Value="#D9534F" /> BorderThickness="1"
</DataTrigger> CornerRadius="8"
</Style.Triggers> MouseDown="OnOperatorPickerDialogMouseDown">
</Style> <Grid x:Name="OperatorPickerPanel">
</Border.Style> <Grid.RowDefinitions>
<TextBlock <RowDefinition Height="Auto" />
VerticalAlignment="Center" <RowDefinition Height="Auto" />
FontFamily="{StaticResource CsdFont}" <RowDefinition Height="*" />
FontSize="11" </Grid.RowDefinitions>
Text="{Binding StatusMessage, StringFormat='Status: {0}'}"
TextTrimming="CharacterEllipsis"> <Border
<TextBlock.Style> Grid.Row="0"
<Style TargetType="TextBlock"> Padding="14,10"
<Setter Property="Foreground" Value="#555" /> Background="#F6F8FB"
<Style.Triggers> BorderBrush="#E5E5E5"
<DataTrigger Binding="{Binding IsStatusError}" Value="True"> BorderThickness="0,0,0,1">
<Setter Property="Foreground" Value="#A12A2A" /> <DockPanel LastChildFill="False">
</DataTrigger> <StackPanel DockPanel.Dock="Left">
</Style.Triggers> <TextBlock
</Style> FontFamily="{StaticResource UiFont}"
</TextBlock.Style> FontSize="14"
</TextBlock> FontWeight="SemiBold"
</Border> Text="选择算子" />
<TextBlock
Margin="0,3,0,0"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Foreground="#666666"
Text="按类别切换 Tab,单击即可添加到当前流水线" />
</StackPanel>
<Button
Width="28"
Height="28"
Margin="8,0,0,0"
Click="OnCloseOperatorPickerClick"
Content="×"
Cursor="Hand"
DockPanel.Dock="Right"
FontSize="14" />
</DockPanel>
</Border>
<Border
Grid.Row="1"
Padding="14,10"
BorderBrush="#E5E5E5"
BorderThickness="0,0,0,1">
<TextBox
x:Name="OperatorSearchBox"
Padding="8,5"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
ToolTip="输入名称或分类过滤算子" />
</Border>
<Grid Grid.Row="2" Margin="14,10,14,14">
<TabControl
x:Name="OperatorCategoryTabs"
ItemContainerStyle="{StaticResource OperatorPickerTabItemStyle}"
ItemsSource="{Binding FilteredGroups}">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CategoryIcon}" />
<TextBlock Margin="6,0,0,0" Text="{Binding CategoryName}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Operators}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Margin="0,0,0,8"
Padding="10,8"
Background="White"
BorderBrush="#D8DDE6"
BorderThickness="1"
Click="OnOperatorPickerItemClick"
Cursor="Hand"
HorizontalContentAlignment="Stretch"
Tag="{Binding Key}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
x:Name="OperatorCard"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="6"
Padding="{TemplateBinding Padding}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="OperatorCard" Property="Background" Value="#EDF5FF" />
<Setter TargetName="OperatorCard" Property="BorderBrush" Value="#8EB8E8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<DockPanel LastChildFill="True">
<Border
Width="32"
Height="32"
Margin="0,0,10,0"
Background="#EEF4FF"
CornerRadius="5"
DockPanel.Dock="Left">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="15"
Text="{Binding IconPath}" />
</Border>
<StackPanel>
<TextBlock
FontFamily="{StaticResource UiFont}"
FontSize="12"
FontWeight="SemiBold"
Foreground="#1F1F1F"
Text="{Binding DisplayName}" />
<TextBlock
Margin="0,3,0,0"
FontFamily="Consolas"
FontSize="10"
Foreground="#7A7A7A"
Text="{Binding Key}" />
</StackPanel>
</DockPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
<Border
Padding="18"
Background="#FAFAFA"
BorderBrush="#E6E6E6"
BorderThickness="1"
CornerRadius="6">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=OperatorCategoryTabs, Path=HasItems}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{StaticResource UiFont}"
FontSize="12"
Foreground="#666666"
Text="没有匹配的算子" />
</Border>
</Grid>
</Grid>
</Border>
</Grid>
</Grid> </Grid>
</Border> </Border>
</UserControl> </UserControl>
@@ -10,21 +10,11 @@
ShowInTaskbar="False"> ShowInTaskbar="False">
<Grid Background="#F3F3F3"> <Grid Background="#F3F3F3">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="240" MinWidth="200" />
<ColumnDefinition Width="*" MinWidth="400" /> <ColumnDefinition Width="*" MinWidth="400" />
<ColumnDefinition Width="250" MinWidth="250" /> <ColumnDefinition Width="320" MinWidth="300" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border Grid.Column="0" <Border Grid.Column="0"
Margin="8"
Background="White"
BorderBrush="#D0D0D0"
BorderThickness="1"
CornerRadius="4">
<views:OperatorToolboxView />
</Border>
<Border Grid.Column="1"
Margin="8,8,4,8" Margin="8,8,4,8"
Background="White" Background="White"
BorderBrush="#D0D0D0" BorderBrush="#D0D0D0"
@@ -34,7 +24,7 @@
Background="White" /> Background="White" />
</Border> </Border>
<Border Grid.Column="2" <Border Grid.Column="1"
Margin="4,8,8,8" Margin="4,8,8,8"
Background="White" Background="White"
BorderBrush="#D0D0D0" BorderBrush="#D0D0D0"
+60 -68
View File
@@ -390,6 +390,10 @@
</telerik:RadRibbonGroup> </telerik:RadRibbonGroup>
</telerik:RadRibbonTab> </telerik:RadRibbonTab>
<telerik:RadRibbonTab Header="操作">
</telerik:RadRibbonTab>
<telerik:RadRibbonTab Header="设置"> <telerik:RadRibbonTab Header="设置">
<telerik:RadRibbonGroup <telerik:RadRibbonGroup
telerik:ScreenTip.Description="Show the Alignment tab of the Format Cells dialog box." telerik:ScreenTip.Description="Show the Alignment tab of the Format Cells dialog box."
@@ -407,22 +411,7 @@
<spreadsheetControls:RadVerticalAlignmentToBooleanConverter x:Key="verticalAlignmentToBooleanConverter" /> <spreadsheetControls:RadVerticalAlignmentToBooleanConverter x:Key="verticalAlignmentToBooleanConverter" />
</telerik:RadRibbonGroup.Resources> </telerik:RadRibbonGroup.Resources>
<StackPanel> <StackPanel/>
<telerik:RadRibbonToggleButton
telerik:ScreenTip.Description="暖机"
telerik:ScreenTip.Title="暖机"
Command="{Binding WarmUpCommand}"
Size="Medium"
SmallImage="/Assets/Icons/heat-engine.png"
Text="暖机" />
<telerik:RadRibbonToggleButton
telerik:ScreenTip.Description="轴复位"
telerik:ScreenTip.Title="轴复位"
Command="{Binding AxisResetCommand}"
Size="Medium"
SmallImage="/Assets/Icons/home.png"
Text="轴复位" />
</StackPanel>
<StackPanel> <StackPanel>
<telerik:RadRibbonToggleButton <telerik:RadRibbonToggleButton
@@ -433,56 +422,67 @@
SmallImage="/Assets/Icons/xray.png" SmallImage="/Assets/Icons/xray.png"
Text="射线源" /> Text="射线源" />
<telerik:RadRibbonToggleButton <telerik:RadRibbonToggleButton
telerik:ScreenTip.Description="探测器控制" telerik:ScreenTip.Description="探测器控制"
telerik:ScreenTip.Title="探测器" telerik:ScreenTip.Title="探测器"
Command="{Binding OpenDetectorConfigCommand}" Command="{Binding OpenDetectorConfigCommand}"
Size="Medium" Size="Medium"
SmallImage="/Assets/Icons/detector2.png" SmallImage="/Assets/Icons/detector2.png"
Text="探测器" /> Text="探测器" />
<telerik:RadRibbonToggleButton <telerik:RadRibbonToggleButton
telerik:ScreenTip.Description="运动控制" telerik:ScreenTip.Description="运动控制"
telerik:ScreenTip.Title="运动控制" telerik:ScreenTip.Title="运动控制"
Command="{Binding OpenMotionDebugCommand}" Command="{Binding OpenMotionDebugCommand}"
Size="Medium" Size="Medium"
SmallImage="/Assets/Icons/xyz.png" SmallImage="/Assets/Icons/xyz.png"
Text="运动控制" /> Text="运动控制" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<telerik:RadRibbonButton <telerik:RadRibbonButton
telerik:ScreenTip.Description="打开相机参数设置窗口" telerik:ScreenTip.Description="打开相机参数设置窗口"
telerik:ScreenTip.Title="相机设置" telerik:ScreenTip.Title="相机设置"
Command="{Binding OpenCameraSettingsCommand}" Command="{Binding OpenCameraSettingsCommand}"
Size="Medium" Size="Medium"
SmallImage="/Assets/Icons/detector2.png" SmallImage="/Assets/Icons/detector2.png"
Text="相机设置" /> Text="相机设置" />
<telerik:RadRibbonButton <telerik:RadRibbonButton
telerik:ScreenTip.Description="打开 PLC 地址配置窗口" telerik:ScreenTip.Description="打开 PLC 地址配置窗口"
telerik:ScreenTip.Title="PLC 地址配置" telerik:ScreenTip.Title="PLC 地址配置"
Command="{Binding OpenPlcAddrConfigCommand}" Command="{Binding OpenPlcAddrConfigCommand}"
Size="Medium" Size="Medium"
SmallImage="/Assets/Icons/tools.png" SmallImage="/Assets/Icons/tools.png"
Text="PLC 地址" /> Text="PLC 地址" />
</StackPanel> </StackPanel>
</telerik:RadRibbonGroup> </telerik:RadRibbonGroup>
<telerik:RadRibbonGroup Header="多语言"> <telerik:RadRibbonGroup Header="多语言">
<telerik:RadRibbonGroup.Variants> <telerik:RadRibbonGroup.Variants>
<telerik:GroupVariant Priority="0" Variant="Large" /> <telerik:GroupVariant Priority="0" Variant="Large" />
</telerik:RadRibbonGroup.Variants> </telerik:RadRibbonGroup.Variants>
<telerik:RadRibbonButton <telerik:RadRibbonButton
telerik:ScreenTip.Description="切换应用程序显示语言" telerik:ScreenTip.Description="切换应用程序显示语言"
telerik:ScreenTip.Title="多语言设置" telerik:ScreenTip.Title="多语言设置"
Size="Large" Size="Large"
SmallImage="/Assets/Icons/tools.png" SmallImage="/Assets/Icons/tools.png"
Command="{Binding OpenLanguageSwitcherCommand}" Command="{Binding OpenLanguageSwitcherCommand}"
Text="语言设置" /> Text="语言设置" />
</telerik:RadRibbonGroup>
<telerik:RadRibbonGroup Header="日志">
<telerik:RadRibbonGroup.Variants>
<telerik:GroupVariant Priority="0" Variant="Large" />
</telerik:RadRibbonGroup.Variants>
<telerik:RadRibbonButton <telerik:RadRibbonButton
telerik:ScreenTip.Description="打开实时日志查看器" telerik:ScreenTip.Description="打开实时日志查看器"
telerik:ScreenTip.Title="查看日志" telerik:ScreenTip.Title="查看日志"
Size="Large" Size="Large"
SmallImage="/Assets/Icons/message.png" SmallImage="/Assets/Icons/message.png"
Command="{Binding OpenRealTimeLogViewerCommand}" Command="{Binding OpenRealTimeLogViewerCommand}"
Text="查看日志" /> Text="查看日志" />
</telerik:RadRibbonGroup> </telerik:RadRibbonGroup>
</telerik:RadRibbonTab> </telerik:RadRibbonTab>
<telerik:RadRibbonTab Header="关于"> <telerik:RadRibbonTab Header="关于">
@@ -493,26 +493,18 @@
<telerik:RadRibbonButton <telerik:RadRibbonButton
Size="Large" Size="Large"
SmallImage="/Assets/Icons/message.png" SmallImage="/Assets/Icons/message.png"
Command="{Binding OpenUserManualCommand}" Command="{Binding OpenUserManualCommand}"
Text="帮助文档" /> Text="帮助文档" />
<telerik:RadRibbonButton <telerik:RadRibbonButton
Size="Large" Size="Large"
SmallImage="/Assets/Icons/tools.png" SmallImage="/Assets/Icons/tools.png"
Command="{Binding OpenLibraryVersionsCommand}" Command="{Binding OpenLibraryVersionsCommand}"
Text="关于" /> Text="关于" />
</telerik:RadRibbonGroup> </telerik:RadRibbonGroup>
</telerik:RadRibbonTab> </telerik:RadRibbonTab>
<telerik:RadRibbonView.ContextualGroups>
<telerik:RadRibbonContextualGroup
x:Name="PictureTools"
Header="Picture Tools"
IsActive="{Binding Path=PictureToolsTab.IsEnabled, Mode=OneWay}" />
</telerik:RadRibbonView.ContextualGroups>
</telerik:RadRibbonView> </telerik:RadRibbonView>
<Grid <Grid
@@ -26,7 +26,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="#333333" Foreground="#333333"
Text="相机预览" /> Text="导航" />
</Border> </Border>
<!-- 相机图像显示区域 --> <!-- 相机图像显示区域 -->
+6
View File
@@ -15,7 +15,10 @@
<ItemGroup> <ItemGroup>
<Page Remove="MainWindow.xaml" /> <Page Remove="MainWindow.xaml" />
<Page Remove="Views\ImageProcessing\ImageProcessingPanelView.xaml" />
<Page Remove="Views\ImageProcessing\ImageProcessingWindow.xaml" />
<Page Remove="Views\Main\MainWindowB.xaml" /> <Page Remove="Views\Main\MainWindowB.xaml" />
<Page Remove="Views\Main\NavigationPanelView.xaml" />
</ItemGroup> </ItemGroup>
<!-- NuGet 包引用 --> <!-- NuGet 包引用 -->
@@ -146,7 +149,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>Libs\Hardware\zh-TW\%(Filename)%(Extension)</Link> <Link>Libs\Hardware\zh-TW\%(Filename)%(Extension)</Link>
</None> </None>
<Compile Remove="Views\ImageProcessing\ImageProcessingPanelView.xaml.cs" />
<Compile Remove="Views\ImageProcessing\ImageProcessingWindow.xaml.cs" />
<Compile Remove="Views\Main\MainWindowB.xaml.cs" /> <Compile Remove="Views\Main\MainWindowB.xaml.cs" />
<Compile Remove="Views\Main\NavigationPanelView.xaml.cs" />
<Content Include="XplorerPlane.ico"> <Content Include="XplorerPlane.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>