|
|
@@ -6,6 +6,13 @@ using Avalonia.VisualTree;
|
|
|
|
|
|
namespace Avalonia.Input
|
|
|
{
|
|
|
+ internal enum CaptureSource
|
|
|
+ {
|
|
|
+ Explicit,
|
|
|
+ Implicit,
|
|
|
+ Platform
|
|
|
+ }
|
|
|
+
|
|
|
public class Pointer : IPointer, IDisposable
|
|
|
{
|
|
|
private static int s_NextFreePointerId = 1000;
|
|
|
@@ -30,46 +37,60 @@ namespace Avalonia.Input
|
|
|
|
|
|
protected virtual void PlatformCapture(IInputElement? element)
|
|
|
{
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
internal void PlatformCaptureLost()
|
|
|
{
|
|
|
if (Captured != null)
|
|
|
- Capture(null, platformInitiated: true);
|
|
|
+ Capture(null, CaptureSource.Platform);
|
|
|
}
|
|
|
|
|
|
public void Capture(IInputElement? control)
|
|
|
{
|
|
|
- Capture(control, platformInitiated: false);
|
|
|
+ Capture(control, CaptureSource.Explicit);
|
|
|
}
|
|
|
|
|
|
- private void Capture(IInputElement? control, bool platformInitiated)
|
|
|
+ internal void Capture(IInputElement? control, CaptureSource source)
|
|
|
{
|
|
|
var oldCapture = Captured;
|
|
|
if (oldCapture == control)
|
|
|
return;
|
|
|
|
|
|
- if (oldCapture is Visual v1)
|
|
|
- v1.DetachedFromVisualTree -= OnCaptureDetached;
|
|
|
+ var oldVisual = oldCapture as Visual;
|
|
|
+
|
|
|
+ IInputElement? commonParent = null;
|
|
|
+ if (oldVisual != null)
|
|
|
+ {
|
|
|
+ commonParent = FindCommonParent(control, oldCapture);
|
|
|
+ foreach (var notifyTarget in oldVisual.GetSelfAndVisualAncestors().OfType<IInputElement>())
|
|
|
+ {
|
|
|
+ if (notifyTarget == commonParent)
|
|
|
+ break;
|
|
|
+ var args = new PointerCaptureChangingEventArgs(notifyTarget, this, control, source);
|
|
|
+ notifyTarget.RaiseEvent(args);
|
|
|
+ if (args.Handled)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (oldVisual != null)
|
|
|
+ oldVisual.DetachedFromVisualTree -= OnCaptureDetached;
|
|
|
Captured = control;
|
|
|
-
|
|
|
- if (!platformInitiated)
|
|
|
+
|
|
|
+ if (source != CaptureSource.Platform)
|
|
|
PlatformCapture(control);
|
|
|
|
|
|
- if (oldCapture is Visual v2)
|
|
|
- {
|
|
|
- var commonParent = FindCommonParent(control, oldCapture);
|
|
|
- foreach (var notifyTarget in v2.GetSelfAndVisualAncestors().OfType<IInputElement>())
|
|
|
+ if (oldVisual != null)
|
|
|
+ foreach (var notifyTarget in oldVisual.GetSelfAndVisualAncestors().OfType<IInputElement>())
|
|
|
{
|
|
|
if (notifyTarget == commonParent)
|
|
|
break;
|
|
|
notifyTarget.RaiseEvent(new PointerCaptureLostEventArgs(notifyTarget, this));
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (Captured is Visual v3)
|
|
|
- v3.DetachedFromVisualTree += OnCaptureDetached;
|
|
|
+ if (Captured is Visual newVisual)
|
|
|
+ newVisual.DetachedFromVisualTree += OnCaptureDetached;
|
|
|
|
|
|
if (Captured != null)
|
|
|
CaptureGestureRecognizer(null);
|
|
|
@@ -92,7 +113,7 @@ namespace Avalonia.Input
|
|
|
|
|
|
|
|
|
public IInputElement? Captured { get; private set; }
|
|
|
-
|
|
|
+
|
|
|
public PointerType Type { get; }
|
|
|
public bool IsPrimary { get; }
|
|
|
|