以硬件库层面运动硬件轴定义为准,同步修改appstate, 包括CNC 节点属性面板和 XP导出

This commit is contained in:
zhengxuan.zhang
2026-05-06 17:11:35 +08:00
parent 1ef876db2c
commit aeef1feee3
11 changed files with 350 additions and 222 deletions
+23 -19
View File
@@ -20,21 +20,25 @@ namespace XplorePlane.Tests.Models
public void MotionState_Default_AllZeros() public void MotionState_Default_AllZeros()
{ {
var state = MotionState.Default; var state = MotionState.Default;
_output.WriteLine($"MotionState.Default: XM={state.XM}, YM={state.YM}, ZT={state.ZT}, ZD={state.ZD}, TiltD={state.TiltD}, Dist={state.Dist}"); _output.WriteLine($"MotionState.Default: StageX={state.StageX}, StageY={state.StageY}, SourceZ={state.SourceZ}, DetectorZ={state.DetectorZ}, DetectorSwing={state.DetectorSwing}, FDD={state.FDD}");
_output.WriteLine($" Speeds: XM={state.XMSpeed}, YM={state.YMSpeed}, ZT={state.ZTSpeed}, ZD={state.ZDSpeed}, TiltD={state.TiltDSpeed}, Dist={state.DistSpeed}"); _output.WriteLine($" Speeds: StageX={state.StageXSpeed}, StageY={state.StageYSpeed}, SourceZ={state.SourceZSpeed}, DetectorZ={state.DetectorZSpeed}, DetectorSwing={state.DetectorSwingSpeed}, FDD={state.FDDSpeed}");
Assert.Equal(0, state.XM); Assert.Equal(0, state.StageX);
Assert.Equal(0, state.YM); Assert.Equal(0, state.StageY);
Assert.Equal(0, state.ZT); Assert.Equal(0, state.SourceZ);
Assert.Equal(0, state.ZD); Assert.Equal(0, state.DetectorZ);
Assert.Equal(0, state.TiltD); Assert.Equal(0, state.DetectorSwing);
Assert.Equal(0, state.Dist); Assert.Equal(0, state.FDD);
Assert.Equal(0, state.XMSpeed); Assert.Equal(0, state.StageXSpeed);
Assert.Equal(0, state.YMSpeed); Assert.Equal(0, state.StageYSpeed);
Assert.Equal(0, state.ZTSpeed); Assert.Equal(0, state.SourceZSpeed);
Assert.Equal(0, state.ZDSpeed); Assert.Equal(0, state.DetectorZSpeed);
Assert.Equal(0, state.TiltDSpeed); Assert.Equal(0, state.DetectorSwingSpeed);
Assert.Equal(0, state.DistSpeed); Assert.Equal(0, state.FDDSpeed);
Assert.Equal(0, state.StageRotation);
Assert.Equal(0, state.FixtureRotation);
Assert.Equal(0, state.FOD);
Assert.Equal(0, state.Magnification);
} }
[Fact] [Fact]
@@ -116,15 +120,15 @@ namespace XplorePlane.Tests.Models
public void MotionState_WithExpression_ProducesNewInstance() public void MotionState_WithExpression_ProducesNewInstance()
{ {
var original = MotionState.Default; var original = MotionState.Default;
var modified = original with { XM = 100 }; var modified = original with { StageX = 100 };
_output.WriteLine($"Original.XM={original.XM}, Modified.XM={modified.XM}, SameRef={ReferenceEquals(original, modified)}"); _output.WriteLine($"Original.StageX={original.StageX}, Modified.StageX={modified.StageX}, SameRef={ReferenceEquals(original, modified)}");
// New instance is different from original // New instance is different from original
Assert.NotSame(original, modified); Assert.NotSame(original, modified);
Assert.Equal(100, modified.XM); Assert.Equal(100, modified.StageX);
// Original is unchanged // Original is unchanged
Assert.Equal(0, original.XM); Assert.Equal(0, original.StageX);
} }
// ── CalibrationMatrix Transform Tests ───────────────────────── // ── CalibrationMatrix Transform Tests ─────────────────────────
@@ -168,4 +172,4 @@ namespace XplorePlane.Tests.Models
Assert.Equal(0, z, precision: 10); Assert.Equal(0, z, precision: 10);
} }
} }
} }
@@ -30,6 +30,8 @@ namespace XplorePlane.Tests.Services
private readonly Mock<ILinearAxis> _mockSourceZ; private readonly Mock<ILinearAxis> _mockSourceZ;
private readonly Mock<ILinearAxis> _mockDetectorZ; private readonly Mock<ILinearAxis> _mockDetectorZ;
private readonly Mock<IRotaryAxis> _mockDetectorSwing; private readonly Mock<IRotaryAxis> _mockDetectorSwing;
private readonly Mock<IRotaryAxis> _mockStageRotation;
private readonly Mock<IRotaryAxis> _mockFixtureRotation;
private readonly Mock<ILoggerService> _mockLogger; private readonly Mock<ILoggerService> _mockLogger;
private readonly EventAggregator _eventAggregator; private readonly EventAggregator _eventAggregator;
private readonly ITestOutputHelper _output; private readonly ITestOutputHelper _output;
@@ -51,6 +53,8 @@ namespace XplorePlane.Tests.Services
_mockSourceZ = CreateLinearAxis(AxisId.SourceZ, 0); _mockSourceZ = CreateLinearAxis(AxisId.SourceZ, 0);
_mockDetectorZ = CreateLinearAxis(AxisId.DetectorZ, 0); _mockDetectorZ = CreateLinearAxis(AxisId.DetectorZ, 0);
_mockDetectorSwing = CreateRotaryAxis(RotaryAxisId.DetectorSwing, 0); _mockDetectorSwing = CreateRotaryAxis(RotaryAxisId.DetectorSwing, 0);
_mockStageRotation = CreateRotaryAxis(RotaryAxisId.StageRotation, 0);
_mockFixtureRotation = CreateRotaryAxis(RotaryAxisId.FixtureRotation, 0);
_mockLogger = new Mock<ILoggerService>(); _mockLogger = new Mock<ILoggerService>();
_eventAggregator = new EventAggregator(); _eventAggregator = new EventAggregator();
@@ -59,6 +63,8 @@ namespace XplorePlane.Tests.Services
_mockMotionSystem.Setup(x => x.GetLinearAxis(AxisId.SourceZ)).Returns(_mockSourceZ.Object); _mockMotionSystem.Setup(x => x.GetLinearAxis(AxisId.SourceZ)).Returns(_mockSourceZ.Object);
_mockMotionSystem.Setup(x => x.GetLinearAxis(AxisId.DetectorZ)).Returns(_mockDetectorZ.Object); _mockMotionSystem.Setup(x => x.GetLinearAxis(AxisId.DetectorZ)).Returns(_mockDetectorZ.Object);
_mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.DetectorSwing)).Returns(_mockDetectorSwing.Object); _mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.DetectorSwing)).Returns(_mockDetectorSwing.Object);
_mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.StageRotation)).Returns(_mockStageRotation.Object);
_mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.FixtureRotation)).Returns(_mockFixtureRotation.Object);
_mockMotionControlService _mockMotionControlService
.Setup(x => x.GetCurrentGeometry()) .Setup(x => x.GetCurrentGeometry())
@@ -82,12 +88,12 @@ namespace XplorePlane.Tests.Services
[Fact] [Fact]
public void DefaultState_MotionState_IsHardwareSnapshot() public void DefaultState_MotionState_IsHardwareSnapshot()
{ {
Assert.Equal(0, _service.MotionState.XM); Assert.Equal(0, _service.MotionState.StageX);
Assert.Equal(0, _service.MotionState.YM); Assert.Equal(0, _service.MotionState.StageY);
Assert.Equal(0, _service.MotionState.ZT); Assert.Equal(0, _service.MotionState.SourceZ);
Assert.Equal(0, _service.MotionState.ZD); Assert.Equal(0, _service.MotionState.DetectorZ);
Assert.Equal(0, _service.MotionState.TiltD); Assert.Equal(0, _service.MotionState.DetectorSwing);
Assert.Equal(0, _service.MotionState.Dist); Assert.Equal(0, _service.MotionState.FDD);
} }
[Fact] [Fact]
@@ -174,12 +180,12 @@ namespace XplorePlane.Tests.Services
_eventAggregator.GetEvent<GeometryUpdatedEvent>() _eventAggregator.GetEvent<GeometryUpdatedEvent>()
.Publish(new GeometryData(100, 222.2, 2.22)); .Publish(new GeometryData(100, 222.2, 2.22));
Assert.Equal(12.5, _service.MotionState.XM); Assert.Equal(12.5, _service.MotionState.StageX);
Assert.Equal(34.5, _service.MotionState.YM); Assert.Equal(34.5, _service.MotionState.StageY);
Assert.Equal(56.5, _service.MotionState.ZT); Assert.Equal(56.5, _service.MotionState.SourceZ);
Assert.Equal(78.5, _service.MotionState.ZD); Assert.Equal(78.5, _service.MotionState.DetectorZ);
Assert.Equal(9.5, _service.MotionState.TiltD); Assert.Equal(9.5, _service.MotionState.DetectorSwing);
Assert.Equal(222.2, _service.MotionState.Dist); Assert.Equal(222.2, _service.MotionState.FDD);
} }
private static Mock<ILinearAxis> CreateLinearAxis(AxisId axisId, double position) private static Mock<ILinearAxis> CreateLinearAxis(AxisId axisId, double position)
@@ -96,7 +96,7 @@ namespace XplorePlane.Tests.Services
var pipeline = new PipelineModel { Name = "TestPipeline" }; var pipeline = new PipelineModel { Name = "TestPipeline" };
var step = _service.RecordCurrentStep(recipe, pipeline); var step = _service.RecordCurrentStep(recipe, pipeline);
_output.WriteLine($"RecordCurrentStep: StepIndex={step.StepIndex}, MotionState.XM={step.MotionState.XM}, RaySource.Voltage={step.RaySourceState.Voltage}, Detector.Resolution={step.DetectorState.Resolution}, Pipeline={step.Pipeline.Name}"); _output.WriteLine($"RecordCurrentStep: StepIndex={step.StepIndex}, MotionState.StageX={step.MotionState.StageX}, RaySource.Voltage={step.RaySourceState.Voltage}, Detector.Resolution={step.DetectorState.Resolution}, Pipeline={step.Pipeline.Name}");
Assert.Equal(0, step.StepIndex); Assert.Equal(0, step.StepIndex);
Assert.Same(motionState, step.MotionState); Assert.Same(motionState, step.MotionState);
@@ -138,4 +138,4 @@ namespace XplorePlane.Tests.Services
} }
} }
} }
} }
+49 -29
View File
@@ -40,69 +40,89 @@ namespace XplorePlane.Models
Guid Id, Guid Id,
int Index, int Index,
CncNodeType NodeType, CncNodeType NodeType,
string Name string Name);
);
/// <summary>参考点节点 | Reference point node</summary> /// <summary>参考点节点 | Reference point node</summary>
public record ReferencePointNode( public record ReferencePointNode(
Guid Id, int Index, string Name, Guid Id,
double XM, double YM, double ZT, double ZD, double TiltD, double Dist, int Index,
bool IsRayOn, double Voltage, double Current string Name,
) : CncNode(Id, Index, CncNodeType.ReferencePoint, Name); [property: JsonPropertyName("XM")] double StageX,
[property: JsonPropertyName("YM")] double StageY,
[property: JsonPropertyName("ZT")] double SourceZ,
[property: JsonPropertyName("ZD")] double DetectorZ,
[property: JsonPropertyName("TiltD")] double DetectorSwing,
[property: JsonPropertyName("Dist")] double FDD,
bool IsRayOn,
double Voltage,
double Current,
double StageRotation = 0,
double FixtureRotation = 0,
double FOD = 0,
double Magnification = 0) : CncNode(Id, Index, CncNodeType.ReferencePoint, Name);
/// <summary>保存节点(含图像)| Save node with image</summary> /// <summary>保存节点(含图像)| Save node with image</summary>
public record SaveNodeWithImageNode( public record SaveNodeWithImageNode(
Guid Id, int Index, string Name, Guid Id,
int Index,
string Name,
MotionState MotionState, MotionState MotionState,
RaySourceState RaySourceState, RaySourceState RaySourceState,
DetectorState DetectorState, DetectorState DetectorState,
string ImageFileName string ImageFileName) : CncNode(Id, Index, CncNodeType.SaveNodeWithImage, Name);
) : CncNode(Id, Index, CncNodeType.SaveNodeWithImage, Name);
/// <summary>保存节点(不含图像)| Save node without image</summary> /// <summary>保存节点(不含图像)| Save node without image</summary>
public record SaveNodeNode( public record SaveNodeNode(
Guid Id, int Index, string Name, Guid Id,
int Index,
string Name,
MotionState MotionState, MotionState MotionState,
RaySourceState RaySourceState, RaySourceState RaySourceState,
DetectorState DetectorState DetectorState DetectorState) : CncNode(Id, Index, CncNodeType.SaveNode, Name);
) : CncNode(Id, Index, CncNodeType.SaveNode, Name);
/// <summary>保存位置节点 | Save position node</summary> /// <summary>保存位置节点 | Save position node</summary>
public record SavePositionNode( public record SavePositionNode(
Guid Id, int Index, string Name, Guid Id,
MotionState MotionState int Index,
) : CncNode(Id, Index, CncNodeType.SavePosition, Name); string Name,
MotionState MotionState) : CncNode(Id, Index, CncNodeType.SavePosition, Name);
/// <summary>检测模块节点 | Inspection module node</summary> /// <summary>检测模块节点 | Inspection module node</summary>
public record InspectionModuleNode( public record InspectionModuleNode(
Guid Id, int Index, string Name, Guid Id,
PipelineModel Pipeline int Index,
) : CncNode(Id, Index, CncNodeType.InspectionModule, Name); string Name,
PipelineModel Pipeline) : CncNode(Id, Index, CncNodeType.InspectionModule, Name);
/// <summary>检测标记节点 | Inspection marker node</summary> /// <summary>检测标记节点 | Inspection marker node</summary>
public record InspectionMarkerNode( public record InspectionMarkerNode(
Guid Id, int Index, string Name, Guid Id,
int Index,
string Name,
string MarkerType, string MarkerType,
double MarkerX, double MarkerY double MarkerX,
) : CncNode(Id, Index, CncNodeType.InspectionMarker, Name); double MarkerY) : CncNode(Id, Index, CncNodeType.InspectionMarker, Name);
/// <summary>停顿对话框节点 | Pause dialog node</summary> /// <summary>停顿对话框节点 | Pause dialog node</summary>
public record PauseDialogNode( public record PauseDialogNode(
Guid Id, int Index, string Name, Guid Id,
int Index,
string Name,
string DialogTitle, string DialogTitle,
string DialogMessage string DialogMessage) : CncNode(Id, Index, CncNodeType.PauseDialog, Name);
) : CncNode(Id, Index, CncNodeType.PauseDialog, Name);
/// <summary>等待延时节点 | Wait delay node</summary> /// <summary>等待延时节点 | Wait delay node</summary>
public record WaitDelayNode( public record WaitDelayNode(
Guid Id, int Index, string Name, Guid Id,
int DelayMilliseconds int Index,
) : CncNode(Id, Index, CncNodeType.WaitDelay, Name); string Name,
int DelayMilliseconds) : CncNode(Id, Index, CncNodeType.WaitDelay, Name);
/// <summary>完成程序节点 | Complete program node</summary> /// <summary>完成程序节点 | Complete program node</summary>
public record CompleteProgramNode( public record CompleteProgramNode(
Guid Id, int Index, string Name Guid Id,
) : CncNode(Id, Index, CncNodeType.CompleteProgram, Name); int Index,
string Name) : CncNode(Id, Index, CncNodeType.CompleteProgram, Name);
// ── CNC 程序 | CNC Program ──────────────────────────────────────── // ── CNC 程序 | CNC Program ────────────────────────────────────────
+53 -51
View File
@@ -1,9 +1,8 @@
using System; using System;
using System.Text.Json.Serialization;
namespace XplorePlane.Models namespace XplorePlane.Models
{ {
// ── Enumerations ──────────────────────────────────────────────────
/// <summary>系统操作模式</summary> /// <summary>系统操作模式</summary>
public enum OperationMode public enum OperationMode
{ {
@@ -23,82 +22,86 @@ namespace XplorePlane.Models
Error // 出错 Error // 出错
} }
// ── State Records ───────────────────────────────────────────────── // State Records
/// <summary>运动控制状态(不可变)</summary> /// <summary>
/// 运动控制状态(不可变)。
/// 统一的运动与几何快照,与运动硬件模型对齐。
/// 保留旧版 JSON 字段名以保持向后兼容性。
/// </summary>
public record MotionState( public record MotionState(
double XM, // X 轴位置 (μm) [property: JsonPropertyName("XM")] double StageX, // X 轴位置μm
double YM, // Y 轴位置 (μm) [property: JsonPropertyName("YM")] double StageY, // Y 轴位置μm
double ZT, // Z 上轴位置 (μm) [property: JsonPropertyName("ZT")] double SourceZ, // Z 上轴位置μm
double ZD, // Z 下轴位置 (μm) [property: JsonPropertyName("ZD")] double DetectorZ, // Z 下轴位置μm
double TiltD, // 倾斜角度 (m°) [property: JsonPropertyName("TiltD")] double DetectorSwing, // 探测器摆角(°)
double Dist, // 距离 (μm) [property: JsonPropertyName("Dist")] double FDD, // 焦点-探测器距离(μm
double XMSpeed, // X 轴速度 (μm/s) [property: JsonPropertyName("XMSpeed")] double StageXSpeed, // X 轴速度μm/s
double YMSpeed, // Y 轴速度 (μm/s) [property: JsonPropertyName("YMSpeed")] double StageYSpeed, // Y 轴速度μm/s
double ZTSpeed, // Z 上轴速度 (μm/s) [property: JsonPropertyName("ZTSpeed")] double SourceZSpeed, // Z 上轴速度μm/s
double ZDSpeed, // Z 下轴速度 (μm/s) [property: JsonPropertyName("ZDSpeed")] double DetectorZSpeed, // Z 下轴速度μm/s
double TiltDSpeed, // 倾斜速度 (m°/s) [property: JsonPropertyName("TiltDSpeed")] double DetectorSwingSpeed, // 探测器摆角速度(°/s
double DistSpeed // 距离速度 (μm/s) [property: JsonPropertyName("DistSpeed")] double FDDSpeed, // 焦点-探测器距离速度μm/s
) double StageRotation = 0, // 载台旋转角度(°)
double FixtureRotation = 0, // 夹具旋转角度(°)
double FOD = 0, // 焦点-物体距离(μm
double Magnification = 0, // 放大倍率
double StageRotationSpeed = 0, // 载台旋转速度(°/s
double FixtureRotationSpeed = 0) // 夹具旋转速度(°/s
{ {
public static readonly MotionState Default = new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); public static readonly MotionState Default = new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
} }
/// <summary>射线源状态(不可变)</summary> /// <summary>射线源状态(不可变)</summary>
public record RaySourceState( public record RaySourceState(
bool IsOn, // 开关状态 bool IsOn, // 是否开启
double Voltage, // 电压 (kV) double Voltage, // 电压kV
double Power // 功率 (W) double Power) // 功率W
)
{ {
public static readonly RaySourceState Default = new(false, 0, 0); public static readonly RaySourceState Default = new(false, 0, 0);
} }
/// <summary>探测器状态(不可变)</summary> /// <summary>探测器状态(不可变)</summary>
public record DetectorState( public record DetectorState(
bool IsConnected, // 连接状态 bool IsConnected, // 是否已连接
bool IsAcquiring, // 是否正在采集 bool IsAcquiring, // 是否正在采集
double FrameRate, // 当前帧率 (fps) double FrameRate, // 帧率(fps
string Resolution // 分辨率描述,如 "2048x2048" string Resolution) // 分辨率描述
)
{ {
public static readonly DetectorState Default = new(false, false, 0, string.Empty); public static readonly DetectorState Default = new(false, false, 0, string.Empty);
} }
/// <summary>系统状态(不可变)</summary> /// <summary>系统整体状态(不可变)</summary>
public record SystemState( public record SystemState(
OperationMode OperationMode, // 当前操作模式 OperationMode OperationMode, // 当前操作模式
bool HasError, // 是否存在系统错误 bool HasError, // 是否存在错误
string ErrorMessage // 错误描述 string ErrorMessage) // 错误信息
)
{ {
public static readonly SystemState Default = new(OperationMode.Idle, false, string.Empty); public static readonly SystemState Default = new(OperationMode.Idle, false, string.Empty);
} }
/// <summary>摄像头视频流状态(不可变)</summary> /// <summary>相机状态(不可变)</summary>
public record CameraState( public record CameraState(
bool IsConnected, // 连接状态 bool IsConnected, // 是否已连接
bool IsStreaming, // 是否正在推流 bool IsStreaming, // 是否正在推流
object CurrentFrame, // 当前帧数据引用(BitmapSource 或 byte[]Frozen object CurrentFrame, // 当前帧数据
int Width, // 分辨率宽 int Width, // 图像宽度(px
int Height, // 分辨率高 int Height, // 图像高度(px
double FrameRate // 帧率 (fps) double FrameRate) // 帧率fps
)
{ {
public static readonly CameraState Default = new(false, false, null, 0, 0, 0); public static readonly CameraState Default = new(false, false, null, 0, 0, 0);
} }
/// <summary>物理坐标</summary> /// <summary>物理坐标位置</summary>
public record PhysicalPosition(double X, double Y, double Z); public record PhysicalPosition(double X, double Y, double Z);
/// <summary>图像标定矩阵,像素坐标 → 物理坐标映射</summary> /// <summary>标定矩阵3×3 仿射变换)</summary>
public record CalibrationMatrix( public record CalibrationMatrix(
double M11, double M12, double M13, // 3x3 仿射变换矩阵 double M11, double M12, double M13,
double M21, double M22, double M23, double M21, double M22, double M23,
double M31, double M32, double M33 double M31, double M32, double M33)
)
{ {
/// <summary>将像素坐标换为物理坐标</summary> /// <summary>将像素坐标换为物理坐标</summary>
public (double X, double Y, double Z) Transform(double pixelX, double pixelY) public (double X, double Y, double Z) Transform(double pixelX, double pixelY)
{ {
double x = M11 * pixelX + M12 * pixelY + M13; double x = M11 * pixelX + M12 * pixelY + M13;
@@ -108,13 +111,12 @@ namespace XplorePlane.Models
} }
} }
/// <summary>画面联动状态(不可变)</summary> /// <summary>联动视图状态(不可变)</summary>
public record LinkedViewState( public record LinkedViewState(
PhysicalPosition TargetPosition, // 目标物理坐标 PhysicalPosition TargetPosition, // 目标物理位置
bool IsExecuting, // 联动是否正在执行 bool IsExecuting, // 是否正在执行移动
DateTime LastRequestTime // 最近一次联动请求时间 DateTime LastRequestTime) // 最近一次请求时间
)
{ {
public static readonly LinkedViewState Default = new(new PhysicalPosition(0, 0, 0), false, DateTime.MinValue); public static readonly LinkedViewState Default = new(new PhysicalPosition(0, 0, 0), false, DateTime.MinValue);
} }
} }
@@ -345,20 +345,28 @@ namespace XplorePlane.Services.AppState
var sourceZ = _motionSystem.GetLinearAxis(AxisId.SourceZ); var sourceZ = _motionSystem.GetLinearAxis(AxisId.SourceZ);
var detectorZ = _motionSystem.GetLinearAxis(AxisId.DetectorZ); var detectorZ = _motionSystem.GetLinearAxis(AxisId.DetectorZ);
var detectorSwing = _motionSystem.GetRotaryAxis(RotaryAxisId.DetectorSwing); var detectorSwing = _motionSystem.GetRotaryAxis(RotaryAxisId.DetectorSwing);
var stageRotation = _motionSystem.GetRotaryAxis(RotaryAxisId.StageRotation);
var fixtureRotation = _motionSystem.GetRotaryAxis(RotaryAxisId.FixtureRotation);
return new MotionState( return new MotionState(
XM: stageX.ActualPosition, StageX: stageX.ActualPosition,
YM: stageY.ActualPosition, StageY: stageY.ActualPosition,
ZT: sourceZ.ActualPosition, SourceZ: sourceZ.ActualPosition,
ZD: detectorZ.ActualPosition, DetectorZ: detectorZ.ActualPosition,
TiltD: detectorSwing.ActualAngle, DetectorSwing: detectorSwing.ActualAngle,
Dist: geometry?.FDD ?? 0, FDD: geometry?.FDD ?? 0,
XMSpeed: 0, StageXSpeed: 0,
YMSpeed: 0, StageYSpeed: 0,
ZTSpeed: 0, SourceZSpeed: 0,
ZDSpeed: 0, DetectorZSpeed: 0,
TiltDSpeed: 0, DetectorSwingSpeed: 0,
DistSpeed: 0); FDDSpeed: 0,
StageRotation: stageRotation.ActualAngle,
FixtureRotation: fixtureRotation.ActualAngle,
FOD: geometry?.FOD ?? 0,
Magnification: geometry?.Magnification ?? 0,
StageRotationSpeed: 0,
FixtureRotationSpeed: 0);
} }
private void SetMotionState(MotionState newState) private void SetMotionState(MotionState newState)
+11 -7
View File
@@ -389,15 +389,19 @@ namespace XplorePlane.Services.Cnc
var raySource = _appStateService.RaySourceState; var raySource = _appStateService.RaySourceState;
return new ReferencePointNode( return new ReferencePointNode(
id, index, $"参考点_{index}", id, index, $"参考点_{index}",
XM: motion.XM, StageX: motion.StageX,
YM: motion.YM, StageY: motion.StageY,
ZT: motion.ZT, SourceZ: motion.SourceZ,
ZD: motion.ZD, DetectorZ: motion.DetectorZ,
TiltD: motion.TiltD, DetectorSwing: motion.DetectorSwing,
Dist: motion.Dist, FDD: motion.FDD,
IsRayOn: raySource.IsOn, IsRayOn: raySource.IsOn,
Voltage: raySource.Voltage, Voltage: raySource.Voltage,
Current: TryReadCurrent()); Current: TryReadCurrent(),
StageRotation: motion.StageRotation,
FixtureRotation: motion.FixtureRotation,
FOD: motion.FOD,
Magnification: motion.Magnification);
} }
/// <summary>创建保存节点(含图像)| Create save node with image</summary> /// <summary>创建保存节点(含图像)| Create save node with image</summary>
@@ -417,7 +417,7 @@ namespace XplorePlane.ViewModels.Cnc
return; return;
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("Index,NodeType,Name,XM,YM,ZT,ZD,TiltD,Dist,Voltage_kV,Current_uA,Power_W,RayOn,DetectorConnected,FrameRate,Resolution,ImageFile,MarkerType,MarkerX,MarkerY,DialogTitle,DialogMessage,DelayMs,Pipeline"); sb.AppendLine("Index,NodeType,Name,StageX,StageY,SourceZ,DetectorZ,DetectorSwing,StageRotation,FixtureRotation,FOD,FDD,Magnification,Voltage_kV,Current_uA,Power_W,RayOn,DetectorConnected,FrameRate,Resolution,ImageFile,MarkerType,MarkerX,MarkerY,DialogTitle,DialogMessage,DelayMs,Pipeline");
var inv = CultureInfo.InvariantCulture; var inv = CultureInfo.InvariantCulture;
@@ -425,16 +425,16 @@ namespace XplorePlane.ViewModels.Cnc
{ {
var row = node switch var row = node switch
{ {
ReferencePointNode rp => $"{rp.Index},{rp.NodeType},{Esc(rp.Name)},{rp.XM.ToString(inv)},{rp.YM.ToString(inv)},{rp.ZT.ToString(inv)},{rp.ZD.ToString(inv)},{rp.TiltD.ToString(inv)},{rp.Dist.ToString(inv)},{rp.Voltage.ToString(inv)},{rp.Current.ToString(inv)},,{rp.IsRayOn},,,,,,,,,,", ReferencePointNode rp => $"{rp.Index},{rp.NodeType},{Esc(rp.Name)},{rp.StageX.ToString(inv)},{rp.StageY.ToString(inv)},{rp.SourceZ.ToString(inv)},{rp.DetectorZ.ToString(inv)},{rp.DetectorSwing.ToString(inv)},{rp.StageRotation.ToString(inv)},{rp.FixtureRotation.ToString(inv)},{rp.FOD.ToString(inv)},{rp.FDD.ToString(inv)},{rp.Magnification.ToString(inv)},{rp.Voltage.ToString(inv)},{rp.Current.ToString(inv)},,{rp.IsRayOn},,,,,,,,,,",
SaveNodeWithImageNode sni => $"{sni.Index},{sni.NodeType},{Esc(sni.Name)},{sni.MotionState.XM.ToString(inv)},{sni.MotionState.YM.ToString(inv)},{sni.MotionState.ZT.ToString(inv)},{sni.MotionState.ZD.ToString(inv)},{sni.MotionState.TiltD.ToString(inv)},{sni.MotionState.Dist.ToString(inv)},{sni.RaySourceState.Voltage.ToString(inv)},,{sni.RaySourceState.Power.ToString(inv)},{sni.RaySourceState.IsOn},{sni.DetectorState.IsConnected},{sni.DetectorState.FrameRate.ToString(inv)},{Esc(sni.DetectorState.Resolution)},{Esc(sni.ImageFileName)},,,,,,", SaveNodeWithImageNode sni => $"{sni.Index},{sni.NodeType},{Esc(sni.Name)},{sni.MotionState.StageX.ToString(inv)},{sni.MotionState.StageY.ToString(inv)},{sni.MotionState.SourceZ.ToString(inv)},{sni.MotionState.DetectorZ.ToString(inv)},{sni.MotionState.DetectorSwing.ToString(inv)},{sni.MotionState.StageRotation.ToString(inv)},{sni.MotionState.FixtureRotation.ToString(inv)},{sni.MotionState.FOD.ToString(inv)},{sni.MotionState.FDD.ToString(inv)},{sni.MotionState.Magnification.ToString(inv)},{sni.RaySourceState.Voltage.ToString(inv)},,{sni.RaySourceState.Power.ToString(inv)},{sni.RaySourceState.IsOn},{sni.DetectorState.IsConnected},{sni.DetectorState.FrameRate.ToString(inv)},{Esc(sni.DetectorState.Resolution)},{Esc(sni.ImageFileName)},,,,,,",
SaveNodeNode sn => $"{sn.Index},{sn.NodeType},{Esc(sn.Name)},{sn.MotionState.XM.ToString(inv)},{sn.MotionState.YM.ToString(inv)},{sn.MotionState.ZT.ToString(inv)},{sn.MotionState.ZD.ToString(inv)},{sn.MotionState.TiltD.ToString(inv)},{sn.MotionState.Dist.ToString(inv)},{sn.RaySourceState.Voltage.ToString(inv)},,{sn.RaySourceState.Power.ToString(inv)},{sn.RaySourceState.IsOn},{sn.DetectorState.IsConnected},{sn.DetectorState.FrameRate.ToString(inv)},{Esc(sn.DetectorState.Resolution)},,,,,,,", SaveNodeNode sn => $"{sn.Index},{sn.NodeType},{Esc(sn.Name)},{sn.MotionState.StageX.ToString(inv)},{sn.MotionState.StageY.ToString(inv)},{sn.MotionState.SourceZ.ToString(inv)},{sn.MotionState.DetectorZ.ToString(inv)},{sn.MotionState.DetectorSwing.ToString(inv)},{sn.MotionState.StageRotation.ToString(inv)},{sn.MotionState.FixtureRotation.ToString(inv)},{sn.MotionState.FOD.ToString(inv)},{sn.MotionState.FDD.ToString(inv)},{sn.MotionState.Magnification.ToString(inv)},{sn.RaySourceState.Voltage.ToString(inv)},,{sn.RaySourceState.Power.ToString(inv)},{sn.RaySourceState.IsOn},{sn.DetectorState.IsConnected},{sn.DetectorState.FrameRate.ToString(inv)},{Esc(sn.DetectorState.Resolution)},,,,,,,",
SavePositionNode sp => $"{sp.Index},{sp.NodeType},{Esc(sp.Name)},{sp.MotionState.XM.ToString(inv)},{sp.MotionState.YM.ToString(inv)},{sp.MotionState.ZT.ToString(inv)},{sp.MotionState.ZD.ToString(inv)},{sp.MotionState.TiltD.ToString(inv)},{sp.MotionState.Dist.ToString(inv)},,,,,,,,,,,,,,", SavePositionNode sp => $"{sp.Index},{sp.NodeType},{Esc(sp.Name)},{sp.MotionState.StageX.ToString(inv)},{sp.MotionState.StageY.ToString(inv)},{sp.MotionState.SourceZ.ToString(inv)},{sp.MotionState.DetectorZ.ToString(inv)},{sp.MotionState.DetectorSwing.ToString(inv)},{sp.MotionState.StageRotation.ToString(inv)},{sp.MotionState.FixtureRotation.ToString(inv)},{sp.MotionState.FOD.ToString(inv)},{sp.MotionState.FDD.ToString(inv)},{sp.MotionState.Magnification.ToString(inv)},,,,,,,,,,,,,,",
InspectionModuleNode im => $"{im.Index},{im.NodeType},{Esc(im.Name)},,,,,,,,,,,,,,,,,,,{Esc(im.Pipeline?.Name ?? string.Empty)}", InspectionModuleNode im => $"{im.Index},{im.NodeType},{Esc(im.Name)},,,,,,,,,,,,,,,,,,,,,,{Esc(im.Pipeline?.Name ?? string.Empty)}",
InspectionMarkerNode mk => $"{mk.Index},{mk.NodeType},{Esc(mk.Name)},,,,,,,,,,,,,,{Esc(mk.MarkerType)},{mk.MarkerX.ToString(inv)},{mk.MarkerY.ToString(inv)},,,", InspectionMarkerNode mk => $"{mk.Index},{mk.NodeType},{Esc(mk.Name)},,,,,,,,,,,,,,,,,{Esc(mk.MarkerType)},{mk.MarkerX.ToString(inv)},{mk.MarkerY.ToString(inv)},,,",
PauseDialogNode pd => $"{pd.Index},{pd.NodeType},{Esc(pd.Name)},,,,,,,,,,,,,,,,,{Esc(pd.DialogTitle)},{Esc(pd.DialogMessage)},,", PauseDialogNode pd => $"{pd.Index},{pd.NodeType},{Esc(pd.Name)},,,,,,,,,,,,,,,,,,,{Esc(pd.DialogTitle)},{Esc(pd.DialogMessage)},,",
WaitDelayNode wd => $"{wd.Index},{wd.NodeType},{Esc(wd.Name)},,,,,,,,,,,,,,,,,,,{wd.DelayMilliseconds},", WaitDelayNode wd => $"{wd.Index},{wd.NodeType},{Esc(wd.Name)},,,,,,,,,,,,,,,,,,,,,{wd.DelayMilliseconds},",
CompleteProgramNode cp => $"{cp.Index},{cp.NodeType},{Esc(cp.Name)},,,,,,,,,,,,,,,,,,,,", CompleteProgramNode cp => $"{cp.Index},{cp.NodeType},{Esc(cp.Name)},,,,,,,,,,,,,,,,,,,,,,",
_ => $"{node.Index},{node.NodeType},{Esc(node.Name)},,,,,,,,,,,,,,,,,,,," _ => $"{node.Index},{node.NodeType},{Esc(node.Name)},,,,,,,,,,,,,,,,,,,,,,"
}; };
sb.AppendLine(row); sb.AppendLine(row);
+128 -60
View File
@@ -116,82 +116,134 @@ namespace XplorePlane.ViewModels.Cnc
_ => string.Empty _ => string.Empty
}; };
public double XM public double StageX
{ {
get => _model switch get => _model switch
{ {
ReferencePointNode rp => rp.XM, ReferencePointNode rp => rp.StageX,
SaveNodeNode sn => sn.MotionState.XM, SaveNodeNode sn => sn.MotionState.StageX,
SaveNodeWithImageNode sni => sni.MotionState.XM, SaveNodeWithImageNode sni => sni.MotionState.StageX,
SavePositionNode sp => sp.MotionState.XM, SavePositionNode sp => sp.MotionState.StageX,
_ => 0d _ => 0d
}; };
set => UpdateMotion(value, MotionAxis.XM); set => UpdateMotion(value, MotionAxis.StageX);
} }
public double YM public double StageY
{ {
get => _model switch get => _model switch
{ {
ReferencePointNode rp => rp.YM, ReferencePointNode rp => rp.StageY,
SaveNodeNode sn => sn.MotionState.YM, SaveNodeNode sn => sn.MotionState.StageY,
SaveNodeWithImageNode sni => sni.MotionState.YM, SaveNodeWithImageNode sni => sni.MotionState.StageY,
SavePositionNode sp => sp.MotionState.YM, SavePositionNode sp => sp.MotionState.StageY,
_ => 0d _ => 0d
}; };
set => UpdateMotion(value, MotionAxis.YM); set => UpdateMotion(value, MotionAxis.StageY);
} }
public double ZT public double SourceZ
{ {
get => _model switch get => _model switch
{ {
ReferencePointNode rp => rp.ZT, ReferencePointNode rp => rp.SourceZ,
SaveNodeNode sn => sn.MotionState.ZT, SaveNodeNode sn => sn.MotionState.SourceZ,
SaveNodeWithImageNode sni => sni.MotionState.ZT, SaveNodeWithImageNode sni => sni.MotionState.SourceZ,
SavePositionNode sp => sp.MotionState.ZT, SavePositionNode sp => sp.MotionState.SourceZ,
_ => 0d _ => 0d
}; };
set => UpdateMotion(value, MotionAxis.ZT); set => UpdateMotion(value, MotionAxis.SourceZ);
} }
public double ZD public double DetectorZ
{ {
get => _model switch get => _model switch
{ {
ReferencePointNode rp => rp.ZD, ReferencePointNode rp => rp.DetectorZ,
SaveNodeNode sn => sn.MotionState.ZD, SaveNodeNode sn => sn.MotionState.DetectorZ,
SaveNodeWithImageNode sni => sni.MotionState.ZD, SaveNodeWithImageNode sni => sni.MotionState.DetectorZ,
SavePositionNode sp => sp.MotionState.ZD, SavePositionNode sp => sp.MotionState.DetectorZ,
_ => 0d _ => 0d
}; };
set => UpdateMotion(value, MotionAxis.ZD); set => UpdateMotion(value, MotionAxis.DetectorZ);
} }
public double TiltD public double DetectorSwing
{ {
get => _model switch get => _model switch
{ {
ReferencePointNode rp => rp.TiltD, ReferencePointNode rp => rp.DetectorSwing,
SaveNodeNode sn => sn.MotionState.TiltD, SaveNodeNode sn => sn.MotionState.DetectorSwing,
SaveNodeWithImageNode sni => sni.MotionState.TiltD, SaveNodeWithImageNode sni => sni.MotionState.DetectorSwing,
SavePositionNode sp => sp.MotionState.TiltD, SavePositionNode sp => sp.MotionState.DetectorSwing,
_ => 0d _ => 0d
}; };
set => UpdateMotion(value, MotionAxis.TiltD); set => UpdateMotion(value, MotionAxis.DetectorSwing);
} }
public double Dist public double StageRotation
{ {
get => _model switch get => _model switch
{ {
ReferencePointNode rp => rp.Dist, ReferencePointNode rp => rp.StageRotation,
SaveNodeNode sn => sn.MotionState.Dist, SaveNodeNode sn => sn.MotionState.StageRotation,
SaveNodeWithImageNode sni => sni.MotionState.Dist, SaveNodeWithImageNode sni => sni.MotionState.StageRotation,
SavePositionNode sp => sp.MotionState.Dist, SavePositionNode sp => sp.MotionState.StageRotation,
_ => 0d _ => 0d
}; };
set => UpdateMotion(value, MotionAxis.Dist); set => UpdateMotion(value, MotionAxis.StageRotation);
}
public double FixtureRotation
{
get => _model switch
{
ReferencePointNode rp => rp.FixtureRotation,
SaveNodeNode sn => sn.MotionState.FixtureRotation,
SaveNodeWithImageNode sni => sni.MotionState.FixtureRotation,
SavePositionNode sp => sp.MotionState.FixtureRotation,
_ => 0d
};
set => UpdateMotion(value, MotionAxis.FixtureRotation);
}
public double FOD
{
get => _model switch
{
ReferencePointNode rp => rp.FOD,
SaveNodeNode sn => sn.MotionState.FOD,
SaveNodeWithImageNode sni => sni.MotionState.FOD,
SavePositionNode sp => sp.MotionState.FOD,
_ => 0d
};
set => UpdateMotion(value, MotionAxis.FOD);
}
public double FDD
{
get => _model switch
{
ReferencePointNode rp => rp.FDD,
SaveNodeNode sn => sn.MotionState.FDD,
SaveNodeWithImageNode sni => sni.MotionState.FDD,
SavePositionNode sp => sp.MotionState.FDD,
_ => 0d
};
set => UpdateMotion(value, MotionAxis.FDD);
}
public double Magnification
{
get => _model switch
{
ReferencePointNode rp => rp.Magnification,
SaveNodeNode sn => sn.MotionState.Magnification,
SaveNodeWithImageNode sni => sni.MotionState.Magnification,
SavePositionNode sp => sp.MotionState.Magnification,
_ => 0d
};
set => UpdateMotion(value, MotionAxis.Magnification);
} }
public bool IsRayOn public bool IsRayOn
@@ -426,12 +478,16 @@ namespace XplorePlane.ViewModels.Cnc
case ReferencePointNode rp: case ReferencePointNode rp:
UpdateModel(axis switch UpdateModel(axis switch
{ {
MotionAxis.XM => rp with { XM = value }, MotionAxis.StageX => rp with { StageX = value },
MotionAxis.YM => rp with { YM = value }, MotionAxis.StageY => rp with { StageY = value },
MotionAxis.ZT => rp with { ZT = value }, MotionAxis.SourceZ => rp with { SourceZ = value },
MotionAxis.ZD => rp with { ZD = value }, MotionAxis.DetectorZ => rp with { DetectorZ = value },
MotionAxis.TiltD => rp with { TiltD = value }, MotionAxis.DetectorSwing => rp with { DetectorSwing = value },
MotionAxis.Dist => rp with { Dist = value }, MotionAxis.StageRotation => rp with { StageRotation = value },
MotionAxis.FixtureRotation => rp with { FixtureRotation = value },
MotionAxis.FOD => rp with { FOD = value },
MotionAxis.FDD => rp with { FDD = value },
MotionAxis.Magnification => rp with { Magnification = value },
_ => rp _ => rp
}); });
break; break;
@@ -519,12 +575,16 @@ namespace XplorePlane.ViewModels.Cnc
{ {
return axis switch return axis switch
{ {
MotionAxis.XM => state with { XM = value }, MotionAxis.StageX => state with { StageX = value },
MotionAxis.YM => state with { YM = value }, MotionAxis.StageY => state with { StageY = value },
MotionAxis.ZT => state with { ZT = value }, MotionAxis.SourceZ => state with { SourceZ = value },
MotionAxis.ZD => state with { ZD = value }, MotionAxis.DetectorZ => state with { DetectorZ = value },
MotionAxis.TiltD => state with { TiltD = value }, MotionAxis.DetectorSwing => state with { DetectorSwing = value },
MotionAxis.Dist => state with { Dist = value }, MotionAxis.StageRotation => state with { StageRotation = value },
MotionAxis.FixtureRotation => state with { FixtureRotation = value },
MotionAxis.FOD => state with { FOD = value },
MotionAxis.FDD => state with { FDD = value },
MotionAxis.Magnification => state with { Magnification = value },
_ => state _ => state
}; };
} }
@@ -557,12 +617,16 @@ namespace XplorePlane.ViewModels.Cnc
RaisePropertyChanged(nameof(IsPositionChild)); RaisePropertyChanged(nameof(IsPositionChild));
RaisePropertyChanged(nameof(IsMotionSnapshotNode)); RaisePropertyChanged(nameof(IsMotionSnapshotNode));
RaisePropertyChanged(nameof(RelationTag)); RaisePropertyChanged(nameof(RelationTag));
RaisePropertyChanged(nameof(XM)); RaisePropertyChanged(nameof(StageX));
RaisePropertyChanged(nameof(YM)); RaisePropertyChanged(nameof(StageY));
RaisePropertyChanged(nameof(ZT)); RaisePropertyChanged(nameof(SourceZ));
RaisePropertyChanged(nameof(ZD)); RaisePropertyChanged(nameof(DetectorZ));
RaisePropertyChanged(nameof(TiltD)); RaisePropertyChanged(nameof(DetectorSwing));
RaisePropertyChanged(nameof(Dist)); RaisePropertyChanged(nameof(StageRotation));
RaisePropertyChanged(nameof(FixtureRotation));
RaisePropertyChanged(nameof(FOD));
RaisePropertyChanged(nameof(FDD));
RaisePropertyChanged(nameof(Magnification));
RaisePropertyChanged(nameof(IsRayOn)); RaisePropertyChanged(nameof(IsRayOn));
RaisePropertyChanged(nameof(Voltage)); RaisePropertyChanged(nameof(Voltage));
RaisePropertyChanged(nameof(Current)); RaisePropertyChanged(nameof(Current));
@@ -591,12 +655,16 @@ namespace XplorePlane.ViewModels.Cnc
private enum MotionAxis private enum MotionAxis
{ {
XM, StageX,
YM, StageY,
ZT, SourceZ,
ZD, DetectorZ,
TiltD, DetectorSwing,
Dist StageRotation,
FixtureRotation,
FOD,
FDD,
Magnification
} }
} }
} }
+28 -12
View File
@@ -489,28 +489,44 @@
Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}"> Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
<UniformGrid Margin="8,8,8,6" Columns="2"> <UniformGrid Margin="8,8,8,6" Columns="2">
<StackPanel Margin="0,0,6,0"> <StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="XM" /> <TextBlock Style="{StaticResource LabelStyle}" Text="StageX" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.XM, UpdateSourceTrigger=LostFocus}" /> <TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.StageX, UpdateSourceTrigger=LostFocus}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="YM" /> <TextBlock Style="{StaticResource LabelStyle}" Text="StageY" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.YM, UpdateSourceTrigger=LostFocus}" /> <TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.StageY, UpdateSourceTrigger=LostFocus}" />
</StackPanel> </StackPanel>
<StackPanel Margin="0,0,6,0"> <StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="ZT" /> <TextBlock Style="{StaticResource LabelStyle}" Text="SourceZ" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZT, UpdateSourceTrigger=LostFocus}" /> <TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.SourceZ, UpdateSourceTrigger=LostFocus}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="ZD" /> <TextBlock Style="{StaticResource LabelStyle}" Text="DetectorZ" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZD, UpdateSourceTrigger=LostFocus}" /> <TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DetectorZ, UpdateSourceTrigger=LostFocus}" />
</StackPanel> </StackPanel>
<StackPanel Margin="0,0,6,0"> <StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="TiltD" /> <TextBlock Style="{StaticResource LabelStyle}" Text="DetectorSwing" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.TiltD, UpdateSourceTrigger=LostFocus}" /> <TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DetectorSwing, UpdateSourceTrigger=LostFocus}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="Dist" /> <TextBlock Style="{StaticResource LabelStyle}" Text="StageRotation" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Dist, UpdateSourceTrigger=LostFocus}" /> <TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.StageRotation, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="FixtureRotation" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.FixtureRotation, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="FOD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.FOD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="FDD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.FDD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="Magnification" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Magnification, UpdateSourceTrigger=LostFocus}" />
</StackPanel> </StackPanel>
</UniformGrid> </UniformGrid>
</GroupBox> </GroupBox>
@@ -53,7 +53,7 @@
Margin="0,0,4,3" Margin="0,0,4,3"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="#333333" Foreground="#333333"
Text="XM" /> Text="StageX" />
<TextBox <TextBox
Grid.Row="0" Grid.Row="0"
Grid.Column="1" Grid.Column="1"
@@ -94,7 +94,7 @@
Margin="0,0,4,3" Margin="0,0,4,3"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="#333333" Foreground="#333333"
Text="YM" /> Text="StageY" />
<TextBox <TextBox
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
@@ -127,7 +127,7 @@
Margin="0,0,4,3" Margin="0,0,4,3"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="#333333" Foreground="#333333"
Text="ZT" /> Text="SourceZ" />
<TextBox <TextBox
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
@@ -151,7 +151,7 @@
Margin="0,0,4,3" Margin="0,0,4,3"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="#333333" Foreground="#333333"
Text="ZD" /> Text="DetectorZ" />
<TextBox <TextBox
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
@@ -175,7 +175,7 @@
Margin="0,0,4,3" Margin="0,0,4,3"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="#333333" Foreground="#333333"
Text="TiltD" /> Text="DetectorSwing" />
<TextBox <TextBox
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
@@ -199,7 +199,7 @@
Margin="0,0,4,0" Margin="0,0,4,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="#333333" Foreground="#333333"
Text="Dist" /> Text="FDD" />
<TextBox <TextBox
Grid.Row="5" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
@@ -228,4 +228,4 @@
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>
</UserControl> </UserControl>