1e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato/*
2e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * Copyright (C) 2009 The Android Open Source Project
3e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato *
4e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * you may not use this file except in compliance with the License.
6e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * You may obtain a copy of the License at
7e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato *
8e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato *
10e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * Unless required by applicable law or agreed to in writing, software
11e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * See the License for the specific language governing permissions and
14e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * limitations under the License.
15e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato */
16e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
17e77c08d15f23c403293dbb40c6a36967de822c89Joe Onoratopackage com.android.launcher2;
18e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
19e77c08d15f23c403293dbb40c6a36967de822c89Joe Onoratoimport android.os.Handler;
20e77c08d15f23c403293dbb40c6a36967de822c89Joe Onoratoimport android.os.SystemClock;
21e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
22e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato/**
23e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato * Provides an animation between 0.0f and 1.0f over a given duration.
24e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato */
25e77c08d15f23c403293dbb40c6a36967de822c89Joe Onoratoclass SymmetricalLinearTween {
26e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
27e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    private static final int FPS = 30;
28e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    private static final int FRAME_TIME = 1000 / FPS;
29e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
30e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    Handler mHandler;
31e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    int mDuration;
32e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    TweenCallback mCallback;
33e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
34e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    boolean mRunning;
35e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    long mBase;
36e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    boolean mDirection;
37e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    float mValue;
38e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
39e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    /**
40e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * @param duration milliseconds duration
41e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * @param callback callbacks
42e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     */
43e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    public SymmetricalLinearTween(boolean initial, int duration, TweenCallback callback) {
44e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        mValue = initial ? 1.0f : 0.0f;
45e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        mDirection = initial;
46e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        mDuration = duration;
47e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        mCallback = callback;
48e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        mHandler = new Handler();
49e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    }
50e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
51e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    /**
52e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * Starts the tweening.
53e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     *
54e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * @param direction If direction is true, the value goes towards 1.0f.  If direction
55e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     *                  is false, the value goes towards 0.0f.
56e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     */
57e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    public void start(boolean direction) {
58e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        start(direction, SystemClock.uptimeMillis());
59e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    }
60e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
61e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    /**
62e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * Starts the tweening.
63e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     *
64e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * @param direction If direction is true, the value goes towards 1.0f.  If direction
65e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     *                  is false, the value goes towards 0.0f.
66e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     * @param baseTime  The time to use as zero for this animation, in the
67e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     *                  {@link SystemClock.uptimeMillis} time base.  This allows you to
68e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     *                  synchronize multiple animations.
69e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato     */
70e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    public void start(boolean direction, long baseTime) {
71e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        if (direction != mDirection) {
72e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            if (!mRunning) {
73e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mBase = baseTime;
74e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mRunning = true;
75e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mCallback.onTweenStarted();
76e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                long next = SystemClock.uptimeMillis() + FRAME_TIME;
77e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mHandler.postAtTime(mTick, next);
78e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            } else {
79e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                // reverse direction
80e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                long now = SystemClock.uptimeMillis();
81e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                long diff = now - mBase;
82e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mBase = now + diff - mDuration;
83e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            }
84e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            mDirection = direction;
85e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        }
86e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    }
87e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
88e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    Runnable mTick = new Runnable() {
89e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        public void run() {
90e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            long base = mBase;
91e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            long now = SystemClock.uptimeMillis();
92e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            long diff = now-base;
93e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            int duration = mDuration;
94e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            float val = diff/(float)duration;
95e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            if (!mDirection) {
96e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                val = 1.0f - val;
97e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            }
98e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            if (val > 1.0f) {
99e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                val = 1.0f;
100e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            } else if (val < 0.0f) {
101e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                val = 0.0f;
102e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            }
103e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            float old = mValue;
104e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            mValue = val;
105e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            mCallback.onTweenValueChanged(val, old);
106e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            int frame = (int)(diff / FRAME_TIME);
107e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            long next = base + ((frame+1)*FRAME_TIME);
108e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            if (diff < duration) {
109e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mHandler.postAtTime(this, next);
110e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            }
111e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            if (diff >= duration) {
112e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mCallback.onTweenFinished();
113e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato                mRunning = false;
114e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato            }
115e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato        }
116e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato    };
117e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato}
118e77c08d15f23c403293dbb40c6a36967de822c89Joe Onorato
119