17c608f25d494c8a0a671e7373efbb47ca635367eChet Haase/*
27c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Copyright (C) 2010 The Android Open Source Project
37c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
47c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Licensed under the Apache License, Version 2.0 (the "License");
57c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * you may not use this file except in compliance with the License.
67c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * You may obtain a copy of the License at
77c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
87c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *      http://www.apache.org/licenses/LICENSE-2.0
97c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
107c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Unless required by applicable law or agreed to in writing, software
117c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * distributed under the License is distributed on an "AS IS" BASIS,
127c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * See the License for the specific language governing permissions and
147c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * limitations under the License.
157c608f25d494c8a0a671e7373efbb47ca635367eChet Haase */
167c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
177c608f25d494c8a0a671e7373efbb47ca635367eChet Haasepackage android.animation;
187c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
197c608f25d494c8a0a671e7373efbb47ca635367eChet Haaseimport android.animation.Keyframe.IntKeyframe;
207c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
217c608f25d494c8a0a671e7373efbb47ca635367eChet Haaseimport java.util.ArrayList;
22d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyarimport java.util.List;
237c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
247c608f25d494c8a0a671e7373efbb47ca635367eChet Haase/**
257c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate
267c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * values between those keyframes for a given animation. The class internal to the animation
277c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * package because it is an implementation detail of how Keyframes are stored and used.
287c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
29b2ab04ffb6894f399d5c9ceb15f64eb17b654426Chet Haase * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for
30b2ab04ffb6894f399d5c9ceb15f64eb17b654426Chet Haase * float, exists to speed up the getValue() method when there is no custom
317c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
327c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Object equivalents of these primitive types.</p>
337c608f25d494c8a0a671e7373efbb47ca635367eChet Haase */
34984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountclass IntKeyframeSet extends KeyframeSet implements Keyframes.IntKeyframes {
357c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private int firstValue;
367c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private int lastValue;
377c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private int deltaValue;
387c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private boolean firstTime = true;
397c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
407c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public IntKeyframeSet(IntKeyframe... keyframes) {
417c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        super(keyframes);
427c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
437c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
447c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    @Override
457c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public Object getValue(float fraction) {
467c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return getIntValue(fraction);
477c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
487c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
497c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    @Override
507c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public IntKeyframeSet clone() {
51d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        List<Keyframe> keyframes = mKeyframes;
527c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        int numKeyframes = mKeyframes.size();
537c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes];
547c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        for (int i = 0; i < numKeyframes; ++i) {
557c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone();
567c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
577c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes);
587c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return newSet;
597c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
607c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
618619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar    @Override
62984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    public void invalidateCache() {
638619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar        firstTime = true;
648619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar    }
658619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar
66984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    @Override
677c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public int getIntValue(float fraction) {
687c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        if (mNumKeyframes == 2) {
697c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (firstTime) {
707c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                firstTime = false;
717c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue();
727c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue();
737c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                deltaValue = lastValue - firstValue;
747c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
757c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (mInterpolator != null) {
767c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = mInterpolator.getInterpolation(fraction);
777c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
787c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (mEvaluator == null) {
797c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return firstValue + (int)(fraction * deltaValue);
807c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            } else {
817c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue();
827c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
837c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
847c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        if (fraction <= 0f) {
857c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
867c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1);
877c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            int prevValue = prevKeyframe.getIntValue();
887c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            int nextValue = nextKeyframe.getIntValue();
897c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevFraction = prevKeyframe.getFraction();
907c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextFraction = nextKeyframe.getFraction();
917c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
927c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (interpolator != null) {
937c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = interpolator.getInterpolation(fraction);
947c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
957c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
967c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            return mEvaluator == null ?
97750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                    prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
987c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
997c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            intValue();
1007c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        } else if (fraction >= 1f) {
1017c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2);
1027c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1);
1037c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            int prevValue = prevKeyframe.getIntValue();
1047c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            int nextValue = nextKeyframe.getIntValue();
1057c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevFraction = prevKeyframe.getFraction();
1067c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextFraction = nextKeyframe.getFraction();
1077c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
1087c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (interpolator != null) {
1097c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = interpolator.getInterpolation(fraction);
1107c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
1117c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
1127c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            return mEvaluator == null ?
113750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                    prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
1147c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
1157c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
1167c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
1177c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        for (int i = 1; i < mNumKeyframes; ++i) {
1187c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i);
1197c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (fraction < nextKeyframe.getFraction()) {
1207c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
1217c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                if (interpolator != null) {
1227c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    fraction = interpolator.getInterpolation(fraction);
1237c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                }
1247c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
1257c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
1267c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                int prevValue = prevKeyframe.getIntValue();
1277c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                int nextValue = nextKeyframe.getIntValue();
1287c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return mEvaluator == null ?
129750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                        prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
1307c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
1317c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                                intValue();
1327c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
1337c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            prevKeyframe = nextKeyframe;
1347c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
1357c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        // shouldn't get here
1367c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
1377c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
1387c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
139984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    @Override
140984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    public Class getType() {
141984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        return Integer.class;
142984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    }
1437c608f25d494c8a0a671e7373efbb47ca635367eChet Haase}
1447c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
145