Use focal point for scrolling.
Change-Id: I025a9d1ad68f6abe86c287552cf0aa17c0ea7cab
diff --git a/src/com/android/videoeditor/widgets/HorizontalScrollView.java b/src/com/android/videoeditor/widgets/HorizontalScrollView.java
index ec7ee93..0687b0f 100644
--- a/src/com/android/videoeditor/widgets/HorizontalScrollView.java
+++ b/src/com/android/videoeditor/widgets/HorizontalScrollView.java
@@ -74,9 +74,14 @@
private EdgeEffect mEdgeGlowRight;
/**
- * Position of the last motion event.
+ * X position of the last focal point.
*/
- private int mLastMotionX;
+ private int mLastFocusX;
+
+ /**
+ * True if the value of mLastFocusX is still valid.
+ */
+ private boolean mHasLastFocusX;
/**
* True when the layout has changed but the traversal has not come through yet.
@@ -122,18 +127,6 @@
private int mOverscrollDistance;
private int mOverflingDistance;
- /**
- * ID of the active pointer. This is used to retain consistency during
- * drags/flings if multiple pointers are used.
- */
- private int mActivePointerId = INVALID_POINTER;
-
- /**
- * Sentinel value for no current active pointer.
- * Used by {@link #mActivePointerId}.
- */
- private static final int INVALID_POINTER = -1;
-
public HorizontalScrollView(Context context) {
this(context, null);
}
@@ -415,6 +408,24 @@
}
}
+ private static int getFocusX(MotionEvent ev) {
+ final int action = ev.getAction();
+ final boolean pointerUp =
+ (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP;
+ final int skipIndex = pointerUp ? ev.getActionIndex() : -1;
+
+ // Determine focal point
+ float sumX = 0;
+ final int count = ev.getPointerCount();
+ for (int i = 0; i < count; i++) {
+ if (skipIndex == i) continue;
+ sumX += ev.getX(i);
+ }
+ final int div = pointerUp ? count - 1 : count;
+ final float focusX = sumX / div;
+ return (int) focusX;
+ }
+
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
if (disallowIntercept) {
@@ -448,22 +459,17 @@
* whether the user has moved far enough from his original down touch.
*/
- /*
- * Locally do absolute value. mLastMotionX is set to the x value
- * of the down event.
- */
- final int activePointerId = mActivePointerId;
- if (activePointerId == INVALID_POINTER) {
- // If we don't have a valid id, the touch down wasn't on content.
+ if (!mHasLastFocusX) {
+ // If we don't have a valid mLastFocusX, the touch down wasn't
+ // on content.
break;
}
- final int pointerIndex = ev.findPointerIndex(activePointerId);
- final int x = (int) ev.getX(pointerIndex);
- final int xDiff = (int) Math.abs(x - mLastMotionX);
+ final int x = getFocusX(ev);
+ final int xDiff = (int) Math.abs(x - mLastFocusX);
if (xDiff > mTouchSlop) {
mIsBeingDragged = true;
- mLastMotionX = x;
+ mLastFocusX = x;
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(ev);
if (mParent != null) mParent.requestDisallowInterceptTouchEvent(true);
@@ -481,10 +487,9 @@
/*
* Remember location of down touch.
- * ACTION_DOWN always refers to pointer index 0.
*/
- mLastMotionX = x;
- mActivePointerId = ev.getPointerId(0);
+ mLastFocusX = getFocusX(ev);
+ mHasLastFocusX = true;
initOrResetVelocityTracker();
mVelocityTracker.addMovement(ev);
@@ -502,20 +507,19 @@
case MotionEvent.ACTION_UP:
/* Release the drag */
mIsBeingDragged = false;
- mActivePointerId = INVALID_POINTER;
+ mHasLastFocusX = false;
if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
postInvalidateOnAnimation();
}
break;
case MotionEvent.ACTION_POINTER_DOWN: {
- final int index = ev.getActionIndex();
- mLastMotionX = (int) ev.getX(index);
- mActivePointerId = ev.getPointerId(index);
+ mLastFocusX = getFocusX(ev);
+ mHasLastFocusX = true;
break;
}
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
- mLastMotionX = (int) ev.getX(ev.findPointerIndex(mActivePointerId));
+ mLastFocusX = getFocusX(ev);
break;
}
@@ -554,14 +558,13 @@
}
// Remember where the motion event started
- mLastMotionX = (int) ev.getX();
- mActivePointerId = ev.getPointerId(0);
+ mLastFocusX = getFocusX(ev);
+ mHasLastFocusX = true;
break;
}
case MotionEvent.ACTION_MOVE:
- final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
- final int x = (int) ev.getX(activePointerIndex);
- int deltaX = mLastMotionX - x;
+ final int x = getFocusX(ev);
+ int deltaX = mLastFocusX - x;
if (!mIsBeingDragged && Math.abs(deltaX) > mTouchSlop) {
final ViewParent parent = getParent();
if (parent != null) {
@@ -576,7 +579,7 @@
}
if (mIsBeingDragged) {
// Scroll to follow the motion event
- mLastMotionX = x;
+ mLastFocusX = x;
final int oldX = mScrollX;
final int oldY = mScrollY;
@@ -615,8 +618,9 @@
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
+ final int pointerId = ev.getPointerId(0);
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
+ int initialVelocity = (int) velocityTracker.getXVelocity(pointerId);
if (getChildCount() > 0) {
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
@@ -629,7 +633,7 @@
}
}
- mActivePointerId = INVALID_POINTER;
+ mHasLastFocusX = false;
mIsBeingDragged = false;
recycleVelocityTracker();
@@ -644,7 +648,7 @@
if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
postInvalidateOnAnimation();
}
- mActivePointerId = INVALID_POINTER;
+ mHasLastFocusX = false;
mIsBeingDragged = false;
recycleVelocityTracker();
@@ -662,19 +666,10 @@
}
private void onSecondaryPointerUp(MotionEvent ev) {
- final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
- MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- final int pointerId = ev.getPointerId(pointerIndex);
- if (pointerId == mActivePointerId) {
- // This was our active pointer going up. Choose a new
- // active pointer and adjust accordingly.
- // TODO: Make this decision more intelligent.
- final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
- mLastMotionX = (int) ev.getX(newPointerIndex);
- mActivePointerId = ev.getPointerId(newPointerIndex);
- if (mVelocityTracker != null) {
- mVelocityTracker.clear();
- }
+ mLastFocusX = getFocusX(ev);
+ mHasLastFocusX = true;
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
}
}
diff --git a/src/com/android/videoeditor/widgets/TimelineHorizontalScrollView.java b/src/com/android/videoeditor/widgets/TimelineHorizontalScrollView.java
index b3d1414..1b0fb89 100755
--- a/src/com/android/videoeditor/widgets/TimelineHorizontalScrollView.java
+++ b/src/com/android/videoeditor/widgets/TimelineHorizontalScrollView.java
@@ -123,19 +123,14 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
mScaleDetector.onTouchEvent(ev);
- return mScaleDetector.isInProgress() || super.onInterceptTouchEvent(ev);
+ return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mEnableUserScrolling) {
mScaleDetector.onTouchEvent(ev);
-
- if (!mScaleDetector.isInProgress()) {
- return super.onTouchEvent(ev);
- } else {
- return true;
- }
+ return super.onTouchEvent(ev);
} else {
if (mScaleDetector.isInProgress()) {
final MotionEvent cancelEvent = MotionEvent.obtain(SystemClock.uptimeMillis(),