Fix capture animation if we are far away from the camera preview.

Bug: 6481823
Change-Id: If2511c8dd08e0483cdc3139068ee190e2b08126d
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
index e7ec3a9..fd08e0e 100644
--- a/src/com/android/gallery3d/ui/PhotoView.java
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -973,21 +973,15 @@
 
     @Override
     protected void render(GLCanvas canvas) {
-        float filmRatio = mPositionController.getFilmRatio();
+        // In page mode, we draw only one previous/next photo. But if we are
+        // doing capture animation, we want to draw all photos.
+        boolean inPageMode = (mPositionController.getFilmRatio() == 0f);
+        boolean inCaptureAnimation = ((mHolding & HOLD_CAPTURE_ANIMATION) != 0);
+        boolean drawOneNeighborOnly = inPageMode && !inCaptureAnimation;
+        int neighbors = drawOneNeighborOnly ? 1 : SCREEN_NAIL_MAX;
 
-        // Draw next photos. In page mode, we draw only one next photo.
-        int lastPhoto = (filmRatio == 0f) ? 1 : SCREEN_NAIL_MAX;
-        for (int i = lastPhoto; i > 0; i--) {
-            Rect r = mPositionController.getPosition(i);
-            mPictures.get(i).draw(canvas, r);
-        }
-
-        // Draw current photo
-        mPictures.get(0).draw(canvas, mPositionController.getPosition(0));
-
-        // Draw previous photos. In page mode, we draw only one previous photo.
-        lastPhoto = (filmRatio == 0f) ? -1: -SCREEN_NAIL_MAX;
-        for (int i = -1; i >= lastPhoto; i--) {
+        // Draw photos from back to front
+        for (int i = neighbors; i >= -neighbors; i--) {
             Rect r = mPositionController.getPosition(i);
             mPictures.get(i).draw(canvas, r);
         }
@@ -1191,6 +1185,17 @@
             mPositionController.startCaptureAnimationSlide(-1);
         } else if (offset == -1) {
             if (mPrevBound >= 0) return false;
+            if (mFilmMode) setFilmMode(false);
+
+            // If we are too far away from the first image (so that we don't
+            // have all the ScreenNails in-between), we go directly without
+            // animation.
+            if (mModel.getCurrentIndex() > SCREEN_NAIL_MAX) {
+                switchToFirstImage();
+                mPositionController.skipAnimation();
+                return true;
+            }
+
             switchToFirstImage();
             mPositionController.startCaptureAnimationSlide(1);
         } else {
diff --git a/src/com/android/gallery3d/ui/PositionController.java b/src/com/android/gallery3d/ui/PositionController.java
index 226826d..bb2b83e 100644
--- a/src/com/android/gallery3d/ui/PositionController.java
+++ b/src/com/android/gallery3d/ui/PositionController.java
@@ -34,7 +34,7 @@
     public static final int IMAGE_AT_TOP_EDGE = 4;
     public static final int IMAGE_AT_BOTTOM_EDGE = 8;
 
-    public static final int CAPTURE_ANIMATION_TIME = 600;
+    public static final int CAPTURE_ANIMATION_TIME = 700;
 
     // Special values for animation time.
     private static final long NO_ANIMATION = -1;
@@ -960,7 +960,27 @@
             }
         }
 
-        // 8. offset the Platform position
+        // 8. calculate the new absolute X coordinates for those box before
+        // first or after last.
+        for (int i = first - 1; i >= -BOX_MAX; i--) {
+            Box a = mBoxes.get(i + 1);
+            Box b = mBoxes.get(i);
+            int wa = widthOf(a);
+            int wb = widthOf(b);
+            Gap g = mGaps.get(i);
+            b.mAbsoluteX = a.mAbsoluteX - wa / 2 - (wb - wb / 2) - g.mCurrentGap;
+        }
+
+        for (int i = last + 1; i <= BOX_MAX; i++) {
+            Box a = mBoxes.get(i - 1);
+            Box b = mBoxes.get(i);
+            int wa = widthOf(a);
+            int wb = widthOf(b);
+            Gap g = mGaps.get(i - 1);
+            b.mAbsoluteX = a.mAbsoluteX + (wa - wa / 2) + wb / 2 + g.mCurrentGap;
+        }
+
+        // 9. offset the Platform position
         int dx = mBoxes.get(0).mAbsoluteX - mPlatform.mCurrentX;
         mPlatform.mCurrentX += dx;
         mPlatform.mFromX += dx;