Files
DentistryHandpieces/DentistryHandpieces/MainWindow.xaml.cs
GukSang.Jin dc83cc8800 更新
2026-06-15 18:45:15 +08:00

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);
}
}