3 Commits

25 changed files with 716 additions and 171 deletions
+42 -6
View File
@@ -136,6 +136,27 @@ namespace XP.Common.Controls
#endregion
#region SwapMouseButtons | SwapMouseButtons Dependency Property
public static readonly DependencyProperty SwapMouseButtonsProperty =
DependencyProperty.Register(nameof(SwapMouseButtons), typeof(bool), typeof(VirtualJoystick),
new PropertyMetadata(false, OnSwapMouseButtonsChanged));
/// <summary>是否交换左右键功能 | Whether to swap left and right button functions</summary>
public bool SwapMouseButtons
{
get => (bool)GetValue(SwapMouseButtonsProperty);
set => SetValue(SwapMouseButtonsProperty, value);
}
private static void OnSwapMouseButtonsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is VirtualJoystick joystick)
joystick.UpdateIconVisibility();
}
#endregion
#region | Directional Icon Dependency Properties
// 左键图标 | Left button icons
@@ -185,7 +206,9 @@ namespace XP.Common.Controls
{
base.OnMouseLeftButtonDown(e);
if (_isDragging || !IsEnabled) return;
StartDrag(MouseButtonType.Left);
// 如果启用了左右键交换,则左键触发右键逻辑,反之亦然
var buttonType = SwapMouseButtons ? MouseButtonType.Right : MouseButtonType.Left;
StartDrag(buttonType);
e.Handled = true;
}
@@ -193,7 +216,9 @@ namespace XP.Common.Controls
{
base.OnMouseRightButtonDown(e);
if (_isDragging || !IsEnabled) return;
StartDrag(MouseButtonType.Right);
// 如果启用了左右键交换,则右键触发左键逻辑,反之亦然
var buttonType = SwapMouseButtons ? MouseButtonType.Left : MouseButtonType.Right;
StartDrag(buttonType);
e.Handled = true;
}
@@ -233,7 +258,10 @@ namespace XP.Common.Controls
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
if (!_isDragging || ActiveMouseButton != MouseButtonType.Left) return;
if (!_isDragging) return;
// 结束拖拽时,根据当前实际按下的按钮类型判断
var expectedType = SwapMouseButtons ? MouseButtonType.Right : MouseButtonType.Left;
if (ActiveMouseButton != expectedType) return;
EndDrag();
e.Handled = true;
}
@@ -241,7 +269,10 @@ namespace XP.Common.Controls
protected override void OnMouseRightButtonUp(MouseButtonEventArgs e)
{
base.OnMouseRightButtonUp(e);
if (!_isDragging || ActiveMouseButton != MouseButtonType.Right) return;
if (!_isDragging) return;
// 结束拖拽时,根据当前实际按下的按钮类型判断
var expectedType = SwapMouseButtons ? MouseButtonType.Left : MouseButtonType.Right;
if (ActiveMouseButton != expectedType) return;
EndDrag();
e.Handled = true;
}
@@ -326,16 +357,21 @@ namespace XP.Common.Controls
SetVisibility(Visibility.Visible, defaultTop, defaultBottom, defaultLeft, defaultRight);
// 根据 ActiveMouseButton 切换 | Switch based on ActiveMouseButton
// 如果启用了左右键交换,则显示相反的图标组
switch (ActiveMouseButton)
{
case MouseButtonType.Left:
SetVisibility(Visibility.Collapsed, defaultTop, defaultBottom, defaultLeft, defaultRight);
SetVisibility(Visibility.Visible, leftTop, leftBottom, leftLeft, leftRight);
// 如果交换了左右键,这里显示的是右键图标组
var leftIcons = SwapMouseButtons ? new[] { rightTop, rightBottom, rightLeft, rightRight } : new[] { leftTop, leftBottom, leftLeft, leftRight };
SetVisibility(Visibility.Visible, leftIcons);
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x3A, 0x7B, 0xC8));
break;
case MouseButtonType.Right:
SetVisibility(Visibility.Collapsed, defaultTop, defaultBottom, defaultLeft, defaultRight);
SetVisibility(Visibility.Visible, rightTop, rightBottom, rightLeft, rightRight);
// 如果交换了左右键,这里显示的是左键图标组
var rightIcons = SwapMouseButtons ? new[] { leftTop, leftBottom, leftLeft, leftRight } : new[] { rightTop, rightBottom, rightLeft, rightRight };
SetVisibility(Visibility.Visible, rightIcons);
if (_thumbElement != null) _thumbElement.Fill = new SolidColorBrush(Color.FromRgb(0x5B, 0xA8, 0x5B));
break;
default:
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

+137 -2
View File
@@ -1,4 +1,4 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
@@ -19,7 +19,7 @@ namespace XP.Hardware.MotionControl.Resources {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -60,6 +60,132 @@ namespace XP.Hardware.MotionControl.Resources {
}
}
/// <summary>
/// 查找类似 轴位置 的本地化字符串。
/// </summary>
internal static string AC_AxisPositions {
get {
return ResourceManager.GetString("AC_AxisPositions", resourceCulture);
}
}
/// <summary>
/// 查找类似 校准计算值 的本地化字符串。
/// </summary>
internal static string AC_CalibrationValue {
get {
return ResourceManager.GetString("AC_CalibrationValue", resourceCulture);
}
}
/// <summary>
/// 查找类似 探测器摆动 的本地化字符串。
/// </summary>
internal static string AC_DetectorSwing {
get {
return ResourceManager.GetString("AC_DetectorSwing", resourceCulture);
}
}
/// <summary>
/// 查找类似 探测器 Z 的本地化字符串。
/// </summary>
internal static string AC_DetectorZ {
get {
return ResourceManager.GetString("AC_DetectorZ", resourceCulture);
}
}
/// <summary>
/// 查找类似 实体操作摇杆使能 的本地化字符串。
/// </summary>
internal static string AC_Enable {
get {
return ResourceManager.GetString("AC_Enable", resourceCulture);
}
}
/// <summary>
/// 查找类似 夹具旋转 的本地化字符串。
/// </summary>
internal static string AC_FixtureRotation {
get {
return ResourceManager.GetString("AC_FixtureRotation", resourceCulture);
}
}
/// <summary>
/// 查找类似 恢复前一位置 的本地化字符串。
/// </summary>
internal static string AC_Restore {
get {
return ResourceManager.GetString("AC_Restore", resourceCulture);
}
}
/// <summary>
/// 查找类似 安全高度 的本地化字符串。
/// </summary>
internal static string AC_SafetyHeight {
get {
return ResourceManager.GetString("AC_SafetyHeight", resourceCulture);
}
}
/// <summary>
/// 查找类似 安全参数 的本地化字符串。
/// </summary>
internal static string AC_SafetyParams {
get {
return ResourceManager.GetString("AC_SafetyParams", resourceCulture);
}
}
/// <summary>
/// 查找类似 保存当前位置 的本地化字符串。
/// </summary>
internal static string AC_Save {
get {
return ResourceManager.GetString("AC_Save", resourceCulture);
}
}
/// <summary>
/// 查找类似 射线源 Z 的本地化字符串。
/// </summary>
internal static string AC_SourceZ {
get {
return ResourceManager.GetString("AC_SourceZ", resourceCulture);
}
}
/// <summary>
/// 查找类似 载物台旋转 的本地化字符串。
/// </summary>
internal static string AC_StageRotation {
get {
return ResourceManager.GetString("AC_StageRotation", resourceCulture);
}
}
/// <summary>
/// 查找类似 载物台 X 的本地化字符串。
/// </summary>
internal static string AC_StageX {
get {
return ResourceManager.GetString("AC_StageX", resourceCulture);
}
}
/// <summary>
/// 查找类似 载物台 Y 的本地化字符串。
/// </summary>
internal static string AC_StageY {
get {
return ResourceManager.GetString("AC_StageY", resourceCulture);
}
}
/// <summary>
/// 查找类似 Actual 的本地化字符串。
/// </summary>
@@ -327,6 +453,15 @@ namespace XP.Hardware.MotionControl.Resources {
}
}
/// <summary>
/// 查找类似 运动控制 的本地化字符串。
/// </summary>
internal static string MC_MotionCtrl {
get {
return ResourceManager.GetString("MC_MotionCtrl", resourceCulture);
}
}
/// <summary>
/// 查找类似 Move 的本地化字符串。
/// </summary>
@@ -258,30 +258,29 @@ SourceZ → {3:F2}mm
DetectorZ → {4:F2}mm
Confirm to filll move matrix?</value>
</data>
<!-- AxisControlView localization resources -->
<data name="AC_AxisPositions" xml:space="preserve">
<value>Axis Positions</value>
</data>
<data name="AC_StageX" xml:space="preserve">
<value>Stage X</value>
<value>X mm</value>
</data>
<data name="AC_StageY" xml:space="preserve">
<value>Stage Y</value>
<value>Y mm</value>
</data>
<data name="AC_SourceZ" xml:space="preserve">
<value>Source Z</value>
<value>SZ mm</value>
</data>
<data name="AC_DetectorZ" xml:space="preserve">
<value>Detector Z</value>
<value>DZ mm</value>
</data>
<data name="AC_DetectorSwing" xml:space="preserve">
<value>Detector Swing</value>
<value>DT' °</value>
</data>
<data name="AC_StageRotation" xml:space="preserve">
<value>Stage Rotation</value>
<value>R' °</value>
</data>
<data name="AC_FixtureRotation" xml:space="preserve">
<value>Fixture Rotation</value>
<value>FR' °</value>
</data>
<data name="AC_SafetyParams" xml:space="preserve">
<value>Safety Parameters</value>
@@ -301,4 +300,7 @@ Confirm to filll move matrix?</value>
<data name="AC_Restore" xml:space="preserve">
<value>Restore Position</value>
</data>
<data name="MC_MotionCtrl" xml:space="preserve">
<value>Motion Control</value>
</data>
</root>
@@ -301,7 +301,6 @@ DetectorZ → {4:F2}mm
确认填入信息? | Confirm to filll move matrix?</value>
<comment>几何反算确认提示 | Geometry inverse confirmation message</comment>
</data>
<!-- AxisControlView 多语言资源 | AxisControlView localization resources -->
<data name="AC_AxisPositions" xml:space="preserve">
<value>轴位置</value>
<comment>轴位置分组标题 | Axis positions group title</comment>
@@ -358,4 +357,8 @@ DetectorZ → {4:F2}mm
<value>恢复前一位置</value>
<comment>恢复按钮文本 | Restore button text</comment>
</data>
<data name="MC_MotionCtrl" xml:space="preserve">
<value>运动控制</value>
<comment>header</comment>
</data>
</root>
@@ -258,30 +258,29 @@ SourceZ → {3:F2}mm
DetectorZ → {4:F2}mm
确认填入目标值信息?</value>
</data>
<!-- AxisControlView 多语言资源 | AxisControlView localization resources -->
<data name="AC_AxisPositions" xml:space="preserve">
<value>轴位置</value>
</data>
<data name="AC_StageX" xml:space="preserve">
<value>载物台 X</value>
<value>X mm</value>
</data>
<data name="AC_StageY" xml:space="preserve">
<value>载物台 Y</value>
<value>Y mm</value>
</data>
<data name="AC_SourceZ" xml:space="preserve">
<value>射线源 Z</value>
<value>SZ mm</value>
</data>
<data name="AC_DetectorZ" xml:space="preserve">
<value>探测器 Z</value>
<value>DZ mm</value>
</data>
<data name="AC_DetectorSwing" xml:space="preserve">
<value>探测器摆动</value>
<value>DT' °</value>
</data>
<data name="AC_StageRotation" xml:space="preserve">
<value>载物台旋转</value>
<value>R' °</value>
</data>
<data name="AC_FixtureRotation" xml:space="preserve">
<value>夹具旋转</value>
<value>FR' °</value>
</data>
<data name="AC_SafetyParams" xml:space="preserve">
<value>安全参数</value>
@@ -301,4 +300,7 @@ DetectorZ → {4:F2}mm
<data name="AC_Restore" xml:space="preserve">
<value>恢复前一位置</value>
</data>
<data name="MC_MotionCtrl" xml:space="preserve">
<value>运动控制</value>
</data>
</root>
@@ -258,30 +258,29 @@ SourceZ → {3:F2}mm
DetectorZ → {4:F2}mm
確填入目標值資料?</value>
</data>
<!-- AxisControlView 多語言資源 | AxisControlView localization resources -->
<data name="AC_AxisPositions" xml:space="preserve">
<value>軸位置</value>
</data>
<data name="AC_StageX" xml:space="preserve">
<value>載物台 X</value>
<value>X mm</value>
</data>
<data name="AC_StageY" xml:space="preserve">
<value>載物台 Y</value>
<value>Y mm</value>
</data>
<data name="AC_SourceZ" xml:space="preserve">
<value>射線源 Z</value>
<value>SZ mm</value>
</data>
<data name="AC_DetectorZ" xml:space="preserve">
<value>探測器 Z</value>
<value>DZ mm</value>
</data>
<data name="AC_DetectorSwing" xml:space="preserve">
<value>探測器擺動</value>
<value>DT' °</value>
</data>
<data name="AC_StageRotation" xml:space="preserve">
<value>載物台旋轉</value>
<value>R' °</value>
</data>
<data name="AC_FixtureRotation" xml:space="preserve">
<value>夾具旋轉</value>
<value>FR' °</value>
</data>
<data name="AC_SafetyParams" xml:space="preserve">
<value>安全參數</value>
@@ -301,4 +300,7 @@ DetectorZ → {4:F2}mm
<data name="AC_Restore" xml:space="preserve">
<value>恢復前一位置</value>
</data>
<data name="MC_MotionCtrl" xml:space="preserve">
<value>運動控制</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

@@ -82,6 +82,7 @@ namespace XP.Hardware.MotionControl.ViewModels
// 初始化命令 | Initialize commands
ToggleEnableCommand = new DelegateCommand(ExecuteToggleEnable, () => IsPlcConnected);
ToggleSwapMouseButtonsCommand = new DelegateCommand(ExecuteToggleSwapMouseButtons);
SavePositionsCommand = new DelegateCommand(ExecuteSavePositions);
RestorePositionsCommand = new DelegateCommand(ExecuteRestorePositions, () => _savedPositions != null && IsPlcConnected);
@@ -254,6 +255,10 @@ namespace XP.Hardware.MotionControl.ViewModels
/// <summary>摇杆使能状态 | Joystick enable state</summary>
public bool IsJoystickEnabled { get => _isJoystickEnabled; set => SetProperty(ref _isJoystickEnabled, value); }
private bool _swapMouseButtons;
/// <summary>是否交换摇杆左右键功能 | Whether to swap left and right joystick button functions</summary>
public bool SwapMouseButtons { get => _swapMouseButtons; set => SetProperty(ref _swapMouseButtons, value); }
private bool _isPlcConnected;
/// <summary>PLC 连接状态 | PLC connection status</summary>
public bool IsPlcConnected { get => _isPlcConnected; set => SetProperty(ref _isPlcConnected, value); }
@@ -264,11 +269,21 @@ namespace XP.Hardware.MotionControl.ViewModels
#endregion
#region | Saved Positions State
/// <summary>是否有保存的位置数据 | Whether saved position data exists</summary>
public bool HasSavedPositions => _savedPositions != null;
#endregion
#region | Commands
/// <summary>切换使能开关命令 | Toggle enable switch command</summary>
public DelegateCommand ToggleEnableCommand { get; }
/// <summary>切换摇杆左右键功能命令 | Toggle joystick button swap command</summary>
public DelegateCommand ToggleSwapMouseButtonsCommand { get; }
/// <summary>保存当前轴位置命令 | Save current axis positions command</summary>
public DelegateCommand SavePositionsCommand { get; }
@@ -375,6 +390,7 @@ namespace XP.Hardware.MotionControl.ViewModels
private void RaiseCommandCanExecuteChanged()
{
ToggleEnableCommand.RaiseCanExecuteChanged();
ToggleSwapMouseButtonsCommand.RaiseCanExecuteChanged();
SavePositionsCommand.RaiseCanExecuteChanged();
RestorePositionsCommand.RaiseCanExecuteChanged();
}
@@ -440,6 +456,15 @@ namespace XP.Hardware.MotionControl.ViewModels
// TODO: 发送使能状态到 PLC(根据实际 PLC 信号定义)| Send enable state to PLC (based on actual PLC signal definition)
}
/// <summary>
/// 切换左右键交换状态 | Toggle swap mouse buttons state
/// </summary>
private void ExecuteToggleSwapMouseButtons()
{
SwapMouseButtons = !SwapMouseButtons;
_logger.Info("摇杆左右键功能交换:{Enabled} | Joystick button swap toggled: {Enabled}", SwapMouseButtons);
}
/// <summary>
/// 保存当前 6 个轴位置到内部变量 | Save current 6 axis positions to internal variable
/// </summary>
@@ -456,6 +481,7 @@ namespace XP.Hardware.MotionControl.ViewModels
FixtureRotation = FixtureRotationAngle
};
RestorePositionsCommand.RaiseCanExecuteChanged();
RaisePropertyChanged(nameof(HasSavedPositions));
_logger.Info("轴位置已保存 | Axis positions saved");
}
@@ -12,24 +12,43 @@
MinWidth="350"
HorizontalAlignment="Stretch" Background="White">
<Grid Margin="6">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ========== 上部:左(轴位置)+ 右(摇杆)========== -->
<!-- 标题栏 -->
<Grid Grid.Row="0">
<Border
Grid.Row="0"
Background="#F0F0F0"
BorderBrush="#DDDDDD"
BorderThickness="0,0,0,1">
<TextBlock
Margin="8,4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontWeight="SemiBold"
Foreground="#333333"
Text="{loc:Localization MC_MotionCtrl}" />
</Border>
</Grid>
<!-- ========== 上部:左(轴位置)+ 右(摇杆)========== -->
<Grid Grid.Row="1" Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- ===== 左侧:轴位置输入框 ===== -->
<Grid Grid.Column="0" Margin="0,0,4,0" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
@@ -41,26 +60,26 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{loc:Localization AC_StageX}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1"/>
<telerik:RadNumericUpDown Grid.Row="0" Grid.Column="1" x:Name="NumStageX" Value="{Binding StageXPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumStageX_GotFocus" LostFocus="NumStageX_LostFocus" KeyDown="NumStageX_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{loc:Localization AC_StageX}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="0" Grid.Column="0" x:Name="NumStageX" Value="{Binding StageXPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageX_GotFocus" LostFocus="NumStageX_LostFocus" KeyDown="NumStageX_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="{loc:Localization AC_StageY}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1"/>
<telerik:RadNumericUpDown Grid.Row="1" Grid.Column="1" x:Name="NumStageY" Value="{Binding StageYPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumStageY_GotFocus" LostFocus="NumStageY_LostFocus" KeyDown="NumStageY_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{loc:Localization AC_StageY}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="1" Grid.Column="0" x:Name="NumStageY" Value="{Binding StageYPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageY_GotFocus" LostFocus="NumStageY_LostFocus" KeyDown="NumStageY_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="{loc:Localization AC_SourceZ}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1"/>
<telerik:RadNumericUpDown Grid.Row="2" Grid.Column="1" x:Name="NumSourceZ" Value="{Binding SourceZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumSourceZ_GotFocus" LostFocus="NumSourceZ_LostFocus" KeyDown="NumSourceZ_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{loc:Localization AC_SourceZ}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="2" Grid.Column="0" x:Name="NumSourceZ" Value="{Binding SourceZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumSourceZ_GotFocus" LostFocus="NumSourceZ_LostFocus" KeyDown="NumSourceZ_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="{loc:Localization AC_DetectorZ}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1"/>
<telerik:RadNumericUpDown Grid.Row="3" Grid.Column="1" x:Name="NumDetectorZ" Value="{Binding DetectorZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumDetectorZ_GotFocus" LostFocus="NumDetectorZ_LostFocus" KeyDown="NumDetectorZ_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{loc:Localization AC_DetectorZ}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1"/>
<telerik:RadNumericUpDown Grid.Row="3" Grid.Column="0" x:Name="NumDetectorZ" Value="{Binding DetectorZPosition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumDetectorZ_GotFocus" LostFocus="NumDetectorZ_LostFocus" KeyDown="NumDetectorZ_KeyDown" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="{loc:Localization AC_DetectorSwing}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1" Visibility="{Binding DetectorSwingVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="4" Grid.Column="1" x:Name="NumDetSwing" Value="{Binding DetectorSwingAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumDetSwing_GotFocus" LostFocus="NumDetSwing_LostFocus" KeyDown="NumDetSwing_KeyDown" Visibility="{Binding DetectorSwingVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="4" Grid.Column="1" Text="{loc:Localization AC_DetectorSwing}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1" Visibility="{Binding DetectorSwingVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="4" Grid.Column="0" x:Name="NumDetSwing" Value="{Binding DetectorSwingAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumDetSwing_GotFocus" LostFocus="NumDetSwing_LostFocus" KeyDown="NumDetSwing_KeyDown" Visibility="{Binding DetectorSwingVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="{loc:Localization AC_StageRotation}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1" Visibility="{Binding StageRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="5" Grid.Column="1" x:Name="NumStageRot" Value="{Binding StageRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumStageRot_GotFocus" LostFocus="NumStageRot_LostFocus" KeyDown="NumStageRot_KeyDown" Visibility="{Binding StageRotationVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="5" Grid.Column="1" Text="{loc:Localization AC_StageRotation}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1" Visibility="{Binding StageRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="5" Grid.Column="0" x:Name="NumStageRot" Value="{Binding StageRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumStageRot_GotFocus" LostFocus="NumStageRot_LostFocus" KeyDown="NumStageRot_KeyDown" Visibility="{Binding StageRotationVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="6" Grid.Column="0" Text="{loc:Localization AC_FixtureRotation}" FontSize="11" VerticalAlignment="Center" Margin="0,1,4,1" Visibility="{Binding FixtureRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="6" Grid.Column="1" x:Name="NumFixtureRot" Value="{Binding FixtureRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="1" SmallChange="0.1" IsEditable="True" GotFocus="NumFixtureRot_GotFocus" LostFocus="NumFixtureRot_LostFocus" KeyDown="NumFixtureRot_KeyDown" Visibility="{Binding FixtureRotationVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Row="6" Grid.Column="1" Text="{loc:Localization AC_FixtureRotation}" FontSize="11" VerticalAlignment="Center" Margin="3,1,1,1" Visibility="{Binding FixtureRotationVisibility}"/>
<telerik:RadNumericUpDown Grid.Row="6" Grid.Column="0" x:Name="NumFixtureRot" Value="{Binding FixtureRotationAngle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ValueFormat="Numeric" NumberDecimalDigits="3" SmallChange="0.1" IsEditable="True" GotFocus="NumFixtureRot_GotFocus" LostFocus="NumFixtureRot_LostFocus" KeyDown="NumFixtureRot_KeyDown" Visibility="{Binding FixtureRotationVisibility}" Margin="0,1" Height="24" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
</Grid>
<!-- ===== 右侧:摇杆区域 ===== -->
@@ -69,102 +88,133 @@
<!-- 单轴摇杆(腰圆)-->
<controls:VirtualJoystick x:Name="SingleJoystick"
JoystickMode="SingleAxisY"
Width="40" Height="160"
Width="41" Height="150"
IsEnabled="{Binding IsJoystickEnabled}"
SwapMouseButtons="{Binding SwapMouseButtons}"
DefaultTopIcon="↑" DefaultBottomIcon="↓"
LeftButtonTopIcon="Src↑" LeftButtonBottomIcon="Src↓"
RightButtonTopIcon="Det↑" RightButtonBottomIcon="Det↓"
LeftButtonTopIcon="SZ↑" LeftButtonBottomIcon="SZ↓"
RightButtonTopIcon="DZ↑" RightButtonBottomIcon="DZ↓"
Margin="2,0,8,0"/>
<!-- 双轴摇杆(圆形)-->
<controls:VirtualJoystick x:Name="DualJoystick"
JoystickMode="DualAxis"
Width="160" Height="160"
Width="150" Height="150"
IsEnabled="{Binding IsJoystickEnabled}"
SwapMouseButtons="{Binding SwapMouseButtons}"
DefaultTopIcon="↑" DefaultBottomIcon="↓" DefaultLeftIcon="←" DefaultRightIcon="→"
LeftButtonTopIcon="Y+" LeftButtonBottomIcon="Y-" LeftButtonLeftIcon="X-" LeftButtonRightIcon="X+"
RightButtonTopIcon="Rot+" RightButtonBottomIcon="Rot-" RightButtonLeftIcon="Swing-" RightButtonRightIcon="Swing+"
Margin="0,0,2,0"/>
RightButtonTopIcon="R+" RightButtonBottomIcon="R-" RightButtonLeftIcon="DT-" RightButtonRightIcon="DT+"
Margin="0,0,2,0" Cursor="Hand"/>
</StackPanel>
</Grid>
<!-- ========== 下部:安全参数(一行均布)+ 操作按钮(一行均布)========== -->
<StackPanel Grid.Row="1" Margin="0,8,0,0">
<!-- 安全参数一行(均布)-->
<Grid Margin="0,0,0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{loc:Localization AC_SafetyHeight}"
FontSize="11" VerticalAlignment="Center" Margin="0,0,4,0"/>
<telerik:RadNumericUpDown Grid.Column="1" x:Name="NumSafetyHeight"
Value="{Binding SafetyHeight, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ValueFormat="Numeric" NumberDecimalDigits="2" SmallChange="0.1" IsEditable="True"
KeyDown="NumSafetyHeight_KeyDown"
Height="24" MinWidth="70" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
<TextBlock Grid.Column="3" Text="{loc:Localization AC_CalibrationValue}"
FontSize="11" VerticalAlignment="Center" Margin="0,0,4,0"/>
<telerik:RadNumericUpDown Grid.Column="4" x:Name="NumCalibration"
Value="{Binding CalibrationValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ValueFormat="Numeric" NumberDecimalDigits="2" SmallChange="0.1" IsEditable="True"
KeyDown="NumCalibration_KeyDown"
Height="24" MinWidth="70" FontSize="11" telerik:StyleManager.Theme="Crystal"/>
</Grid>
<!-- ========== 下部:操作按钮(一行均布)========== -->
<StackPanel Grid.Row="2" Margin="6,0,6,6">
<!-- 操作按钮一行(均布)-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 使能开关 -->
<TextBlock Grid.Column="0" Text="{loc:Localization AC_Enable}" FontSize="11" VerticalAlignment="Center" Margin="0,0,4,0"/>
<telerik:RadToggleSwitchButton Grid.Column="1" IsChecked="{Binding IsJoystickEnabled, Mode=TwoWay}"
<!-- 虚拟摇杆使能开关 -->
<telerik:RadButton Grid.Column="1" Width="35" Height="24" Margin="0,0,8,0"
Command="{Binding ToggleEnableCommand}"
telerik:StyleManager.Theme="Crystal"/>
ToolTip="{loc:Localization AC_Enable}"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/ToggleDisable.png" Width="15" Height="15"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsJoystickEnabled}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/ToggleEnable.png" Width="15" Height="15"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>
<!-- 摇杆左右键功能切换开关 -->
<telerik:RadButton Grid.Column="2" Width="35" Height="24" Margin="0,0,8,0"
Command="{Binding ToggleSwapMouseButtonsCommand}"
ToolTip="{loc:Localization AC_SwapMouseButtons}"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SwingDisable.png" Width="19" Height="17"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding SwapMouseButtons}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SwingEnable.png" Width="17" Height="17"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>
<!-- 保存当前位置 -->
<telerik:RadButton Grid.Column="3" Content="{loc:Localization AC_Save}"
<telerik:RadButton Grid.Column="3" Width="35" Height="24" Margin="0,0,8,0"
Command="{Binding SavePositionsCommand}"
Height="24" MinWidth="80" Padding="8,0" FontSize="11"
telerik:StyleManager.Theme="Crystal"/>
ToolTip="{loc:Localization AC_Save}"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/SavePoint.png" Width="14" Height="14"/>
</Setter.Value>
</Setter>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>
<!-- 恢复前一位置 -->
<telerik:RadButton Grid.Column="5" Content="{loc:Localization AC_Restore}"
<telerik:RadButton Grid.Column="4" Width="35" Height="24" Margin="0,0,8,0"
Command="{Binding RestorePositionsCommand}"
Height="24" MinWidth="80" Padding="8,0" FontSize="11"
telerik:StyleManager.Theme="Crystal"/>
ToolTip="{loc:Localization AC_Restore}"
IsEnabled="{Binding HasSavedPositions}"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/BackPointDisable.png" Width="14" Height="14"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HasSavedPositions}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="pack://application:,,,/XP.Hardware.MotionControl;component/Resources/BackPointEnable.png" Width="14" Height="14"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>
</Grid>
<!-- 错误信息 -->
<TextBlock Text="{Binding ErrorMessage}" FontSize="10" Foreground="#FFE53935"
TextWrapping="Wrap" Margin="0,4,0,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ErrorMessage}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding ErrorMessage}" Value="">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Grid>
</UserControl>
@@ -13,16 +13,29 @@
<ProjectReference Include="..\XP.Hardware.PLC\XP.Hardware.PLC.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Resource Include="Resources\*.png" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Resource Update="Resources\BackPointDisable.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Update="Resources\BackPointEnable.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Update="Resources\SavePoint.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Update="Resources\SwingDisable.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Update="Resources\SwingEnable.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Update="Resources\ToggleDisable.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Update="Resources\ToggleEnable.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
</ItemGroup>
</Project>
+13 -4
View File
@@ -1,4 +1,4 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
@@ -19,7 +19,7 @@ namespace XP.Hardware.RaySource.Resources {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -133,7 +133,7 @@ namespace XP.Hardware.RaySource.Resources {
}
/// <summary>
/// 查找类似 射线源配置 的本地化字符串。
/// 查找类似 射线源高级选项 的本地化字符串。
/// </summary>
internal static string RaySource_ConfigWindowTitle {
get {
@@ -604,7 +604,7 @@ namespace XP.Hardware.RaySource.Resources {
/// <summary>
/// 查找类似 射线源
///不可用 的本地化字符串。
///未连接 的本地化字符串。
/// </summary>
internal static string RaySource_StatusUnavailable {
get {
@@ -855,6 +855,15 @@ namespace XP.Hardware.RaySource.Resources {
}
}
/// <summary>
/// 查找类似 射线 的本地化字符串。
/// </summary>
internal static string RaySource_XRay {
get {
return ResourceManager.GetString("RaySource_XRay", resourceCulture);
}
}
/// <summary>
/// 查找类似 关闭 的本地化字符串。
/// </summary>
@@ -1,5 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
@@ -179,7 +238,7 @@ Opened</value>
</data>
<data name="RaySource_StatusUnavailable" xml:space="preserve">
<value>X-Ray
Unavailable</value>
Not Connected</value>
</data>
<data name="RaySource_ConnectButton" xml:space="preserve">
<value>Connect Ray Source</value>
@@ -215,7 +274,7 @@ Unavailable</value>
<value>Config</value>
</data>
<data name="RaySource_ConfigWindowTitle" xml:space="preserve">
<value>X-Ray Source Configuration</value>
<value>X-Ray Source Advanced Options</value>
</data>
<data name="RaySource_WarmUpLabel" xml:space="preserve">
<value>Warm-Up:</value>
@@ -244,8 +303,8 @@ Unavailable</value>
<data name="RaySource_InterlockNormal" xml:space="preserve">
<value>Normal</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>X-Ray:</value>
<data name="RaySource_XRay" xml:space="preserve">
<value>X-Ray</value>
</data>
<data name="RaySource_XRayOn" xml:space="preserve">
<value>On</value>
@@ -334,4 +393,7 @@ Unavailable</value>
<data name="RaySource_Operation_Sent" xml:space="preserve">
<value>Operation command sent, waiting for device execution...</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>X-Ray:</value>
</data>
</root>
+67 -5
View File
@@ -1,5 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
@@ -190,7 +249,7 @@
</data>
<data name="RaySource_StatusUnavailable" xml:space="preserve">
<value>射线源
不可用</value>
未连接</value>
<comment>RaySourceOperateView - 射线源不可用状态文本 | X-Ray unavailable status text</comment>
</data>
<data name="RaySource_ConnectButton" xml:space="preserve">
@@ -238,7 +297,7 @@
<comment>RaySourceOperateView - 配置按钮 | Config button</comment>
</data>
<data name="RaySource_ConfigWindowTitle" xml:space="preserve">
<value>射线源配置</value>
<value>射线源高级选项</value>
<comment>RaySourceConfigWindow - 窗口标题 | Window title</comment>
</data>
<data name="RaySource_WarmUpLabel" xml:space="preserve">
@@ -277,9 +336,8 @@
<value>正常</value>
<comment>RaySourceConfigView - 连锁正常状态 | Interlock normal status</comment>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>射线状态:</value>
<comment>RaySourceConfigView - 射线开启状态标签 | X-ray on status label</comment>
<data name="RaySource_XRay" xml:space="preserve">
<value>射线</value>
</data>
<data name="RaySource_XRayOn" xml:space="preserve">
<value>开启</value>
@@ -383,4 +441,8 @@
<data name="RaySource_Operation_Sent" xml:space="preserve">
<value>操作指令已发送,等待设备执行...</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>射线状态:</value>
<comment>RaySourceConfigView - 射线开启状态标签 | X-ray on status label</comment>
</data>
</root>
@@ -1,5 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
@@ -179,7 +238,7 @@
</data>
<data name="RaySource_StatusUnavailable" xml:space="preserve">
<value>射线源
不可用</value>
未连接</value>
</data>
<data name="RaySource_ConnectButton" xml:space="preserve">
<value>连接射线源</value>
@@ -215,7 +274,7 @@
<value>配置</value>
</data>
<data name="RaySource_ConfigWindowTitle" xml:space="preserve">
<value>射线源配置</value>
<value>射线源高级选项</value>
</data>
<data name="RaySource_WarmUpLabel" xml:space="preserve">
<value>暖机:</value>
@@ -244,8 +303,8 @@
<data name="RaySource_InterlockNormal" xml:space="preserve">
<value>正常</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>射线状态:</value>
<data name="RaySource_XRay" xml:space="preserve">
<value>射线</value>
</data>
<data name="RaySource_XRayOn" xml:space="preserve">
<value>开启</value>
@@ -334,4 +393,7 @@
<data name="RaySource_Operation_Sent" xml:space="preserve">
<value>操作指令已发送,等待设备执行...</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>射线状态:</value>
</data>
</root>
@@ -1,5 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
@@ -179,7 +238,7 @@
</data>
<data name="RaySource_StatusUnavailable" xml:space="preserve">
<value>射線源
不可用</value>
未連線</value>
</data>
<data name="RaySource_ConnectButton" xml:space="preserve">
<value>連接射線源</value>
@@ -215,7 +274,7 @@
<value>配置</value>
</data>
<data name="RaySource_ConfigWindowTitle" xml:space="preserve">
<value>射線源配置</value>
<value>射線源高級選項</value>
</data>
<data name="RaySource_WarmUpLabel" xml:space="preserve">
<value>暖機:</value>
@@ -244,8 +303,8 @@
<data name="RaySource_InterlockNormal" xml:space="preserve">
<value>正常</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>射線狀態:</value>
<data name="RaySource_XRay" xml:space="preserve">
<value>射線</value>
</data>
<data name="RaySource_XRayOn" xml:space="preserve">
<value>開啟</value>
@@ -334,4 +393,7 @@
<data name="RaySource_Operation_Sent" xml:space="preserve">
<value>操作指令已發送,等待設備執行...</value>
</data>
<data name="RaySource_XRayOnLabel" xml:space="preserve">
<value>射線狀態:</value>
</data>
</root>
@@ -9,7 +9,7 @@
xmlns:prism="http://prismlibrary.com/"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="XP.Hardware.RaySource.Views.RaySourceOperateView"
mc:Ignorable="d" d:DesignWidth="350"
prism:ViewModelLocator.AutoWireViewModel="True" Height="249" Background="White" >
prism:ViewModelLocator.AutoWireViewModel="True" Height="245" Background="White" >
<UserControl.Resources>
<!-- 转换器 | Converters -->
<converters:RaySourceStatusToColorConverter x:Key="StatusToColorConverter"/>
@@ -61,26 +61,44 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" MinHeight="70" />
<RowDefinition Height="Auto" MinHeight="70" />
</Grid.RowDefinitions>
<!-- 标题栏 -->
<Grid Grid.Row="0">
<Border
Grid.Row="0"
Background="#F0F0F0"
BorderBrush="#DDDDDD"
BorderThickness="0,0,0,1">
<TextBlock
Margin="8,4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontWeight="SemiBold"
Foreground="#333333"
Text="{loc:Localization RaySource_XRay}" />
</Border>
</Grid>
<!-- 1. 状态区:腰圆指示器 + 按钮 | Status Area: Capsule Indicator + Buttons -->
<Grid Grid.Row="0" Margin="5,5,5,10">
<Grid Grid.Row="1" Margin="3,10,3,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 腰圆状态指示器 | Capsule Status Indicator -->
<Grid Grid.Column="0" Width="200" Height="80" Margin="20 0 0 5">
<Grid Grid.Column="0" Width="190" Height="70" Margin="20 0 0 5">
<Border x:Name="StatusIndicator"
Width="200" Height="80"
Width="190" Height="70"
Background="{Binding RaySourceStatus, Converter={StaticResource StatusToColorConverter}}"
BorderBrush="{Binding RaySourceStatus, Converter={StaticResource StatusToBorderColorConverter}}"
BorderThickness="2"
CornerRadius="40">
CornerRadius="35">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
@@ -98,7 +116,7 @@
</Border.Style>
</Border>
<TextBlock Text="{Binding StatusText}"
Foreground="White" FontSize="18" FontWeight="Bold"
Foreground="White" FontSize="16" FontWeight="Bold"
HorizontalAlignment="Center" VerticalAlignment="Center"
TextAlignment="Center" LineHeight="20"/>
<!-- 连锁状态图标(腰圆右侧圆弧区域)| Interlock status icon (right arc area of capsule) -->
@@ -126,10 +144,10 @@
<!-- 按钮区 | Button Area -->
<StackPanel Grid.Column="1" Orientation="Vertical"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Margin="20 0 20 0">
Margin="15 0 15 0">
<telerik:RadButton Content="{loc:Localization RaySource_TurnOnButton}"
Command="{Binding TurnOnCommand}"
Margin="0 0 0 8" Height="35" HorizontalAlignment="Stretch"
Margin="0 0 0 7" Height="30" HorizontalAlignment="Stretch"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
@@ -140,7 +158,7 @@
</telerik:RadButton>
<telerik:RadButton Content="{loc:Localization RaySource_TurnOffButton}"
Command="{Binding TurnOffCommand}"
Margin="0 0 0 0" Height="35" HorizontalAlignment="Stretch"
Margin="0 0 0 0" Height="30" HorizontalAlignment="Stretch"
telerik:StyleManager.Theme="Crystal">
<telerik:RadButton.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
@@ -153,7 +171,7 @@
</Grid>
<!-- 2. 电压区 | Voltage Area -->
<Grid Grid.Row="1" Margin="20,0,20,0">
<Grid Grid.Row="2" Margin="15,0,15,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
@@ -167,7 +185,7 @@
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_VoltageLabel}"
FontSize="14" FontWeight="Bold" VerticalAlignment="Center"/>
FontSize="13" FontWeight="Bold" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="{Binding VoltageActualText}"
FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right"/>
</Grid>
@@ -206,15 +224,15 @@
</Grid>
<!-- 按钮行:配置 | Button Row: Config -->
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0">
<telerik:RadButton Content="{loc:Localization RaySource_ConfigButton}"
<telerik:RadButton Content="{loc:Localization RaySource_AdvanceButton}"
Command="{Binding ConfigCommand}"
Width="70"
telerik:StyleManager.Theme="Crystal" FontSize="10"/>
telerik:StyleManager.Theme="Crystal" FontSize="10" Visibility="Collapsed"/>
</StackPanel>
</Grid>
<!-- 3. 电流区 | Current Area -->
<Grid Grid.Row="1" Margin="20,75,20,0" Grid.RowSpan="2">
<Grid Grid.Row="3" Margin="15,-10,15,0" Grid.RowSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
@@ -228,7 +246,7 @@
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{loc:Localization RaySource_CurrentLabel}"
FontSize="14" FontWeight="Bold" VerticalAlignment="Center"/>
FontSize="13" FontWeight="Bold" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="{Binding CurrentActualText}"
FontSize="10" VerticalAlignment="Center" HorizontalAlignment="Right"/>
</Grid>
@@ -269,10 +287,10 @@
<!-- 按钮行:高级 | Button Row: Advance -->
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,0,0">
<telerik:RadButton Content="{loc:Localization RaySource_AdvanceButton}"
<telerik:RadButton Content="{loc:Localization RaySource_ConfigButton}"
Command="{Binding SettingsCommand}"
Width="70"
telerik:StyleManager.Theme="Crystal" FontSize="10"/>
telerik:StyleManager.Theme="Crystal" FontSize="10" Visibility="Collapsed"/>
</StackPanel>
</Grid>
</Grid>
+1 -1
View File
@@ -149,7 +149,7 @@
<add key="MotionControl:FixtureRotation:Min" value="-90" />
<add key="MotionControl:FixtureRotation:Max" value="90" />
<add key="MotionControl:FixtureRotation:Origin" value="0" />
<add key="MotionControl:FixtureRotation:Enabled" value="true" />
<add key="MotionControl:FixtureRotation:Enabled" value="false" />
<!-- 几何原点(mm| Geometry origins (mm) -->
<add key="MotionControl:Geometry:SourceZOrigin" value="0" />
<add key="MotionControl:Geometry:DetectorZOrigin" value="600" />
+5 -5
View File
@@ -541,7 +541,7 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ViewportPanelWidth}" />
<ColumnDefinition Width="{Binding ImagePanelWidth}" />
<ColumnDefinition Width="350" />
<ColumnDefinition Width="370" />
</Grid.ColumnDefinitions>
<Border
@@ -560,16 +560,16 @@
<Grid Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="350*" />
<ColumnDefinition Width="370"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<views1:RaySourceOperateView Grid.Row="0" Grid.ColumnSpan="2" />
<mcViews:AxisControlView Grid.Row="1" Grid.ColumnSpan="2" />
<views:NavigationPropertyPanelView Grid.Row="2" Grid.ColumnSpan="2" />
<views1:RaySourceOperateView Grid.Row="0" Margin="0,0,5,0" />
<mcViews:AxisControlView Grid.Row="1" Margin="0,0,5,0" />
<views:NavigationPropertyPanelView Grid.Row="2" Margin="0,0,5,0" Grid.RowSpan="2" />
</Grid>
</Grid>
+1
View File
@@ -56,6 +56,7 @@
<PropertyGroup>
<TelerikDir>..\ExternalLibraries\Telerik</TelerikDir>
<BaseOutputPath>..\bin\</BaseOutputPath>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Telerik.Windows.Controls">