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.launcher3;
18
19import android.animation.Animator;
20import android.animation.Animator.AnimatorListener;
21import android.animation.TimeInterpolator;
22import android.view.View;
23import android.view.ViewPropertyAnimator;
24
25import java.util.ArrayList;
26import java.util.EnumSet;
27
28public class LauncherViewPropertyAnimator extends Animator implements AnimatorListener {
29    enum Properties {
30            TRANSLATION_X,
31            TRANSLATION_Y,
32            SCALE_X,
33            SCALE_Y,
34            ROTATION_Y,
35            ALPHA,
36            START_DELAY,
37            DURATION,
38            INTERPOLATOR,
39            WITH_LAYER
40    }
41    EnumSet<Properties> mPropertiesToSet = EnumSet.noneOf(Properties.class);
42    ViewPropertyAnimator mViewPropertyAnimator;
43    View mTarget;
44
45    float mTranslationX;
46    float mTranslationY;
47    float mScaleX;
48    float mScaleY;
49    float mRotationY;
50    float mAlpha;
51    long mStartDelay;
52    long mDuration;
53    TimeInterpolator mInterpolator;
54    ArrayList<Animator.AnimatorListener> mListeners;
55    boolean mRunning = false;
56    FirstFrameAnimatorHelper mFirstFrameHelper;
57
58    public LauncherViewPropertyAnimator(View target) {
59        mTarget = target;
60        mListeners = new ArrayList<Animator.AnimatorListener>();
61    }
62
63    @Override
64    public void addListener(Animator.AnimatorListener listener) {
65        mListeners.add(listener);
66    }
67
68    @Override
69    public void cancel() {
70        if (mViewPropertyAnimator != null) {
71            mViewPropertyAnimator.cancel();
72        }
73    }
74
75    @Override
76    public Animator clone() {
77        throw new RuntimeException("Not implemented");
78    }
79
80    @Override
81    public void end() {
82        throw new RuntimeException("Not implemented");
83    }
84
85    @Override
86    public long getDuration() {
87        return mDuration;
88    }
89
90    @Override
91    public ArrayList<Animator.AnimatorListener> getListeners() {
92        return mListeners;
93    }
94
95    @Override
96    public long getStartDelay() {
97        return mStartDelay;
98    }
99
100    @Override
101    public void onAnimationCancel(Animator animation) {
102        for (int i = 0; i < mListeners.size(); i++) {
103            Animator.AnimatorListener listener = mListeners.get(i);
104            listener.onAnimationCancel(this);
105        }
106        mRunning = false;
107    }
108
109    @Override
110    public void onAnimationEnd(Animator animation) {
111        for (int i = 0; i < mListeners.size(); i++) {
112            Animator.AnimatorListener listener = mListeners.get(i);
113            listener.onAnimationEnd(this);
114        }
115        mRunning = false;
116    }
117
118    @Override
119    public void onAnimationRepeat(Animator animation) {
120        for (int i = 0; i < mListeners.size(); i++) {
121            Animator.AnimatorListener listener = mListeners.get(i);
122            listener.onAnimationRepeat(this);
123        }
124    }
125
126    @Override
127    public void onAnimationStart(Animator animation) {
128        // This is the first time we get a handle to the internal ValueAnimator
129        // used by the ViewPropertyAnimator.
130        mFirstFrameHelper.onAnimationStart(animation);
131
132        for (int i = 0; i < mListeners.size(); i++) {
133            Animator.AnimatorListener listener = mListeners.get(i);
134            listener.onAnimationStart(this);
135        }
136        mRunning = true;
137    }
138
139    @Override
140    public boolean isRunning() {
141        return mRunning;
142    }
143
144    @Override
145    public boolean isStarted() {
146        return mViewPropertyAnimator != null;
147    }
148
149    @Override
150    public void removeAllListeners() {
151        mListeners.clear();
152    }
153
154    @Override
155    public void removeListener(Animator.AnimatorListener listener) {
156        mListeners.remove(listener);
157    }
158
159    @Override
160    public Animator setDuration(long duration) {
161        mPropertiesToSet.add(Properties.DURATION);
162        mDuration = duration;
163        return this;
164    }
165
166    @Override
167    public void setInterpolator(TimeInterpolator value) {
168        mPropertiesToSet.add(Properties.INTERPOLATOR);
169        mInterpolator = value;
170    }
171
172    @Override
173    public void setStartDelay(long startDelay) {
174        mPropertiesToSet.add(Properties.START_DELAY);
175        mStartDelay = startDelay;
176    }
177
178    @Override
179    public void setTarget(Object target) {
180        throw new RuntimeException("Not implemented");
181    }
182
183    @Override
184    public void setupEndValues() {
185
186    }
187
188    @Override
189    public void setupStartValues() {
190    }
191
192    @Override
193    public void start() {
194        mViewPropertyAnimator = mTarget.animate();
195
196        // FirstFrameAnimatorHelper hooks itself up to the updates on the animator,
197        // and then adjusts the play time to keep the first two frames jank-free
198        mFirstFrameHelper = new FirstFrameAnimatorHelper(mViewPropertyAnimator, mTarget);
199
200        if (mPropertiesToSet.contains(Properties.TRANSLATION_X)) {
201            mViewPropertyAnimator.translationX(mTranslationX);
202        }
203        if (mPropertiesToSet.contains(Properties.TRANSLATION_Y)) {
204            mViewPropertyAnimator.translationY(mTranslationY);
205        }
206        if (mPropertiesToSet.contains(Properties.SCALE_X)) {
207            mViewPropertyAnimator.scaleX(mScaleX);
208        }
209        if (mPropertiesToSet.contains(Properties.ROTATION_Y)) {
210            mViewPropertyAnimator.rotationY(mRotationY);
211        }
212        if (mPropertiesToSet.contains(Properties.SCALE_Y)) {
213            mViewPropertyAnimator.scaleY(mScaleY);
214        }
215        if (mPropertiesToSet.contains(Properties.ALPHA)) {
216            mViewPropertyAnimator.alpha(mAlpha);
217        }
218        if (mPropertiesToSet.contains(Properties.START_DELAY)) {
219            mViewPropertyAnimator.setStartDelay(mStartDelay);
220        }
221        if (mPropertiesToSet.contains(Properties.DURATION)) {
222            mViewPropertyAnimator.setDuration(mDuration);
223        }
224        if (mPropertiesToSet.contains(Properties.INTERPOLATOR)) {
225            mViewPropertyAnimator.setInterpolator(mInterpolator);
226        }
227        if (mPropertiesToSet.contains(Properties.WITH_LAYER)) {
228            mViewPropertyAnimator.withLayer();
229        }
230        mViewPropertyAnimator.setListener(this);
231        mViewPropertyAnimator.start();
232        LauncherAnimUtils.cancelOnDestroyActivity(this);
233    }
234
235    public LauncherViewPropertyAnimator translationX(float value) {
236        mPropertiesToSet.add(Properties.TRANSLATION_X);
237        mTranslationX = value;
238        return this;
239    }
240
241    public LauncherViewPropertyAnimator translationY(float value) {
242        mPropertiesToSet.add(Properties.TRANSLATION_Y);
243        mTranslationY = value;
244        return this;
245    }
246
247    public LauncherViewPropertyAnimator scaleX(float value) {
248        mPropertiesToSet.add(Properties.SCALE_X);
249        mScaleX = value;
250        return this;
251    }
252
253    public LauncherViewPropertyAnimator scaleY(float value) {
254        mPropertiesToSet.add(Properties.SCALE_Y);
255        mScaleY = value;
256        return this;
257    }
258
259    public LauncherViewPropertyAnimator rotationY(float value) {
260        mPropertiesToSet.add(Properties.ROTATION_Y);
261        mRotationY = value;
262        return this;
263    }
264
265    public LauncherViewPropertyAnimator alpha(float value) {
266        mPropertiesToSet.add(Properties.ALPHA);
267        mAlpha = value;
268        return this;
269    }
270
271    public LauncherViewPropertyAnimator withLayer() {
272        mPropertiesToSet.add(Properties.WITH_LAYER);
273        return this;
274    }
275}
276