Browse Source

Use TouchDevice on Android.

José Pedro 4 years ago
parent
commit
7fb6e14716

+ 2 - 6
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);
     }
 }

+ 0 - 14
src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs

@@ -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()
-        {
-
-        }
-    }
-}

+ 4 - 6
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<TopLevelImpl>(this);
             _touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(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; }
 

+ 22 - 69
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<IInputRoot> getInputRoot, Func<MotionEvent, Point> getPointfunc)
+        public AndroidTouchEventsHelper(TView view, Func<IInputRoot> getInputRoot, Func<MotionEvent, int, Point> 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<MotionEvent, Point> _getPointFunc;
+        private TouchDevice _touchDevice = new TouchDevice();
+        private Func<MotionEvent, int, Point> _getPointFunc;
         private Func<IInputRoot> _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;
-                    }
                 }
             }