public override bool OnTouchEvent(MotionEvent ev) { MotionEventActions action = ev.Action; switch (action & MotionEventActions.Mask) { case MotionEventActions.Down: mActivePointerId = ev.GetPointerId(0); break; case MotionEventActions.Cancel: case MotionEventActions.Up: mActivePointerId = INVALID_POINTER_ID; break; case MotionEventActions.PointerUp: // Ignore deprecation, ACTION_POINTER_ID_MASK and // ACTION_POINTER_ID_SHIFT has same value and are deprecated // You can have either deprecation or lint target api warning int pointerIndex = Compat.GetPointerIndex(ev.Action); int pointerId = ev.GetPointerId(pointerIndex); if (pointerId == mActivePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. int newPointerIndex = pointerIndex == 0 ? 1 : 0; mActivePointerId = ev.GetPointerId(newPointerIndex); mLastTouchX = ev.GetX(newPointerIndex); mLastTouchY = ev.GetY(newPointerIndex); } break; } mActivePointerIndex = ev .FindPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId : 0); return base.OnTouchEvent(ev); }
public void HandleDragEvent(MotionEvent ev) { MotionEventActions action = ev.Action & MotionEventActions.Mask; int pointerIndex; switch (action) { case MotionEventActions.Down: _lastTouchX = ev.RawX; _lastTouchY = ev.RawY; _activePointerId = ev.GetPointerId (0); _posX = _posX == 0 ? Shape.Center_X - Shape.Radius : _posX; _posY = _posY == 0 ? Shape.Center_Y - Shape.Radius : _posX; break; case MotionEventActions.Move: pointerIndex = ev.FindPointerIndex (_activePointerId); float x = ev.RawX; float y = ev.RawY; float deltaX = x - _lastTouchX; float deltaY = y - _lastTouchY; _posX += deltaX; _posY += deltaY; if (RequestLayout != null) RequestLayout ((int)_posX, (int)_posY, (int)_posX + Shape.Radius * 2, (int)_posY + Shape.Radius * 2); _lastTouchX = x; _lastTouchY = y; break; case MotionEventActions.Up: _lastTouchX = ev.RawX; _lastTouchY = ev.RawY; Shape.Center_X = (int)_posX + Shape.Radius; Shape.Center_Y = (int)_posY + Shape.Radius; _posX = 0; _posY = 0; break; case MotionEventActions.Cancel: // We no longer need to keep track of the active pointer. _activePointerId = -1; break; case MotionEventActions.PointerUp: // check to make sure that the pointer that went up is for the gesture we're tracking. pointerIndex = (int)(ev.Action & MotionEventActions.PointerIndexMask) >> (int)MotionEventActions.PointerIndexShift; int pointerId = ev.GetPointerId (pointerIndex); if (pointerId == _activePointerId) { _lastTouchX = ev.RawX; _lastTouchY = ev.RawY; Shape.Center_X = (int)_posX + Shape.Radius; Shape.Center_Y = (int)_posY + Shape.Radius; } break; } }
public override bool OnTouchEvent (MotionEvent ev) { _scaleDetector.OnTouchEvent (ev); MotionEventActions action = ev.Action & MotionEventActions.Mask; int pointerIndex; switch (action) { case MotionEventActions.Down: _lastTouchX = ev.GetX (); _lastTouchY = ev.GetY (); _activePointerId = ev.GetPointerId (0); break; case MotionEventActions.Move: pointerIndex = ev.FindPointerIndex (_activePointerId); float x = ev.GetX (pointerIndex); float y = ev.GetY (pointerIndex); if (!_scaleDetector.IsInProgress) { // Only move the ScaleGestureDetector isn't already processing a gesture. float deltaX = x - _lastTouchX; float deltaY = y - _lastTouchY; _posX += deltaX; _posY += deltaY; Invalidate (); } _lastTouchX = x; _lastTouchY = y; break; case MotionEventActions.Up: case MotionEventActions.Cancel: // This events occur when something cancels the gesture (for example the // activity going in the background) or when the pointer has been lifted up. // We no longer need to keep track of the active pointer. _activePointerId = InvalidPointerId; break; case MotionEventActions.PointerUp: // We only want to update the last touch position if the the appropriate pointer // has been lifted off the screen. pointerIndex = (int)(ev.Action & MotionEventActions.PointerIndexMask) >> (int)MotionEventActions.PointerIndexShift; int pointerId = ev.GetPointerId (pointerIndex); if (pointerId == _activePointerId) { // This was our active pointer going up. Choose a new // action pointer and adjust accordingly int newPointerIndex = pointerIndex == 0 ? 1 : 0; _lastTouchX = ev.GetX (newPointerIndex); _lastTouchY = ev.GetY (newPointerIndex); _activePointerId = ev.GetPointerId (newPointerIndex); } break; } return true; }
public override bool OnTouchEvent(MotionEvent e) { int touchesCount = e.PointerCount; List<Point> TouchPlace = new List<Point>(); for (int i = 0; i < touchesCount; i++) { TouchPlace.Add(new Point((int)e.GetX(i), (int)e.GetY(i))); } switch (e.ActionMasked) { case MotionEventActions.PointerDown: case MotionEventActions.Down: foreach (Point touch in TouchPlace) { foreach (CirclePaint circle in _touches) { if (circle.IsTouched(touch)) { circle.Touched = TouchPlace.IndexOf(touch); } } } break; case MotionEventActions.Move: foreach (CirclePaint circle in _touches) { if (circle.Touched >= 0) { circle.MoveTo(TouchPlace[e.FindPointerIndex(circle.Touched)]); Invalidate(); } } break; case MotionEventActions.PointerUp: case MotionEventActions.Up: case MotionEventActions.Cancel: foreach (CirclePaint circle in _touches) { if (circle.Touched == e.GetPointerId(e.ActionIndex)) { circle.Touched = -1; } } break; default: break; } return true; }
private MotionEvent.PointerCoords GetPointerCoords(Android.Views.MotionEvent e, int pointerId) { // Get the pointer coords var pointerIndex = e.FindPointerIndex(pointerId); if (pointerIndex < 0) { return(null); } var point = new MotionEvent.PointerCoords(); e.GetPointerCoords(pointerIndex, point); return(point); }
public override bool OnTouchEvent (MotionEvent ev) { Log.Debug("PullToZoomScrollView", "onTouchEvent --> action = " + (0xFF & (int)ev.Action)); if (_isHeaderTop && _isEnableZoom) { switch ((MotionEventActions)0xFF & ev.Action) { case MotionEventActions.Down: case MotionEventActions.Outside: if (!_scalingRunnable.IsFinished()) { _scalingRunnable.AbortAnimation(); } _lastMotionY = ev.GetY(); _activePointerId = ev.GetPointerId(0); _maxScale = (_screenHeight / _zoomHeight); _lastScale = (_zoomContainer.Bottom / _zoomHeight); if (_onScrollViewZoomListener != null) { _onScrollViewZoomListener.onStart(); } break; case MotionEventActions.Move: Log.Debug("PullToZoomScrollView", "_activePointerId = " + _activePointerId); int j = ev.FindPointerIndex(_activePointerId); if (j == -1) { Log.Error("PullToZoomScrollView", "Invalid pointerId = " + _activePointerId + " in onTouchEvent"); } else { if (_lastMotionY == -1.0F) { _lastMotionY = ev.GetY(j); } if (_zoomContainer.Bottom >= _zoomHeight) { FrameLayout.LayoutParams localLayoutParams = (FrameLayout.LayoutParams) _zoomContainer.LayoutParameters; ViewGroup.LayoutParams headLayoutParams = _headerContainer.LayoutParameters; float f = ((ev.GetY(j) - _lastMotionY + _zoomContainer.Bottom) / _zoomHeight - _lastScale) / 2.0F + _lastScale; if ((_lastScale <= 1.0D) && (f < _lastScale)) { localLayoutParams.Height = _zoomHeight; localLayoutParams.Width = _zoomWidth; localLayoutParams.Gravity = GravityFlags.Center; headLayoutParams.Height = _zoomHeight; _zoomContainer.LayoutParameters=localLayoutParams; _headerContainer.LayoutParameters=headLayoutParams; return base.OnTouchEvent(ev); } _lastScale = Math.Min(Math.Max(f, 1.0F), _maxScale); localLayoutParams.Height = ((int) (_zoomHeight * _lastScale)); localLayoutParams.Width = ((int) (_zoomWidth * _lastScale)); localLayoutParams.Gravity = GravityFlags.Center; headLayoutParams.Height = ((int) (_zoomHeight * _lastScale)); if (localLayoutParams.Height < _screenHeight) { _zoomContainer.LayoutParameters=localLayoutParams; _headerContainer.LayoutParameters=headLayoutParams; } _lastMotionY = ev.GetY(j); return true; } _lastMotionY = ev.GetY(j); } break; case MotionEventActions.Up: Reset(); EndScaling(); if (_onScrollViewZoomListener != null) { _onScrollViewZoomListener.onFinish(); } break; case MotionEventActions.Cancel: int i = ev.ActionIndex; _lastMotionY = ev.GetY(i); _activePointerId = ev.GetPointerId(i); break; case MotionEventActions.PointerDown: OnSecondaryPointerUp(ev); _lastMotionY = ev.GetY(ev.FindPointerIndex(_activePointerId)); break; } } return base.OnTouchEvent (ev); }
public override bool OnInterceptTouchEvent(MotionEvent ev) { int currenrMotionX; int currentMotionY; if (ev.Action == MotionEventActions.Move && this.isBeingDragged) { return true; } if (this.ScrollX == 0 && !this.CanScrollVertically(1) && this.ScrollY == 0 && !this.CanScrollHorizontally(1)) { return false; } switch (ev.Action & MotionEventActions.Mask) { case MotionEventActions.Move: { this.FindViewWhoScrolling((int)ev.GetX(), (int)ev.GetY(), 1, 1); if (this.childWhoScrolling != null) { return false; } if (this.activePointerId == InvalidPointerId) { break; } int pointerIndex = ev.FindPointerIndex(this.activePointerId); if (pointerIndex == -1) { break; } currenrMotionX = (int)ev.GetX(pointerIndex); currentMotionY = (int)ev.GetY(pointerIndex); int xDiff = Math.Abs(currenrMotionX - this.lastMotionX); int yDiff = Math.Abs(currentMotionY - this.lastMotionY); if (xDiff > this.touchSlop || yDiff > this.touchSlop) { this.isBeingDragged = true; this.lastMotionX = currenrMotionX; this.lastMotionY = currentMotionY; this.InitVelocityTrackerIfNotExists(); this.velocityTracker.AddMovement(ev); if (this.Parent != null) { this.Parent.RequestDisallowInterceptTouchEvent(true); } } break; } case MotionEventActions.Down: { this.FindViewWhoScrolling((int)ev.GetX(), (int)ev.GetY(), 1, 1); if (this.childWhoScrolling != null) { return false; } // Stop, if touched during movement on inertia if (!this.scroller.IsFinishedY) { this.scroller.AbortAnimation(); ////FlingStrictSpan } currenrMotionX = (int)ev.GetX(); currentMotionY = (int)ev.GetY(); this.lastMotionX = currenrMotionX; this.lastMotionY = currentMotionY; this.activePointerId = ev.GetPointerId(0); ////if (this.inChild(x, y)) { this.isBeingDragged = false; this.RecycleVelocityTracker(); ////break; } this.InitOrResetVelocityTracker(); this.velocityTracker.AddMovement(ev); ////this.isBeingDragged = this.scroller.IsFinished; break; } case MotionEventActions.Cancel: case MotionEventActions.Up: if (this.childWhoScrolling != null) { this.childWhoScrolling = null; return false; } this.isBeingDragged = false; this.activePointerId = InvalidPointerId; this.RecycleVelocityTracker(); //if (this.scroller.SpringBack(this.ScrollX, this.ScrollY, 0, 0, this.GetScrollRangeX(), this.GetScrollRangeY())) //{ // TODO: possible something like postInvalidate (postInvalidateOnAnimation) //} break; case MotionEventActions.PointerUp: if (this.childWhoScrolling != null) { return false; } this.OnSecondaryPointerUp(ev); break; } return this.isBeingDragged; }
public override bool OnTouchEvent (MotionEvent e) { Log.Debug("PullToZoomListView", "action = " + (0xFF & (int)e.Action)); if (_headerView != null && !_isHideHeader && _isEnableZoom) { switch ((MotionEventActions)0xFF & e.Action) { case MotionEventActions.Down: case MotionEventActions.Outside: if (!_scalingRunnable.IsFinished()) { _scalingRunnable.AbortAnimation(); } _lastMotionY = e.GetY(); _activePointerId = e.GetPointerId(0); _maxScale = (_screenHeight / _headerHeight); _lastScale = (_headerContainer.Bottom / _headerHeight); break; case MotionEventActions.Move: Log.Debug("PullToZoomListView", "_activePointerId" + _activePointerId); int j = e.FindPointerIndex(_activePointerId); if (j == -1) { Log.Error("PullToZoomListView", "Invalid pointerId=" + _activePointerId + " in onTouchEvent"); } else { if (_lastMotionY == -1.0F) { _lastMotionY = e.GetY(j); } if (_headerContainer.Bottom >= _headerHeight) { ViewGroup.LayoutParams localLayoutParams = _headerContainer.LayoutParameters; float f = ((e.GetY(j) - _lastMotionY + _headerContainer.Bottom) / _headerHeight - _lastScale) / 2.0F + _lastScale; if ((_lastScale <= 1.0D) && (f < _lastScale)) { localLayoutParams.Height = _headerHeight; _headerContainer.LayoutParameters=localLayoutParams; return base.OnTouchEvent(e); } _lastScale = Java.Lang.Math.Min(Java.Lang.Math.Max(f, 1.0F), _maxScale); localLayoutParams.Height = ((int) (_headerHeight * _lastScale)); if (localLayoutParams.Height < _screenHeight) { _headerContainer.LayoutParameters=localLayoutParams; } _lastMotionY = e.GetY(j); return true; } _lastMotionY = e.GetY(j); } break; case MotionEventActions.Up: Reset(); EndScaling(); break; case MotionEventActions.Cancel: int i = e.ActionIndex; _lastMotionY = e.GetY(i); _activePointerId = e.GetPointerId(i); break; case MotionEventActions.PointerDown: OnSecondaryPointerUp(e); _lastMotionY = e.GetY(e.FindPointerIndex(_activePointerId)); break; } } return base.OnTouchEvent (e); }
public override bool OnTouchEvent(MotionEvent ev) { _scaleDetector.OnTouchEvent(ev); MotionEventActions action = ev.Action & MotionEventActions.Mask; int pointerIndex; switch (action) { case MotionEventActions.Down: _lastTouchX = ev.GetX(); _lastTouchY = ev.GetY(); _activePointerId = ev.GetPointerId(0); break; case MotionEventActions.Move: pointerIndex = ev.FindPointerIndex(_activePointerId); float x = ev.GetX(pointerIndex); float y = ev.GetY(pointerIndex); if (!_scaleDetector.IsInProgress) { // Only move the ScaleGestureDetector isn't already processing a gesture. float deltaX = x - _lastTouchX; float deltaY = y - _lastTouchY; _posX += deltaX; _posY += deltaY; Invalidate(); } _lastTouchX = x; _lastTouchY = y; break; case MotionEventActions.Up: case MotionEventActions.Cancel: // We no longer need to keep track of the active pointer. _activePointerId = InvalidPointerId; break; case MotionEventActions.PointerUp: // check to make sure that the pointer that went up is for the gesture we're tracking. pointerIndex = (int) (ev.Action & MotionEventActions.PointerIndexMask) >> (int) MotionEventActions.PointerIndexShift; int pointerId = ev.GetPointerId(pointerIndex); if (pointerId == _activePointerId) { // This was our active pointer going up. Choose a new // action pointer and adjust accordingly int newPointerIndex = pointerIndex == 0 ? 1 : 0; _lastTouchX = ev.GetX(newPointerIndex); _lastTouchY = ev.GetY(newPointerIndex); _activePointerId = ev.GetPointerId(newPointerIndex); } break; } return true; }
public bool OnTouchEvent (MotionEvent evt) { var action = evt.ActionMasked; if (action == MotionEventActions.Down) { Reset(); // Start fresh } bool handled = true; if (mInvalidGesture) { handled = false; } else if (!mGestureInProgress) { switch (action) { case MotionEventActions.Down: { mActiveId0 = evt.GetPointerId(0); mActive0MostRecent = true; } break; case MotionEventActions.Up: Reset(); break; case MotionEventActions.PointerDown: { // We have a new multi-finger gesture if (mPrevEvent != null) mPrevEvent.Recycle(); mPrevEvent = MotionEvent.Obtain(evt); mTimeDelta = 0; int index1 = evt.ActionIndex; int index0 = evt.FindPointerIndex(mActiveId0); mActiveId1 = evt.GetPointerId(index1); if (index0 < 0 || index0 == index1) { // Probably someone sending us a broken evt stream. index0 = FindNewActiveIndex(evt, mActiveId1, -1); mActiveId0 = evt.GetPointerId(index0); } mActive0MostRecent = false; SetContext(evt); mGestureInProgress = mListener.OnScaleBegin(this); break; } } } else { // Transform gesture in progress - attempt to handle it switch (action) { case MotionEventActions.Down: { // End the old gesture and begin a new one with the most recent two fingers. mListener.OnScaleEnd(this); int oldActive0 = mActiveId0; int oldActive1 = mActiveId1; Reset(); mPrevEvent = MotionEvent.Obtain(evt); mActiveId0 = mActive0MostRecent ? oldActive0 : oldActive1; mActiveId1 = evt.GetPointerId(evt.ActionIndex); mActive0MostRecent = false; int index0 = evt.FindPointerIndex (mActiveId0); if (index0 < 0 || mActiveId0 == mActiveId1) { index0 = FindNewActiveIndex(evt, mActiveId1, -1); mActiveId0 = evt.GetPointerId(index0); } SetContext(evt); mGestureInProgress = mListener.OnScaleBegin(this); } break; case MotionEventActions.PointerUp: { int pointerCount = evt.PointerCount; int actionIndex = evt.ActionIndex; int actionId = evt.GetPointerId(actionIndex); bool gestureEnded = false; if (pointerCount > 2) { if (actionId == mActiveId0) { int newIndex = FindNewActiveIndex(evt, mActiveId1, actionIndex); if (newIndex >= 0) { mListener.OnScaleEnd(this); mActiveId0 = evt.GetPointerId(newIndex); mActive0MostRecent = true; mPrevEvent = MotionEvent.Obtain(evt); SetContext(evt); mGestureInProgress = mListener.OnScaleBegin(this); } else { gestureEnded = true; } } else if (actionId == mActiveId1) { int newIndex = FindNewActiveIndex(evt, mActiveId0, actionIndex); if (newIndex >= 0) { mListener.OnScaleEnd(this); mActiveId1 = evt.GetPointerId(newIndex); mActive0MostRecent = false; mPrevEvent = MotionEvent.Obtain(evt); SetContext(evt); mGestureInProgress = mListener.OnScaleBegin(this); } else { gestureEnded = true; } } mPrevEvent.Recycle(); mPrevEvent = MotionEvent.Obtain(evt); SetContext(evt); } else { gestureEnded = true; } if (gestureEnded) { // Gesture ended SetContext(evt); // Set focus point to the remaining finger int activeId = actionId == mActiveId0 ? mActiveId1 : mActiveId0; int index = evt.FindPointerIndex(activeId); mFocusX = evt.GetX(index); mFocusY = evt.GetY(index); mListener.OnScaleEnd(this); Reset(); mActiveId0 = activeId; mActive0MostRecent = true; } } break; case MotionEventActions.Cancel: mListener.OnScaleEnd(this); Reset(); break; case MotionEventActions.Up: Reset(); break; case MotionEventActions.Move: { SetContext(evt); // Only accept the evt if our relative pressure is within // a certain limit - this can help filter shaky data as a // finger is lifted. if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) { bool updatePrevious = mListener.OnScale(this); if (updatePrevious) { mPrevEvent.Recycle(); mPrevEvent = MotionEvent.Obtain(evt); } } } break; } } return handled; }
void SetContext (MotionEvent curr) { if (mCurrEvent != null) { mCurrEvent.Recycle(); } mCurrEvent = MotionEvent.Obtain(curr); mCurrLen = -1; mPrevLen = -1; mScaleFactor = -1; MotionEvent prev = mPrevEvent; int prevIndex0 = prev.FindPointerIndex(mActiveId0); int prevIndex1 = prev.FindPointerIndex(mActiveId1); int currIndex0 = curr.FindPointerIndex(mActiveId0); int currIndex1 = curr.FindPointerIndex(mActiveId1); if (prevIndex0 < 0 || prevIndex1 < 0 || currIndex0 < 0 || currIndex1 < 0) { mInvalidGesture = true; if (mGestureInProgress) { mListener.OnScaleEnd(this); } return; } float px0 = prev.GetX(prevIndex0); float py0 = prev.GetY(prevIndex0); float px1 = prev.GetX(prevIndex1); float py1 = prev.GetY(prevIndex1); float cx0 = curr.GetX(currIndex0); float cy0 = curr.GetY(currIndex0); float cx1 = curr.GetX(currIndex1); float cy1 = curr.GetY(currIndex1); float pvx = px1 - px0; float pvy = py1 - py0; float cvx = cx1 - cx0; float cvy = cy1 - cy0; mPrevFingerDiffX = pvx; mPrevFingerDiffY = pvy; mCurrFingerDiffX = cvx; mCurrFingerDiffY = cvy; mFocusX = cx0 + cvx * 0.5f; mFocusY = cy0 + cvy * 0.5f; mTimeDelta = curr.EventTime - prev.EventTime; mCurrPressure = curr.GetPressure(currIndex0) + curr.GetPressure(currIndex1); mPrevPressure = prev.GetPressure(prevIndex0) + prev.GetPressure(prevIndex1); }
int FindNewActiveIndex(MotionEvent ev, int otherActiveId, int removedPointerIndex) { int pointerCount = ev.PointerCount; // It's ok if this isn't found and returns -1, it simply won't match. int otherActiveIndex = ev.FindPointerIndex(otherActiveId); // Pick a new id and update tracking state. for (int i = 0; i < pointerCount; i++) { if (i != removedPointerIndex && i != otherActiveIndex) { return i; } } return -1; }
//TODO: Step 5 - Subscribe to touch events in the view public override bool OnTouchEvent(MotionEvent ev) { Log.Debug(GetType().FullName, "Number of touches: {0}", ev.PointerCount); Log.Debug(GetType().FullName, "Touch Type: {0}", ev.Action); float width = _icon.IntrinsicWidth, height = _icon.IntrinsicHeight; //TODO: Step 6 - Detect scale events _scaleDetector.OnTouchEvent(ev); MotionEventActions action = ev.Action & MotionEventActions.Mask; int pointerIndex; switch (action) { case MotionEventActions.Down: _lastTouchX = ev.GetX (); _lastTouchY = ev.GetY (); _activePointerId = ev.GetPointerId (0); break; case MotionEventActions.Move: pointerIndex = ev.FindPointerIndex (_activePointerId); float x = ev.GetX (pointerIndex); float y = ev.GetY (pointerIndex); if (!_scaleDetector.IsInProgress) { // Only move the ScaleGestureDetector isn't already processing a gesture. float deltaX = x - _lastTouchX; float deltaY = y - _lastTouchY; _posX += deltaX; _posY += deltaY; Invalidate (); } _lastTouchX = x; _lastTouchY = y; break; case MotionEventActions.Up: case MotionEventActions.Cancel: // This events occur when something cancels the gesture (for example the // activity going in the background) or when the pointer has been lifted up. // We no longer need to keep track of the active pointer. _activePointerId = InvalidPointerId; break; case MotionEventActions.PointerUp: // We only want to update the last touch position if the the appropriate pointer // has been lifted off the screen. pointerIndex = (int)(ev.Action & MotionEventActions.PointerIndexMask) >> (int)MotionEventActions.PointerIndexShift; int pointerId = ev.GetPointerId (pointerIndex); if (pointerId == _activePointerId) { // This was our active pointer going up. Choose a new // action pointer and adjust accordingly int newPointerIndex = pointerIndex == 0 ? 1 : 0; _lastTouchX = ev.GetX (newPointerIndex); _lastTouchY = ev.GetY (newPointerIndex); _activePointerId = ev.GetPointerId (newPointerIndex); } break; } //Determine if the image is within the touch area if (Math.Abs(_scaleFactor - 1.0f) > 0.001) { width *= _scaleFactor; height *= _scaleFactor; } var rc = new RectF(_posX, _posY, _posX + width, _posY + height); float touchX = ev.GetX(), touchY = ev.GetY(); bool contains = rc.Contains(touchX, touchY); Log.Debug(GetType().FullName, "{0} - ({1},{2}) - CONTAINS: {3}", rc, touchX, touchY, contains); return true; }