|
|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|