package com.android.gallery3d.filtershow.imageshow;
+import android.animation.Animator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.NinePatchDrawable;
import android.support.v4.widget.EdgeEffectCompat;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
private int mCurrentEdgeEffect = 0;
private int mEdgeSize = 100;
+ private static final int mAnimationSnapDelay = 200;
+ private static final int mAnimationZoomDelay = 400;
+ private ValueAnimator mAnimatorScale = null;
+ private ValueAnimator mAnimatorTranslateX = null;
+ private ValueAnimator mAnimatorTranslateY = null;
+
private enum InteractionMode {
NONE,
SCALE,
if (image == null) {
return;
}
- Matrix m = MasterImage.getImage().computeImageToScreen(image, 0, false);
+ MasterImage master = MasterImage.getImage();
+ Matrix m = master.computeImageToScreen(image, 0, false);
if (m == null) {
return;
}
canvas.save();
- MasterImage master = MasterImage.getImage();
RectF d = new RectF(0, 0, image.getWidth(), image.getHeight());
m.mapRect(d);
// Animation uses the image before the change
Bitmap previousImage = master.getPreviousImage();
- Matrix mp = MasterImage.getImage().computeImageToScreen(previousImage, 0, false);
+ Matrix mp = master.computeImageToScreen(previousImage, 0, false);
RectF dp = new RectF(0, 0, previousImage.getWidth(), previousImage.getHeight());
mp.mapRect(dp);
Rect previousBounds = new Rect();
}
public void drawCompareImage(Canvas canvas, Bitmap image) {
- boolean showsOriginal = MasterImage.getImage().showsOriginal();
+ MasterImage master = MasterImage.getImage();
+ boolean showsOriginal = master.showsOriginal();
if (!showsOriginal && !mTouchShowOriginal)
return;
canvas.save();
}
}
canvas.clipRect(d);
- Matrix m = MasterImage.getImage().computeImageToScreen(image, 0, false);
+ Matrix m = master.computeImageToScreen(image, 0, false);
canvas.drawBitmap(image, m, mPaint);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
return true;
}
+ private void startAnimTranslation(int fromX, int toX,
+ int fromY, int toY, int delay) {
+ if (fromX == toX && fromY == toY) {
+ return;
+ }
+ if (mAnimatorTranslateX != null) {
+ mAnimatorTranslateX.cancel();
+ }
+ if (mAnimatorTranslateY != null) {
+ mAnimatorTranslateY.cancel();
+ }
+ mAnimatorTranslateX = ValueAnimator.ofInt(fromX, toX);
+ mAnimatorTranslateY = ValueAnimator.ofInt(fromY, toY);
+ mAnimatorTranslateX.setDuration(delay);
+ mAnimatorTranslateY.setDuration(delay);
+ mAnimatorTranslateX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ Point translation = MasterImage.getImage().getTranslation();
+ translation.x = (Integer) animation.getAnimatedValue();
+ MasterImage.getImage().setTranslation(translation);
+ invalidate();
+ }
+ });
+ mAnimatorTranslateY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ Point translation = MasterImage.getImage().getTranslation();
+ translation.y = (Integer) animation.getAnimatedValue();
+ MasterImage.getImage().setTranslation(translation);
+ invalidate();
+ }
+ });
+ mAnimatorTranslateX.start();
+ mAnimatorTranslateY.start();
+ }
+
+ private void applyTranslationConstraints() {
+ float scaleFactor = MasterImage.getImage().getScaleFactor();
+ Point translation = MasterImage.getImage().getTranslation();
+ int x = translation.x;
+ int y = translation.y;
+ constrainTranslation(translation, scaleFactor);
+
+ if (x != translation.x || y != translation.y) {
+ startAnimTranslation(x, translation.x,
+ y, translation.y,
+ mAnimationSnapDelay);
+ }
+ }
+
protected boolean enableComparison() {
return true;
}
public boolean onDoubleTap(MotionEvent arg0) {
mZoomIn = !mZoomIn;
float scale = 1.0f;
+ final float x = arg0.getX();
+ final float y = arg0.getY();
if (mZoomIn) {
scale = MasterImage.getImage().getMaxScaleFactor();
}
if (scale != MasterImage.getImage().getScaleFactor()) {
- MasterImage.getImage().setScaleFactor(scale);
- float translateX = (getWidth() / 2 - arg0.getX());
- float translateY = (getHeight() / 2 - arg0.getY());
+ if (mAnimatorScale != null) {
+ mAnimatorScale.cancel();
+ }
+ mAnimatorScale = ValueAnimator.ofFloat(
+ MasterImage.getImage().getScaleFactor(),
+ scale
+ );
+ float translateX = (getWidth() / 2 - x);
+ float translateY = (getHeight() / 2 - y);
Point translation = MasterImage.getImage().getTranslation();
- translation.x = (int) (mOriginalTranslation.x + translateX);
- translation.y = (int) (mOriginalTranslation.y + translateY);
+ int startTranslateX = translation.x;
+ int startTranslateY = translation.y;
+ if (scale != 1.0f) {
+ translation.x = (int) (mOriginalTranslation.x + translateX);
+ translation.y = (int) (mOriginalTranslation.y + translateY);
+ } else {
+ translation.x = 0;
+ translation.y = 0;
+ }
constrainTranslation(translation, scale);
- MasterImage.getImage().setTranslation(translation);
- invalidate();
+
+ startAnimTranslation(startTranslateX, translation.x,
+ startTranslateY, translation.y,
+ mAnimationZoomDelay);
+ mAnimatorScale.setDuration(mAnimationZoomDelay);
+ mAnimatorScale.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ MasterImage.getImage().setScaleFactor((Float) animation.getAnimatedValue());
+ invalidate();
+ }
+ });
+ mAnimatorScale.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ applyTranslationConstraints();
+ MasterImage.getImage().needsUpdatePartialPreview();
+ invalidate();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ });
+ mAnimatorScale.start();
}
return true;
}
int currentEdgeEffect = 0;
if (scale <= 1) {
mCurrentEdgeEffect = 0;
+ mEdgeEffect.finish();
return;
}
if (mCurrentEdgeEffect != currentEdgeEffect) {
if (mCurrentEdgeEffect == 0 || currentEdgeEffect != 0) {
mCurrentEdgeEffect = currentEdgeEffect;
+ mEdgeEffect.finish();
}
- mEdgeEffect.finish();
mEdgeEffect.setSize(getWidth(), mEdgeSize);
- mEdgeEffect.onPull(mEdgeSize);
- } else {
+ }
+ if (currentEdgeEffect != 0) {
mEdgeEffect.onPull(mEdgeSize);
}
}
if (scaleFactor > MasterImage.getImage().getMaxScaleFactor()) {
scaleFactor = MasterImage.getImage().getMaxScaleFactor();
}
- if (scaleFactor < 0.5) {
- scaleFactor = 0.5f;
+ if (scaleFactor < 1.0f) {
+ scaleFactor = 1.0f;
}
MasterImage.getImage().setScaleFactor(scaleFactor);
scaleFactor = img.getScaleFactor();
&& preset.contains(FilterRepresentation.TYPE_FX)) {
FilterRepresentation rep = preset.getFilterRepresentationForType(
FilterRepresentation.TYPE_FX);
- removeFilter(rep);
- if (!isNoneBorderFilter(rep)) {
- mFilters.add(rep);
- }
+ addFilter(rep);
} else {
// user preset replaces everything
mFilters.clear();
for (int i = 0; i < preset.nbFilters(); i++) {
addFilter(preset.getFilterRepresentation(i));
}
- mFilters.add(representation);
}
} else if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) {
// Add geometry filter, removing duplicates and do-nothing operations.
mFilters.add(representation);
}
} else if (representation.getFilterType() == FilterRepresentation.TYPE_FX) {
- boolean found = false;
+ boolean replaced = false;
for (int i = 0; i < mFilters.size(); i++) {
FilterRepresentation current = mFilters.elementAt(i);
- int type = current.getFilterType();
- if (found) {
- if (type != FilterRepresentation.TYPE_VIGNETTE) {
- mFilters.remove(i);
- continue;
- }
- }
- if (type == FilterRepresentation.TYPE_FX) {
- if (current instanceof FilterUserPresetRepresentation) {
- ImagePreset preset = ((FilterUserPresetRepresentation) current)
- .getImagePreset();
- // If we had an existing user preset, let's remove all the presets that
- // were added by it
- for (int j = 0; j < preset.nbFilters(); j++) {
- FilterRepresentation rep = preset.getFilterRepresentation(j);
- int pos = getPositionForRepresentation(rep);
- if (pos != -1) {
- mFilters.remove(pos);
- }
- }
- int pos = getPositionForRepresentation(current);
- if (pos != -1) {
- mFilters.remove(pos);
- } else {
- pos = 0;
- }
- if (!isNoneFxFilter(representation)) {
- mFilters.add(pos, representation);
- }
-
- } else {
- mFilters.remove(i);
- if (!isNoneFxFilter(representation)) {
- mFilters.add(i, representation);
- }
+ if (current.getFilterType() == FilterRepresentation.TYPE_FX) {
+ mFilters.remove(i);
+ replaced = true;
+ if (!isNoneBorderFilter(representation)) {
+ mFilters.add(i, representation);
}
- found = true;
+ break;
}
}
- if (!found) {
- if (!isNoneFxFilter(representation)) {
- mFilters.add(representation);
- }
+ if (!replaced) {
+ mFilters.add(0, representation);
}
} else {
mFilters.add(representation);