summaryrefslogtreecommitdiffstats
path: root/graphics/java/android/graphics/Interpolator.java
blob: f695a9ea2cf4d65959b3979765c2b4918af6bbae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics;

import android.os.SystemClock;

public class Interpolator {

    public Interpolator(int valueCount) {
        mValueCount = valueCount;
        mFrameCount = 2;
        native_instance = nativeConstructor(valueCount, 2);
    }
    
    public Interpolator(int valueCount, int frameCount) {
        mValueCount = valueCount;
        mFrameCount = frameCount;
        native_instance = nativeConstructor(valueCount, frameCount);
    }
    
    /**
     * Reset the Interpolator to have the specified number of values and an
     * implicit keyFrame count of 2 (just a start and end). After this call the
     * values for each keyFrame must be assigned using setKeyFrame().
     */
    public void reset(int valueCount) {
        reset(valueCount, 2);
    }
    
    /**
     * Reset the Interpolator to have the specified number of values and
     * keyFrames. After this call the values for each keyFrame must be assigned
     * using setKeyFrame().
     */
    public void reset(int valueCount, int frameCount) {
        mValueCount = valueCount;
        mFrameCount = frameCount;
        nativeReset(native_instance, valueCount, frameCount);
    }
    
    public final int getKeyFrameCount() {
        return mFrameCount;
    }
    
    public final int getValueCount() {
        return mValueCount;
    }
    
    /**
     * Assign the keyFrame (specified by index) a time value and an array of key
     * values (with an implicity blend array of [0, 0, 1, 1] giving linear
     * transition to the next set of key values).
     * 
     * @param index The index of the key frame to assign
     * @param msec The time (in mililiseconds) for this key frame. Based on the
     *        SystemClock.uptimeMillis() clock
     * @param values Array of values associated with theis key frame
     */
    public void setKeyFrame(int index, int msec, float[] values) {
        setKeyFrame(index, msec, values, null);
    }

    /**
     * Assign the keyFrame (specified by index) a time value and an array of key
     * values and blend array.
     * 
     * @param index The index of the key frame to assign
     * @param msec The time (in mililiseconds) for this key frame. Based on the
     *        SystemClock.uptimeMillis() clock
     * @param values Array of values associated with theis key frame
     * @param blend (may be null) Optional array of 4 blend values
     */
    public void setKeyFrame(int index, int msec, float[] values, float[] blend) {
        if (index < 0 || index >= mFrameCount) {
            throw new IndexOutOfBoundsException();
        }
        if (values.length < mValueCount) {
            throw new ArrayStoreException();
        }
        if (blend != null && blend.length < 4) {
            throw new ArrayStoreException();
        }
        nativeSetKeyFrame(native_instance, index, msec, values, blend);
    }
    
    /**
     * Set a repeat count (which may be fractional) for the interpolator, and
     * whether the interpolator should mirror its repeats. The default settings
     * are repeatCount = 1, and mirror = false.
     */
    public void setRepeatMirror(float repeatCount, boolean mirror) {
        if (repeatCount >= 0) {
            nativeSetRepeatMirror(native_instance, repeatCount, mirror);
        }
    }
    
    public enum Result {
        NORMAL,
        FREEZE_START,
        FREEZE_END
    }

    /**
     * Calls timeToValues(msec, values) with the msec set to now (by calling
     * (int)SystemClock.uptimeMillis().)
     */
    public Result timeToValues(float[] values) {
        return timeToValues((int)SystemClock.uptimeMillis(), values);
    }

    /**
     * Given a millisecond time value (msec), return the interpolated values and
     * return whether the specified time was within the range of key times
     * (NORMAL), was before the first key time (FREEZE_START) or after the last
     * key time (FREEZE_END). In any event, computed values are always returned.
     * 
     * @param msec The time (in milliseconds) used to sample into the
     *        Interpolator. Based on the SystemClock.uptimeMillis() clock
     * @param values Where to write the computed values (may be NULL).
     * @return how the values were computed (even if values == null)
     */
    public Result timeToValues(int msec, float[] values) {
        if (values != null && values.length < mValueCount) {
            throw new ArrayStoreException();
        }
        switch (nativeTimeToValues(native_instance, msec, values)) {
            case 0: return Result.NORMAL;
            case 1: return Result.FREEZE_START;
            default: return Result.FREEZE_END;
        }
    }
    
    @Override
    protected void finalize() throws Throwable {
        nativeDestructor(native_instance);
    }
    
    private int mValueCount;
    private int mFrameCount;
    private final long native_instance;

    private static native long nativeConstructor(int valueCount, int frameCount);
    private static native void nativeDestructor(long native_instance);
    private static native void nativeReset(long native_instance, int valueCount, int frameCount);
    private static native void nativeSetKeyFrame(long native_instance, int index, int msec, float[] values, float[] blend);
    private static native void nativeSetRepeatMirror(long native_instance, float repeatCount, boolean mirror);
    private static native int  nativeTimeToValues(long native_instance, int msec, float[] values);
}