blob: ba6ec3751d4c6398fa68120551ea5885c7c7038e [file] [log] [blame]
package com.android.gallery3d.ui;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import java.util.ArrayList;
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 removeDisplayItem(DisplayItem item) {
if (item.mPanel != this) throw new IllegalArgumentException();
mItems.remove(item);
item.mPanel = null;
}
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(GLCanvas canvas) {
canvas.translate(-mScrollX, 0, 0);
if (mAnimationStartTime == NO_ANIMATION) {
for (DisplayItem item: mItems) {
renderItem(canvas, item);
}
} else {
long now = canvas.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(canvas, item, interpolate);
}
if (timeRatio == 1.0f) {
onTransitionComplete();
mAnimationStartTime = NO_ANIMATION;
} else {
invalidate();
}
}
canvas.translate(mScrollX, 0, 0);
}
private void renderItem(GLCanvas canvas, DisplayItem item) {
canvas.save(GLCanvas.ALPHA_SAVE_FLAG | GLCanvas.MATRIX_SAVE_FLAG);
item.mCurrent.apply(canvas);
item.render(canvas);
canvas.restore();
}
private void renderItem(
GLCanvas canvas, DisplayItem item, float interpolate) {
canvas.save(GLCanvas.ALPHA_SAVE_FLAG | GLCanvas.MATRIX_SAVE_FLAG);
switch (item.mState) {
case STATE_MOVED:
item.updateCurrentPosition(interpolate);
break;
case STATE_NEWBIE:
canvas.multiplyAlpha(interpolate);
break;
case STATE_REMOVED:
canvas.multiplyAlpha(1.0f - interpolate);
break;
}
item.mCurrent.apply(canvas);
item.render(canvas);
canvas.restore();
}
}