blob: 5d4abde02bd851eaf869b132a686e5243df5fc95 [file] [log] [blame]
package com.android.gallery3d.ui;
import android.graphics.Matrix;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL11;
public class DisplayItemPanel extends GLView {
private static final int TRANSITION_DURATION = 1000;
// The state of the display item.
// The state of those items to be removed
private static final int STATE_REMOVED = 1;
// The state of the items that is just added to this panel
private static final int STATE_NEWBIE = 2;
// The state of the items that changed position
private static final int STATE_MOVED = 3;
private static final long NO_ANIMATION = -1;
private static final long START_ANIMATION = 0;
private ArrayList<DisplayItem> mItems = new ArrayList<DisplayItem>();
private long mAnimationStartTime = NO_ANIMATION;
private boolean mPrepareTransition = false;
private final Interpolator mInterpolator = new DecelerateInterpolator(4);
/**
* Puts the item center at the given position and angle.
*/
public void putDisplayItem(
DisplayItem item, float x, float y, float theata) {
if (item.mPanel != this && item.mPanel != null) {
throw new IllegalArgumentException();
}
item.mTarget.set(x, y, theata);
if (item.mPanel != this) {
item.mPanel = this;
item.mState = STATE_NEWBIE;
mItems.add(item);
item.mCurrent.set(x, y, theata);
} else {
item.mState = STATE_MOVED;
if (mPrepareTransition) {
item.mSource.set(item.mCurrent);
} else {
item.mCurrent.set(x, y, theata);
}
}
if (!mPrepareTransition) invalidate();
}
public void prepareTransition() {
mPrepareTransition = true;
for (DisplayItem item : mItems) {
item.mState = STATE_REMOVED;
}
}
public void startTransition() {
mPrepareTransition = false;
mAnimationStartTime = START_ANIMATION;
invalidate();
}
private void onTransitionComplete() {
ArrayList<DisplayItem> list = new ArrayList<DisplayItem>();
for (DisplayItem item: mItems) {
if (item.mState == STATE_REMOVED) {
item.mPanel = null;
} else {
list.add(item);
}
}
mItems = list;
}
@Override
protected void render(GLRootView view, GL11 gl) {
if (mAnimationStartTime == NO_ANIMATION) {
for (DisplayItem item: mItems) {
renderItem(view, item);
}
} else {
long now = view.currentAnimationTimeMillis();
if (mAnimationStartTime == START_ANIMATION) {
mAnimationStartTime = now;
}
float timeRatio = Util.clamp((float)
(now - mAnimationStartTime) / TRANSITION_DURATION, 0, 1);
float interpolate = mInterpolator.getInterpolation(timeRatio);
for (DisplayItem item: mItems) {
renderItem(view, item, interpolate);
}
if (timeRatio == 1.0f) {
onTransitionComplete();
mAnimationStartTime = NO_ANIMATION;
} else {
invalidate();
}
}
}
private void renderItem(GLRootView root, DisplayItem item) {
Transformation transform = root.getTransformation();
Matrix matrix = transform.getMatrix();
item.mCurrent.apply(matrix);
item.render(root);
item.mCurrent.inverse(matrix);
}
private void renderItem(
GLRootView root, DisplayItem item, float interpolate) {
Transformation transform = root.getTransformation();
float alpha = transform.getAlpha();
Matrix matrix = transform.getMatrix();
switch (item.mState) {
case STATE_MOVED:
item.updateCurrentPosition(interpolate);
break;
case STATE_NEWBIE:
transform.setAlpha(alpha * interpolate);
break;
case STATE_REMOVED:
transform.setAlpha(alpha * (1.0f - interpolate));
break;
}
item.mCurrent.apply(matrix);
item.render(root);
item.mCurrent.inverse(matrix);
transform.setAlpha(alpha);
}
}