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 25 import java.util.Random; 26 27 import javax.microedition.khronos.opengles.GL11; 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 next(Bitmap bitmap, int rotation)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 release()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 render(GLCanvas canvas)93 protected void render(GLCanvas canvas) { 94 long animTime = AnimationTime.get(); 95 boolean requestRender = mTransitionAnimation.calculate(animTime); 96 GL11 gl = canvas.getGLInstance(); 97 gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); 98 float alpha = mPrevTexture == null ? 1f : mTransitionAnimation.get(); 99 100 if (mPrevTexture != null && alpha != 1f) { 101 requestRender |= mPrevAnimation.calculate(animTime); 102 canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX); 103 canvas.setAlpha(1f - alpha); 104 mPrevAnimation.apply(canvas); 105 canvas.rotate(mPrevRotation, 0, 0, 1); 106 mPrevTexture.draw(canvas, -mPrevTexture.getWidth() / 2, 107 -mPrevTexture.getHeight() / 2); 108 canvas.restore(); 109 } 110 if (mCurrentTexture != null) { 111 requestRender |= mCurrentAnimation.calculate(animTime); 112 canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX); 113 canvas.setAlpha(alpha); 114 mCurrentAnimation.apply(canvas); 115 canvas.rotate(mCurrentRotation, 0, 0, 1); 116 mCurrentTexture.draw(canvas, -mCurrentTexture.getWidth() / 2, 117 -mCurrentTexture.getHeight() / 2); 118 canvas.restore(); 119 } 120 if (requestRender) invalidate(); 121 gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); 122 } 123 124 private class SlideshowAnimation extends CanvasAnimation { 125 private final int mWidth; 126 private final int mHeight; 127 128 private final PointF mMovingVector; 129 private float mProgress; 130 SlideshowAnimation(int width, int height, Random random)131 public SlideshowAnimation(int width, int height, Random random) { 132 mWidth = width; 133 mHeight = height; 134 mMovingVector = new PointF( 135 MOVE_SPEED * mWidth * (random.nextFloat() - 0.5f), 136 MOVE_SPEED * mHeight * (random.nextFloat() - 0.5f)); 137 setDuration(SLIDESHOW_DURATION); 138 } 139 140 @Override apply(GLCanvas canvas)141 public void apply(GLCanvas canvas) { 142 int viewWidth = getWidth(); 143 int viewHeight = getHeight(); 144 145 float initScale = Math.min(2f, Math.min((float) 146 viewWidth / mWidth, (float) viewHeight / mHeight)); 147 float scale = initScale * (1 + SCALE_SPEED * mProgress); 148 149 float centerX = viewWidth / 2 + mMovingVector.x * mProgress; 150 float centerY = viewHeight / 2 + mMovingVector.y * mProgress; 151 152 canvas.translate(centerX, centerY); 153 canvas.scale(scale, scale, 0); 154 } 155 156 @Override getCanvasSaveFlags()157 public int getCanvasSaveFlags() { 158 return GLCanvas.SAVE_FLAG_MATRIX; 159 } 160 161 @Override onCalculate(float progress)162 protected void onCalculate(float progress) { 163 mProgress = progress; 164 } 165 } 166 } 167