Add capture animation in Gallery.
Change-Id: Ibf95cc64f37a4518377e64124af6606c4f14cdaa
diff --git a/src/com/android/gallery3d/ui/PositionController.java b/src/com/android/gallery3d/ui/PositionController.java
index 46f0121..e6c132b 100644
--- a/src/com/android/gallery3d/ui/PositionController.java
+++ b/src/com/android/gallery3d/ui/PositionController.java
@@ -45,6 +45,7 @@
private static final int ANIM_KIND_ZOOM = 4;
private static final int ANIM_KIND_OPENING = 5;
private static final int ANIM_KIND_FLING = 6;
+ private static final int ANIM_KIND_CAPTURE = 7;
// Animation time in milliseconds. The order must match ANIM_KIND_* above.
private static final int ANIM_TIME[] = {
@@ -55,6 +56,7 @@
300, // ANIM_KIND_ZOOM
600, // ANIM_KIND_OPENING
0, // ANIM_KIND_FLING (the duration is calculated dynamically)
+ 800, // ANIM_KIND_CAPTURE
};
// We try to scale up the image to fill the screen. But in order not to
@@ -139,7 +141,7 @@
public interface Listener {
void invalidate();
- boolean isDown();
+ boolean isHolding();
// EdgeView
void onPull(int offset, int direction);
@@ -187,8 +189,8 @@
public void setImageSize(int index, int width, int height) {
if (width == 0 || height == 0) {
initBox(index);
- } else {
- setBoxSize(index, width, height, false);
+ } else if (!setBoxSize(index, width, height, false)) {
+ return;
}
updateScaleAndGapLimit();
@@ -196,17 +198,18 @@
snapAndRedraw();
}
- private void setBoxSize(int i, int width, int height, boolean isViewSize) {
+ // Returns false if the box size doesn't change.
+ private boolean setBoxSize(int i, int width, int height, boolean isViewSize) {
Box b = mBoxes.get(i);
boolean wasViewSize = b.mUseViewSize;
// If we already have an image size, we don't want to use the view size.
- if (!wasViewSize && isViewSize) return;
+ if (!wasViewSize && isViewSize) return false;
b.mUseViewSize = isViewSize;
if (width == b.mImageW && height == b.mImageH) {
- return;
+ return false;
}
// The ratio of the old size and the new size.
@@ -232,6 +235,8 @@
mFocusX /= ratio;
mFocusY /= ratio;
}
+
+ return true;
}
private void startOpeningAnimationIfNeeded() {
@@ -339,7 +344,7 @@
redraw();
}
- public void up() {
+ public void snapback() {
snapAndRedraw();
}
@@ -406,11 +411,26 @@
snapAndRedraw();
}
- public void startHorizontalSlide(int distance) {
+ // Slide the focused box to the center of the view.
+ public void startHorizontalSlide() {
Box b = mBoxes.get(0);
- Platform p = mPlatform;
- startAnimation(getTargetX(p) + distance, getTargetY(b),
- b.mCurrentScale, ANIM_KIND_SLIDE);
+ startAnimation(mViewW / 2, mViewH / 2, b.mScaleMin, ANIM_KIND_SLIDE);
+ }
+
+ // Slide the focused box to the center of the view with the capture
+ // animation. In addition to the sliding, the animation will also scale the
+ // the focused box, the specified neighbor box, and the gap between the
+ // two. The specified offset should be 1 or -1.
+ public void startCaptureAnimationSlide(int offset) {
+ Box b = mBoxes.get(0);
+ Box n = mBoxes.get(offset); // the neighbor box
+ Gap g = mGaps.get(offset); // the gap between the two boxes
+
+ mPlatform.doAnimation(mViewW / 2, ANIM_KIND_CAPTURE);
+ b.doAnimation(mViewH / 2, b.mScaleMin, ANIM_KIND_CAPTURE);
+ n.doAnimation(mViewH / 2, n.mScaleMin, ANIM_KIND_CAPTURE);
+ g.doAnimation(g.mDefaultSize, ANIM_KIND_CAPTURE);
+ redraw();
}
public void startScroll(float dx, float dy) {
@@ -762,7 +782,7 @@
// N N N N N N N -- all new boxes
// -3 -2 -1 0 1 2 3 -- nothing changed
// -2 -1 0 1 2 3 N -- focus goes to the next box
- // N-3 -2 -1 0 1 2 -- focuse goes to the previous box
+ // N -3 -2 -1 0 1 2 -- focuse goes to the previous box
// -3 -2 -1 1 2 3 N -- the focused box was deleted.
public void moveBox(int fromIndex[], boolean hasPrev, boolean hasNext) {
//debugMoveBox(fromIndex);
@@ -837,12 +857,12 @@
first = last = 0;
}
// Now for those boxes between first and last, just assign the same
- // position as the previous box. (We can do better, but this should be
+ // position as the next box. (We can do better, but this should be
// rare). For the boxes before first or after last, we will use a new
// default gap size below.
- for (int i = first + 1; i < last; i++) {
+ for (int i = last - 1; i > first; i--) {
if (from.get(i) != Integer.MAX_VALUE) continue;
- mBoxes.get(i).mAbsoluteX = mBoxes.get(i - 1).mAbsoluteX;
+ mBoxes.get(i).mAbsoluteX = mBoxes.get(i + 1).mAbsoluteX;
}
// 7. recycle the gaps that are not used in the new array.
@@ -1089,6 +1109,7 @@
switch (kind) {
case ANIM_KIND_SCROLL:
case ANIM_KIND_FLING:
+ case ANIM_KIND_CAPTURE:
progress = 1 - f; // linear
break;
case ANIM_KIND_SCALE:
@@ -1116,7 +1137,7 @@
public boolean startSnapback() {
if (mAnimationStartTime != NO_ANIMATION) return false;
if (mAnimationKind == ANIM_KIND_SCROLL
- && mListener.isDown()) return false;
+ && mListener.isHolding()) return false;
Box b = mBoxes.get(0);
float scaleMin = mExtraScalingRange ?
@@ -1211,8 +1232,14 @@
mCurrentX = mToX;
return true;
} else {
- mCurrentX = (int) (mFromX + progress * (mToX - mFromX));
- return (mCurrentX == mToX);
+ if (mAnimationKind == ANIM_KIND_CAPTURE) {
+ progress = CaptureAnimation.calculateSlide(progress);
+ mCurrentX = (int) (mFromX + progress * (mToX - mFromX));
+ return false;
+ } else {
+ mCurrentX = (int) (mFromX + progress * (mToX - mFromX));
+ return (mCurrentX == mToX);
+ }
}
}
}
@@ -1247,7 +1274,7 @@
public boolean startSnapback() {
if (mAnimationStartTime != NO_ANIMATION) return false;
if (mAnimationKind == ANIM_KIND_SCROLL
- && mListener.isDown()) return false;
+ && mListener.isHolding()) return false;
if (mInScale && this == mBoxes.get(0)) return false;
int y;
@@ -1288,7 +1315,8 @@
targetY = mViewH / 2;
}
- if (mCurrentY == targetY && mCurrentScale == targetScale) {
+ if (mCurrentY == targetY && mCurrentScale == targetScale
+ && kind != ANIM_KIND_CAPTURE) {
return false;
}
@@ -1341,7 +1369,13 @@
} else {
mCurrentY = (int) (mFromY + progress * (mToY - mFromY));
mCurrentScale = mFromScale + progress * (mToScale - mFromScale);
- return (mCurrentY == mToY && mCurrentScale == mToScale);
+ if (mAnimationKind == ANIM_KIND_CAPTURE) {
+ float f = CaptureAnimation.calculateScale(progress);
+ mCurrentScale *= f;
+ return false;
+ } else {
+ return (mCurrentY == mToY && mCurrentScale == mToScale);
+ }
}
}
}
@@ -1361,13 +1395,15 @@
@Override
public boolean startSnapback() {
if (mAnimationStartTime != NO_ANIMATION) return false;
- return doAnimation(mDefaultSize);
+ return doAnimation(mDefaultSize, ANIM_KIND_SNAPBACK);
}
// Starts an animation for a gap.
- public boolean doAnimation(int targetSize) {
- if (mCurrentGap == targetSize) return false;
- mAnimationKind = ANIM_KIND_SNAPBACK;
+ public boolean doAnimation(int targetSize, int kind) {
+ if (mCurrentGap == targetSize && kind != ANIM_KIND_CAPTURE) {
+ return false;
+ }
+ mAnimationKind = kind;
mFromGap = mCurrentGap;
mToGap = targetSize;
mAnimationStartTime = AnimationTime.startTime();
@@ -1383,7 +1419,13 @@
return true;
} else {
mCurrentGap = (int) (mFromGap + progress * (mToGap - mFromGap));
- return (mCurrentGap == mToGap);
+ if (mAnimationKind == ANIM_KIND_CAPTURE) {
+ float f = CaptureAnimation.calculateScale(progress);
+ mCurrentGap = (int) (mCurrentGap * f);
+ return false;
+ } else {
+ return (mCurrentGap == mToGap);
+ }
}
}
}