DrawableContainer.java revision f390f770ee570f1f4def41b165cb9492e381be40
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19c2974809373697147cbe5754835cc871fb93aef1Dianne Hackbornimport android.content.res.Resources;
2078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Canvas;
2178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.ColorFilter;
22bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milneimport android.graphics.Insets;
2378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PixelFormat;
2478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Rect;
25079e23575024e103358c982152afb7a720ae1a8aDianne Hackbornimport android.os.SystemClock;
26f390f770ee570f1f4def41b165cb9492e381be40Alan Viveretteimport android.util.SparseArray;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne/**
2978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A helper class that contains several {@link Drawable}s and selects which one to use.
3078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne *
3178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * You can subclass it to create your own DrawableContainers or directly use one its child classes.
3278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DrawableContainer extends Drawable implements Drawable.Callback {
34079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private static final boolean DEBUG = false;
35079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private static final String TAG = "DrawableContainer";
36211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed
37211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed    /**
38211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * To be proper, we should have a getter for dither (and alpha, etc.)
39211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * so that proxy classes like this can save/restore their delegates'
40211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * values, but we don't have getters. Since we do have setters
41211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * (e.g. setDither), which this proxy forwards on, we have to have some
42211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * default/initial setting.
43211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     *
44211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * The initial setting for dither is now true, since it almost always seems
45211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * to improve the quality at negligible cost.
46211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     */
47211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed    private static final boolean DEFAULT_DITHER = true;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private DrawableContainerState mDrawableContainerState;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mCurrDrawable;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAlpha = 0xFF;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ColorFilter mColorFilter;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mCurIndex = -1;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMutated;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    // Animations.
57079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private Runnable mAnimationRunnable;
58079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private long mEnterAnimationEnd;
59079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private long mExitAnimationEnd;
60079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private Drawable mLastDrawable;
61079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // overrides from Drawable
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.draw(canvas);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
69079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
70079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.draw(canvas);
71079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.getChangingConfigurations()
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mDrawableContainerState.mChangingConfigurations
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mDrawableContainerState.mChildrenChangingConfigurations;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
80f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getPadding(Rect padding) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect r = mDrawableContainerState.getConstantPadding();
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (r != null) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.set(r);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.getPadding(padding);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.getPadding(padding);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
951557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
961557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * @hide
971557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
981557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    @Override
997b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    public Insets getOpticalInsets() {
1007b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        return (mCurrDrawable == null) ? Insets.NONE : mCurrDrawable.getOpticalInsets();
1011557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    }
1021557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAlpha != alpha) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAlpha = alpha;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
108079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mEnterAnimationEnd == 0) {
1095f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(alpha);
110079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
111079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animate(false);
112079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
118b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    public int getAlpha() {
119b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        return mAlpha;
120b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    }
121b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
122b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {
124a41581ed4033004c73115113f45b9844e9b0210fRomain Guy        if (mDrawableContainerState.mDither != dither) {
125a41581ed4033004c73115113f45b9844e9b0210fRomain Guy            mDrawableContainerState.mDither = dither;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
1275f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                mCurrDrawable.mutate().setDither(mDrawableContainerState.mDither);
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(ColorFilter cf) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mColorFilter != cf) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mColorFilter = cf;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
1375f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                mCurrDrawable.mutate().setColorFilter(cf);
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
141f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
142079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
143079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * Change the global fade duration when a new drawable is entering
144079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * the scene.
145079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * @param ms The amount of time to fade in milliseconds.
146079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
147079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void setEnterFadeDuration(int ms) {
148079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        mDrawableContainerState.mEnterFadeDuration = ms;
149079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
150f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
151079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
152079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * Change the global fade duration when a new drawable is leaving
153079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * the scene.
154079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * @param ms The amount of time to fade in milliseconds.
155079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
156079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void setExitFadeDuration(int ms) {
157079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        mDrawableContainerState.mExitFadeDuration = ms;
158079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
159f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect bounds) {
162079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
163079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.setBounds(bounds);
164079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.setBounds(bounds);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
169f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isStateful() {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDrawableContainerState.isStateful();
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
174f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
176079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void jumpToCurrentState() {
177079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        boolean changed = false;
178079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
179079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.jumpToCurrentState();
180079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable = null;
181079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
182079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
183079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mCurrDrawable != null) {
184079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mCurrDrawable.jumpToCurrentState();
1855f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy            mCurrDrawable.mutate().setAlpha(mAlpha);
186079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
187079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mExitAnimationEnd != 0) {
188079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitAnimationEnd = 0;
189079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
190079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
191079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mEnterAnimationEnd != 0) {
192079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterAnimationEnd = 0;
193079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
194079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
195079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (changed) {
196079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            invalidateSelf();
197079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
198079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
199079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
200079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    @Override
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onStateChange(int[] state) {
202079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
203079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mLastDrawable.setState(state);
204079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.setState(state);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) {
213079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
214079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mLastDrawable.setLevel(level);
215079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.setLevel(level);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantWidth();
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantHeight();
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1;
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
237f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumWidth() {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantMinimumWidth();
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumHeight() {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantMinimumHeight();
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25472146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
255079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void invalidateDrawable(Drawable who) {
256f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
257f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().invalidateDrawable(this);
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26172146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
262079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void scheduleDrawable(Drawable who, Runnable what, long when) {
263f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
264f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().scheduleDrawable(this, what, when);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26872146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
269079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void unscheduleDrawable(Drawable who, Runnable what) {
270f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
271f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().unscheduleDrawable(this, what);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setVisible(boolean visible, boolean restart) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = super.setVisible(visible, restart);
278079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
279079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.setVisible(visible, restart);
280079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.setVisible(visible, restart);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
28983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT :
29083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                mDrawableContainerState.getOpacity();
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne    public boolean selectDrawable(int idx) {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (idx == mCurIndex) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
297079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
298079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        final long now = SystemClock.uptimeMillis();
299079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
300079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx
301079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                + ": exit=" + mDrawableContainerState.mExitFadeDuration
302079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                + " enter=" + mDrawableContainerState.mEnterFadeDuration);
303079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
304079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mDrawableContainerState.mExitFadeDuration > 0) {
305079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mLastDrawable != null) {
306079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable.setVisible(false, false);
307079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
309079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable = mCurrDrawable;
310079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration;
311079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            } else {
312079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable = null;
313079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitAnimationEnd = 0;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
315079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else if (mCurrDrawable != null) {
316079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mCurrDrawable.setVisible(false, false);
317079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
318079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
319079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
320f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable d = mDrawableContainerState.getChild(idx);
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable = d;
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIndex = idx;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (d != null) {
3245f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                d.mutate();
325079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mDrawableContainerState.mEnterFadeDuration > 0) {
326079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
327079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
328079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    d.setAlpha(mAlpha);
329079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setVisible(isVisible(), true);
331a41581ed4033004c73115113f45b9844e9b0210fRomain Guy                d.setDither(mDrawableContainerState.mDither);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setColorFilter(mColorFilter);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setState(getState());
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setLevel(getLevel());
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setBounds(getBounds());
336731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio                d.setLayoutDirection(getLayoutDirection());
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable = null;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIndex = -1;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
342079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
343079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) {
344079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mAnimationRunnable == null) {
345079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mAnimationRunnable = new Runnable() {
346079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    @Override public void run() {
347079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                        animate(true);
348079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                        invalidateSelf();
349079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    }
350079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                };
351079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            } else {
352079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                unscheduleSelf(mAnimationRunnable);
353079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
354079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            // Compute first frame and schedule next animation.
355079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            animate(true);
356079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
357079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invalidateSelf();
359079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
362f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
363079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    void animate(boolean schedule) {
364079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        final long now = SystemClock.uptimeMillis();
365079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        boolean animating = false;
366079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mCurrDrawable != null) {
367079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mEnterAnimationEnd != 0) {
368079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mEnterAnimationEnd <= now) {
3695f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(mAlpha);
370079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mEnterAnimationEnd = 0;
371079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
372079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    int animAlpha = (int)((mEnterAnimationEnd-now)*255)
373079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                            / mDrawableContainerState.mEnterFadeDuration;
374079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha);
3755f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(((255-animAlpha)*mAlpha)/255);
376079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animating = true;
377079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
378079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
379079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else {
380079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterAnimationEnd = 0;
381079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
382079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
383079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mExitAnimationEnd != 0) {
384079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mExitAnimationEnd <= now) {
385079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mLastDrawable.setVisible(false, false);
386079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mLastDrawable = null;
387079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mExitAnimationEnd = 0;
388079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
389079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    int animAlpha = (int)((mExitAnimationEnd-now)*255)
390079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                            / mDrawableContainerState.mExitFadeDuration;
391079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha);
3925f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mLastDrawable.mutate().setAlpha((animAlpha*mAlpha)/255);
393079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animating = true;
394079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
395079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
396079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else {
397079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitAnimationEnd = 0;
398079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
399079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
400079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (schedule && animating) {
401079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            scheduleSelf(mAnimationRunnable, now + 1000/60);
402079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
403079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
404079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getCurrent() {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.canConstantState()) {
4136efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais            mDrawableContainerState.mChangingConfigurations = getChangingConfigurations();
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mMutated && super.mutate() == this) {
42272146433322588c1116ee06c27ac758ad09d869cAlan Viverette            mDrawableContainerState.mutate();
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMutated = true;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne    /**
42978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * A ConstantState that can contain several {@link Drawable}s.
43078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     *
43178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * This class was made public to enable testing, and its visibility may change in a future
43278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * release.
43378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     */
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract static class DrawableContainerState extends ConstantState {
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final DrawableContainer mOwner;
436f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        final Resources mRes;
437f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
438f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        SparseArray<ConstantStateFuture> mDrawableFutures;
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
440f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mChangingConfigurations;
441f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mChildrenChangingConfigurations;
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
443f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        Drawable[] mDrawables;
444f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mNumChildren;
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
446f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mVariablePadding;
447f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mPaddingChecked;
448f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        Rect mConstantPadding;
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
450f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mConstantSize;
451f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mComputedConstantSize;
452f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantWidth;
453f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantHeight;
454f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantMinimumWidth;
455f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantMinimumHeight;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
457f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedOpacity;
458f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mOpacity;
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
460f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedStateful;
461f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mStateful;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
463f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedConstantState;
464f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCanConstantState;
4655140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy
466f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mDither = DEFAULT_DITHER;
467f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
468f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mMutated;
469f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mLayoutDirection;
470f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
471f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mEnterFadeDuration;
472f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mExitFadeDuration;
473079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
474c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
475c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                Resources res) {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOwner = owner;
477f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mRes = res;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (orig != null) {
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChangingConfigurations = orig.mChangingConfigurations;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
483f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedConstantState = true;
484f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCanConstantState = true;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mVariablePadding = orig.mVariablePadding;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mConstantSize = orig.mConstantSize;
488a41581ed4033004c73115113f45b9844e9b0210fRomain Guy                mDither = orig.mDither;
489f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mMutated = orig.mMutated;
490f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mLayoutDirection = orig.mLayoutDirection;
491079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mEnterFadeDuration = orig.mEnterFadeDuration;
492079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitFadeDuration = orig.mExitFadeDuration;
493079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
494f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // Cloning the following values may require creating futures.
495f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantPadding = orig.getConstantPadding();
496f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mPaddingChecked = true;
497f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
498f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantWidth = orig.getConstantWidth();
499f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantHeight = orig.getConstantHeight();
500f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantMinimumWidth = orig.getConstantMinimumWidth();
501f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantMinimumHeight = orig.getConstantMinimumHeight();
502f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mComputedConstantSize = true;
503f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
504f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mOpacity = orig.getOpacity();
505f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedOpacity = true;
506f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
507f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mStateful = orig.isStateful();
508f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedStateful = true;
509f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
510f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // Postpone cloning children and futures until we're absolutely
511f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // sure that we're done computing values for the original state.
512f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable[] origDr = orig.mDrawables;
513f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mDrawables = new Drawable[origDr.length];
514f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mNumChildren = orig.mNumChildren;
515f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
516f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures;
517f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (origDf != null) {
518f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures = origDf.clone();
519f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                } else {
520f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
521f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
522f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
523f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int N = mNumChildren;
524f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                for (int i = 0; i < N; i++) {
525f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    if (origDr[i] != null) {
526f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                        mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
527f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    }
528f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDrawables = new Drawable[10];
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNumChildren = 0;
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
534f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
537dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio            return mChangingConfigurations | mChildrenChangingConfigurations;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final int addChild(Drawable dr) {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pos = mNumChildren;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos >= mDrawables.length) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                growArray(pos, pos+10);
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dr.setVisible(false, true);
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dr.setCallback(mOwner);
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDrawables[pos] = dr;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mNumChildren++;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mChildrenChangingConfigurations |= dr.getChangingConfigurations();
553f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedStateful = false;
554f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedOpacity = false;
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantPadding = null;
5575140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            mPaddingChecked = false;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mComputedConstantSize = false;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return pos;
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56372146433322588c1116ee06c27ac758ad09d869cAlan Viverette        final int getCapacity() {
56472146433322588c1116ee06c27ac758ad09d869cAlan Viverette            return mDrawables.length;
56572146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
56672146433322588c1116ee06c27ac758ad09d869cAlan Viverette
567f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        private final void createAllFutures() {
568f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mDrawableFutures != null) {
569f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int futureCount = mDrawableFutures.size();
570f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) {
571f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    final int index = mDrawableFutures.keyAt(keyIndex);
572f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this);
573f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
574f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
575f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mDrawableFutures = null;
576f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
577f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
578f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
57983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getChildCount() {
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mNumChildren;
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58372146433322588c1116ee06c27ac758ad09d869cAlan Viverette        /*
58472146433322588c1116ee06c27ac758ad09d869cAlan Viverette         * @deprecated Use {@link #getChild} instead.
58572146433322588c1116ee06c27ac758ad09d869cAlan Viverette         */
58683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final Drawable[] getChildren() {
587f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // Create all futures for backwards compatibility.
588f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
589f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawables;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59372146433322588c1116ee06c27ac758ad09d869cAlan Viverette        public final Drawable getChild(int index) {
594f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable result = mDrawables[index];
595f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (result != null) {
596f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return result;
597f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
598f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
599f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // Prepare future drawable if necessary.
600f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mDrawableFutures != null) {
601f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int keyIndex = mDrawableFutures.indexOfKey(index);
602f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (keyIndex >= 0) {
603f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this);
604f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawables[index] = prepared;
605f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures.removeAt(keyIndex);
606f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return prepared;
607f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
608f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
609f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
610f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return null;
611f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
612f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
613f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        final void setLayoutDirection(int layoutDirection) {
614f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // No need to call createAllFutures, since future drawables will
615f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // change layout direction when they are prepared.
616f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
617f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
618f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            for (int i = 0; i < N; i++) {
619f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i] != null) {
620f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    drawables[i].setLayoutDirection(layoutDirection);
621f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
622f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
623f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
624f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mLayoutDirection = layoutDirection;
62572146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
62672146433322588c1116ee06c27ac758ad09d869cAlan Viverette
62772146433322588c1116ee06c27ac758ad09d869cAlan Viverette        final void mutate() {
628f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // No need to call createAllFutures, since future drawables will
629f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // mutate when they are prepared.
630f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
63172146433322588c1116ee06c27ac758ad09d869cAlan Viverette            final Drawable[] drawables = mDrawables;
63272146433322588c1116ee06c27ac758ad09d869cAlan Viverette            for (int i = 0; i < N; i++) {
633f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i] != null) {
634f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    drawables[i].mutate();
635f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
63672146433322588c1116ee06c27ac758ad09d869cAlan Viverette            }
637f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
638f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mMutated = true;
63972146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
64072146433322588c1116ee06c27ac758ad09d869cAlan Viverette
641f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        /**
642f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * A boolean value indicating whether to use the maximum padding value
643f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * of all frames in the set (false), or to use the padding value of the
644f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * frame being shown (true). Default value is false.
645f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         */
64683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final void setVariablePadding(boolean variable) {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mVariablePadding = variable;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
65083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final Rect getConstantPadding() {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mVariablePadding) {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
654f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
655f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if ((mConstantPadding != null) || mPaddingChecked) {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mConstantPadding;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
660f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
6615140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            Rect r = null;
66283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Rect t = new Rect();
663f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
66483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
66583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 0; i < N; i++) {
66683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                if (drawables[i].getPadding(t)) {
6675140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy                    if (r == null) r = new Rect(0, 0, 0, 0);
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.left > r.left) r.left = t.left;
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.top > r.top) r.top = t.top;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.right > r.right) r.right = t.right;
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.bottom > r.bottom) r.bottom = t.bottom;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
674f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
6755140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            mPaddingChecked = true;
6765140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            return (mConstantPadding = r);
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
67983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final void setConstantSize(boolean constant) {
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantSize = constant;
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
68383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final boolean isConstantSize() {
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantSize;
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
68783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantWidth() {
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantWidth;
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
69583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantHeight() {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantHeight;
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
70383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantMinimumWidth() {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantMinimumWidth;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
71183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantMinimumHeight() {
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantMinimumHeight;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
71978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne        protected void computeConstantSize() {
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mComputedConstantSize = true;
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
722f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
723f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
724f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
72583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
72678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne            mConstantWidth = mConstantHeight = -1;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantMinimumWidth = mConstantMinimumHeight = 0;
72883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 0; i < N; i++) {
729f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable dr = drawables[i];
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int s = dr.getIntrinsicWidth();
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantWidth) mConstantWidth = s;
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getIntrinsicHeight();
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantHeight) mConstantHeight = s;
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getMinimumWidth();
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantMinimumWidth) mConstantMinimumWidth = s;
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getMinimumHeight();
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantMinimumHeight) mConstantMinimumHeight = s;
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
741079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final void setEnterFadeDuration(int duration) {
742079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterFadeDuration = duration;
743079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
744079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
745079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final int getEnterFadeDuration() {
746079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mEnterFadeDuration;
747079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
748079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
749079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final void setExitFadeDuration(int duration) {
750079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitFadeDuration = duration;
751079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
752079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
753079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final int getExitFadeDuration() {
754079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mExitFadeDuration;
755079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
756079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
75783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getOpacity() {
758f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedOpacity) {
759f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return mOpacity;
760f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
761f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
762f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
763f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
764f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedOpacity = true;
765f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
766f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
76783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
768f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
76983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 1; i < N; i++) {
77083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
772f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOpacity = op;
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return op;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
77683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final boolean isStateful() {
778f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedStateful) {
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mStateful;
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
781f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
782f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
783f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
784f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedStateful = true;
785f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
786f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
787f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
789f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i].isStateful()) {
790f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mStateful = true;
791f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return true;
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
794f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
795f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mStateful = false;
796f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return false;
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
79983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public void growArray(int oldSize, int newSize) {
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable[] newDrawables = new Drawable[newSize];
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize);
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDrawables = newDrawables;
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public synchronized boolean canConstantState() {
806f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedConstantState) {
807f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return mCanConstantState;
808f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
809f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
810f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
811f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
812f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedConstantState = true;
813f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
814f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
815f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
816f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            for (int i = 0; i < N; i++) {
817f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i].getConstantState() == null) {
818f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mCanConstantState = false;
819f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return false;
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
823f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCanConstantState = true;
824f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return true;
825f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
826f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
827f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        /**
828f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * Class capable of cloning a Drawable from another Drawable's
829f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * ConstantState.
830f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         */
831f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        private static class ConstantStateFuture {
832f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            private final ConstantState mConstantState;
833f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
834f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            private ConstantStateFuture(Drawable source) {
835f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantState = source.getConstantState();
836f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
837f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
838f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            /**
839f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * Obtains and prepares the Drawable represented by this future.
840f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             *
841f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * @param state the container into which this future will be placed
842f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * @return a prepared Drawable
843f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             */
844f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            public Drawable get(DrawableContainerState state) {
845f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable result = (state.mRes == null) ?
846f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                        mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes);
847f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                result.setLayoutDirection(state.mLayoutDirection);
848f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                result.setCallback(state.mOwner);
849f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
850f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (state.mMutated) {
851f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    result.mutate();
852f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
853f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
854f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return result;
855f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette    protected void setConstantState(DrawableContainerState state) {
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDrawableContainerState = state;
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
863