Browse Source

Use TouchDevice on Android.

pull/5693/head
José Pedro 6 years ago
parent
commit
7fb6e14716
No known key found for this signature in database GPG Key ID: B8247B9301707B83
  1. 8
      src/Android/Avalonia.Android/AvaloniaActivity.cs
  2. 14
      src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs
  3. 10
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  4. 91
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs

8
src/Android/Avalonia.Android/AvaloniaActivity.cs

@ -1,4 +1,3 @@
using Android.App; using Android.App;
using Android.OS; using Android.OS;
using Android.Views; using Android.Views;
@ -7,7 +6,6 @@ namespace Avalonia.Android
{ {
public abstract class AvaloniaActivity : Activity public abstract class AvaloniaActivity : Activity
{ {
internal AvaloniaView View; internal AvaloniaView View;
object _content; object _content;
@ -35,9 +33,7 @@ namespace Avalonia.Android
} }
} }
public override bool DispatchKeyEvent(KeyEvent e) public override bool DispatchKeyEvent(KeyEvent e) =>
{ View.DispatchKeyEvent(e) ? true : base.DispatchKeyEvent(e);
return View.DispatchKeyEvent(e);
}
} }
} }

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

10
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -6,7 +6,6 @@ using Android.Runtime;
using Android.Views; using Android.Views;
using Avalonia.Android.OpenGL; using Avalonia.Android.OpenGL;
using Avalonia.Android.Platform.Input;
using Avalonia.Android.Platform.Specific; using Avalonia.Android.Platform.Specific;
using Avalonia.Android.Platform.Specific.Helpers; using Avalonia.Android.Platform.Specific.Helpers;
using Avalonia.Controls; using Avalonia.Controls;
@ -35,7 +34,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
_view = new ViewImpl(context, this, placeOnTop); _view = new ViewImpl(context, this, placeOnTop);
_keyboardHelper = new AndroidKeyboardEventsHelper<TopLevelImpl>(this); _keyboardHelper = new AndroidKeyboardEventsHelper<TopLevelImpl>(this);
_touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(this, () => InputRoot, _touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(this, () => InputRoot,
p => GetAvaloniaPointFromEvent(p)); GetAvaloniaPointFromEvent);
_gl = GlPlatformSurface.TryCreate(this); _gl = GlPlatformSurface.TryCreate(this);
_framebuffer = new FramebufferManager(this); _framebuffer = new FramebufferManager(this);
@ -44,8 +43,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform
_view.Resources.DisplayMetrics.HeightPixels); _view.Resources.DisplayMetrics.HeightPixels);
} }
private bool _handleEvents; private bool _handleEvents;
public 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; } 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; } public Action Closed { get; set; }

91
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs

@ -11,7 +11,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers
private TView _view; private TView _view;
public bool HandleEvents { get; set; } 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; this._view = view;
HandleEvents = true; HandleEvents = true;
@ -19,11 +19,9 @@ namespace Avalonia.Android.Platform.Specific.Helpers
_getInputRoot = getInputRoot; _getInputRoot = getInputRoot;
} }
private DateTime _lastTouchMoveEventTime = DateTime.Now; private TouchDevice _touchDevice = new TouchDevice();
private Point? _lastTouchMovePoint; private Func<MotionEvent, int, Point> _getPointFunc;
private Func<MotionEvent, Point> _getPointFunc;
private Func<IInputRoot> _getInputRoot; private Func<IInputRoot> _getInputRoot;
private Point _point;
public bool? DispatchTouchEvent(MotionEvent e, out bool callBase) public bool? DispatchTouchEvent(MotionEvent e, out bool callBase)
{ {
@ -33,89 +31,44 @@ namespace Avalonia.Android.Platform.Specific.Helpers
return null; return null;
} }
RawPointerEventType? mouseEventType = null;
var eventTime = DateTime.Now; var eventTime = DateTime.Now;
//Basic touch support //Basic touch support
switch (e.Action) var pointerEventType = e.Action switch
{ {
case MotionEventActions.Move: MotionEventActions.Down => RawPointerEventType.TouchBegin,
//may be bot flood the evnt system with too many event especially on not so powerfull mobile devices MotionEventActions.Up => RawPointerEventType.TouchEnd,
if ((eventTime - _lastTouchMoveEventTime).TotalMilliseconds > 10) MotionEventActions.Cancel => RawPointerEventType.TouchCancel,
{ _ => RawPointerEventType.TouchUpdate
mouseEventType = RawPointerEventType.Move; };
}
break;
case MotionEventActions.Down:
mouseEventType = RawPointerEventType.LeftButtonDown;
break; if (e.Action.HasFlag(MotionEventActions.PointerDown))
{
pointerEventType = RawPointerEventType.TouchBegin;
}
case MotionEventActions.Up: if (e.Action.HasFlag(MotionEventActions.PointerUp))
mouseEventType = RawPointerEventType.LeftButtonUp; {
break; 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 //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 x = _view.View.GetX();
double y = _view.View.GetY(); double y = _view.View.GetY();
double r = x + _view.View.Width; double r = x + _view.View.Width;
double b = y + _view.View.Height; 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 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, var mouseEvent = new RawTouchEventArgs(_touchDevice, (uint)eventTime.Ticks, inputRoot,
mouseEventType.Value, _point, RawInputModifiers.LeftMouseButton); i == e.ActionIndex ? pointerEventType : RawPointerEventType.TouchUpdate, point, RawInputModifiers.None, e.GetPointerId(i));
_view.Input(mouseEvent); _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;
}
} }
} }

Loading…
Cancel
Save