SlideshowView.java revision 7e6537ca106a80aeb4a52182b31ddc9aa642abe5
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 android.graphics.Bitmap;
20import android.graphics.PointF;
21
22import com.android.gallery3d.anim.CanvasAnimation;
23import com.android.gallery3d.anim.FloatAnimation;
24
25import java.util.Random;
26
27import javax.microedition.khronos.opengles.GL11;
28
29public 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        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
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
141        public void apply(GLCanvas canvas) {
142            int viewWidth = getWidth();
143            int viewHeight = getHeight();
144
145            float initScale = 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
157        public int getCanvasSaveFlags() {
158            return GLCanvas.SAVE_FLAG_MATRIX;
159        }
160
161        @Override
162        protected void onCalculate(float progress) {
163            mProgress = progress;
164        }
165    }
166}
167