internal PointerRoutedEventArgs(MotionEvent nativeEvent, int pointerIndex, UIElement originalSource, UIElement receiver) : this() { _nativeEvent = nativeEvent; _pointerIndex = pointerIndex; _receiver = receiver; // Here we assume that usually pointerId is 'PointerIndexShift' bits long (8 bits / 255 ids), // and that usually the deviceId is [0, something_not_too_big_hopefully_less_than_0x00ffffff]. // If deviceId is greater than 0x00ffffff, we might have a conflict but only in case of multi touch // and with a high variation of deviceId. We assume that's safe enough. // Note: Make sure to use the GetPointerId in order to make sure to keep the same id while: down_1 / down_2 / up_1 / up_2 // otherwise up_2 will be with the id of 1 var pointerId = ((uint)nativeEvent.GetPointerId(pointerIndex) & _pointerIdsCount) << _pointerIdsShift | (uint)nativeEvent.DeviceId; var nativePointerAction = nativeEvent.Action; var nativePointerButtons = nativeEvent.ButtonState; var nativePointerType = nativeEvent.GetToolType(_pointerIndex); var pointerType = nativePointerType.ToPointerDeviceType(); var isInContact = IsInContact(nativeEvent, (PointerDeviceType)pointerType, nativePointerAction, nativePointerButtons); var keys = nativeEvent.MetaState.ToVirtualKeyModifiers(); FrameId = (uint)_nativeEvent.EventTime; Pointer = new Pointer(pointerId, (PointerDeviceType)pointerType, isInContact, isInRange: true); KeyModifiers = keys; OriginalSource = originalSource; _properties = GetProperties(nativePointerType, nativePointerAction, nativePointerButtons); // Last: we need the Pointer property to be set! }
private PointerPointProperties GetProperties() { var props = new PointerPointProperties { IsPrimary = true, IsInRange = Pointer.IsInRange }; var type = _nativeEvent.GetToolType(_pointerIndex); var action = _nativeEvent.Action; var isDown = action.HasFlag(MotionEventActions.Down) || action.HasFlag(MotionEventActions.PointerDown); var isUp = action.HasFlag(MotionEventActions.Up) || action.HasFlag(MotionEventActions.PointerUp); var updates = _none; switch (type) { case MotionEventToolType.Finger: props.IsLeftButtonPressed = Pointer.IsInContact; updates = isDown ? _fingerDownUpdates : isUp ? _fingerUpUpdates : _none; break; case MotionEventToolType.Mouse: props.IsLeftButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.Primary); props.IsMiddleButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.Tertiary); props.IsRightButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.Secondary); updates = isDown ? _mouseDownUpdates : isUp ? _mouseUpUpdates : _none; break; case MotionEventToolType.Stylus: props.IsBarrelButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.StylusPrimary); props.IsLeftButtonPressed = Pointer.IsInContact && !props.IsBarrelButtonPressed; break; case MotionEventToolType.Eraser: props.IsEraser = true; break; case MotionEventToolType.Unknown: // used by Xamarin.UITest props.IsLeftButtonPressed = true; break; default: break; } if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.M && // ActionButton was introduced with API 23 (https://developer.android.com/reference/android/view/MotionEvent.html#getActionButton()) updates.TryGetValue(_nativeEvent.ActionButton, out var update)) { props.PointerUpdateKind = update; } return(props); }
private PointerPointProperties GetProperties() { var props = new PointerPointProperties { IsPrimary = true, IsInRange = Pointer.IsInRange }; var type = _nativeEvent.GetToolType(_nativeEvent.ActionIndex); var action = _nativeEvent.Action; var isDown = action.HasFlag(MotionEventActions.Down) || action.HasFlag(MotionEventActions.PointerDown); var isUp = action.HasFlag(MotionEventActions.Up) || action.HasFlag(MotionEventActions.PointerUp); var updates = _none; switch (type) { case MotionEventToolType.Finger: props.IsLeftButtonPressed = Pointer.IsInContact; updates = isDown ? _fingerDownUpdates : isUp ? _fingerUpUpdates : _none; break; case MotionEventToolType.Mouse: props.IsLeftButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.Primary); props.IsMiddleButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.Tertiary); props.IsRightButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.Secondary); updates = isDown ? _mouseDownUpdates : isUp ? _mouseUpUpdates : _none; break; case MotionEventToolType.Stylus: props.IsBarrelButtonPressed = _nativeEvent.IsButtonPressed(MotionEventButtonState.StylusPrimary); props.IsLeftButtonPressed = Pointer.IsInContact && !props.IsBarrelButtonPressed; break; case MotionEventToolType.Eraser: props.IsEraser = true; break; case MotionEventToolType.Unknown: // used by Xamarin.UITest props.IsLeftButtonPressed = true; break; default: break; } if (updates.TryGetValue(_nativeEvent.ActionButton, out var update)) { props.PointerUpdateKind = update; } return(props); }
internal PointerRoutedEventArgs(MotionEvent nativeEvent, UIElement originalSource, UIElement receiver) : this() { _nativeEvent = nativeEvent; _receiver = receiver; var pointerId = (uint)nativeEvent.DeviceId; // The nativeEvent.GetPointerId(**) almost always returns 0 var type = nativeEvent.GetToolType(nativeEvent.ActionIndex).ToPointerDeviceType(); var isInContact = IsInContact(type, nativeEvent); var keys = nativeEvent.MetaState.ToVirtualKeyModifiers(); FrameId = (uint)_nativeEvent.EventTime; Pointer = new Pointer(pointerId, type, isInContact, isInRange: true); KeyModifiers = keys; OriginalSource = originalSource; CanBubbleNatively = true; }
bool OnTouchOrHoverEvent(MotionEvent e, bool isTouch) { MotionEventButtonState buttonState = e.ButtonState; MotionEventButtonState pressedButtons = buttonState & ~mOldButtonState; mOldButtonState = buttonState; if ((pressedButtons & MotionEventButtonState.Secondary) != 0) { // Advance color when the right mouse button or first stylus button // is pressed. AdvanceColor(); } PaintMode mode; if ((buttonState & MotionEventButtonState.Tertiary) != 0) { // Splat paint when the middle mouse button or second stylus button is pressed. mode = PaintMode.Splat; } else if (isTouch || (buttonState & MotionEventButtonState.Primary) != 0) { // Draw paint when touching or if the primary button is pressed. mode = PaintMode.Draw; } else { // Otherwise, do not paint anything. return(false); } MotionEventActions action = e.ActionMasked; if (action == MotionEventActions.Down || action == MotionEventActions.Move || action == MotionEventActions.HoverMove) { int N = e.HistorySize; int P = e.PointerCount; for (int i = 0; i < N; i++) { for (int j = 0; j < P; j++) { Paint(GetPaintModeForTool(e.GetToolType(j), mode), e.GetHistoricalX(j, i), e.GetHistoricalY(j, i), e.GetHistoricalPressure(j, i), e.GetHistoricalTouchMajor(j, i), e.GetHistoricalTouchMinor(j, i), e.GetHistoricalOrientation(j, i), e.GetHistoricalAxisValue(Axis.Distance, j, i), e.GetHistoricalAxisValue(Axis.Tilt, j, i)); } } for (int j = 0; j < P; j++) { Paint(GetPaintModeForTool(e.GetToolType(j), mode), e.GetX(j), e.GetY(j), e.GetPressure(j), e.GetTouchMajor(j), e.GetTouchMinor(j), e.GetOrientation(j), e.GetAxisValue(Axis.Distance, j), e.GetAxisValue(Axis.Tilt, j)); } mCurX = e.GetX(); mCurY = e.GetY(); } return(true); }