1/*
2 * Copyright (C) 2012 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.camera;
18
19import android.graphics.Color;
20import android.os.SystemClock;
21import android.view.animation.DecelerateInterpolator;
22import android.view.animation.Interpolator;
23
24import com.android.gallery3d.ui.GLCanvas;
25import com.android.gallery3d.ui.RawTexture;
26
27/**
28 * Class to handle the capture animation.
29 */
30public class CaptureAnimManager {
31    @SuppressWarnings("unused")
32    private static final String TAG = "CAM_Capture";
33    private static final int TIME_FLASH = 200;
34    private static final int TIME_HOLD = 400;
35    private static final int TIME_SLIDE = 400;  // milliseconds.
36
37    private static final int ANIM_BOTH = 0;
38    private static final int ANIM_FLASH = 1;
39    private static final int ANIM_SLIDE = 2;
40
41    private final Interpolator mSlideInterpolator = new DecelerateInterpolator();
42
43    private int mAnimOrientation;  // Could be 0, 90, 180 or 270 degrees.
44    private long mAnimStartTime;  // milliseconds.
45    private float mX;  // The center of the whole view including preview and review.
46    private float mY;
47    private float mDelta;
48    private int mDrawWidth;
49    private int mDrawHeight;
50    private int mAnimType;
51
52    /* preview: camera preview view.
53     * review: view of picture just taken.
54     */
55    public CaptureAnimManager() {
56    }
57
58    public void setOrientation(int displayRotation) {
59        mAnimOrientation = (360 - displayRotation) % 360;
60    }
61
62    public void animateSlide() {
63        if (mAnimType != ANIM_FLASH) {
64            return;
65        }
66        mAnimType = ANIM_SLIDE;
67        mAnimStartTime = SystemClock.uptimeMillis();
68    }
69
70    public void animateFlash() {
71        mAnimType = ANIM_FLASH;
72    }
73
74    public void animateFlashAndSlide() {
75        mAnimType = ANIM_BOTH;
76    }
77
78    // x, y, w and h: the rectangle area where the animation takes place.
79    public void startAnimation(int x, int y, int w, int h) {
80        mAnimStartTime = SystemClock.uptimeMillis();
81        // Set the views to the initial positions.
82        mDrawWidth = w;
83        mDrawHeight = h;
84        mX = x;
85        mY = y;
86        switch (mAnimOrientation) {
87            case 0:  // Preview is on the left.
88                mDelta = w;
89                break;
90            case 90:  // Preview is below.
91                mDelta = -h;
92                break;
93            case 180:  // Preview on the right.
94                mDelta = -w;
95                break;
96            case 270:  // Preview is above.
97                mDelta = h;
98                break;
99        }
100    }
101
102    // Returns true if the animation has been drawn.
103    public boolean drawAnimation(GLCanvas canvas, CameraScreenNail preview,
104                RawTexture review) {
105        long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime;
106        // Check if the animation is over
107        if (mAnimType == ANIM_SLIDE && timeDiff > TIME_SLIDE) return false;
108        if (mAnimType == ANIM_BOTH && timeDiff > TIME_HOLD + TIME_SLIDE) return false;
109
110        int animStep = mAnimType;
111        if (mAnimType == ANIM_BOTH) {
112            animStep = (timeDiff < TIME_HOLD) ? ANIM_FLASH : ANIM_SLIDE;
113            if (animStep == ANIM_SLIDE) {
114                timeDiff -= TIME_HOLD;
115            }
116        }
117
118        if (animStep == ANIM_FLASH) {
119            review.draw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight);
120            if (timeDiff < TIME_FLASH) {
121                float f = 0.3f - 0.3f * timeDiff / TIME_FLASH;
122                int color = Color.argb((int) (255 * f), 255, 255, 255);
123                canvas.fillRect(mX, mY, mDrawWidth, mDrawHeight, color);
124            }
125        } else if (animStep == ANIM_SLIDE) {
126            float fraction = (float) (timeDiff) / TIME_SLIDE;
127            float x = mX;
128            float y = mY;
129            if (mAnimOrientation == 0 || mAnimOrientation == 180) {
130                x = x + mDelta * mSlideInterpolator.getInterpolation(fraction);
131            } else {
132                y = y + mDelta * mSlideInterpolator.getInterpolation(fraction);
133            }
134            // float alpha = canvas.getAlpha();
135            // canvas.setAlpha(fraction);
136            preview.directDraw(canvas, (int) mX, (int) mY,
137                    mDrawWidth, mDrawHeight);
138            // canvas.setAlpha(alpha);
139
140            review.draw(canvas, (int) x, (int) y, mDrawWidth, mDrawHeight);
141        } else {
142            return false;
143        }
144        return true;
145    }
146}
147