internal override void ProcessMotionEvent(GestureMotionEvent e) { _startTime = DateTime.Now; if (e.Action == MotionEventActions.Down && PointerId == -1) { OnDown(e); if (State == GestureRecognizerState.Began) { e.IsConsumed = true; e.IsCancelled = true; } } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; Console.WriteLine("GESTURE CANCELLED"); PointerId = -1; SendGestureUpdate(); } else if (e.ActionMasked == MotionEventActions.Up) { OnUp(e); if (PointerId == e.GetPointerId(0)) { e.IsConsumed = State != GestureRecognizerState.Failed; } } }
public bool DispatchTouchEvent(MotionEvent ev) { if (_delayedMotionEvents.ContainsKey(ev)) { Console.WriteLine("was delayed event - processing now " + ev); var gestureEvent = _delayedMotionEvents [ev]; _delayedMotionEvents.Remove(ev); var restoredEvent = gestureEvent.GetCachedEvent(); _activity.DispatchTouchEvent(restoredEvent); var handled = _delayedMotionEvents.Remove(restoredEvent); return(handled); } var gestureMotionEvent = new GestureMotionEvent(ev); //find if there's a view container with a gesture, which is currently on the screen. foreach (var recognizer in NativeGestureCoordinator.GroupRecognizers) { var nativeRecognizer = recognizer.NativeGestureRecognizer as BaseNativeGestureRecognizer; // Console.WriteLine ("checkign gesture touch"); nativeRecognizer.ProcessGestureMotionEvent(gestureMotionEvent); } if (gestureMotionEvent.IsCancelled) { ev.Action = MotionEventActions.Cancel; } if (gestureMotionEvent.IsMarkedForDelay) { _delayedMotionEvents [ev] = gestureMotionEvent; } return(gestureMotionEvent.IsConsumed); }
void OnUp(GestureMotionEvent e) { NumberOfTouches = e.PointerCount; var tookTooLong = (DateTime.Now - _startTime).Milliseconds > MaxSwipeDuration; var wrongAmountOfTouches = NumberOfTouches < SwipeGestureRecognizer.NumberOfTouchesRequired; if (tookTooLong || wrongAmountOfTouches) { State = GestureRecognizerState.Failed; SendGestureEvent(); PointerId = -1; return; } var endTouchPoint = new Xamarin.Forms.Point(e.GetX(0), e.GetY(0)); double velocityX = endTouchPoint.X - FirstTouchPoint.X; double velocityY = endTouchPoint.Y - FirstTouchPoint.Y; var direction = GetSwipeDirection(velocityX, velocityY); var expectedDirection = (Recognizer as SwipeGestureRecognizer).Direction; if (direction == expectedDirection) { State = GestureRecognizerState.Recognized; SendGestureEvent(); } else { State = GestureRecognizerState.Failed; Console.WriteLine("failed gesture was expecting {0} got {1}", expectedDirection, direction); } PointerId = -1; }
internal override void ProcessMotionEvent(GestureMotionEvent e) { // Console.WriteLine ("pan gesture state - {0} e.action {1}", State, e.Action); if (e.Action == MotionEventActions.Down && PointerId == -1) { OnDown(e); // e.IsConsumed = State == GestureRecognizerState.Possible; } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else { if (PointerId == e.GetPointerId(0)) { if (e.ActionMasked == MotionEventActions.Cancel || e.ActionMasked == MotionEventActions.Up) { OnUp(e); // e.IsConsumed = true; } else if (e.Action == MotionEventActions.Move) { OnMove(e); // e.IsConsumed = State != GestureRecognizerState.Cancelled && State != GestureRecognizerState.Ended && State != GestureRecognizerState.Failed; } } } }
internal override void ProcessMotionEvent(GestureMotionEvent e) { if (e.ActionMasked == MotionEventActions.Down && PointerId == -1) { OnDown(e); e.IsConsumed = true; e.IsCancelled = Recognizer.CancelsTouchesInView; } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else { var xMovement = Math.Abs(e.GetX(0) - FirstTouchPoint.X); var yMovement = Math.Abs(e.GetY(0) - FirstTouchPoint.Y); var isMovedBeyondMaxDistance = xMovement > LongPressGestureRecognizer.MaxDistanceTolerance || yMovement > LongPressGestureRecognizer.MaxDistanceTolerance; Console.WriteLine("isMovedBeyondMaxDistance {0} xd {1} yd{2}", isMovedBeyondMaxDistance, xMovement, yMovement); if (e.ActionMasked == MotionEventActions.Cancel || isMovedBeyondMaxDistance) { State = GestureRecognizerState.Cancelled; Console.WriteLine("LONG PRESS CANCELLED"); PointerId = -1; SendGestureUpdate(); } else if (e.ActionMasked == MotionEventActions.Up) { OnUp(e); e.IsConsumed = true; } } }
internal override void ProcessMotionEvent(GestureMotionEvent e) { if (e.Action == MotionEventActions.Down && PointerId == -1) { OnDown(e); //TODO - this should probably be possible at this point? if (State == GestureRecognizerState.Began) { //TODO track all pointers that are down. PointerId = e.GetPointerId(0); e.IsConsumed = true; e.IsCancelled = Recognizer.CancelsTouchesInView; } } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; Console.WriteLine("GESTURE CANCELLED"); PointerId = -1; SendGestureUpdate(); } else if (e.ActionMasked == MotionEventActions.Up) { OnUp(e); e.IsConsumed = State != GestureRecognizerState.Failed; } }
void OnUp (GestureMotionEvent e) { NumberOfTouches = e.PointerCount; var tooLongBetweenTouches = (DateTime.Now - _startTime).Milliseconds > 400; var wrongNumberOfTouches = NumberOfTouches < (this.Recognizer as TapGestureRecognizer).NumberOfTouchesRequired; if (tooLongBetweenTouches || wrongNumberOfTouches) { State = GestureRecognizerState.Failed; return; } _currentTapCount++; Console.WriteLine ("Tapped current tap count " + _currentTapCount); var requiredTaps = (this.Recognizer as TapGestureRecognizer).NumberOfTapsRequired; if (requiredTaps == 1) { State = GestureRecognizerState.Recognized; } else { if (_currentTapCount == requiredTaps) { Console.WriteLine ("did multi tap, required " + requiredTaps); NumberOfTouches = 1; State = GestureRecognizerState.Recognized; ResetMultiTapTimer (false); _currentTapCount = 0; } else { Console.WriteLine ("incomplete multi tap, " + _currentTapCount + "/" + requiredTaps); } } return; }
public bool DispatchTouchEvent (MotionEvent ev) { bool wasDelayed = _delayedMotionEvents.ContainsKey (ev); if (wasDelayed) { Console.WriteLine ("was delayed event - processing now " + ev); var gestureEvent = _delayedMotionEvents [ev]; _delayedMotionEvents.Remove (ev); var restoredEvent = gestureEvent.GetCachedEvent (); _activity.DispatchTouchEvent (restoredEvent); var handled = _delayedMotionEvents.Remove (restoredEvent); return handled; } var gestureMotionEvent = new GestureMotionEvent (ev); //find if there's a view container with a gesture, which is currently on the screen. foreach (var recognizer in NativeGestureCoordinator.GroupRecognizers) { var nativeRecognizer = recognizer.NativeGestureRecognizer as BaseNativeGestureRecognizer; // Console.WriteLine ("checkign gesture touch"); nativeRecognizer.ProcessGestureMotionEvent (gestureMotionEvent); gestureMotionEvent.IsConsumed = GetIsConsumedState (nativeRecognizer.State); wasDelayed = wasDelayed || gestureMotionEvent.IsMarkedForDelay; } if (gestureMotionEvent.IsConsumed && gestureMotionEvent.IsCancelled) { ev.Action = MotionEventActions.Cancel; } if (gestureMotionEvent.IsMarkedForDelay) { _delayedMotionEvents [ev] = gestureMotionEvent; } else if (wasDelayed) { //it's been released from being delayed _activity.DispatchTouchEvent (ev); } return gestureMotionEvent.IsConsumed; }
void _nativeView_Touch(object sender, View.TouchEventArgs e) { var gestureMotionEvent = new GestureMotionEvent(e.Event); foreach (var recognizer in NativeRecognizers) { recognizer.ProcessMotionEvent(gestureMotionEvent); } }
void OnDown (GestureMotionEvent e) { //TODO - should really be possible until all taps/fingers are satisfied. State = GestureRecognizerState.Began; // State = (e.PointerCount == SwipeGestureRecognizer.NumberOfTouchesRequired) ? GestureRecognizerState.Began : GestureRecognizerState.Failed; FirstTouchPoint = new Xamarin.Forms.Point (e.GetX (0), e.GetY (0)); _startTime = DateTime.Now; }
void OnUp (GestureMotionEvent e) { ResetLongPressTimer (false); //TODO track the correct fingers if (State == GestureRecognizerState.Began) { State = GestureRecognizerState.Failed; Console.WriteLine ("LONG PRESS CANCELLED"); } }
void OnDown(GestureMotionEvent e) { //TODO - should really be possible until all taps/fingers are satisfied. State = GestureRecognizerState.Began; // State = (e.PointerCount == SwipeGestureRecognizer.NumberOfTouchesRequired) ? GestureRecognizerState.Began : GestureRecognizerState.Failed; FirstTouchPoint = new Xamarin.Forms.Point(e.GetX(0), e.GetY(0)); _startTime = DateTime.Now; }
void OnUp (GestureMotionEvent e) { if (State == GestureRecognizerState.Possible) { State = GestureRecognizerState.Failed; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; } else if (e.ActionMasked == MotionEventActions.Up) { State = GestureRecognizerState.Ended; } }
void OnUp(GestureMotionEvent e) { ResetLongPressTimer(false); //TODO track the correct fingers if (State == GestureRecognizerState.Began) { State = GestureRecognizerState.Failed; Console.WriteLine("LONG PRESS CANCELLED"); } }
void OnDown (GestureMotionEvent e) { //TODO - should really be possible until all taps/fingers are satisfied. State = (e.PointerCount == TapGestureRecognizer.NumberOfTouchesRequired) ? GestureRecognizerState.Began : GestureRecognizerState.Failed; _currentTapCount = 0; //TODO track all pointers that are down. PointerId = e.GetPointerId (0); FirstTouchPoint = new Xamarin.Forms.Point (e.GetX (0), e.GetY (0)); if (TapGestureRecognizer.NumberOfTapsRequired > 1 && State == GestureRecognizerState.Began) { ResetMultiTapTimer (true); } }
void OnDown(GestureMotionEvent e) { //TODO - should really be possible until all taps/fingers are satisfied. State = (e.PointerCount == TapGestureRecognizer.NumberOfTouchesRequired) ? GestureRecognizerState.Began : GestureRecognizerState.Failed; _currentTapCount = 0; //TODO track all pointers that are down. PointerId = e.GetPointerId(0); FirstTouchPoint = new Xamarin.Forms.Point(e.GetX(0), e.GetY(0)); if (TapGestureRecognizer.NumberOfTapsRequired > 1 && State == GestureRecognizerState.Began) { ResetMultiTapTimer(true); } }
void OnDown (GestureMotionEvent e) { //TODO - should really be possible until all taps/fingers are satisfied. if (e.PointerCount == LongPressGestureRecognizer.NumberOfTouchesRequired) { State = GestureRecognizerState.Began; PointerId = e.GetPointerId (0); FirstTouchPoint = new Xamarin.Forms.Point (e.GetX (0), e.GetY (0)); ResetLongPressTimer (true); } else { State = GestureRecognizerState.Failed; } }
void OnDown(GestureMotionEvent e) { //TODO - really should be possible at this point - min distance should trigger began State = GestureRecognizerState.Possible; PointerId = e.GetPointerId(0); Console.WriteLine("PAN POSSIBLE"); _rawTranslation = new Xamarin.Forms.Point(0, 0); _currentPoint = new Xamarin.Forms.Point(e.GetX(), e.GetY()); _currentScreenPoint = new Xamarin.Forms.Point(e.GetX(), e.GetY()); _previousPoint = new Xamarin.Forms.Point(e.GetX(), e.GetY()); _startPoint = new Xamarin.Forms.Point(NativeView.GetX(), NativeView.GetY()); SendGestureEvent(); }
void OnUp(GestureMotionEvent e) { if (State == GestureRecognizerState.Possible) { State = GestureRecognizerState.Failed; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; } else if (e.ActionMasked == MotionEventActions.Up) { State = GestureRecognizerState.Ended; } }
void OnDown(GestureMotionEvent e) { //TODO - should really be possible until all taps/fingers are satisfied. if (e.PointerCount == LongPressGestureRecognizer.NumberOfTouchesRequired) { State = GestureRecognizerState.Began; PointerId = e.GetPointerId(0); FirstTouchPoint = new Xamarin.Forms.Point(e.GetX(0), e.GetY(0)); ResetLongPressTimer(true); } else { State = GestureRecognizerState.Failed; } }
/** * We have an issue with Android that makes it pretty much impossible to compose gestures. * Below is my stab at picking up gestures from the activity - the idea is that the main activity would pass all touches to this method * the system will work, and will work very richly (with delay touch, cancel touches, delegate callback for should * recognize in parallel, etc) * However, my time is limited, so this is crude for now. */ public void ProcessGestureMotionEvent(GestureMotionEvent gestureEvent) { var ev = gestureEvent.MotionEvent; //TODO work out if it's our view in here, then update the coordinates int[] location = new int[2]; NativeView.GetLocationOnScreen(location); var nativeViewScreenLocation = new Xamarin.Forms.Point(location [0], location [1]); var offset = Xamarin.Forms.Point.Zero; var touchPoint = new Xamarin.Forms.Point(ev.GetX(), ev.GetY()); var mainPointerId = ev.GetPointerId(0); //1. is it inside the view? Console.WriteLine("touch point {0} view bounds {1} size {2},{3}", touchPoint, nativeViewScreenLocation, NativeView.Width, NativeView.Height); var isInsideOfView = touchPoint.X >= nativeViewScreenLocation.X && touchPoint.Y >= nativeViewScreenLocation.Y && touchPoint.X <= (NativeView.Width + nativeViewScreenLocation.X) && touchPoint.Y <= (NativeView.Height + nativeViewScreenLocation.Y); //2. report touches inside, or outside but tracked? (so cancels can occur) //TODO track more touches if (isInsideOfView || PointerId == mainPointerId) { //if letting the view know, translate the coords into local view coords (apply the offsets to the touch) offset.X = -nativeViewScreenLocation.X; offset.Y = -nativeViewScreenLocation.Y; ev.OffsetLocation((float)offset.X, (float)offset.Y); var offsetLocation = new Xamarin.Forms.Point(ev.GetX(), ev.GetY()); if (isInsideOfView) { Console.WriteLine("INSIDE " + ev.Action + " offset " + offset + " results in " + offsetLocation); } else { Console.WriteLine("touch outside view, but was tracked " + offset); } //TODO - ask the view if it's happy to process this touch at the same time as another gesture - I see no way to make it work for views.. (without //an entire Touch dispatching mechanism:/) //that will be done by 2 parses - one to discover all *gestures* that want the touch, then another parse to go back through and either cancel //or pass the touches long //that's not implemented yet though (time) ProcessMotionEvent(gestureEvent); //remove the offset ev.OffsetLocation((float)-offset.X, (float)-offset.Y); } // Console.WriteLine ("location " + ev.GetX () + ", " + ev.GetY () + " offset " + offset); }
void OnUp(GestureMotionEvent e) { NumberOfTouches = e.PointerCount; var tooLongBetweenTouches = (DateTime.Now - _startTime).Milliseconds > 400; var wrongNumberOfTouches = NumberOfTouches < (this.Recognizer as TapGestureRecognizer).NumberOfTouchesRequired; if (tooLongBetweenTouches || wrongNumberOfTouches) { State = GestureRecognizerState.Failed; SendGestureEvent(); PointerId = -1; return; } _currentTapCount++; Console.WriteLine("Tapped current tap count " + _currentTapCount); var requiredTaps = (this.Recognizer as TapGestureRecognizer).NumberOfTapsRequired; if (requiredTaps == 1) { State = GestureRecognizerState.Recognized; SendGestureEvent(); PointerId = -1; } else { if (_currentTapCount == requiredTaps) { Console.WriteLine("did multi tap, required " + requiredTaps); NumberOfTouches = 1; State = GestureRecognizerState.Recognized; ResetMultiTapTimer(false); SendGestureEvent(); _currentTapCount = 0; PointerId = -1; } else { Console.WriteLine("incomplete multi tap, " + _currentTapCount + "/" + requiredTaps); } } return; }
void OnUp(GestureMotionEvent e) { if (State == GestureRecognizerState.Possible) { State = GestureRecognizerState.Failed; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; } else if (e.ActionMasked == MotionEventActions.Up) { State = GestureRecognizerState.Ended; } PointerId = -1; SendGestureEvent(); //TODO think about if we're going to capture this return; }
internal override void ProcessMotionEvent (GestureMotionEvent e) { // Console.WriteLine ("pan gesture state - {0} e.action {1}", State, e.Action); if (e.Action == MotionEventActions.Down && PointerId == -1) { OnDown (e); // e.IsConsumed = State == GestureRecognizerState.Possible; } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else { if (PointerId == e.GetPointerId (0)) { if (e.ActionMasked == MotionEventActions.Cancel || e.ActionMasked == MotionEventActions.Up) { OnUp (e); // e.IsConsumed = true; } else if (e.Action == MotionEventActions.Move) { OnMove (e); // e.IsConsumed = State != GestureRecognizerState.Cancelled && State != GestureRecognizerState.Ended && State != GestureRecognizerState.Failed; } } } }
internal override void ProcessMotionEvent (GestureMotionEvent e) { _startTime = DateTime.Now; if (e.Action == MotionEventActions.Down && PointerId == -1) { OnDown (e); if (State == GestureRecognizerState.Began) { // e.IsConsumed = true; e.IsCancelled = true; } } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; Console.WriteLine ("GESTURE CANCELLED"); } else if (e.ActionMasked == MotionEventActions.Up) { OnUp (e); if (PointerId == e.GetPointerId (0)) { // e.IsConsumed = State != GestureRecognizerState.Failed; } } }
void OnUp (GestureMotionEvent e) { NumberOfTouches = e.PointerCount; var tookTooLong = (DateTime.Now - _startTime).Milliseconds > MaxSwipeDuration; var wrongAmountOfTouches = NumberOfTouches < SwipeGestureRecognizer.NumberOfTouchesRequired; if (tookTooLong || wrongAmountOfTouches) { State = GestureRecognizerState.Failed; return; } var endTouchPoint = new Xamarin.Forms.Point (e.GetX (0), e.GetY (0)); double velocityX = endTouchPoint.X - FirstTouchPoint.X; double velocityY = endTouchPoint.Y - FirstTouchPoint.Y; var direction = GetSwipeDirection (velocityX, velocityY); var expectedDirection = (Recognizer as SwipeGestureRecognizer).Direction; if (direction == expectedDirection) { State = GestureRecognizerState.Recognized; } else { State = GestureRecognizerState.Failed; Console.WriteLine ("failed gesture was expecting {0} got {1}", expectedDirection, direction); } }
internal override void ProcessMotionEvent (GestureMotionEvent e) { if (e.Action == MotionEventActions.Down && PointerId == -1) { OnDown (e); //TODO - this should probably be possible at this point? if (State == GestureRecognizerState.Began) { //TODO track all pointers that are down. PointerId = e.GetPointerId (0); // e.IsConsumed = true; e.IsCancelled = Recognizer.CancelsTouchesInView; } } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else if (e.ActionMasked == MotionEventActions.Cancel) { State = GestureRecognizerState.Cancelled; Console.WriteLine ("GESTURE CANCELLED"); } else if (e.ActionMasked == MotionEventActions.Up) { OnUp (e); // e.IsConsumed = State != GestureRecognizerState.Failed; } }
bool OnMove(GestureMotionEvent e) { _currentScreenPoint = new Xamarin.Forms.Point(e.GetX(), e.GetY()); var currentViewPosition = new Xamarin.Forms.Point(NativeView.GetX(), NativeView.GetY()); var currentViewOffset = new Xamarin.Forms.Point(currentViewPosition.X - _startPoint.X, currentViewPosition.Y - _startPoint.Y); var eventPoint = new Xamarin.Forms.Point(e.GetX() + currentViewOffset.X, e.GetY() + currentViewOffset.Y); var coords = new MotionEvent.PointerCoords(); e.GetPointerCoords(0, coords); // Console.WriteLine ("CHANGED e2{0} coords {1},{2}", eventPoint, coords.X, coords.Y); if (State != GestureRecognizerState.Possible && State != GestureRecognizerState.Began && State != GestureRecognizerState.Changed) { return(false); } if (e.GetX() < 0 || e.GetX() > NativeView.Width || e.GetY() < 0 || e.GetY() > NativeView.Height) { Console.WriteLine("Gesture exited from view - it's over"); State = GestureRecognizerState.Ended; PointerId = -1; SendGestureEvent(); return(false); } if (e.ActionMasked == MotionEventActions.Move || e.ActionMasked == MotionEventActions.Scroll) { _previousPoint = _currentPoint; _currentPoint = eventPoint; _velocity = new Xamarin.Forms.Point(_currentPoint.X - _previousPoint.X, _currentPoint.Y - _previousPoint.Y); //TODO proper conversion _rawTranslation.X += _velocity.X / 2; _rawTranslation.Y += _velocity.Y / 2; State = State == GestureRecognizerState.Possible ? GestureRecognizerState.Began : GestureRecognizerState.Changed; e.IsCancelled = Recognizer.CancelsTouchesInView; } // Console.WriteLine ("State " + State + "_previousPoint " + _previousPoint + " _currentPoint" + _currentPoint); SendGestureEvent(); return(false); }
internal override void ProcessMotionEvent (GestureMotionEvent e) { if (e.ActionMasked == MotionEventActions.Down && PointerId == -1) { OnDown (e); // e.IsConsumed = true; e.IsCancelled = Recognizer.CancelsTouchesInView; } else if (State == GestureRecognizerState.Cancelled || State == GestureRecognizerState.Ended || State == GestureRecognizerState.Failed) { return; } else { var xMovement = Math.Abs (e.GetX (0) - FirstTouchPoint.X); var yMovement = Math.Abs (e.GetY (0) - FirstTouchPoint.Y); var isMovedBeyondMaxDistance = xMovement > LongPressGestureRecognizer.MaxDistanceTolerance || yMovement > LongPressGestureRecognizer.MaxDistanceTolerance; Console.WriteLine ("isMovedBeyondMaxDistance {0} xd {1} yd{2}", isMovedBeyondMaxDistance, xMovement, yMovement); if (e.ActionMasked == MotionEventActions.Cancel || isMovedBeyondMaxDistance) { State = GestureRecognizerState.Cancelled; Console.WriteLine ("LONG PRESS CANCELLED"); } else if (e.ActionMasked == MotionEventActions.Up) { OnUp (e); // e.IsConsumed = true; } } }
void OnMove(GestureMotionEvent e) { _currentScreenPoint = new Xamarin.Forms.Point(e.GetX(), e.GetY()); var currentViewPosition = Recognizer.View.GetNativeScreenPosition(); var currentViewOffset = new Xamarin.Forms.Point(currentViewPosition.X - _viewStartLocation.X, currentViewPosition.Y - _viewStartLocation.Y); var eventPoint = new Xamarin.Forms.Point(e.GetX() + currentViewOffset.X, e.GetY() + currentViewOffset.Y); // Console.WriteLine ("ePoint {0} cvp {1} voffset {2} csp {3}", eventPoint.PrettyPrint (), currentViewPosition.PrettyPrint (), currentViewOffset.PrettyPrint (), _currentScreenPoint.PrettyPrint ()); if (State == GestureRecognizerState.Possible || State == GestureRecognizerState.Began || State == GestureRecognizerState.Changed) { // // if (e.GetX () < 0 || e.GetX () > NativeView.Width || e.GetY () < 0 || e.GetY () > NativeView.Height) { // Console.WriteLine ("Gesture exited from view - it's over"); // State = GestureRecognizerState.Ended; // } else if (e.ActionMasked == MotionEventActions.Move || e.ActionMasked == MotionEventActions.Scroll) { _previousPoint = _currentPoint; _currentPoint = eventPoint; _velocity = new Xamarin.Forms.Point(_currentPoint.X - _previousPoint.X, _currentPoint.Y - _previousPoint.Y); if (State == GestureRecognizerState.Possible && !IsMoveSufficientToBegin(_currentScreenPoint)) { Console.WriteLine("not moved enough - not starting"); return; } //TODO proper conversion _rawTranslation.X += _velocity.X / 2; _rawTranslation.Y += _velocity.Y / 2; State = State == GestureRecognizerState.Possible ? GestureRecognizerState.Began : GestureRecognizerState.Changed; e.IsCancelled = Recognizer.CancelsTouchesInView; } // Console.WriteLine ("State " + State + "_previousPoint " + _previousPoint.PrettyPrint () + " _currentPoint" + _currentPoint.PrettyPrint () + "rt " + _rawTranslation.PrettyPrint ()); } }
/// <summary> /// Processes the motion event. /// Overriding methods should updat the GestureMotionEvent state properties, marking for cancels, delays or consumption /// </summary> /// <param name="e">E.</param> internal abstract void ProcessMotionEvent(GestureMotionEvent e);
internal override void ProcessMotionEvent (GestureMotionEvent e) { }
void OnMove (GestureMotionEvent e) { _currentScreenPoint = new Xamarin.Forms.Point (e.GetX (), e.GetY ()); var currentViewPosition = Recognizer.View.GetNativeScreenPosition (); var currentViewOffset = new Xamarin.Forms.Point (currentViewPosition.X - _viewStartLocation.X, currentViewPosition.Y - _viewStartLocation.Y); var eventPoint = new Xamarin.Forms.Point (e.GetX () + currentViewOffset.X, e.GetY () + currentViewOffset.Y); // Console.WriteLine ("ePoint {0} cvp {1} voffset {2} csp {3}", eventPoint.PrettyPrint (), currentViewPosition.PrettyPrint (), currentViewOffset.PrettyPrint (), _currentScreenPoint.PrettyPrint ()); if (State == GestureRecognizerState.Possible || State == GestureRecognizerState.Began || State == GestureRecognizerState.Changed) { // // if (e.GetX () < 0 || e.GetX () > NativeView.Width || e.GetY () < 0 || e.GetY () > NativeView.Height) { // Console.WriteLine ("Gesture exited from view - it's over"); // State = GestureRecognizerState.Ended; // } else if (e.ActionMasked == MotionEventActions.Move || e.ActionMasked == MotionEventActions.Scroll) { _previousPoint = _currentPoint; _currentPoint = eventPoint; _velocity = new Xamarin.Forms.Point (_currentPoint.X - _previousPoint.X, _currentPoint.Y - _previousPoint.Y); if (State == GestureRecognizerState.Possible && !IsMoveSufficientToBegin (_currentScreenPoint)) { Console.WriteLine ("not moved enough - not starting"); return; } //TODO proper conversion _rawTranslation.X += _velocity.X / 2; _rawTranslation.Y += _velocity.Y / 2; State = State == GestureRecognizerState.Possible ? GestureRecognizerState.Began : GestureRecognizerState.Changed; e.IsCancelled = Recognizer.CancelsTouchesInView; } // Console.WriteLine ("State " + State + "_previousPoint " + _previousPoint.PrettyPrint () + " _currentPoint" + _currentPoint.PrettyPrint () + "rt " + _rawTranslation.PrettyPrint ()); } }
void OnDown (GestureMotionEvent e) { //TODO - really should be possible at this point - min distance should trigger began State = GestureRecognizerState.Possible; PointerId = e.GetPointerId (0); Console.WriteLine ("PAN POSSIBLE"); _rawTranslation = new Xamarin.Forms.Point (0, 0); FirstTouchPoint = new Xamarin.Forms.Point (e.GetX (), e.GetY ()); _currentPoint = FirstTouchPoint; _currentScreenPoint = FirstTouchPoint; _previousPoint = FirstTouchPoint; _viewStartLocation = Recognizer.View.GetNativeScreenPosition (); }
internal override void ProcessMotionEvent(GestureMotionEvent e) { }
void _nativeView_Touch (object sender, View.TouchEventArgs e) { var gestureMotionEvent = new GestureMotionEvent (e.Event); foreach (var recognizer in NativeRecognizers) { recognizer.ProcessMotionEvent (gestureMotionEvent); } }
/** * We have an issue with Android that makes it pretty much impossible to compose gestures. * Below is my stab at picking up gestures from the activity - the idea is that the main activity would pass all touches to this method * the system will work, and will work very richly (with delay touch, cancel touches, delegate callback for should * recognize in parallel, etc) * However, my time is limited, so this is crude for now. */ public void ProcessGestureMotionEvent (GestureMotionEvent gestureEvent) { var ev = gestureEvent.MotionEvent; var nativeViewScreenLocation = Recognizer.View.GetNativeScreenPosition (); var offset = Xamarin.Forms.Point.Zero; var touchPoint = new Xamarin.Forms.Point (ev.GetX (), ev.GetY ()); var mainPointerId = ev.GetPointerId (0); //1. is it inside the view? // Console.WriteLine ("touch point {0} vlocs {1} vlocw {2}", touchPoint.PrettyPrint (), nativeViewScreenLocation.PrettyPrint (), nativeViewWindowLocation.PrettyPrint ()); // Console.WriteLine ("touch point {0} view bounds {1} size {2},{3}", touchPoint, nativeViewScreenLocation, NativeView.Width, NativeView.Height); var isInsideOfView = touchPoint.X >= nativeViewScreenLocation.X && touchPoint.Y >= nativeViewScreenLocation.Y && touchPoint.X <= (NativeView.Width + nativeViewScreenLocation.X) && touchPoint.Y <= (NativeView.Height + nativeViewScreenLocation.Y); //2. report touches inside, or outside but tracked? (so cancels can occur) //TODO track more touches if (isInsideOfView || PointerId == mainPointerId) { //if letting the view know, translate the coords into local view coords (apply the offsets to the touch) offset.X = -nativeViewScreenLocation.X; offset.Y = -nativeViewScreenLocation.Y; ev.OffsetLocation ((float)offset.X, (float)offset.Y); var offsetLocation = new Xamarin.Forms.Point (ev.GetX (), ev.GetY ()); if (isInsideOfView) { // Console.WriteLine ("INSIDE " + ev.Action + " offset " + offset.PrettyPrint () + " results in " + offsetLocation.PrettyPrint ()); } else { // Console.WriteLine ("touch outside view, but was tracked " + offset); } //TODO - ask the view if it's happy to process this touch at the same time as another gesture - I see no way to make it work for views.. (without //an entire Touch dispatching mechanism:/) //that will be done by 2 parses - one to discover all *gestures* that want the touch, then another parse to go back through and either cancel //or pass the touches long //that's not implemented yet though (time) ProcessMotionEvent (gestureEvent); //remove the offset ev.OffsetLocation ((float)-offset.X, (float)-offset.Y); } // Console.WriteLine ("location " + ev.GetX () + ", " + ev.GetY () + " offset " + offset); }
/// <summary> /// Processes the motion event. /// Overriding methods should updat the GestureMotionEvent state properties, marking for cancels, delays or consumption /// </summary> /// <param name="e">E.</param> internal abstract void ProcessMotionEvent (GestureMotionEvent e);