Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2010 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.ui;
     18 
     19 import android.graphics.Bitmap;
     20 import android.graphics.PointF;
     21 
     22 import com.android.gallery3d.anim.CanvasAnimation;
     23 import com.android.gallery3d.anim.FloatAnimation;
     24 import com.android.gallery3d.glrenderer.BitmapTexture;
     25 import com.android.gallery3d.glrenderer.GLCanvas;
     26 
     27 import java.util.Random;
     28 
     29 public class SlideshowView extends GLView {
     30     @SuppressWarnings("unused")
     31     private static final String TAG = "SlideshowView";
     32 
     33     private static final int SLIDESHOW_DURATION = 3500;
     34     private static final int TRANSITION_DURATION = 1000;
     35 
     36     private static final float SCALE_SPEED = 0.20f ;
     37     private static final float MOVE_SPEED = SCALE_SPEED;
     38 
     39     private int mCurrentRotation;
     40     private BitmapTexture mCurrentTexture;
     41     private SlideshowAnimation mCurrentAnimation;
     42 
     43     private int mPrevRotation;
     44     private BitmapTexture mPrevTexture;
     45     private SlideshowAnimation mPrevAnimation;
     46 
     47     private final FloatAnimation mTransitionAnimation =
     48             new FloatAnimation(0, 1, TRANSITION_DURATION);
     49 
     50     private Random mRandom = new Random();
     51 
     52     public void next(Bitmap bitmap, int rotation) {
     53 
     54         mTransitionAnimation.start();
     55 
     56         if (mPrevTexture != null) {
     57             mPrevTexture.getBitmap().recycle();
     58             mPrevTexture.recycle();
     59         }
     60 
     61         mPrevTexture = mCurrentTexture;
     62         mPrevAnimation = mCurrentAnimation;
     63         mPrevRotation = mCurrentRotation;
     64 
     65         mCurrentRotation = rotation;
     66         mCurrentTexture = new BitmapTexture(bitmap);
     67         if (((rotation / 90) & 0x01) == 0) {
     68             mCurrentAnimation = new SlideshowAnimation(
     69                     mCurrentTexture.getWidth(), mCurrentTexture.getHeight(),
     70                     mRandom);
     71         } else {
     72             mCurrentAnimation = new SlideshowAnimation(
     73                     mCurrentTexture.getHeight(), mCurrentTexture.getWidth(),
     74                     mRandom);
     75         }
     76         mCurrentAnimation.start();
     77 
     78         invalidate();
     79     }
     80 
     81     public void release() {
     82         if (mPrevTexture != null) {
     83             mPrevTexture.recycle();
     84             mPrevTexture = null;
     85         }
     86         if (mCurrentTexture != null) {
     87             mCurrentTexture.recycle();
     88             mCurrentTexture = null;
     89         }
     90     }
     91 
     92     @Override
     93     protected void render(GLCanvas canvas) {
     94         long animTime = AnimationTime.get();
     95         boolean requestRender = mTransitionAnimation.calculate(animTime);
     96         float alpha = mPrevTexture == null ? 1f : mTransitionAnimation.get();
     97 
     98         if (mPrevTexture != null && alpha != 1f) {
     99             requestRender |= mPrevAnimation.calculate(animTime);
    100             canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
    101             canvas.setAlpha(1f - alpha);
    102             mPrevAnimation.apply(canvas);
    103             canvas.rotate(mPrevRotation, 0, 0, 1);
    104             mPrevTexture.draw(canvas, -mPrevTexture.getWidth() / 2,
    105                     -mPrevTexture.getHeight() / 2);
    106             canvas.restore();
    107         }
    108         if (mCurrentTexture != null) {
    109             requestRender |= mCurrentAnimation.calculate(animTime);
    110             canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
    111             canvas.setAlpha(alpha);
    112             mCurrentAnimation.apply(canvas);
    113             canvas.rotate(mCurrentRotation, 0, 0, 1);
    114             mCurrentTexture.draw(canvas, -mCurrentTexture.getWidth() / 2,
    115                     -mCurrentTexture.getHeight() / 2);
    116             canvas.restore();
    117         }
    118         if (requestRender) invalidate();
    119     }
    120 
    121     private class SlideshowAnimation extends CanvasAnimation {
    122         private final int mWidth;
    123         private final int mHeight;
    124 
    125         private final PointF mMovingVector;
    126         private float mProgress;
    127 
    128         public SlideshowAnimation(int width, int height, Random random) {
    129             mWidth = width;
    130             mHeight = height;
    131             mMovingVector = new PointF(
    132                     MOVE_SPEED * mWidth * (random.nextFloat() - 0.5f),
    133                     MOVE_SPEED * mHeight * (random.nextFloat() - 0.5f));
    134             setDuration(SLIDESHOW_DURATION);
    135         }
    136 
    137         @Override
    138         public void apply(GLCanvas canvas) {
    139             int viewWidth = getWidth();
    140             int viewHeight = getHeight();
    141 
    142             float initScale = Math.min((float)
    143                     viewWidth / mWidth, (float) viewHeight / mHeight);
    144             float scale = initScale * (1 + SCALE_SPEED * mProgress);
    145 
    146             float centerX = viewWidth / 2 + mMovingVector.x * mProgress;
    147             float centerY = viewHeight / 2 + mMovingVector.y * mProgress;
    148 
    149             canvas.translate(centerX, centerY);
    150             canvas.scale(scale, scale, 0);
    151         }
    152 
    153         @Override
    154         public int getCanvasSaveFlags() {
    155             return GLCanvas.SAVE_FLAG_MATRIX;
    156         }
    157 
    158         @Override
    159         protected void onCalculate(float progress) {
    160             mProgress = progress;
    161         }
    162     }
    163 }
    164