diff --git a/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Create.cs b/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Create.cs index a40ad902..dcfe4b41 100644 --- a/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Create.cs +++ b/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Create.cs @@ -35,6 +35,7 @@ public sealed partial class BiliPlayer private StackPanel _notificationContainer; private LoadingWidget _loadingWidget; private EmptyHolder _failedHolder; + private GestureRecognizer _gestureRecognizer; /// /// 注入弹幕控件创建函数. @@ -57,6 +58,10 @@ public void InjectSubtitleControlFunc(Func createSubtitleCont private void CreateOverlayContainer() { var rootGrid = new CursorGrid(); + _gestureRecognizer = new GestureRecognizer + { + GestureSettings = GestureSettings.HoldWithMouse | GestureSettings.Hold, + }; if (!ViewModel.IsExternalPlayer) { diff --git a/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Methods.cs b/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Methods.cs index acfde1ff..438a521b 100644 --- a/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Methods.cs +++ b/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.Methods.cs @@ -139,6 +139,15 @@ private void RestoreCursor() } } + private void OnInteractionControlContextRequested(UIElement sender, ContextRequestedEventArgs args) + { + if (_isHolding) + { + args.Handled = true; + sender.ContextFlyout?.Hide(); + } + } + private void OnInteractionControlManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e) { _manipulationVolume = 0; @@ -224,10 +233,14 @@ private void OnInteractionControlManipulationStarted(object sender, Manipulation } private void OnRootPointerCanceled(object sender, PointerRoutedEventArgs e) - => HandlePointerEvent(e, true); + { + _gestureRecognizer.ProcessUpEvent(e.GetCurrentPoint((UIElement)sender)); + HandlePointerEvent(e, true); + } private void OnRootPointerPressed(object sender, PointerRoutedEventArgs e) { + _gestureRecognizer.ProcessDownEvent(e.GetCurrentPoint((UIElement)sender)); if (ViewModel is IslandPlayerViewModel) { var point = e.GetCurrentPoint((UIElement)sender); @@ -264,5 +277,11 @@ private void OnRootPointerEntered(object sender, PointerRoutedEventArgs e) => HandlePointerEvent(e); private void OnRootPointerMoved(object sender, PointerRoutedEventArgs e) - => HandlePointerEvent(e); + { + _gestureRecognizer.ProcessMoveEvents(e.GetIntermediatePoints((UIElement)sender)); + HandlePointerEvent(e); + } + + private void OnRootPointerReleased(object sender, PointerRoutedEventArgs e) + => _gestureRecognizer.ProcessUpEvent(e.GetCurrentPoint((UIElement)sender)); } diff --git a/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.cs b/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.cs index 6dc9944a..b1e9d2ad 100644 --- a/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.cs +++ b/src/Desktop/BiliCopilot.UI/Controls/Core/Player/BiliPlayer.cs @@ -18,6 +18,7 @@ public sealed partial class BiliPlayer : PlayerControlBase private Rect _transportControlTriggerRect; private DispatcherTimer? _cursorTimer; + private bool _isHolding; private double _lastSpeed; private double _cursorStayTime; private double _mtcStayTime; @@ -127,6 +128,23 @@ private void HookRootPointerEvents() _overlayContainer.PointerExited += OnRootPointerExited; _overlayContainer.PointerPressed += OnRootPointerPressed; _overlayContainer.PointerCanceled += OnRootPointerCanceled; + _overlayContainer.PointerReleased += OnRootPointerReleased; + } + + private void OnGestureRecognizerHolding(GestureRecognizer sender, HoldingEventArgs args) + { + _isHolding = true; + if (args.HoldingState == HoldingState.Started) + { + _lastSpeed = ViewModel.Speed; + ViewModel.SetSpeedCommand.Execute(3d); + } + else + { + _lastSpeed = _lastSpeed == 0 ? 1.0 : _lastSpeed; + ViewModel.SetSpeedCommand.Execute(_lastSpeed); + _lastSpeed = 0; + } } private void UnhookRootPointerEvents() @@ -138,6 +156,7 @@ private void UnhookRootPointerEvents() _overlayContainer.PointerExited -= OnRootPointerExited; _overlayContainer.PointerPressed -= OnRootPointerPressed; _overlayContainer.PointerCanceled -= OnRootPointerCanceled; + _overlayContainer.PointerReleased -= OnRootPointerReleased; } } @@ -145,11 +164,12 @@ private void HookInteractionControlEvents() { _interactionControl.Tapped += OnCoreTapped; _interactionControl.DoubleTapped += OnCoreDoubleTapped; - _interactionControl.Holding += OnCoreHolding; _interactionControl.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY; _interactionControl.ManipulationStarted += OnInteractionControlManipulationStarted; _interactionControl.ManipulationDelta += OnInteractionControlManipulationDelta; _interactionControl.ManipulationCompleted += OnInteractionControlManipulationCompleted; + _interactionControl.ContextRequested += OnInteractionControlContextRequested; + _gestureRecognizer.Holding += OnGestureRecognizerHolding; } private void UnhookInteractionControlEvents() @@ -158,10 +178,11 @@ private void UnhookInteractionControlEvents() { _interactionControl.Tapped -= OnCoreTapped; _interactionControl.DoubleTapped -= OnCoreDoubleTapped; - _interactionControl.Holding -= OnCoreHolding; _interactionControl.ManipulationStarted -= OnInteractionControlManipulationStarted; _interactionControl.ManipulationDelta -= OnInteractionControlManipulationDelta; _interactionControl.ManipulationCompleted -= OnInteractionControlManipulationCompleted; + _interactionControl.ContextRequested -= OnInteractionControlContextRequested; + _gestureRecognizer.Holding -= OnGestureRecognizerHolding; } } @@ -237,6 +258,12 @@ private void OnViewModelInitialized(object? sender, EventArgs e) private void OnCoreTapped(object sender, TappedRoutedEventArgs e) { + if (_isHolding) + { + _isHolding = false; + return; + } + var isManual = SettingsToolkit.ReadLocalSetting(SettingNames.MTCBehavior, MTCBehavior.Automatic) == MTCBehavior.Manual; if (isManual) { @@ -274,21 +301,6 @@ private void OnCoreDoubleTapped(object sender, DoubleTappedRoutedEventArgs e) } } - private void OnCoreHolding(object sender, HoldingRoutedEventArgs e) - { - if (e.HoldingState == HoldingState.Started) - { - _lastSpeed = ViewModel.Speed; - ViewModel.SetSpeedCommand.Execute(3d); - } - else - { - _lastSpeed = _lastSpeed == 0 ? 1.0 : _lastSpeed; - ViewModel.SetSpeedCommand.Execute(_lastSpeed); - _lastSpeed = 0; - } - } - private void OnViewModelInnerPropertyChanged(object? sender, PropertyChangedEventArgs e) { if (_overlayContainer is not null)