AndroidTouchEventsHelper.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using System;
  2. using Android.Views;
  3. using Avalonia.Input;
  4. using Avalonia.Input.Raw;
  5. using Avalonia.Platform;
  6. namespace Avalonia.Android.Platform.Specific.Helpers
  7. {
  8. public class AndroidTouchEventsHelper<TView> : IDisposable where TView : ITopLevelImpl, IAndroidView
  9. {
  10. private TView _view;
  11. public bool HandleEvents { get; set; }
  12. public AndroidTouchEventsHelper(TView view, Func<IInputRoot> getInputRoot, Func<MotionEvent, int, Point> getPointfunc)
  13. {
  14. this._view = view;
  15. HandleEvents = true;
  16. _getPointFunc = getPointfunc;
  17. _getInputRoot = getInputRoot;
  18. }
  19. private TouchDevice _touchDevice = new TouchDevice();
  20. private Func<MotionEvent, int, Point> _getPointFunc;
  21. private Func<IInputRoot> _getInputRoot;
  22. public bool? DispatchTouchEvent(MotionEvent e, out bool callBase)
  23. {
  24. if (!HandleEvents)
  25. {
  26. callBase = true;
  27. return null;
  28. }
  29. var eventTime = DateTime.Now;
  30. //Basic touch support
  31. var pointerEventType = e.Action switch
  32. {
  33. MotionEventActions.Down => RawPointerEventType.TouchBegin,
  34. MotionEventActions.Up => RawPointerEventType.TouchEnd,
  35. MotionEventActions.Cancel => RawPointerEventType.TouchCancel,
  36. _ => RawPointerEventType.TouchUpdate
  37. };
  38. if (e.Action.HasFlag(MotionEventActions.PointerDown))
  39. {
  40. pointerEventType = RawPointerEventType.TouchBegin;
  41. }
  42. if (e.Action.HasFlag(MotionEventActions.PointerUp))
  43. {
  44. pointerEventType = RawPointerEventType.TouchEnd;
  45. }
  46. for (int i = 0; i < e.PointerCount; i++)
  47. {
  48. //if point is in view otherwise it's possible avalonia not to find the proper window to dispatch the event
  49. var point = _getPointFunc(e, i);
  50. double x = _view.View.GetX();
  51. double y = _view.View.GetY();
  52. double r = x + _view.View.Width;
  53. double b = y + _view.View.Height;
  54. if (x <= point.X && r >= point.X && y <= point.Y && b >= point.Y)
  55. {
  56. var inputRoot = _getInputRoot();
  57. var mouseEvent = new RawTouchEventArgs(_touchDevice, (uint)eventTime.Ticks, inputRoot,
  58. i == e.ActionIndex ? pointerEventType : RawPointerEventType.TouchUpdate, point, RawInputModifiers.None, e.GetPointerId(i));
  59. _view.Input(mouseEvent);
  60. }
  61. }
  62. callBase = true;
  63. //if return false events for move and up are not received!!!
  64. return e.Action != MotionEventActions.Up;
  65. }
  66. public void Dispose()
  67. {
  68. HandleEvents = false;
  69. }
  70. }
  71. }