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