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