SlideshowView.java revision f9a0a4306d589b4a4e20554fed512a603426bfa1
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, 0);
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