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