1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.ui; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.anim.CanvasAnimation; 20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.anim.FloatAnimation; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.PointF; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.Random; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL11; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class SlideshowView extends GLView { 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @SuppressWarnings("unused") 30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "SlideshowView"; 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int SLIDESHOW_DURATION = 3500; 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int TRANSITION_DURATION = 1000; 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final float SCALE_SPEED = 0.20f ; 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final float MOVE_SPEED = SCALE_SPEED; 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mCurrentRotation; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private BitmapTexture mCurrentTexture; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private SlideshowAnimation mCurrentAnimation; 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mPrevRotation; 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private BitmapTexture mPrevTexture; 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private SlideshowAnimation mPrevAnimation; 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final FloatAnimation mTransitionAnimation = 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new FloatAnimation(0, 1, TRANSITION_DURATION); 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Random mRandom = new Random(); 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void next(Bitmap bitmap, int rotation) { 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTransitionAnimation.start(); 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mPrevTexture != null) { 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevTexture.getBitmap().recycle(); 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevTexture.recycle(); 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevTexture = mCurrentTexture; 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevAnimation = mCurrentAnimation; 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevRotation = mCurrentRotation; 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentRotation = rotation; 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentTexture = new BitmapTexture(bitmap); 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (((rotation / 90) & 0x01) == 0) { 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentAnimation = new SlideshowAnimation( 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentTexture.getWidth(), mCurrentTexture.getHeight(), 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRandom); 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentAnimation = new SlideshowAnimation( 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentTexture.getHeight(), mCurrentTexture.getWidth(), 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRandom); 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentAnimation.start(); 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin invalidate(); 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void release() { 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mPrevTexture != null) { 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevTexture.recycle(); 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevTexture = null; 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mCurrentTexture != null) { 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentTexture.recycle(); 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentTexture = null; 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void render(GLCanvas canvas) { 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long currentTimeMillis = canvas.currentAnimationTimeMillis(); 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean requestRender = mTransitionAnimation.calculate(currentTimeMillis); 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = canvas.getGLInstance(); 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float alpha = mPrevTexture == null ? 1f : mTransitionAnimation.get(); 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mPrevTexture != null && alpha != 1f) { 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestRender |= mPrevAnimation.calculate(currentTimeMillis); 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX); 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.setAlpha(1f - alpha); 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevAnimation.apply(canvas); 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.rotate(mPrevRotation, 0, 0, 1); 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPrevTexture.draw(canvas, -mPrevTexture.getWidth() / 2, 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin -mPrevTexture.getHeight() / 2); 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.restore(); 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mCurrentTexture != null) { 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestRender |= mCurrentAnimation.calculate(currentTimeMillis); 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX); 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.setAlpha(alpha); 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentAnimation.apply(canvas); 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.rotate(mCurrentRotation, 0, 0, 1); 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCurrentTexture.draw(canvas, -mCurrentTexture.getWidth() / 2, 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin -mCurrentTexture.getHeight() / 2); 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.restore(); 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (requestRender) invalidate(); 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class SlideshowAnimation extends CanvasAnimation { 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mWidth; 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mHeight; 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final PointF mMovingVector; 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private float mProgress; 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public SlideshowAnimation(int width, int height, Random random) { 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mWidth = width; 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHeight = height; 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMovingVector = new PointF( 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MOVE_SPEED * mWidth * (random.nextFloat() - 0.5f), 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MOVE_SPEED * mHeight * (random.nextFloat() - 0.5f)); 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setDuration(SLIDESHOW_DURATION); 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void apply(GLCanvas canvas) { 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int viewWidth = getWidth(); 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int viewHeight = getHeight(); 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float initScale = Math.min(2f, Math.min((float) 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin viewWidth / mWidth, (float) viewHeight / mHeight)); 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float scale = initScale * (1 + SCALE_SPEED * mProgress); 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float centerX = viewWidth / 2 + mMovingVector.x * mProgress; 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float centerY = viewHeight / 2 + mMovingVector.y * mProgress; 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.translate(centerX, centerY, 0); 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin canvas.scale(scale, scale, 0); 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getCanvasSaveFlags() { 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return GLCanvas.SAVE_FLAG_MATRIX; 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void onCalculate(float progress) { 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mProgress = progress; 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 166