blob: bf8a5440545073a4f7d137dcff0d970a12fb1bdf [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.gallery3d.anim;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import com.android.gallery3d.glrenderer.GLCanvas;
import com.android.gallery3d.glrenderer.RawTexture;
import com.android.gallery3d.ui.GLView;
import com.android.gallery3d.ui.TiledScreenNail;
public class StateTransitionAnimation extends Animation {
public static class Spec {
public static final Spec OUTGOING;
public static final Spec INCOMING;
public static final Spec PHOTO_INCOMING;
private static final Interpolator DEFAULT_INTERPOLATOR =
new DecelerateInterpolator();
public int duration = 330;
public float backgroundAlphaFrom = 0;
public float backgroundAlphaTo = 0;
public float backgroundScaleFrom = 0;
public float backgroundScaleTo = 0;
public float contentAlphaFrom = 1;
public float contentAlphaTo = 1;
public float contentScaleFrom = 1;
public float contentScaleTo = 1;
public float overlayAlphaFrom = 0;
public float overlayAlphaTo = 0;
public float overlayScaleFrom = 0;
public float overlayScaleTo = 0;
public Interpolator interpolator = DEFAULT_INTERPOLATOR;
static {
OUTGOING = new Spec();
OUTGOING.backgroundAlphaFrom = 0.5f;
OUTGOING.backgroundAlphaTo = 0f;
OUTGOING.backgroundScaleFrom = 1f;
OUTGOING.backgroundScaleTo = 0f;
OUTGOING.contentAlphaFrom = 0.5f;
OUTGOING.contentAlphaTo = 1f;
OUTGOING.contentScaleFrom = 3f;
OUTGOING.contentScaleTo = 1f;
INCOMING = new Spec();
INCOMING.overlayAlphaFrom = 1f;
INCOMING.overlayAlphaTo = 0f;
INCOMING.overlayScaleFrom = 1f;
INCOMING.overlayScaleTo = 3f;
INCOMING.contentAlphaFrom = 0f;
INCOMING.contentAlphaTo = 1f;
INCOMING.contentScaleFrom = 0.25f;
INCOMING.contentScaleTo = 1f;
PHOTO_INCOMING = INCOMING;
}
private static Spec specForTransition(Transition t) {
switch (t) {
case Outgoing:
return Spec.OUTGOING;
case Incoming:
return Spec.INCOMING;
case PhotoIncoming:
return Spec.PHOTO_INCOMING;
case None:
default:
return null;
}
}
}
public static enum Transition { None, Outgoing, Incoming, PhotoIncoming }
private final Spec mTransitionSpec;
private float mCurrentContentScale;
private float mCurrentContentAlpha;
private float mCurrentBackgroundScale;
private float mCurrentBackgroundAlpha;
private float mCurrentOverlayScale;
private float mCurrentOverlayAlpha;
private RawTexture mOldScreenTexture;
public StateTransitionAnimation(Transition t, RawTexture oldScreen) {
this(Spec.specForTransition(t), oldScreen);
}
public StateTransitionAnimation(Spec spec, RawTexture oldScreen) {
mTransitionSpec = spec != null ? spec : Spec.OUTGOING;
setDuration(mTransitionSpec.duration);
setInterpolator(mTransitionSpec.interpolator);
mOldScreenTexture = oldScreen;
TiledScreenNail.disableDrawPlaceholder();
}
@Override
public boolean calculate(long currentTimeMillis) {
boolean retval = super.calculate(currentTimeMillis);
if (!isActive()) {
if (mOldScreenTexture != null) {
mOldScreenTexture.recycle();
mOldScreenTexture = null;
}
TiledScreenNail.enableDrawPlaceholder();
}
return retval;
}
@Override
protected void onCalculate(float progress) {
mCurrentContentScale = mTransitionSpec.contentScaleFrom
+ (mTransitionSpec.contentScaleTo - mTransitionSpec.contentScaleFrom) * progress;
mCurrentContentAlpha = mTransitionSpec.contentAlphaFrom
+ (mTransitionSpec.contentAlphaTo - mTransitionSpec.contentAlphaFrom) * progress;
mCurrentBackgroundAlpha = mTransitionSpec.backgroundAlphaFrom
+ (mTransitionSpec.backgroundAlphaTo - mTransitionSpec.backgroundAlphaFrom)
* progress;
mCurrentBackgroundScale = mTransitionSpec.backgroundScaleFrom
+ (mTransitionSpec.backgroundScaleTo - mTransitionSpec.backgroundScaleFrom)
* progress;
mCurrentOverlayScale = mTransitionSpec.overlayScaleFrom
+ (mTransitionSpec.overlayScaleTo - mTransitionSpec.overlayScaleFrom) * progress;
mCurrentOverlayAlpha = mTransitionSpec.overlayAlphaFrom
+ (mTransitionSpec.overlayAlphaTo - mTransitionSpec.overlayAlphaFrom) * progress;
}
private void applyOldTexture(GLView view, GLCanvas canvas, float alpha, float scale, boolean clear) {
if (mOldScreenTexture == null)
return;
if (clear) canvas.clearBuffer(view.getBackgroundColor());
canvas.save();
canvas.setAlpha(alpha);
int xOffset = view.getWidth() / 2;
int yOffset = view.getHeight() / 2;
canvas.translate(xOffset, yOffset);
canvas.scale(scale, scale, 1);
mOldScreenTexture.draw(canvas, -xOffset, -yOffset);
canvas.restore();
}
public void applyBackground(GLView view, GLCanvas canvas) {
if (mCurrentBackgroundAlpha > 0f) {
applyOldTexture(view, canvas, mCurrentBackgroundAlpha, mCurrentBackgroundScale, true);
}
}
public void applyContentTransform(GLView view, GLCanvas canvas) {
int xOffset = view.getWidth() / 2;
int yOffset = view.getHeight() / 2;
canvas.translate(xOffset, yOffset);
canvas.scale(mCurrentContentScale, mCurrentContentScale, 1);
canvas.translate(-xOffset, -yOffset);
canvas.setAlpha(mCurrentContentAlpha);
}
public void applyOverlay(GLView view, GLCanvas canvas) {
if (mCurrentOverlayAlpha > 0f) {
applyOldTexture(view, canvas, mCurrentOverlayAlpha, mCurrentOverlayScale, false);
}
}
}