255 lines
9.8 KiB
C#
255 lines
9.8 KiB
C#
|
|
using MainShell.Common;
|
|||
|
|
using MainShell.Hardware;
|
|||
|
|
using MainShell.Models;
|
|||
|
|
using MwFramework.Controls.ControlCanvas;
|
|||
|
|
using Stylet;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.ObjectModel;
|
|||
|
|
using System.ComponentModel;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Windows.Input;
|
|||
|
|
|
|||
|
|
namespace MainShell.Common.ViewModel
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 单个光源通道的包装类
|
|||
|
|
/// </summary>
|
|||
|
|
public class LightChannelViewModel : PropertyChangedBase
|
|||
|
|
{
|
|||
|
|
private readonly object _sourceConfig;
|
|||
|
|
private readonly PropertyInfo _propertyInfo;
|
|||
|
|
|
|||
|
|
public string Name { get; set; }
|
|||
|
|
|
|||
|
|
public int Value
|
|||
|
|
{
|
|||
|
|
get => (int)_propertyInfo.GetValue(_sourceConfig);
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (value != Value)
|
|||
|
|
{
|
|||
|
|
_propertyInfo.SetValue(_sourceConfig, value);
|
|||
|
|
NotifyOfPropertyChange();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public LightChannelViewModel(object sourceConfig, PropertyInfo propertyInfo, string displayName)
|
|||
|
|
{
|
|||
|
|
_sourceConfig = sourceConfig;
|
|||
|
|
_propertyInfo = propertyInfo;
|
|||
|
|
Name = displayName;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 相机及光源参数设置弹窗 ViewModel
|
|||
|
|
/// </summary>
|
|||
|
|
public class CameraSettingsViewModel : Screen
|
|||
|
|
{
|
|||
|
|
private readonly IWindowManager _windowManager;
|
|||
|
|
private readonly HardwareManager _hardwareManager;
|
|||
|
|
|
|||
|
|
// 核心标志位:是否正在从硬件同步数据
|
|||
|
|
private bool _isSyncingFromHardware;
|
|||
|
|
|
|||
|
|
private CameraType _currentCameraType;
|
|||
|
|
private object _currentLightConfig;
|
|||
|
|
|
|||
|
|
private CameraConfig _cameraConfig;
|
|||
|
|
public CameraConfig CameraConfig
|
|||
|
|
{
|
|||
|
|
get => _cameraConfig;
|
|||
|
|
set => SetAndNotify(ref _cameraConfig, value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private ObservableCollection<LightChannelViewModel> _lightChannels;
|
|||
|
|
public ObservableCollection<LightChannelViewModel> LightChannels
|
|||
|
|
{
|
|||
|
|
get => _lightChannels;
|
|||
|
|
set => SetAndNotify(ref _lightChannels, value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public ICommand ReadFromHardwareCommand { get; }
|
|||
|
|
public ICommand SaveAndCloseCommand { get; }
|
|||
|
|
|
|||
|
|
public CameraSettingsViewModel(IWindowManager windowManager, HardwareManager hardwareManager)
|
|||
|
|
{
|
|||
|
|
_windowManager = windowManager;
|
|||
|
|
_hardwareManager = hardwareManager;
|
|||
|
|
|
|||
|
|
ReadFromHardwareCommand = new DelegateCommand(ReadFromHardware);
|
|||
|
|
SaveAndCloseCommand = new DelegateCommand(SaveAndClose);
|
|||
|
|
DisplayName = "相机光源参数设置";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 初始化并绑定数据
|
|||
|
|
/// </summary>
|
|||
|
|
public void Initialize(CameraConfig cameraConfig, object lightConfig, CameraType cameraType)
|
|||
|
|
{
|
|||
|
|
// 1. 解绑旧对象的事件(如果有)
|
|||
|
|
if (CameraConfig != null) CameraConfig.PropertyChanged -= OnConfigPropertyChanged;
|
|||
|
|
if (_currentLightConfig is INotifyPropertyChanged oldLight) oldLight.PropertyChanged -= OnConfigPropertyChanged;
|
|||
|
|
|
|||
|
|
_currentCameraType = cameraType;
|
|||
|
|
CameraConfig = cameraConfig;
|
|||
|
|
_currentLightConfig = lightConfig;
|
|||
|
|
|
|||
|
|
// 2. 重新订阅事件
|
|||
|
|
if (CameraConfig != null) CameraConfig.PropertyChanged += OnConfigPropertyChanged;
|
|||
|
|
if (_currentLightConfig is INotifyPropertyChanged newLight) newLight.PropertyChanged += OnConfigPropertyChanged;
|
|||
|
|
|
|||
|
|
// 3. 生成光源通道列表
|
|||
|
|
LightChannels = new ObservableCollection<LightChannelViewModel>();
|
|||
|
|
if (lightConfig != null)
|
|||
|
|
{
|
|||
|
|
var properties = lightConfig.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
|||
|
|
foreach (var prop in properties)
|
|||
|
|
{
|
|||
|
|
if (prop.PropertyType == typeof(int) && prop.CanRead && prop.CanWrite)
|
|||
|
|
{
|
|||
|
|
var descAttr = prop.GetCustomAttribute<DescriptionAttribute>();
|
|||
|
|
// 必须有 Description 才认为是光源通道
|
|||
|
|
if (descAttr != null)
|
|||
|
|
{
|
|||
|
|
var vm = new LightChannelViewModel(lightConfig, prop, descAttr.Description);
|
|||
|
|
LightChannels.Add(vm);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 统一处理属性变更事件 => 设置硬件
|
|||
|
|
/// </summary>
|
|||
|
|
private void OnConfigPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|||
|
|
{
|
|||
|
|
// 关键逻辑:如果是从硬件读取过程中,则忽略,不要反向设置回去
|
|||
|
|
if (_isSyncingFromHardware) return;
|
|||
|
|
|
|||
|
|
ApplySettingToHardware(sender, e.PropertyName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ApplySettingToHardware(object source, string propertyName)
|
|||
|
|
{
|
|||
|
|
// 1. 设置相机参数
|
|||
|
|
if (source == CameraConfig)
|
|||
|
|
{
|
|||
|
|
// TODO: 替换为实际的 set 相机参数代码
|
|||
|
|
/*
|
|||
|
|
var camDevice = _hardwareManager.GetCamera(_currentCameraType);
|
|||
|
|
if (propertyName == nameof(CameraConfig.ExposureTime))
|
|||
|
|
{
|
|||
|
|
camDevice.SetExposure(CameraConfig.ExposureTime);
|
|||
|
|
}
|
|||
|
|
else if (propertyName == nameof(CameraConfig.Gain))
|
|||
|
|
{
|
|||
|
|
camDevice.SetGain(CameraConfig.Gain);
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
System.Diagnostics.Debug.WriteLine($"[Hardware Set] Cam: {_currentCameraType}, Prop: {propertyName}");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. 设置光源参数 (根据类型直接判断)
|
|||
|
|
if (source is MapCamLightConfig mapConfig)
|
|||
|
|
{
|
|||
|
|
if (propertyName == nameof(MapCamLightConfig.RedLight))
|
|||
|
|
{
|
|||
|
|
// TODO: _hardwareManager.SetMapRedLight(mapConfig.RedLight);
|
|||
|
|
System.Diagnostics.Debug.WriteLine($"[Hardware Set] MapCam Red: {mapConfig.RedLight}");
|
|||
|
|
}
|
|||
|
|
else if (propertyName == nameof(MapCamLightConfig.BlueLight))
|
|||
|
|
{
|
|||
|
|
// TODO: _hardwareManager.SetMapBlueLight(mapConfig.BlueLight);
|
|||
|
|
System.Diagnostics.Debug.WriteLine($"[Hardware Set] MapCam Blue: {mapConfig.BlueLight}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (source is UpCamLightConfig upConfig)
|
|||
|
|
{
|
|||
|
|
if (propertyName == nameof(UpCamLightConfig.PointRedLight))
|
|||
|
|
{
|
|||
|
|
// TODO: _hardwareManager.SetUpPointRed(upConfig.PointRedLight);
|
|||
|
|
System.Diagnostics.Debug.WriteLine($"[Hardware Set] UpCam PointRed: {upConfig.PointRedLight}");
|
|||
|
|
}
|
|||
|
|
else if (propertyName == nameof(UpCamLightConfig.RingRedLight))
|
|||
|
|
{
|
|||
|
|
// TODO: ...
|
|||
|
|
}
|
|||
|
|
// ... 处理其他 UpCam 通道
|
|||
|
|
}
|
|||
|
|
else if (source is DownCamLightConfig downConfig)
|
|||
|
|
{
|
|||
|
|
if (propertyName == nameof(DownCamLightConfig.PointRedLight))
|
|||
|
|
{
|
|||
|
|
// TODO: ...
|
|||
|
|
}
|
|||
|
|
// ... 处理其他 DownCam 通道
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从硬件读取当前值 => 更新 UI (不触发设置)
|
|||
|
|
/// </summary>
|
|||
|
|
private void ReadFromHardware()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
_isSyncingFromHardware = true; // 开启静默模式
|
|||
|
|
|
|||
|
|
// 1. 读取相机实际参数
|
|||
|
|
/*
|
|||
|
|
var camDevice = _hardwareManager.GetCamera(_currentCameraType);
|
|||
|
|
if (camDevice != null) {
|
|||
|
|
CameraConfig.ExposureTime = (int)camDevice.CurrentExposure;
|
|||
|
|
CameraConfig.Gain = (int)camDevice.CurrentGain;
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
// 2. 读取光源实际参数
|
|||
|
|
if (_currentLightConfig is MapCamLightConfig mapConfig)
|
|||
|
|
{
|
|||
|
|
// TODO: 读取实际硬件值
|
|||
|
|
mapConfig.RedLight = _hardwareManager.GetMapRedLightIntensity();
|
|||
|
|
mapConfig.BlueLight = _hardwareManager.GetMapBlueLightIntensity();
|
|||
|
|
}
|
|||
|
|
else if (_currentLightConfig is UpCamLightConfig upConfig)
|
|||
|
|
{
|
|||
|
|
upConfig.PointRedLight = _hardwareManager.GetUpPointRedLightIntensity();
|
|||
|
|
upConfig.PointBlueLight=_hardwareManager.GetUpPointBlueLightIntensity();
|
|||
|
|
upConfig.RingRedLight=_hardwareManager.GetUpRingRedLightIntensity();
|
|||
|
|
upConfig.RingBlueLight=_hardwareManager.GetUpRingBlueLightIntensity();
|
|||
|
|
upConfig.RedBackLight=_hardwareManager.GetUpRedBackLightIntensity();
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
else if (_currentLightConfig is DownCamLightConfig downConfig)
|
|||
|
|
{
|
|||
|
|
// downConfig.PointRedLight = ...
|
|||
|
|
downConfig.PointRedLight = _hardwareManager.GetDownPointRedLightIntensity();
|
|||
|
|
downConfig.PointBlueLight = _hardwareManager.GetDownPointBlueLightIntensity();
|
|||
|
|
downConfig.RingRedLight = _hardwareManager.GetDownRingRedLightIntensity();
|
|||
|
|
downConfig.RingBlueLight = _hardwareManager.GetDownRingBlueLightIntensity();
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
foreach (var channel in LightChannels)
|
|||
|
|
{
|
|||
|
|
// 强制刷新 UI
|
|||
|
|
channel.Refresh();
|
|||
|
|
}
|
|||
|
|
_isSyncingFromHardware = false; // 必须复位
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void SaveAndClose()
|
|||
|
|
{
|
|||
|
|
RequestClose(true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|