显示xmp文件名;取消实时图像底部栏

This commit is contained in:
zhengxuan.zhang
2026-04-23 17:29:25 +08:00
parent 92ece60c01
commit 24e0489cde
6 changed files with 86 additions and 12 deletions
@@ -26,6 +26,7 @@ namespace XplorePlane.ViewModels.Cnc
private CncNodeViewModel _activeModuleNode; private CncNodeViewModel _activeModuleNode;
private PipelineNodeViewModel _selectedNode; private PipelineNodeViewModel _selectedNode;
private string _statusMessage = "请选择检测模块以编辑其流水线。"; private string _statusMessage = "请选择检测模块以编辑其流水线。";
private string _pipelineFileDisplayName = "未命名模块.xpm";
private string _currentFilePath; private string _currentFilePath;
private bool _isSynchronizing; private bool _isSynchronizing;
@@ -71,6 +72,14 @@ namespace XplorePlane.ViewModels.Cnc
private set => SetProperty(ref _statusMessage, value); private set => SetProperty(ref _statusMessage, value);
} }
public bool IsStatusError => false;
public string PipelineFileDisplayName
{
get => _pipelineFileDisplayName;
private set => SetProperty(ref _pipelineFileDisplayName, value);
}
public bool HasActiveModule => _activeModuleNode?.IsInspectionModule == true; public bool HasActiveModule => _activeModuleNode?.IsInspectionModule == true;
public Visibility EditorVisibility => HasActiveModule ? Visibility.Visible : Visibility.Collapsed; public Visibility EditorVisibility => HasActiveModule ? Visibility.Visible : Visibility.Collapsed;
@@ -113,6 +122,7 @@ namespace XplorePlane.ViewModels.Cnc
_activeModuleNode = null; _activeModuleNode = null;
PipelineNodes.Clear(); PipelineNodes.Clear();
SelectedNode = null; SelectedNode = null;
PipelineFileDisplayName = "未命名模块.xpm";
StatusMessage = "请选择检测模块以编辑其流水线。"; StatusMessage = "请选择检测模块以编辑其流水线。";
RaiseModuleVisibilityChanged(); RaiseModuleVisibilityChanged();
RaiseCommandCanExecuteChanged(); RaiseCommandCanExecuteChanged();
@@ -120,6 +130,7 @@ namespace XplorePlane.ViewModels.Cnc
} }
_activeModuleNode = selected; _activeModuleNode = selected;
_currentFilePath = null;
LoadPipelineModel(_activeModuleNode.Pipeline ?? new PipelineModel LoadPipelineModel(_activeModuleNode.Pipeline ?? new PipelineModel
{ {
Name = _activeModuleNode.Name Name = _activeModuleNode.Name
@@ -234,6 +245,7 @@ namespace XplorePlane.ViewModels.Cnc
PipelineNodes.Clear(); PipelineNodes.Clear();
SelectedNode = null; SelectedNode = null;
_currentFilePath = null; _currentFilePath = null;
PipelineFileDisplayName = GetActivePipelineFileDisplayName();
PersistActiveModule("已为当前检测模块新建空流水线。"); PersistActiveModule("已为当前检测模块新建空流水线。");
} }
@@ -264,6 +276,7 @@ namespace XplorePlane.ViewModels.Cnc
var model = BuildPipelineModel(); var model = BuildPipelineModel();
await _persistenceService.SaveAsync(model, dialog.FileName); await _persistenceService.SaveAsync(model, dialog.FileName);
_currentFilePath = dialog.FileName; _currentFilePath = dialog.FileName;
PipelineFileDisplayName = FormatPipelinePath(dialog.FileName);
StatusMessage = $"已导出模块流水线:{Path.GetFileName(dialog.FileName)}"; StatusMessage = $"已导出模块流水线:{Path.GetFileName(dialog.FileName)}";
} }
@@ -283,6 +296,7 @@ namespace XplorePlane.ViewModels.Cnc
var model = await _persistenceService.LoadAsync(dialog.FileName); var model = await _persistenceService.LoadAsync(dialog.FileName);
_currentFilePath = dialog.FileName; _currentFilePath = dialog.FileName;
PipelineFileDisplayName = FormatPipelinePath(dialog.FileName);
LoadPipelineModel(model); LoadPipelineModel(model);
PersistActiveModule($"已加载模块流水线:{model.Name}"); PersistActiveModule($"已加载模块流水线:{model.Name}");
} }
@@ -314,6 +328,8 @@ namespace XplorePlane.ViewModels.Cnc
} }
SelectedNode = PipelineNodes.FirstOrDefault(); SelectedNode = PipelineNodes.FirstOrDefault();
if (string.IsNullOrEmpty(_currentFilePath))
PipelineFileDisplayName = GetActivePipelineFileDisplayName();
StatusMessage = HasActiveModule StatusMessage = HasActiveModule
? $"正在编辑检测模块:{_activeModuleNode.Name}" ? $"正在编辑检测模块:{_activeModuleNode.Name}"
: "请选择检测模块以编辑其流水线。"; : "请选择检测模块以编辑其流水线。";
@@ -389,6 +405,21 @@ namespace XplorePlane.ViewModels.Cnc
: _activeModuleNode.Pipeline.Name; : _activeModuleNode.Pipeline.Name;
} }
private string GetActivePipelineFileDisplayName()
{
var pipelineName = GetActivePipelineName();
return pipelineName.EndsWith(".xpm", StringComparison.OrdinalIgnoreCase)
? pipelineName
: $"{pipelineName}.xpm";
}
private static string FormatPipelinePath(string filePath)
{
return string.IsNullOrWhiteSpace(filePath)
? "未命名模块.xpm"
: Path.GetFullPath(filePath).Replace('\\', '/');
}
private void RenumberNodes() private void RenumberNodes()
{ {
for (var i = 0; i < PipelineNodes.Count; i++) for (var i = 0; i < PipelineNodes.Count; i++)
@@ -11,6 +11,10 @@ namespace XplorePlane.ViewModels
string StatusMessage { get; } string StatusMessage { get; }
bool IsStatusError { get; }
string PipelineFileDisplayName { get; }
ICommand AddOperatorCommand { get; } ICommand AddOperatorCommand { get; }
ICommand RemoveOperatorCommand { get; } ICommand RemoveOperatorCommand { get; }
@@ -21,6 +21,7 @@ namespace XplorePlane.ViewModels
{ {
private const int MaxPipelineLength = 20; private const int MaxPipelineLength = 20;
private const int DebounceDelayMs = 300; private const int DebounceDelayMs = 300;
private const string DefaultPipelineFileDisplayName = "未命名模块.xpm";
private readonly IImageProcessingService _imageProcessingService; private readonly IImageProcessingService _imageProcessingService;
private readonly IPipelineExecutionService _executionService; private readonly IPipelineExecutionService _executionService;
@@ -36,6 +37,7 @@ namespace XplorePlane.ViewModels
private bool _isExecuting; private bool _isExecuting;
private bool _isStatusError; private bool _isStatusError;
private string _statusMessage = string.Empty; private string _statusMessage = string.Empty;
private string _pipelineFileDisplayName = DefaultPipelineFileDisplayName;
private string _currentFilePath; private string _currentFilePath;
private CancellationTokenSource _executionCts; private CancellationTokenSource _executionCts;
@@ -155,6 +157,12 @@ namespace XplorePlane.ViewModels
private set => SetProperty(ref _isStatusError, value); private set => SetProperty(ref _isStatusError, value);
} }
public string PipelineFileDisplayName
{
get => _pipelineFileDisplayName;
private set => SetProperty(ref _pipelineFileDisplayName, value);
}
// ── Commands ────────────────────────────────────────────────── // ── Commands ──────────────────────────────────────────────────
public DelegateCommand<string> AddOperatorCommand { get; } public DelegateCommand<string> AddOperatorCommand { get; }
@@ -526,6 +534,7 @@ namespace XplorePlane.ViewModels
PipelineName = "新建流水线"; PipelineName = "新建流水线";
PreviewImage = null; PreviewImage = null;
_currentFilePath = null; _currentFilePath = null;
PipelineFileDisplayName = DefaultPipelineFileDisplayName;
StatusMessage = "已新建流水线"; StatusMessage = "已新建流水线";
} }
@@ -576,6 +585,7 @@ namespace XplorePlane.ViewModels
{ {
var model = BuildPipelineModel(); var model = BuildPipelineModel();
await _persistenceService.SaveAsync(model, filePath); await _persistenceService.SaveAsync(model, filePath);
PipelineFileDisplayName = FormatPipelinePath(filePath);
StatusMessage = $"流水线已保存:{Path.GetFileName(filePath)}"; StatusMessage = $"流水线已保存:{Path.GetFileName(filePath)}";
} }
catch (IOException ex) catch (IOException ex)
@@ -624,6 +634,7 @@ namespace XplorePlane.ViewModels
PipelineName = model.Name; PipelineName = model.Name;
SelectedDevice = model.DeviceId; SelectedDevice = model.DeviceId;
_currentFilePath = dialog.FileName; _currentFilePath = dialog.FileName;
PipelineFileDisplayName = FormatPipelinePath(dialog.FileName);
foreach (var nodeModel in model.Nodes) foreach (var nodeModel in model.Nodes)
{ {
@@ -702,5 +713,12 @@ namespace XplorePlane.ViewModels
Directory.CreateDirectory(dir); Directory.CreateDirectory(dir);
return dir; return dir;
} }
private static string FormatPipelinePath(string filePath)
{
return string.IsNullOrWhiteSpace(filePath)
? DefaultPipelineFileDisplayName
: Path.GetFullPath(filePath).Replace('\\', '/');
}
} }
} }
@@ -68,7 +68,14 @@
Background="#F5F5F5" Background="#F5F5F5"
BorderBrush="{StaticResource PanelBorder}" BorderBrush="{StaticResource PanelBorder}"
BorderThickness="0,1,0,1"> BorderThickness="0,1,0,1">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal"> <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="0"
Orientation="Horizontal">
<Button <Button
Command="{Binding NewPipelineCommand}" Command="{Binding NewPipelineCommand}"
Content="新建" Content="新建"
@@ -91,7 +98,20 @@
Content="加载" Content="加载"
Style="{StaticResource ToolbarBtn}" Style="{StaticResource ToolbarBtn}"
ToolTip="加载流水线" /> ToolTip="加载流水线" />
</StackPanel> </StackPanel>
<TextBlock
Grid.Row="1"
Margin="2,4,2,0"
VerticalAlignment="Center"
FontFamily="{StaticResource CsdFont}"
FontSize="11"
FontWeight="SemiBold"
Foreground="#333333"
Text="{Binding PipelineFileDisplayName}"
TextAlignment="Left"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding PipelineFileDisplayName}" />
</Grid>
</Border> </Border>
<ListBox <ListBox
@@ -323,7 +343,8 @@
<Border <Border
Grid.Row="4" Grid.Row="4"
Padding="6,4" Height="24"
Padding="6,0"
BorderThickness="0,1,0,0"> BorderThickness="0,1,0,0">
<Border.Style> <Border.Style>
<Style TargetType="Border"> <Style TargetType="Border">
@@ -338,6 +359,7 @@
</Style> </Style>
</Border.Style> </Border.Style>
<TextBlock <TextBlock
VerticalAlignment="Center"
FontFamily="{StaticResource CsdFont}" FontFamily="{StaticResource CsdFont}"
FontSize="11" FontSize="11"
Text="{Binding StatusMessage, StringFormat='Status: {0}'}" Text="{Binding StatusMessage, StringFormat='Status: {0}'}"
@@ -4,7 +4,7 @@
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="600" d:DesignHeight="424"
d:DesignWidth="400" d:DesignWidth="400"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Background="#FFFFFF"> <Grid Background="#FFFFFF">
@@ -48,12 +48,15 @@
<Border <Border
Grid.Row="2" Grid.Row="2"
Background="#000000" Background="#000000"
Padding="8,4"> Height="24"
<TextBlock FontSize="12"> Padding="8,0">
<TextBlock
VerticalAlignment="Center"
FontSize="12">
<Run Foreground="#FFFFFF" Text="{Binding CameraStatusText, Mode=OneWay}" /> <Run Foreground="#FFFFFF" Text="{Binding CameraStatusText, Mode=OneWay}" />
<Run Text=" " /> <Run Text=" " />
<Run Foreground="#0078D4" Text="{Binding CameraPixelCoord, Mode=OneWay}" /> <Run Foreground="#0078D4" Text="{Binding CameraPixelCoord, Mode=OneWay}" />
</TextBlock> </TextBlock>
</Border> </Border>
</Grid> </Grid>
</UserControl> </UserControl>
@@ -28,10 +28,6 @@
ImageSource="{Binding ImageSource}" ImageSource="{Binding ImageSource}"
Background="White" /> Background="White" />
<!-- 图像信息栏 -->
<Border Grid.Row="2" Background="#F0F0F0" BorderBrush="#DDDDDD" BorderThickness="0,1,0,0">
<TextBlock Margin="4,2" FontSize="11" Foreground="#666666"
Text="{Binding ImageInfo}" />
</Border>
</Grid> </Grid>
</UserControl> </UserControl>