Home | History | Annotate | Download | only in anim
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.anim;
     18 
     19 import android.view.animation.AccelerateInterpolator;
     20 import android.view.animation.DecelerateInterpolator;
     21 import android.view.animation.Interpolator;
     22 
     23 import com.android.gallery3d.glrenderer.GLCanvas;
     24 import com.android.gallery3d.glrenderer.RawTexture;
     25 import com.android.gallery3d.ui.GLView;
     26 import com.android.gallery3d.ui.TiledScreenNail;
     27 
     28 public class StateTransitionAnimation extends Animation {
     29 
     30     public static class Spec {
     31         public static final Spec OUTGOING;
     32         public static final Spec INCOMING;
     33         public static final Spec PHOTO_INCOMING;
     34 
     35         private static final Interpolator DEFAULT_INTERPOLATOR =
     36                 new DecelerateInterpolator();
     37 
     38         public int duration = 330;
     39         public float backgroundAlphaFrom = 0;
     40         public float backgroundAlphaTo = 0;
     41         public float backgroundScaleFrom = 0;
     42         public float backgroundScaleTo = 0;
     43         public float contentAlphaFrom = 1;
     44         public float contentAlphaTo = 1;
     45         public float contentScaleFrom = 1;
     46         public float contentScaleTo = 1;
     47         public float overlayAlphaFrom = 0;
     48         public float overlayAlphaTo = 0;
     49         public float overlayScaleFrom = 0;
     50         public float overlayScaleTo = 0;
     51         public Interpolator interpolator = DEFAULT_INTERPOLATOR;
     52 
     53         static {
     54             OUTGOING = new Spec();
     55             OUTGOING.backgroundAlphaFrom = 0.5f;
     56             OUTGOING.backgroundAlphaTo = 0f;
     57             OUTGOING.backgroundScaleFrom = 1f;
     58             OUTGOING.backgroundScaleTo = 0f;
     59             OUTGOING.contentAlphaFrom = 0.5f;
     60             OUTGOING.contentAlphaTo = 1f;
     61             OUTGOING.contentScaleFrom = 3f;
     62             OUTGOING.contentScaleTo = 1f;
     63 
     64             INCOMING = new Spec();
     65             INCOMING.overlayAlphaFrom = 1f;
     66             INCOMING.overlayAlphaTo = 0f;
     67             INCOMING.overlayScaleFrom = 1f;
     68             INCOMING.overlayScaleTo = 3f;
     69             INCOMING.contentAlphaFrom = 0f;
     70             INCOMING.contentAlphaTo = 1f;
     71             INCOMING.contentScaleFrom = 0.25f;
     72             INCOMING.contentScaleTo = 1f;
     73 
     74             PHOTO_INCOMING = INCOMING;
     75         }
     76 
     77         private static Spec specForTransition(Transition t) {
     78             switch (t) {
     79                 case Outgoing:
     80                     return Spec.OUTGOING;
     81                 case Incoming:
     82                     return Spec.INCOMING;
     83                 case PhotoIncoming:
     84                     return Spec.PHOTO_INCOMING;
     85                 case None:
     86                 default:
     87                     return null;
     88             }
     89         }
     90     }
     91 
     92     public static enum Transition { None, Outgoing, Incoming, PhotoIncoming }
     93 
     94     private final Spec mTransitionSpec;
     95     private float mCurrentContentScale;
     96     private float mCurrentContentAlpha;
     97     private float mCurrentBackgroundScale;
     98     private float mCurrentBackgroundAlpha;
     99     private float mCurrentOverlayScale;
    100     private float mCurrentOverlayAlpha;
    101     private RawTexture mOldScreenTexture;
    102 
    103     public StateTransitionAnimation(Transition t, RawTexture oldScreen) {
    104         this(Spec.specForTransition(t), oldScreen);
    105     }
    106 
    107     public StateTransitionAnimation(Spec spec, RawTexture oldScreen) {
    108         mTransitionSpec = spec != null ? spec : Spec.OUTGOING;
    109         setDuration(mTransitionSpec.duration);
    110         setInterpolator(mTransitionSpec.interpolator);
    111         mOldScreenTexture = oldScreen;
    112         TiledScreenNail.disableDrawPlaceholder();
    113     }
    114 
    115     @Override
    116     public boolean calculate(long currentTimeMillis) {
    117         boolean retval = super.calculate(currentTimeMillis);
    118         if (!isActive()) {
    119             if (mOldScreenTexture != null) {
    120                 mOldScreenTexture.recycle();
    121                 mOldScreenTexture = null;
    122             }
    123             TiledScreenNail.enableDrawPlaceholder();
    124         }
    125         return retval;
    126     }
    127 
    128     @Override
    129     protected void onCalculate(float progress) {
    130         mCurrentContentScale = mTransitionSpec.contentScaleFrom
    131                 + (mTransitionSpec.contentScaleTo - mTransitionSpec.contentScaleFrom) * progress;
    132         mCurrentContentAlpha = mTransitionSpec.contentAlphaFrom
    133                 + (mTransitionSpec.contentAlphaTo - mTransitionSpec.contentAlphaFrom) * progress;
    134         mCurrentBackgroundAlpha = mTransitionSpec.backgroundAlphaFrom
    135                 + (mTransitionSpec.backgroundAlphaTo - mTransitionSpec.backgroundAlphaFrom)
    136                 * progress;
    137         mCurrentBackgroundScale = mTransitionSpec.backgroundScaleFrom
    138                 + (mTransitionSpec.backgroundScaleTo - mTransitionSpec.backgroundScaleFrom)
    139                 * progress;
    140         mCurrentOverlayScale = mTransitionSpec.overlayScaleFrom
    141                 + (mTransitionSpec.overlayScaleTo - mTransitionSpec.overlayScaleFrom) * progress;
    142         mCurrentOverlayAlpha = mTransitionSpec.overlayAlphaFrom
    143                 + (mTransitionSpec.overlayAlphaTo - mTransitionSpec.overlayAlphaFrom) * progress;
    144     }
    145 
    146     private void applyOldTexture(GLView view, GLCanvas canvas, float alpha, float scale, boolean clear) {
    147         if (mOldScreenTexture == null)
    148             return;
    149         if (clear) canvas.clearBuffer(view.getBackgroundColor());
    150         canvas.save();
    151         canvas.setAlpha(alpha);
    152         int xOffset = view.getWidth() / 2;
    153         int yOffset = view.getHeight() / 2;
    154         canvas.translate(xOffset, yOffset);
    155         canvas.scale(scale, scale, 1);
    156         mOldScreenTexture.draw(canvas, -xOffset, -yOffset);
    157         canvas.restore();
    158     }
    159 
    160     public void applyBackground(GLView view, GLCanvas canvas) {
    161         if (mCurrentBackgroundAlpha > 0f) {
    162             applyOldTexture(view, canvas, mCurrentBackgroundAlpha, mCurrentBackgroundScale, true);
    163         }
    164     }
    165 
    166     public void applyContentTransform(GLView view, GLCanvas canvas) {
    167         int xOffset = view.getWidth() / 2;
    168         int yOffset = view.getHeight() / 2;
    169         canvas.translate(xOffset, yOffset);
    170         canvas.scale(mCurrentContentScale, mCurrentContentScale, 1);
    171         canvas.translate(-xOffset, -yOffset);
    172         canvas.setAlpha(mCurrentContentAlpha);
    173     }
    174 
    175     public void applyOverlay(GLView view, GLCanvas canvas) {
    176         if (mCurrentOverlayAlpha > 0f) {
    177             applyOldTexture(view, canvas, mCurrentOverlayAlpha, mCurrentOverlayScale, false);
    178         }
    179     }
    180 }
    181