Fix 5254974: Add EdgeEffect for PhotoView.
Change-Id: Ib9ea8fff14a932e8ec25c3f272fe0539776bb062
diff --git a/src/com/android/gallery3d/ui/PositionController.java b/src/com/android/gallery3d/ui/PositionController.java
index 5d66f70..abffbc5 100644
--- a/src/com/android/gallery3d/ui/PositionController.java
+++ b/src/com/android/gallery3d/ui/PositionController.java
@@ -63,6 +63,7 @@
private static final float SCALE_LIMIT = 4;
private PhotoView mViewer;
+ private EdgeView mEdgeView;
private int mImageW, mImageH;
private int mViewW, mViewH;
@@ -95,8 +96,10 @@
private RectF mTempRect = new RectF();
private float[] mTempPoints = new float[8];
- public PositionController(PhotoView viewer, Context context) {
+ public PositionController(PhotoView viewer, Context context,
+ EdgeView edgeView) {
mViewer = viewer;
+ mEdgeView = edgeView;
mScroller = new FlingScroller();
}
@@ -325,16 +328,46 @@
scrollBy(distance, 0, ANIM_KIND_SLIDE);
}
- public void startScroll(float dx, float dy) {
- scrollBy(dx, dy, ANIM_KIND_SCROLL);
- }
-
private void scrollBy(float dx, float dy, int type) {
startAnimation(getTargetX() + Math.round(dx / mCurrentScale),
getTargetY() + Math.round(dy / mCurrentScale),
mCurrentScale, type);
}
+ public void startScroll(float dx, float dy, boolean hasNext,
+ boolean hasPrev) {
+ int x = getTargetX() + Math.round(dx / mCurrentScale);
+ int y = getTargetY() + Math.round(dy / mCurrentScale);
+
+ calculateStableBound(mCurrentScale);
+
+ // Vertical direction: If we have space to move in the vertical
+ // direction, we show the edge effect when scrolling reaches the edge.
+ if (mBoundTop != mBoundBottom) {
+ if (y < mBoundTop) {
+ mEdgeView.onPull(mBoundTop - y, EdgeView.TOP);
+ } else if (y > mBoundBottom) {
+ mEdgeView.onPull(y - mBoundBottom, EdgeView.BOTTOM);
+ }
+ }
+
+ y = Utils.clamp(y, mBoundTop, mBoundBottom);
+
+ // Horizontal direction: we show the edge effect when the scrolling
+ // tries to go left of the first image or go right of the last image.
+ if (!hasPrev && x < mBoundLeft) {
+ int pixels = Math.round((mBoundLeft - x) * mCurrentScale);
+ mEdgeView.onPull(pixels, EdgeView.LEFT);
+ x = mBoundLeft;
+ } else if (!hasNext && x > mBoundRight) {
+ int pixels = Math.round((x - mBoundRight) * mCurrentScale);
+ mEdgeView.onPull(pixels, EdgeView.RIGHT);
+ x = mBoundRight;
+ }
+
+ startAnimation(x, y, mCurrentScale, ANIM_KIND_SCROLL);
+ }
+
public boolean fling(float velocityX, float velocityY) {
// We only want to do fling when the picture is zoomed-in.
if (mImageW * mCurrentScale <= mViewW &&
@@ -439,9 +472,27 @@
private void flingInterpolate(float progress) {
mScroller.computeScrollOffset(progress);
+ int oldX = mCurrentX;
+ int oldY = mCurrentY;
mCurrentX = mScroller.getCurrX();
mCurrentY = mScroller.getCurrY();
- mViewer.setPosition(mCurrentX, mCurrentY, mCurrentScale);
+
+ // Check if we hit the edges; show edge effects if we do.
+ if (oldX > mBoundLeft && mCurrentX == mBoundLeft) {
+ int v = Math.round(-mScroller.getCurrVelocityX() * mCurrentScale);
+ mEdgeView.onAbsorb(v, EdgeView.LEFT);
+ } else if (oldX < mBoundRight && mCurrentX == mBoundRight) {
+ int v = Math.round(mScroller.getCurrVelocityX() * mCurrentScale);
+ mEdgeView.onAbsorb(v, EdgeView.RIGHT);
+ }
+
+ if (oldY > mBoundTop && mCurrentY == mBoundTop) {
+ int v = Math.round(-mScroller.getCurrVelocityY() * mCurrentScale);
+ mEdgeView.onAbsorb(v, EdgeView.TOP);
+ } else if (oldY < mBoundBottom && mCurrentY == mBoundBottom) {
+ int v = Math.round(mScroller.getCurrVelocityY() * mCurrentScale);
+ mEdgeView.onAbsorb(v, EdgeView.BOTTOM);
+ }
}
// Interpolates mCurrent{X,Y,Scale} given the progress in [0, 1].
@@ -596,4 +647,14 @@
public int getImageHeight() {
return mImageH;
}
+
+ public boolean isAtLeftEdge() {
+ calculateStableBound(mCurrentScale);
+ return mCurrentX <= mBoundLeft;
+ }
+
+ public boolean isAtRightEdge() {
+ calculateStableBound(mCurrentScale);
+ return mCurrentX >= mBoundRight;
+ }
}