diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs index 52b68f8e2f..b3a7585520 100644 --- a/src/Android/Avalonia.Android/AvaloniaActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs @@ -1,4 +1,3 @@ - using Android.App; using Android.OS; using Android.Views; @@ -7,7 +6,6 @@ namespace Avalonia.Android { public abstract class AvaloniaActivity : Activity { - internal AvaloniaView View; object _content; @@ -35,9 +33,7 @@ namespace Avalonia.Android } } - public override bool DispatchKeyEvent(KeyEvent e) - { - return View.DispatchKeyEvent(e); - } + public override bool DispatchKeyEvent(KeyEvent e) => + View.DispatchKeyEvent(e) ? true : base.DispatchKeyEvent(e); } } diff --git a/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs b/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs deleted file mode 100644 index d52eeb15e4..0000000000 --- a/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Avalonia.Input; - -namespace Avalonia.Android.Platform.Input -{ - public class AndroidMouseDevice : MouseDevice - { - public static AndroidMouseDevice Instance { get; } = new AndroidMouseDevice(); - - public AndroidMouseDevice() - { - - } - } -} \ No newline at end of file diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index 10bf414f25..4fd9bc040b 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -6,7 +6,6 @@ using Android.Runtime; using Android.Views; using Avalonia.Android.OpenGL; -using Avalonia.Android.Platform.Input; using Avalonia.Android.Platform.Specific; using Avalonia.Android.Platform.Specific.Helpers; using Avalonia.Controls; @@ -35,7 +34,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform _view = new ViewImpl(context, this, placeOnTop); _keyboardHelper = new AndroidKeyboardEventsHelper(this); _touchHelper = new AndroidTouchEventsHelper(this, () => InputRoot, - p => GetAvaloniaPointFromEvent(p)); + GetAvaloniaPointFromEvent); _gl = GlPlatformSurface.TryCreate(this); _framebuffer = new FramebufferManager(this); @@ -44,8 +43,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform _view.Resources.DisplayMetrics.HeightPixels); } - - private bool _handleEvents; public bool HandleEvents @@ -58,7 +55,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform } } - public virtual Point GetAvaloniaPointFromEvent(MotionEvent e) => new Point(e.GetX(), e.GetY()); + public virtual Point GetAvaloniaPointFromEvent(MotionEvent e, int pointerIndex) => + new Point(e.GetX(pointerIndex), e.GetY(pointerIndex)) / RenderScaling; public IInputRoot InputRoot { get; private set; } @@ -76,7 +74,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform } } - public IMouseDevice MouseDevice => AndroidMouseDevice.Instance; + public IMouseDevice MouseDevice { get; } = new MouseDevice(); public Action Closed { get; set; } diff --git a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs index 0bfbb1c2df..6142598514 100644 --- a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs +++ b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs @@ -11,7 +11,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers private TView _view; public bool HandleEvents { get; set; } - public AndroidTouchEventsHelper(TView view, Func getInputRoot, Func getPointfunc) + public AndroidTouchEventsHelper(TView view, Func getInputRoot, Func getPointfunc) { this._view = view; HandleEvents = true; @@ -19,11 +19,9 @@ namespace Avalonia.Android.Platform.Specific.Helpers _getInputRoot = getInputRoot; } - private DateTime _lastTouchMoveEventTime = DateTime.Now; - private Point? _lastTouchMovePoint; - private Func _getPointFunc; + private TouchDevice _touchDevice = new TouchDevice(); + private Func _getPointFunc; private Func _getInputRoot; - private Point _point; public bool? DispatchTouchEvent(MotionEvent e, out bool callBase) { @@ -33,89 +31,44 @@ namespace Avalonia.Android.Platform.Specific.Helpers return null; } - RawPointerEventType? mouseEventType = null; var eventTime = DateTime.Now; + //Basic touch support - switch (e.Action) + var pointerEventType = e.Action switch { - case MotionEventActions.Move: - //may be bot flood the evnt system with too many event especially on not so powerfull mobile devices - if ((eventTime - _lastTouchMoveEventTime).TotalMilliseconds > 10) - { - mouseEventType = RawPointerEventType.Move; - } - break; - - case MotionEventActions.Down: - mouseEventType = RawPointerEventType.LeftButtonDown; + MotionEventActions.Down => RawPointerEventType.TouchBegin, + MotionEventActions.Up => RawPointerEventType.TouchEnd, + MotionEventActions.Cancel => RawPointerEventType.TouchCancel, + _ => RawPointerEventType.TouchUpdate + }; - break; + if (e.Action.HasFlag(MotionEventActions.PointerDown)) + { + pointerEventType = RawPointerEventType.TouchBegin; + } - case MotionEventActions.Up: - mouseEventType = RawPointerEventType.LeftButtonUp; - break; + if (e.Action.HasFlag(MotionEventActions.PointerUp)) + { + pointerEventType = RawPointerEventType.TouchEnd; } - if (mouseEventType != null) + for (int i = 0; i < e.PointerCount; i++) { //if point is in view otherwise it's possible avalonia not to find the proper window to dispatch the event - _point = _getPointFunc(e); + var point = _getPointFunc(e, i); double x = _view.View.GetX(); double y = _view.View.GetY(); double r = x + _view.View.Width; double b = y + _view.View.Height; - if (x <= _point.X && r >= _point.X && y <= _point.Y && b >= _point.Y) + if (x <= point.X && r >= point.X && y <= point.Y && b >= point.Y) { var inputRoot = _getInputRoot(); - var mouseDevice = Avalonia.Android.Platform.Input.AndroidMouseDevice.Instance; - - //in order the controls to work in a predictable way - //we need to generate mouse move before first mouse down event - //as this is the way buttons are working every time - //otherwise there is a problem sometimes - if (mouseEventType == RawPointerEventType.LeftButtonDown) - { - var me = new RawPointerEventArgs(mouseDevice, (uint)eventTime.Ticks, inputRoot, - RawPointerEventType.Move, _point, RawInputModifiers.None); - _view.Input(me); - } - var mouseEvent = new RawPointerEventArgs(mouseDevice, (uint)eventTime.Ticks, inputRoot, - mouseEventType.Value, _point, RawInputModifiers.LeftMouseButton); + var mouseEvent = new RawTouchEventArgs(_touchDevice, (uint)eventTime.Ticks, inputRoot, + i == e.ActionIndex ? pointerEventType : RawPointerEventType.TouchUpdate, point, RawInputModifiers.None, e.GetPointerId(i)); _view.Input(mouseEvent); - - if (e.Action == MotionEventActions.Move && mouseDevice.Captured == null) - { - if (_lastTouchMovePoint != null) - { - //raise mouse scroll event so the scrollers - //are moving with the cursor - double vectorX = _point.X - _lastTouchMovePoint.Value.X; - double vectorY = _point.Y - _lastTouchMovePoint.Value.Y; - //based on test correction of 0.02 is working perfect - double correction = 0.02; - var ps = AndroidPlatform.Instance.LayoutScalingFactor; - var mouseWheelEvent = new RawMouseWheelEventArgs( - mouseDevice, - (uint)eventTime.Ticks, - inputRoot, - _point, - new Vector(vectorX * correction / ps, vectorY * correction / ps), RawInputModifiers.LeftMouseButton); - _view.Input(mouseWheelEvent); - } - _lastTouchMovePoint = _point; - _lastTouchMoveEventTime = eventTime; - } - else if (e.Action == MotionEventActions.Down) - { - _lastTouchMovePoint = _point; - } - else - { - _lastTouchMovePoint = null; - } } }