Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5910cb53 authored by Adam Powell's avatar Adam Powell Committed by Android (Google) Code Review
Browse files

Merge "Edge of screen slop detection for ScaleGestureDetector." into eclair

parents de54a95b 380b5252
Loading
Loading
Loading
Loading
+95 −10
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.view;

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;

/**
 * Detects transformation gestures involving more than one pointer ("multitouch")
@@ -138,9 +140,19 @@ public class ScaleGestureDetector {
    private float mPrevPressure;
    private long mTimeDelta;
    
    private float mEdgeSlop;
    private float mRightSlopEdge;
    private float mBottomSlopEdge;
    private boolean mSloppyGesture;

    public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
        ViewConfiguration config = ViewConfiguration.get(context);
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        mContext = context;
        mListener = listener;
        mEdgeSlop = config.getScaledEdgeSlop();
        mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
        mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
    }

    public boolean onTouchEvent(MotionEvent event) {
@@ -160,8 +172,61 @@ public class ScaleGestureDetector {
                mTimeDelta = 0;

                setContext(event);

                // Check if we have a sloppy gesture. If so, delay
                // the beginning of the gesture until we're sure that's
                // what the user wanted. Sloppy gestures can happen if the
                // edge of the user's hand is touching the screen, for example.
                final float edgeSlop = mEdgeSlop;
                final float rightSlop = mRightSlopEdge;
                final float bottomSlop = mBottomSlopEdge;
                final float x0 = event.getRawX();
                final float y0 = event.getRawY();
                final float x1 = getRawX(event, 1);
                final float y1 = getRawY(event, 1);

                boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop ||
                        x1 < edgeSlop || y1 < edgeSlop;
                boolean p1sloppy = x0 > rightSlop || y0 > bottomSlop ||
                        x1 > rightSlop || y1 > bottomSlop;

                if (p0sloppy) {
                    mFocusX = event.getX(1);
                    mFocusY = event.getY(1);
                    mSloppyGesture = true;
                } else if (p1sloppy) {
                    mFocusX = event.getX(0);
                    mFocusY = event.getY(0);
                    mSloppyGesture = true;
                } else {
                    mGestureInProgress = mListener.onScaleBegin(this);
                }
            } else if (action == MotionEvent.ACTION_MOVE && mSloppyGesture) {
                // Initiate sloppy gestures if we've moved outside of the slop area.
                final float edgeSlop = mEdgeSlop;
                final float rightSlop = mRightSlopEdge;
                final float bottomSlop = mBottomSlopEdge;
                final float x0 = event.getRawX();
                final float y0 = event.getRawY();
                final float x1 = getRawX(event, 1);
                final float y1 = getRawY(event, 1);

                boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop ||
                x1 < edgeSlop || y1 < edgeSlop;
                boolean p1sloppy = x0 > rightSlop || y0 > bottomSlop ||
                x1 > rightSlop || y1 > bottomSlop;

                if (p0sloppy) {
                    mFocusX = event.getX(1);
                    mFocusY = event.getY(1);
                } else if (p1sloppy) {
                    mFocusX = event.getX(0);
                    mFocusY = event.getY(0);
                } else {
                    mSloppyGesture = false;
                    mGestureInProgress = mListener.onScaleBegin(this);
                }
            }
        } else {
            // Transform gesture in progress - attempt to handle it
            switch (action) {
@@ -176,15 +241,17 @@ public class ScaleGestureDetector {
                    mFocusX = event.getX(id);
                    mFocusY = event.getY(id);

                    if (!mSloppyGesture) {
                        mListener.onScaleEnd(this);
                    mGestureInProgress = false;
                    }

                    reset();
                    break;

                case MotionEvent.ACTION_CANCEL:
                    if (!mSloppyGesture) {
                        mListener.onScaleEnd(this);
                    mGestureInProgress = false;
                    }

                    reset();
                    break;
@@ -209,6 +276,22 @@ public class ScaleGestureDetector {
        return handled;
    }
    
    /**
     * MotionEvent has no getRawX(int) method; simulate it pending future API approval. 
     */
    private static float getRawX(MotionEvent event, int pointerIndex) {
        float offset = event.getX() - event.getRawX();
        return event.getX(pointerIndex) + offset;
    }
    
    /**
     * MotionEvent has no getRawY(int) method; simulate it pending future API approval. 
     */
    private static float getRawY(MotionEvent event, int pointerIndex) {
        float offset = event.getY() - event.getRawY();
        return event.getY(pointerIndex) + offset;
    }

    private void setContext(MotionEvent curr) {
        if (mCurrEvent != null) {
            mCurrEvent.recycle();
@@ -255,6 +338,8 @@ public class ScaleGestureDetector {
            mCurrEvent.recycle();
            mCurrEvent = null;
        }
        mSloppyGesture = false;
        mGestureInProgress = false;
    }

    /**