コード例 #1
0
        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);
        }
コード例 #2
0
        public override bool DispatchTouchEvent(MotionEvent ev)
        {
            float x = ev.GetX();
            float y = ev.GetY();
            MotionEventActions action = ev.Action;

            if (action == MotionEventActions.Down &&
                mTouchTarget == null &&
                mPinnedSection != null &&
                isPinnedViewTouched(mPinnedSection.view, x, y))                      // create touch target

            // user touched pinned view
            {
                mTouchTarget  = mPinnedSection.view;
                mTouchPoint.X = x;
                mTouchPoint.Y = y;

                // copy down event for eventually be used later
                mDownEvent = MotionEvent.Obtain(ev);
            }

            if (mTouchTarget != null)
            {
                if (isPinnedViewTouched(mTouchTarget, x, y))                   // forward event to pinned view
                {
                    mTouchTarget.DispatchTouchEvent(ev);
                }

                if (action == MotionEventActions.Up)                   // perform onClick on pinned view
                {
                    base.DispatchTouchEvent(ev);
                    performPinnedItemClick();
                    clearTouchTarget();
                }
                else if (action == MotionEventActions.Cancel)                     // cancel
                {
                    clearTouchTarget();
                }
                else if (action == MotionEventActions.Move)
                {
                    if (Math.Abs(y - mTouchPoint.Y) > mTouchSlop)
                    {
                        // cancel sequence on touch target
                        MotionEvent events = MotionEvent.Obtain(ev);
                        events.Action = MotionEventActions.Cancel;
                        mTouchTarget.DispatchTouchEvent(events);
                        events.Recycle();

                        // provide correct sequence to super class for further handling
                        base.DispatchTouchEvent(mDownEvent);
                        base.DispatchTouchEvent(ev);
                        clearTouchTarget();
                    }
                }

                return(true);
            }

            return(base.DispatchTouchEvent(ev));
        }
コード例 #3
0
 private void clearTouchTarget()
 {
     mTouchTarget = null;
     if (mDownEvent != null)
     {
         mDownEvent.Recycle();
         mDownEvent = null;
     }
 }
コード例 #4
0
        private bool handleMoveEvent(View view, MotionEvent motionEvent)
        {
            if (mVelocityTracker == null || mCurrentView == null)
            {
                return(false);
            }

            mVelocityTracker.AddMovement(motionEvent);

            float deltaX = motionEvent.GetX() - mDownX;
            float deltaY = motionEvent.GetY() - mDownY;

            if (Math.Abs(deltaX) > mSlop && Math.Abs(deltaX) > Math.Abs(deltaY))
            {
                if (!mSwiping)
                {
                    mActiveSwipeCount++;
                    onStartSwipe(mCurrentView, mCurrentPosition);
                }
                mSwiping = true;
                mListViewWrapper.getListView().RequestDisallowInterceptTouchEvent(true);

                /* Cancel ListView's touch (un-highlighting the item) */
                if (view != null)
                {
                    MotionEvent cancelEvent = MotionEvent.Obtain(motionEvent);

                    int mode = (int)MotionEventActions.Cancel | (motionEvent.ActionIndex << (int)MotionEventActions.PointerIndexShift);
                    cancelEvent.Action = (MotionEventActions)mode;
                    view.OnTouchEvent(cancelEvent);
                    cancelEvent.Recycle();
                }
            }

            if (mSwiping)
            {
                if (mCanDismissCurrent)
                {
                    //ViewHelper.setTranslationX(mSwipingView, deltaX);
                    mSwipingView.TranslationX = deltaX;
                    //ViewHelper.setAlpha(mSwipingView, Math.Max(mMinimumAlpha, Math.Min(1, 1 - 2 * Math.Abs(deltaX) / mViewWidth)));
                    mSwipingView.Alpha = Math.Max(mMinimumAlpha, Math.Min(1, 1 - 2 * Math.Abs(deltaX) / mViewWidth));
                }
                else
                {
                    //ViewHelper.setTranslationX(mSwipingView, deltaX * 0.1f);
                    mSwipingView.TranslationX = deltaX * 0.1f;
                }
                return(true);
            }
            return(false);
        }
        public override bool DispatchTouchEvent(MotionEvent ev)
        {
            if (ev.Action == MotionEventActions.Down)
            {
                m_DownY           = ev.GetY();
                m_HeaderOwnsTouch = m_Header != null && m_DownY <= m_Header.Height + m_HeaderOffset;
            }

            bool handled = false;

            if (m_HeaderOwnsTouch)
            {
                if (m_Header != null && Math.Abs(m_DownY - ev.GetY()) <= m_TouchSlop)
                {
                    handled = m_Header.DispatchTouchEvent(ev);
                }
                else
                {
                    if (m_Header != null)
                    {
                        MotionEvent cancelEvent = MotionEvent.Obtain(ev);
                        cancelEvent.Action = MotionEventActions.Cancel;
                        m_Header.DispatchTouchEvent(cancelEvent);
                        cancelEvent.Recycle();
                    }

                    MotionEvent downEvent = MotionEvent.Obtain(ev.DownTime, ev.EventTime, ev.Action, ev.GetX(), m_DownY, ev.MetaState);
                    downEvent.Action = MotionEventActions.Down;
                    handled          = base.DispatchTouchEvent(downEvent);
                    downEvent.Recycle();
                    m_HeaderOwnsTouch = false;
                }
            }
            else
            {
                handled = base.DispatchTouchEvent(ev);
            }

            return(handled);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        public bool OnTouch(View view, MotionEvent motionEvent)
        {
            if (mViewWidth < 2)
            {
                mViewWidth = mListView.Width;
            }

            switch (motionEvent.ActionMasked)
            {
            case MotionEventActions.Down:
                if (mPaused)
                {
                    return(false);
                }
                // TODO: ensure this is a finger, and set a flag
                // Find the child view that was touched (perform a hit test)
                Rect  rect           = new Rect();
                int   childCount     = mListView.ChildCount;
                int[] listViewCoords = new int[2];
                mListView.GetLocationOnScreen(listViewCoords);
                int  x = (int)motionEvent.RawX - listViewCoords [0];
                int  y = (int)motionEvent.RawY - listViewCoords [1];
                View child;
                for (int i = 0; i < childCount; i++)
                {
                    child = mListView.GetChildAt(i);
                    child.GetHitRect(rect);
                    if (rect.Contains(x, y))
                    {
                        mDownView = child;
                        break;
                    }
                }

                if (mDownView != null)
                {
                    mDownX        = motionEvent.RawX;
                    mDownY        = motionEvent.RawY;
                    mDownPosition = mListView.GetPositionForView(mDownView);
                    if (mCallbacks.canDismiss(mDownPosition))
                    {
                        mVelocityTracker = VelocityTracker.Obtain();
                        mVelocityTracker.AddMovement(motionEvent);
                    }
                    else
                    {
                        mDownView = null;
                    }
                }
                return(false);

            case MotionEventActions.Cancel: {
                if (mVelocityTracker == null)
                {
                    break;
                }

                if (mDownView != null && mSwiping)
                {
                    // cancel
                    mDownView.Animate()
                    .TranslationX(0)
                    .Alpha(1)
                    .SetDuration(mAnimationTime)
                    .SetListener(null);
                }
                mVelocityTracker.Recycle();
                mVelocityTracker = null;
                mDownX           = 0;
                mDownY           = 0;
                mDownView        = null;
                mDownPosition    = ListView.InvalidPosition;
                mSwiping         = false;
                break;
            }

            case MotionEventActions.Up: {
                if (mVelocityTracker == null)
                {
                    break;
                }

                float deltaX = motionEvent.RawX - mDownX;
                mVelocityTracker.AddMovement(motionEvent);
                mVelocityTracker.ComputeCurrentVelocity(1000);
                float velocityX    = mVelocityTracker.XVelocity;
                float absVelocityX = Math.Abs(velocityX);
                float absVelocityY = Math.Abs(mVelocityTracker.YVelocity);
                bool  dismiss      = false;
                bool  dismissRight = false;
                if (Math.Abs(deltaX) > mViewWidth / 2)
                {
                    dismiss      = true;
                    dismissRight = deltaX > 0;
                }
                else
                if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity && absVelocityY < absVelocityX && mSwiping)
                {
                    // dismiss only if flinging in the same direction as dragging
                    dismiss      = (velocityX < 0) == (deltaX < 0);
                    dismissRight = mVelocityTracker.XVelocity > 0;
                }
                if (dismiss && mDownPosition != ListView.InvalidPosition)
                {
                    // dismiss
                    View downView     = mDownView;                         // mDownView gets null'd before animation ends
                    int  downPosition = mDownPosition;
                    ++mDismissAnimationRefCount;
                    var anim = mDownView.Animate()
                               .TranslationX(dismissRight ? mViewWidth : -mViewWidth)
                               .Alpha(0)
                               .SetDuration(mAnimationTime)
                               .SetListener(new DownAnimatorListenerAdapter(this, downView, downPosition));
                }

                else
                {
                    // cancel
                    mDownView.Animate()
                    .TranslationX(0)
                    .Alpha(1)
                    .SetDuration(mAnimationTime)
                    .SetListener(null);
                }
                mVelocityTracker.Recycle();
                mVelocityTracker = null;
                mDownX           = 0;
                mDownY           = 0;
                mDownView        = null;
                mDownPosition    = ListView.InvalidPosition;
                mSwiping         = false;
                break;
            }

            case MotionEventActions.Move: {
                if (mVelocityTracker == null || mPaused)
                {
                    break;
                }

                mVelocityTracker.AddMovement(motionEvent);
                float deltaX = motionEvent.RawX - mDownX;
                float deltaY = motionEvent.RawY - mDownY;
                if (Math.Abs(deltaX) > mSlop && Math.Abs(deltaY) < Math.Abs(deltaX) / 2)
                {
                    mSwiping     = true;
                    mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
                    mListView.RequestDisallowInterceptTouchEvent(true);

                    // Cancel ListView's touch (un-highlighting the item)
                    MotionEvent cancelEvent = MotionEvent.Obtain(motionEvent);
                    cancelEvent.Action = (Android.Views.MotionEventActions)((int)MotionEventActions.Cancel |
                                                                            ((int)motionEvent.ActionIndex << (int)MotionEventActions.PointerIndexShift));
                    mListView.OnTouchEvent(cancelEvent);
                    cancelEvent.Recycle();
                }

                if (mSwiping)
                {
                    mDownView.TranslationX = deltaX - mSwipingSlop;
                    mDownView.Alpha        = Math.Max(0f, Math.Min(1f, 1f - 2f * Math.Abs(deltaX) / mViewWidth));
                    return(true);
                }
                break;
            }
            }
            return(false);
        }
コード例 #8
0
        public bool OnTouchEvent(View view, MotionEvent Event)
        {
            try
            {
                var action = Event.ActionMasked;
                if (action == MotionEventActions.Down)
                {
                    Reset(); // Start fresh
                }

                bool handled = true;
                if (MInvalidGesture)
                {
                    handled = false;
                }
                else if (!MGestureInProgress)
                {
                    switch (action)
                    {
                    case MotionEventActions.Down:
                    {
                        MActiveId0         = Event.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(Event);
                        MTimeDelta = 0;

                        int index1 = Event.ActionIndex;
                        int index0 = Event.FindPointerIndex(MActiveId0);
                        MActiveId1 = Event.GetPointerId(index1);
                        if (index0 < 0 || index0 == index1)
                        {
                            // Probably someone sending us a broken Event stream.
                            index0     = FindNewActiveIndex(Event, MActiveId1, -1);
                            MActiveId0 = Event.GetPointerId(index0);
                        }

                        MActive0MostRecent = false;

                        SetContext(view, Event);

                        MGestureInProgress = MListener.OnScaleBegin(view, this);
                        break;
                    }
                    }
                }
                else
                {
                    // Transform gesture in progress - attempt to handle it
                    switch (action)
                    {
                    case MotionEventActions.PointerDown:
                    {
                        // End the old gesture and begin a new one with the most recent two fingers.
                        MListener.OnScaleEnd(view, this);
                        int oldActive0 = MActiveId0;
                        int oldActive1 = MActiveId1;
                        Reset();

                        MPrevEvent         = MotionEvent.Obtain(Event);
                        MActiveId0         = MActive0MostRecent ? oldActive0 : oldActive1;
                        MActiveId1         = Event.GetPointerId(Event.ActionIndex);
                        MActive0MostRecent = false;

                        int index0 = Event.FindPointerIndex(MActiveId0);
                        if (index0 < 0 || MActiveId0 == MActiveId1)
                        {
                            // Probably someone sending us a broken Event stream.
                            index0     = FindNewActiveIndex(Event, MActiveId1, -1);
                            MActiveId0 = Event.GetPointerId(index0);
                        }

                        SetContext(view, Event);

                        MGestureInProgress = MListener.OnScaleBegin(view, this);
                    }
                    break;

                    case MotionEventActions.PointerUp:
                    {
                        int pointerCount = Event.PointerCount;
                        int actionIndex  = Event.ActionIndex;
                        int actionId     = Event.GetPointerId(actionIndex);

                        bool gestureEnded = false;
                        if (pointerCount > 2)
                        {
                            if (actionId == MActiveId0)
                            {
                                int newIndex = FindNewActiveIndex(Event, MActiveId1, actionIndex);
                                if (newIndex >= 0)
                                {
                                    MListener.OnScaleEnd(view, this);
                                    MActiveId0         = Event.GetPointerId(newIndex);
                                    MActive0MostRecent = true;
                                    MPrevEvent         = MotionEvent.Obtain(Event);
                                    SetContext(view, Event);
                                    MGestureInProgress = MListener.OnScaleBegin(view, this);
                                }
                                else
                                {
                                    gestureEnded = true;
                                }
                            }
                            else if (actionId == MActiveId1)
                            {
                                int newIndex = FindNewActiveIndex(Event, MActiveId0, actionIndex);
                                if (newIndex >= 0)
                                {
                                    MListener.OnScaleEnd(view, this);
                                    MActiveId1         = Event.GetPointerId(newIndex);
                                    MActive0MostRecent = false;
                                    MPrevEvent         = MotionEvent.Obtain(Event);
                                    SetContext(view, Event);
                                    MGestureInProgress = MListener.OnScaleBegin(view, this);
                                }
                                else
                                {
                                    gestureEnded = true;
                                }
                            }

                            MPrevEvent.Recycle();
                            MPrevEvent = MotionEvent.Obtain(Event);
                            SetContext(view, Event);
                        }
                        else
                        {
                            gestureEnded = true;
                        }

                        if (gestureEnded)
                        {
                            // Gesture ended
                            SetContext(view, Event);

                            // Set focus point to the remaining finger
                            int activeId = actionId == MActiveId0 ? MActiveId1 : MActiveId0;
                            int index    = Event.FindPointerIndex(activeId);
                            MFocusX = Event.GetX(index);
                            MFocusY = Event.GetY(index);

                            MListener.OnScaleEnd(view, this);
                            Reset();
                            MActiveId0         = activeId;
                            MActive0MostRecent = true;
                        }
                    }
                    break;

                    case MotionEventActions.Cancel:
                        MListener.OnScaleEnd(view, this);
                        Reset();
                        break;

                    case MotionEventActions.Up:
                        Reset();
                        break;

                    case MotionEventActions.Move:
                    {
                        SetContext(view, Event);

                        // Only accept the Event if our relative pressure is within
                        // a certain limit - this can help filter shaky data as a
                        // finger is lifted.
                        if (MCurrPressure / MPrevPressure > PressureThreshold)
                        {
                            bool updatePrevious = MListener.OnScale(view, this);

                            if (updatePrevious)
                            {
                                MPrevEvent.Recycle();
                                MPrevEvent = MotionEvent.Obtain(Event);
                            }
                        }
                    }
                    break;
                    }
                }

                return(handled);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return(false);
            }
        }
コード例 #9
0
        public void SetContext(View view, MotionEvent curr)
        {
            try
            {
                if (MCurrEvent != null)
                {
                    MCurrEvent.Recycle();
                }

                MCurrEvent = MotionEvent.Obtain(curr);

                MCurrLen     = -1;
                MPrevLen     = -1;
                MScaleFactor = -1;
                MCurrSpanVector.Set(0.0f, 0.0f);

                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;
                    Log.Error(Tag, "Invalid MotionEvent stream detected.", new Throwable());
                    if (MGestureInProgress)
                    {
                        MListener.OnScaleEnd(view, 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;

                MCurrSpanVector.Set(cvx, cvy);

                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);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }