326 lines
9.6 KiB
C#
326 lines
9.6 KiB
C#
using System.ComponentModel;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using Serilog;
|
|
|
|
namespace DentistryHandpieces;
|
|
|
|
public partial class MainWindow : Window
|
|
{
|
|
private readonly HashSet<ManualMotionTarget> _activeManualMotionTargets = [];
|
|
private readonly ModbusTcpPlcCoilService _plcService;
|
|
private readonly DispatcherTimer _hiddenSettingsPressTimer;
|
|
private bool _isHiddenSettingsPressActive;
|
|
private bool _hasOpenedHiddenSettingsForCurrentPress;
|
|
private bool _isCloseStopInProgress;
|
|
private bool _allowConfirmedClose;
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
_plcService = new ModbusTcpPlcCoilService();
|
|
DataContext = new MainWindowViewModel(_plcService, _plcService, new WpfFileDialogService());
|
|
_hiddenSettingsPressTimer = new DispatcherTimer
|
|
{
|
|
Interval = TimeSpan.FromSeconds(2)
|
|
};
|
|
_hiddenSettingsPressTimer.Tick += HiddenSettingsPressTimer_Tick;
|
|
Deactivated += (_, _) => ReleaseAllManualMotionTargetsAsync();
|
|
Closing += MainWindow_Closing;
|
|
Log.Information("主窗口创建完成");
|
|
}
|
|
|
|
private async void MainWindow_Closing(object? sender, CancelEventArgs e)
|
|
{
|
|
if (_allowConfirmedClose
|
|
|| DataContext is not MainWindowViewModel viewModel
|
|
|| !viewModel.HasActiveControlRun())
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.Cancel = true;
|
|
if (_isCloseStopInProgress)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isCloseStopInProgress = true;
|
|
try
|
|
{
|
|
Log.Warning("检测到活动测试,关闭窗口前开始发送并确认停止指令");
|
|
if (!await viewModel.TryStopActiveTestsForCloseAsync())
|
|
{
|
|
viewModel.CancelCloseStopRequest();
|
|
MessageBox.Show(
|
|
"测试停止状态未确认,软件将保持开启。请检查设备状态并再次点击停止。",
|
|
"无法安全关闭",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Warning);
|
|
return;
|
|
}
|
|
|
|
_allowConfirmedClose = true;
|
|
Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
viewModel.CancelCloseStopRequest();
|
|
Log.Error(ex, "关闭软件前停止活动测试失败,窗口保持开启");
|
|
MessageBox.Show(
|
|
$"关闭软件前停止测试失败,软件将保持开启:{OperatorMessageFormatter.FromException(ex)}",
|
|
"无法安全关闭",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Error);
|
|
}
|
|
finally
|
|
{
|
|
_isCloseStopInProgress = false;
|
|
}
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
{
|
|
e.Handled = true;
|
|
HiddenSettingsHotspot.CaptureMouse();
|
|
BeginHiddenSettingsPress();
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
e.Handled = true;
|
|
HiddenSettingsHotspot.ReleaseMouseCapture();
|
|
EndHiddenSettingsPress();
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_PreviewTouchDown(object sender, TouchEventArgs e)
|
|
{
|
|
e.Handled = true;
|
|
HiddenSettingsHotspot.CaptureTouch(e.TouchDevice);
|
|
BeginHiddenSettingsPress();
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_PreviewTouchUp(object sender, TouchEventArgs e)
|
|
{
|
|
e.Handled = true;
|
|
HiddenSettingsHotspot.ReleaseTouchCapture(e.TouchDevice);
|
|
EndHiddenSettingsPress();
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
if (HiddenSettingsHotspot.IsMouseCaptured)
|
|
{
|
|
HiddenSettingsHotspot.ReleaseMouseCapture();
|
|
EndHiddenSettingsPress();
|
|
}
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_LostMouseCapture(object sender, MouseEventArgs e)
|
|
{
|
|
EndHiddenSettingsPress();
|
|
}
|
|
|
|
private void HiddenSettingsHotspot_LostTouchCapture(object sender, TouchEventArgs e)
|
|
{
|
|
EndHiddenSettingsPress();
|
|
}
|
|
|
|
private void BeginHiddenSettingsPress()
|
|
{
|
|
if (_isHiddenSettingsPressActive)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isHiddenSettingsPressActive = true;
|
|
_hasOpenedHiddenSettingsForCurrentPress = false;
|
|
_hiddenSettingsPressTimer.Stop();
|
|
_hiddenSettingsPressTimer.Start();
|
|
}
|
|
|
|
private void EndHiddenSettingsPress()
|
|
{
|
|
_isHiddenSettingsPressActive = false;
|
|
_hiddenSettingsPressTimer.Stop();
|
|
}
|
|
|
|
private void HiddenSettingsPressTimer_Tick(object? sender, EventArgs e)
|
|
{
|
|
_hiddenSettingsPressTimer.Stop();
|
|
if (!_isHiddenSettingsPressActive || _hasOpenedHiddenSettingsForCurrentPress)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isHiddenSettingsPressActive = false;
|
|
_hasOpenedHiddenSettingsForCurrentPress = true;
|
|
HiddenSettingsHotspot.ReleaseMouseCapture();
|
|
HiddenSettingsHotspot.ReleaseAllTouchCaptures();
|
|
|
|
if (DataContext is MainWindowViewModel viewModel)
|
|
{
|
|
Log.Information("打开隐藏速度设置窗口");
|
|
var window = new HiddenSpeedSettingsWindow(_plcService, viewModel.GetPlcConnectionConfig())
|
|
{
|
|
Owner = this
|
|
};
|
|
window.ShowDialog();
|
|
}
|
|
}
|
|
|
|
private async void ManualMotionButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.Handled = true;
|
|
button.CaptureMouse();
|
|
await BeginManualMotionAsync(button);
|
|
}
|
|
|
|
private async void ManualMotionButton_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.Handled = true;
|
|
button.ReleaseMouseCapture();
|
|
await EndManualMotionAsync(button);
|
|
}
|
|
|
|
private async void ManualMotionButton_PreviewTouchDown(object sender, TouchEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.Handled = true;
|
|
button.CaptureTouch(e.TouchDevice);
|
|
await BeginManualMotionAsync(button);
|
|
}
|
|
|
|
private async void ManualMotionButton_PreviewTouchUp(object sender, TouchEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.Handled = true;
|
|
button.ReleaseTouchCapture(e.TouchDevice);
|
|
await EndManualMotionAsync(button);
|
|
}
|
|
|
|
private async void ManualMotionButton_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
if (sender is Button button && button.IsMouseCaptured)
|
|
{
|
|
button.ReleaseMouseCapture();
|
|
await EndManualMotionAsync(button);
|
|
}
|
|
}
|
|
|
|
private async void ManualMotionButton_LostMouseCapture(object sender, MouseEventArgs e)
|
|
{
|
|
if (sender is Button button)
|
|
{
|
|
await EndManualMotionAsync(button);
|
|
}
|
|
}
|
|
|
|
private async void ManualMotionButton_LostTouchCapture(object sender, TouchEventArgs e)
|
|
{
|
|
if (sender is Button button)
|
|
{
|
|
await EndManualMotionAsync(button);
|
|
}
|
|
}
|
|
|
|
private async Task BeginManualMotionAsync(Button button)
|
|
{
|
|
if (!TryGetManualMotionTarget(button, out ManualMotionTarget target)
|
|
|| !_activeManualMotionTargets.Add(target)
|
|
|| DataContext is not MainWindowViewModel viewModel)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!await viewModel.BeginManualMotionAsync(target))
|
|
{
|
|
_activeManualMotionTargets.Remove(target);
|
|
}
|
|
}
|
|
|
|
private async Task EndManualMotionAsync(Button button)
|
|
{
|
|
if (!TryGetManualMotionTarget(button, out ManualMotionTarget target)
|
|
|| !_activeManualMotionTargets.Remove(target)
|
|
|| DataContext is not MainWindowViewModel viewModel)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await viewModel.EndManualMotionAsync(target);
|
|
}
|
|
|
|
private async void ReleaseAllManualMotionTargetsAsync()
|
|
{
|
|
if (DataContext is not MainWindowViewModel viewModel || _activeManualMotionTargets.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ManualMotionTarget[] targets = [.. _activeManualMotionTargets];
|
|
_activeManualMotionTargets.Clear();
|
|
foreach (ManualMotionTarget target in targets)
|
|
{
|
|
await viewModel.EndManualMotionAsync(target);
|
|
}
|
|
}
|
|
|
|
private static bool TryGetManualMotionTarget(Button button, out ManualMotionTarget target)
|
|
{
|
|
target = default;
|
|
return button.Tag is string tag
|
|
&& Enum.TryParse(tag, ignoreCase: true, out target);
|
|
}
|
|
|
|
private void TorqueTrendZoomIn_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
RealtimeTorqueTrend.ZoomIn();
|
|
}
|
|
|
|
private void TorqueTrendZoomOut_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
RealtimeTorqueTrend.ZoomOut();
|
|
}
|
|
|
|
private void TorqueTrendReset_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
RealtimeTorqueTrend.ResetView();
|
|
}
|
|
|
|
private void TorqueTrendFullscreen_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (DataContext is not MainWindowViewModel viewModel)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var window = new TorqueTrendWindow(viewModel.TorqueSamples, RealtimeTorqueTrend.GetViewState())
|
|
{
|
|
Owner = this
|
|
};
|
|
window.ShowDialog();
|
|
RealtimeTorqueTrend.ApplyViewState(window.ViewState);
|
|
}
|
|
}
|