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.anim;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.Utils;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.view.animation.Interpolator;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// Animation calculates a value according to the current input time.
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 1. First we need to use setDuration(int) to set the duration of the
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//    animation. The duration is in milliseconds.
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 2. Then we should call start(). The actual start time is the first value
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//    passed to calculate(long).
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 3. Each time we want to get an animation value, we call
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//    calculate(long currentTimeMillis) to ask the Animation to calculate it.
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//    The parameter passed to calculate(long) should be nonnegative.
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 4. Use get() to get that value.
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// In step 3, onCalculate(float progress) is called so subclasses can calculate
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// the value according to progress (progress is a value in [0,1]).
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// Before onCalculate(float) is called, There is an optional interpolator which
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// can change the progress value. The interpolator can be set by
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// setInterpolator(Interpolator). If the interpolator is used, the value passed
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// to onCalculate may be (for example, the overshoot effect).
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// The isActive() method returns true after the animation start() is called and
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// before calculate is passed a value which reaches the duration of the
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// animation.
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// The start() method can be called again to restart the Animation.
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin//
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linabstract public class Animation {
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final long ANIMATION_START = -1;
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final long NO_ANIMATION = -2;
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private long mStartTime = NO_ANIMATION;
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private int mDuration;
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private Interpolator mInterpolator;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void setInterpolator(Interpolator interpolator) {
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mInterpolator = interpolator;
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void setDuration(int duration) {
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mDuration = duration;
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void start() {
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mStartTime = ANIMATION_START;
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void setStartTime(long time) {
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mStartTime = time;
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public boolean isActive() {
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mStartTime != NO_ANIMATION;
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void forceStop() {
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mStartTime = NO_ANIMATION;
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public boolean calculate(long currentTimeMillis) {
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mStartTime == NO_ANIMATION) return false;
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mStartTime == ANIMATION_START) mStartTime = currentTimeMillis;
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int elapse = (int) (currentTimeMillis - mStartTime);
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        float x = Utils.clamp((float) elapse / mDuration, 0f, 1f);
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Interpolator i = mInterpolator;
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        onCalculate(i != null ? i.getInterpolation(x) : x);
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (elapse >= mDuration) mStartTime = NO_ANIMATION;
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mStartTime != NO_ANIMATION;
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    abstract protected void onCalculate(float progress);
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
93