create changelog entry
[debian/openrocket] / android-libraries / ActionBarSherlock / src / com / actionbarsherlock / internal / nineoldandroids / animation / Keyframe.java
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
17 package com.actionbarsherlock.internal.nineoldandroids.animation;
18
19 import android.view.animation.Interpolator;
20
21 /**
22  * This class holds a time/value pair for an animation. The Keyframe class is used
23  * by {@link ValueAnimator} to define the values that the animation target will have over the course
24  * of the animation. As the time proceeds from one keyframe to the other, the value of the
25  * target object will animate between the value at the previous keyframe and the value at the
26  * next keyframe. Each keyframe also holds an optional {@link TimeInterpolator}
27  * object, which defines the time interpolation over the intervalue preceding the keyframe.
28  *
29  * <p>The Keyframe class itself is abstract. The type-specific factory methods will return
30  * a subclass of Keyframe specific to the type of value being stored. This is done to improve
31  * performance when dealing with the most common cases (e.g., <code>float</code> and
32  * <code>int</code> values). Other types will fall into a more general Keyframe class that
33  * treats its values as Objects. Unless your animation requires dealing with a custom type
34  * or a data structure that needs to be animated directly (and evaluated using an implementation
35  * of {@link TypeEvaluator}), you should stick to using float and int as animations using those
36  * types have lower runtime overhead than other types.</p>
37  */
38 @SuppressWarnings("rawtypes")
39 public abstract class Keyframe implements Cloneable {
40     /**
41      * The time at which mValue will hold true.
42      */
43     float mFraction;
44
45     /**
46      * The type of the value in this Keyframe. This type is determined at construction time,
47      * based on the type of the <code>value</code> object passed into the constructor.
48      */
49     Class mValueType;
50
51     /**
52      * The optional time interpolator for the interval preceding this keyframe. A null interpolator
53      * (the default) results in linear interpolation over the interval.
54      */
55     private /*Time*/Interpolator mInterpolator = null;
56
57     /**
58      * Flag to indicate whether this keyframe has a valid value. This flag is used when an
59      * animation first starts, to populate placeholder keyframes with real values derived
60      * from the target object.
61      */
62     boolean mHasValue = false;
63
64     /**
65      * Constructs a Keyframe object with the given time and value. The time defines the
66      * time, as a proportion of an overall animation's duration, at which the value will hold true
67      * for the animation. The value for the animation between keyframes will be calculated as
68      * an interpolation between the values at those keyframes.
69      *
70      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
71      * of time elapsed of the overall animation duration.
72      * @param value The value that the object will animate to as the animation time approaches
73      * the time in this keyframe, and the the value animated from as the time passes the time in
74      * this keyframe.
75      */
76     public static Keyframe ofInt(float fraction, int value) {
77         return new IntKeyframe(fraction, value);
78     }
79
80     /**
81      * Constructs a Keyframe object with the given time. The value at this time will be derived
82      * from the target object when the animation first starts (note that this implies that keyframes
83      * with no initial value must be used as part of an {@link ObjectAnimator}).
84      * The time defines the
85      * time, as a proportion of an overall animation's duration, at which the value will hold true
86      * for the animation. The value for the animation between keyframes will be calculated as
87      * an interpolation between the values at those keyframes.
88      *
89      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
90      * of time elapsed of the overall animation duration.
91      */
92     public static Keyframe ofInt(float fraction) {
93         return new IntKeyframe(fraction);
94     }
95
96     /**
97      * Constructs a Keyframe object with the given time and value. The time defines the
98      * time, as a proportion of an overall animation's duration, at which the value will hold true
99      * for the animation. The value for the animation between keyframes will be calculated as
100      * an interpolation between the values at those keyframes.
101      *
102      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
103      * of time elapsed of the overall animation duration.
104      * @param value The value that the object will animate to as the animation time approaches
105      * the time in this keyframe, and the the value animated from as the time passes the time in
106      * this keyframe.
107      */
108     public static Keyframe ofFloat(float fraction, float value) {
109         return new FloatKeyframe(fraction, value);
110     }
111
112     /**
113      * Constructs a Keyframe object with the given time. The value at this time will be derived
114      * from the target object when the animation first starts (note that this implies that keyframes
115      * with no initial value must be used as part of an {@link ObjectAnimator}).
116      * The time defines the
117      * time, as a proportion of an overall animation's duration, at which the value will hold true
118      * for the animation. The value for the animation between keyframes will be calculated as
119      * an interpolation between the values at those keyframes.
120      *
121      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
122      * of time elapsed of the overall animation duration.
123      */
124     public static Keyframe ofFloat(float fraction) {
125         return new FloatKeyframe(fraction);
126     }
127
128     /**
129      * Constructs a Keyframe object with the given time and value. The time defines the
130      * time, as a proportion of an overall animation's duration, at which the value will hold true
131      * for the animation. The value for the animation between keyframes will be calculated as
132      * an interpolation between the values at those keyframes.
133      *
134      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
135      * of time elapsed of the overall animation duration.
136      * @param value The value that the object will animate to as the animation time approaches
137      * the time in this keyframe, and the the value animated from as the time passes the time in
138      * this keyframe.
139      */
140     public static Keyframe ofObject(float fraction, Object value) {
141         return new ObjectKeyframe(fraction, value);
142     }
143
144     /**
145      * Constructs a Keyframe object with the given time. The value at this time will be derived
146      * from the target object when the animation first starts (note that this implies that keyframes
147      * with no initial value must be used as part of an {@link ObjectAnimator}).
148      * The time defines the
149      * time, as a proportion of an overall animation's duration, at which the value will hold true
150      * for the animation. The value for the animation between keyframes will be calculated as
151      * an interpolation between the values at those keyframes.
152      *
153      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
154      * of time elapsed of the overall animation duration.
155      */
156     public static Keyframe ofObject(float fraction) {
157         return new ObjectKeyframe(fraction, null);
158     }
159
160     /**
161      * Indicates whether this keyframe has a valid value. This method is called internally when
162      * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at
163      * that time by deriving the value for the property from the target object.
164      *
165      * @return boolean Whether this object has a value assigned.
166      */
167     public boolean hasValue() {
168         return mHasValue;
169     }
170
171     /**
172      * Gets the value for this Keyframe.
173      *
174      * @return The value for this Keyframe.
175      */
176     public abstract Object getValue();
177
178     /**
179      * Sets the value for this Keyframe.
180      *
181      * @param value value for this Keyframe.
182      */
183     public abstract void setValue(Object value);
184
185     /**
186      * Gets the time for this keyframe, as a fraction of the overall animation duration.
187      *
188      * @return The time associated with this keyframe, as a fraction of the overall animation
189      * duration. This should be a value between 0 and 1.
190      */
191     public float getFraction() {
192         return mFraction;
193     }
194
195     /**
196      * Sets the time for this keyframe, as a fraction of the overall animation duration.
197      *
198      * @param fraction time associated with this keyframe, as a fraction of the overall animation
199      * duration. This should be a value between 0 and 1.
200      */
201     public void setFraction(float fraction) {
202         mFraction = fraction;
203     }
204
205     /**
206      * Gets the optional interpolator for this Keyframe. A value of <code>null</code> indicates
207      * that there is no interpolation, which is the same as linear interpolation.
208      *
209      * @return The optional interpolator for this Keyframe.
210      */
211     public /*Time*/Interpolator getInterpolator() {
212         return mInterpolator;
213     }
214
215     /**
216      * Sets the optional interpolator for this Keyframe. A value of <code>null</code> indicates
217      * that there is no interpolation, which is the same as linear interpolation.
218      *
219      * @return The optional interpolator for this Keyframe.
220      */
221     public void setInterpolator(/*Time*/Interpolator interpolator) {
222         mInterpolator = interpolator;
223     }
224
225     /**
226      * Gets the type of keyframe. This information is used by ValueAnimator to determine the type of
227      * {@link TypeEvaluator} to use when calculating values between keyframes. The type is based
228      * on the type of Keyframe created.
229      *
230      * @return The type of the value stored in the Keyframe.
231      */
232     public Class getType() {
233         return mValueType;
234     }
235
236     @Override
237     public abstract Keyframe clone();
238
239     /**
240      * This internal subclass is used for all types which are not int or float.
241      */
242     static class ObjectKeyframe extends Keyframe {
243
244         /**
245          * The value of the animation at the time mFraction.
246          */
247         Object mValue;
248
249         ObjectKeyframe(float fraction, Object value) {
250             mFraction = fraction;
251             mValue = value;
252             mHasValue = (value != null);
253             mValueType = mHasValue ? value.getClass() : Object.class;
254         }
255
256         public Object getValue() {
257             return mValue;
258         }
259
260         public void setValue(Object value) {
261             mValue = value;
262             mHasValue = (value != null);
263         }
264
265         @Override
266         public ObjectKeyframe clone() {
267             ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue);
268             kfClone.setInterpolator(getInterpolator());
269             return kfClone;
270         }
271     }
272
273     /**
274      * Internal subclass used when the keyframe value is of type int.
275      */
276     static class IntKeyframe extends Keyframe {
277
278         /**
279          * The value of the animation at the time mFraction.
280          */
281         int mValue;
282
283         IntKeyframe(float fraction, int value) {
284             mFraction = fraction;
285             mValue = value;
286             mValueType = int.class;
287             mHasValue = true;
288         }
289
290         IntKeyframe(float fraction) {
291             mFraction = fraction;
292             mValueType = int.class;
293         }
294
295         public int getIntValue() {
296             return mValue;
297         }
298
299         public Object getValue() {
300             return mValue;
301         }
302
303         public void setValue(Object value) {
304             if (value != null && value.getClass() == Integer.class) {
305                 mValue = ((Integer)value).intValue();
306                 mHasValue = true;
307             }
308         }
309
310         @Override
311         public IntKeyframe clone() {
312             IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue);
313             kfClone.setInterpolator(getInterpolator());
314             return kfClone;
315         }
316     }
317
318     /**
319      * Internal subclass used when the keyframe value is of type float.
320      */
321     static class FloatKeyframe extends Keyframe {
322         /**
323          * The value of the animation at the time mFraction.
324          */
325         float mValue;
326
327         FloatKeyframe(float fraction, float value) {
328             mFraction = fraction;
329             mValue = value;
330             mValueType = float.class;
331             mHasValue = true;
332         }
333
334         FloatKeyframe(float fraction) {
335             mFraction = fraction;
336             mValueType = float.class;
337         }
338
339         public float getFloatValue() {
340             return mValue;
341         }
342
343         public Object getValue() {
344             return mValue;
345         }
346
347         public void setValue(Object value) {
348             if (value != null && value.getClass() == Float.class) {
349                 mValue = ((Float)value).floatValue();
350                 mHasValue = true;
351             }
352         }
353
354         @Override
355         public FloatKeyframe clone() {
356             FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue);
357             kfClone.setInterpolator(getInterpolator());
358             return kfClone;
359         }
360     }
361 }