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
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
24021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.Canvas;
25021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.ColorFilter;
26021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.PixelFormat;
27021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.Rect;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Drawable that manages an array of other Drawables. These are drawn in array
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * order, so the element with the largest index will be drawn on top.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It can be defined in an XML file with the <code>&lt;layer-list></code> element.
38dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * Each Drawable in the layer is defined in a nested <code>&lt;item></code>. For more
39dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a
40dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p>
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_left
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_top
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_right
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_bottom
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_drawable
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_id
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class LayerDrawable extends Drawable implements Drawable.Callback {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayerState mLayerState;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    private int mOpacityOverride = PixelFormat.UNKNOWN;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingL;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingT;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingR;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingB;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Rect mTmpRect = new Rect();
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMutated;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new layer drawable with the list of specified layers.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layers A list of drawables to use as layers in this new drawable.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public LayerDrawable(Drawable[] layers) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(layers, null);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new layer drawable with the specified list of layers and the specified
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * constant state.
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layers The list of layers to add to this drawable.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param state The constant drawable state.
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayerDrawable(Drawable[] layers, LayerState state) {
78c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        this(state, null);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = layers.length;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ChildDrawable[] r = new ChildDrawable[length];
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < length; i++) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r[i] = new ChildDrawable();
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r[i].mDrawable = layers[i];
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            layers[i].setCallback(this);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLayerState.mChildrenChangingConfigurations |= layers[i].getChangingConfigurations();
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mNum = length;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mChildren = r;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensurePadding();
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayerDrawable() {
95c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        this((LayerState) null, null);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
98c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn    LayerDrawable(LayerState state, Resources res) {
99c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        LayerState as = createConstantState(state, res);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState = as;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (as.mNum > 0) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ensurePadding();
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
106c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn    LayerState createConstantState(LayerState state, Resources res) {
107c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        return new LayerState(state, this, res);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.inflate(r, parser, attrs);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
117e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.LayerDrawable);
118e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
119e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        mOpacityOverride = a.getInt(com.android.internal.R.styleable.LayerDrawable_opacity,
120e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato                PixelFormat.UNKNOWN);
121e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
1223f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.LayerDrawable_autoMirrored,
1233f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                false));
1243f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
125e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        a.recycle();
126e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int innerDepth = parser.getDepth() + 1;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int depth;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (type != XmlPullParser.START_TAG) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (depth > innerDepth || !parser.getName().equals("item")) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
139e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato            a = r.obtainAttributes(attrs,
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.LayerDrawableItem);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int left = a.getDimensionPixelOffset(
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.LayerDrawableItem_left, 0);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int top = a.getDimensionPixelOffset(
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.LayerDrawableItem_top, 0);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int right = a.getDimensionPixelOffset(
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.LayerDrawableItem_right, 0);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int bottom = a.getDimensionPixelOffset(
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.LayerDrawableItem_bottom, 0);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int drawableRes = a.getResourceId(
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.LayerDrawableItem_drawable, 0);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = a.getResourceId(com.android.internal.R.styleable.LayerDrawableItem_id,
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    View.NO_ID);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            a.recycle();
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable dr;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (drawableRes != 0) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dr = r.getDrawable(drawableRes);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((type = parser.next()) == XmlPullParser.TEXT) {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (type != XmlPullParser.START_TAG) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new XmlPullParserException(parser.getPositionDescription()
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + ": <item> tag requires a 'drawable' attribute or "
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + "child tag defining a drawable");
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dr = Drawable.createFromXmlInner(r, parser, attrs);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addLayer(dr, id, left, top, right, bottom);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensurePadding();
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onStateChange(getState());
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Add a new layer to this drawable. The new layer is identified by an id.
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layer The drawable to add as a layer.
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The id of the new layer.
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param left The left padding of the new layer.
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param top The top padding of the new layer.
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param right The right padding of the new layer.
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bottom The bottom padding of the new layer.
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addLayer(Drawable layer, int id, int left, int top, int right, int bottom) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final LayerState st = mLayerState;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int N = st.mChildren != null ? st.mChildren.length : 0;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i = st.mNum;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i >= N) {
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ChildDrawable[] nu = new ChildDrawable[N + 10];
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i > 0) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.arraycopy(st.mChildren, 0, nu, 0, i);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            st.mChildren = nu;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations();
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ChildDrawable childDrawable = new ChildDrawable();
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        st.mChildren[i] = childDrawable;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mId = id;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mDrawable = layer;
2063f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        childDrawable.mDrawable.setAutoMirrored(isAutoMirrored());
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetL = left;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetT = top;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetR = right;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetB = bottom;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        st.mNum++;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        layer.setCallback(this);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Look for a layer with the given id, and returns its {@link Drawable}.
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The layer ID to search for.
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The {@link Drawable} of the layer that has the given id in the hierarchy or null.
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable findDrawableByLayerId(int id) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] layers = mLayerState.mChildren;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = mLayerState.mNum - 1; i >= 0; i--) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (layers[i].mId == id) {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return layers[i].mDrawable;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the ID of a layer.
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The index of the layer which will received the ID.
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The ID to assign to the layer.
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setId(int index, int id) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mChildren[index].mId = id;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the number of layers contained within this.
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of layers.
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getNumberOfLayers() {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.mNum;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the drawable at the specified layer index.
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The layer index of the drawable to retrieve.
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The {@link android.graphics.drawable.Drawable} at the specified layer index.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getDrawable(int index) {
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.mChildren[index].mDrawable;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the id of the specified layer.
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The index of the layer.
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id.
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getId(int index) {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.mChildren[index].mId;
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets (or replaces) the {@link Drawable} for the layer with the given id.
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The layer ID to search for.
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param drawable The replacement {@link Drawable}.
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether the {@link Drawable} was replaced (could return false if
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the id was not found).
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setDrawableByLayerId(int id, Drawable drawable) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] layers = mLayerState.mChildren;
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = mLayerState.mNum - 1; i >= 0; i--) {
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (layers[i].mId == id) {
287fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                if (layers[i].mDrawable != null) {
288fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    if (drawable != null) {
289fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                        Rect bounds = layers[i].mDrawable.getBounds();
290fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                        drawable.setBounds(bounds);
291fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    }
292fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    layers[i].mDrawable.setCallback(null);
293fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                }
294fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                if (drawable != null) {
295fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    drawable.setCallback(this);
296fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                layers[i].mDrawable = drawable;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Specify modifiers to the bounds for the drawable[index].
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        left += l
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        top += t;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        right -= r;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bottom -= b;
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLayerInset(int index, int l, int t, int r, int b) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ChildDrawable childDrawable = mLayerState.mChildren[index];
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetL = l;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetT = t;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetR = r;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetB = b;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // overrides from Drawable.Callback
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void invalidateDrawable(Drawable who) {
322f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        final Callback callback = getCallback();
323f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (callback != null) {
324f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            callback.invalidateDrawable(this);
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void scheduleDrawable(Drawable who, Runnable what, long when) {
329f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        final Callback callback = getCallback();
330f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (callback != null) {
331f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            callback.scheduleDrawable(this, what, when);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unscheduleDrawable(Drawable who, Runnable what) {
336f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        final Callback callback = getCallback();
337f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (callback != null) {
338f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            callback.unscheduleDrawable(this, what);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // overrides from Drawable
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.draw(canvas);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.getChangingConfigurations()
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mLayerState.mChangingConfigurations
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mLayerState.mChildrenChangingConfigurations;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getPadding(Rect padding) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Arbitrarily get the padding from the first image.
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Technically we should maybe do something more intelligent,
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // like take the max padding of all the images.
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.left = 0;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.top = 0;
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.right = 0;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.bottom = 0;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            reapplyPadding(i, array[i]);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.left += mPaddingL[i];
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.top += mPaddingT[i];
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.right += mPaddingR[i];
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.bottom += mPaddingB[i];
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setVisible(boolean visible, boolean restart) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = super.setVisible(visible, restart);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setVisible(visible, restart);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setDither(dither);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setAlpha(alpha);
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
409b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
410b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
411b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    public int getAlpha() {
412b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        final ChildDrawable[] array = mLayerState.mChildren;
413b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        if (mLayerState.mNum > 0) {
414b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase            // All layers should have the same alpha set on them - just return the first one
415b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase            return array[0].mDrawable.getAlpha();
416b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        } else {
417b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase            return super.getAlpha();
418b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        }
419b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    }
420b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(ColorFilter cf) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setColorFilter(cf);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
429e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
430e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    /**
431e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * Sets the opacity of this drawable directly, instead of collecting the states from
432e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * the layers
433e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     *
434e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @param opacity The opacity to use, or {@link PixelFormat#UNKNOWN PixelFormat.UNKNOWN}
435e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * for the default behavior
436e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     *
437e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#UNKNOWN
438e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#TRANSLUCENT
439e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#TRANSPARENT
440e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#OPAQUE
441e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     */
442e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    public void setOpacity(int opacity) {
443e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        mOpacityOverride = opacity;
444e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
448e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        if (mOpacityOverride != PixelFormat.UNKNOWN) {
449e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato            return mOpacityOverride;
450e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.getOpacity();
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4553f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public void setAutoMirrored(boolean mirrored) {
4563f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        mLayerState.mAutoMirrored = mirrored;
4573f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        final ChildDrawable[] array = mLayerState.mChildren;
4583f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        final int N = mLayerState.mNum;
4593f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        for (int i=0; i<N; i++) {
4603f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio            array[i].mDrawable.setAutoMirrored(mirrored);
4613f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        }
4623f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
4633f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
4643f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
4653f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public boolean isAutoMirrored() {
4663f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        return mLayerState.mAutoMirrored;
4673f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
4683f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
4693f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isStateful() {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.isStateful();
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onStateChange(int[] state) {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean paddingChanged = false;
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = false;
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (r.mDrawable.setState(state)) {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                changed = true;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (reapplyPadding(i, r)) {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paddingChanged = true;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (paddingChanged) {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onBoundsChange(getBounds());
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean paddingChanged = false;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = false;
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (r.mDrawable.setLevel(level)) {
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                changed = true;
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (reapplyPadding(i, r)) {
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paddingChanged = true;
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (paddingChanged) {
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onBoundsChange(getBounds());
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect bounds) {
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int padL=0, padT=0, padR=0, padB=0;
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r.mDrawable.setBounds(bounds.left + r.mInsetL + padL,
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bounds.top + r.mInsetT + padT,
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bounds.right - r.mInsetR - padR,
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                  bounds.bottom - r.mInsetB - padB);
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padL += mPaddingL[i];
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padR += mPaddingR[i];
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padT += mPaddingT[i];
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padB += mPaddingB[i];
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int width = -1;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int padL=0, padR=0;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int w = r.mDrawable.getIntrinsicWidth()
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                  + r.mInsetL + r.mInsetR + padL + padR;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (w > width) {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                width = w;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padL += mPaddingL[i];
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padR += mPaddingR[i];
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return width;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int height = -1;
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int padT=0, padB=0;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + + padT + padB;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (h > height) {
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                height = h;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padT += mPaddingT[i];
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padB += mPaddingB[i];
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return height;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean reapplyPadding(int i, ChildDrawable r) {
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect rect = mTmpRect;
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.mDrawable.getPadding(rect);
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingL[i] = rect.left;
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingT[i] = rect.top;
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingR[i] = rect.right;
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingB[i] = rect.bottom;
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void ensurePadding() {
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPaddingL != null && mPaddingL.length >= N) {
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingL = new int[N];
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingT = new int[N];
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingR = new int[N];
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingB = new int[N];
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLayerState.canConstantState()) {
5996efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais            mLayerState.mChangingConfigurations = getChangingConfigurations();
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mLayerState;
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mMutated && super.mutate() == this) {
60890e10cc58690678937575b54e1b20b899445d0e4Romain Guy            mLayerState = createConstantState(mLayerState, null);
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable[] array = mLayerState.mChildren;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mLayerState.mNum;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                array[i].mDrawable.mutate();
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMutated = true;
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619fc4947491f785600b8770112fa1d19ece06d42f9Dianne Hackborn    /** @hide */
6200af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    @Override
6210af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    public void setLayoutDirection(int layoutDirection) {
622731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio        final ChildDrawable[] array = mLayerState.mChildren;
623731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio        final int N = mLayerState.mNum;
624731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio        for (int i = 0; i < N; i++) {
625731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio            array[i].mDrawable.setLayoutDirection(layoutDirection);
6260af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        }
6270af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        super.setLayoutDirection(layoutDirection);
6280af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    }
6290af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class ChildDrawable {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Drawable mDrawable;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mInsetL, mInsetT, mInsetR, mInsetB;
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mId;
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class LayerState extends ConstantState {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mNum;
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ChildDrawable[] mChildren;
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mChangingConfigurations;
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mChildrenChangingConfigurations;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mHaveOpacity = false;
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int mOpacity;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mHaveStateful = false;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mStateful;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mCheckedConstantState;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean mCanConstantState;
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6523f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        private boolean mAutoMirrored;
6533f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
654c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        LayerState(LayerState orig, LayerDrawable owner, Resources res) {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (orig != null) {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final ChildDrawable[] origChildDrawable = orig.mChildren;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int N = orig.mNum;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNum = N;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildren = new ChildDrawable[N];
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChangingConfigurations = orig.mChangingConfigurations;
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < N; i++) {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    final ChildDrawable r = mChildren[i] = new ChildDrawable();
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    final ChildDrawable or = origChildDrawable[i];
668c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                    if (res != null) {
669c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                        r.mDrawable = or.mDrawable.getConstantState().newDrawable(res);
670c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                    } else {
671c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                        r.mDrawable = or.mDrawable.getConstantState().newDrawable();
672c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                    }
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.mDrawable.setCallback(owner);
674731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio                    r.mDrawable.setLayoutDirection(or.mDrawable.getLayoutDirection());
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.mInsetL = or.mInsetL;
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.mInsetT = or.mInsetT;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.mInsetR = or.mInsetR;
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.mInsetB = or.mInsetB;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.mId = or.mId;
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHaveOpacity = orig.mHaveOpacity;
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOpacity = orig.mOpacity;
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHaveStateful = orig.mHaveStateful;
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStateful = orig.mStateful;
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCheckedConstantState = mCanConstantState = true;
6873f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                mAutoMirrored = orig.mAutoMirrored;
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNum = 0;
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildren = null;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Drawable newDrawable() {
696c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn            return new LayerDrawable(this, null);
697c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        }
698c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn
699c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        @Override
700c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        public Drawable newDrawable(Resources res) {
701c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn            return new LayerDrawable(this, res);
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mChangingConfigurations;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final int getOpacity() {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveOpacity) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mOpacity;
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mNum;
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int op = N > 0 ? mChildren[0].mDrawable.getOpacity() : PixelFormat.TRANSPARENT;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 1; i < N; i++) {
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                op = Drawable.resolveOpacity(op, mChildren[i].mDrawable.getOpacity());
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOpacity = op;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveOpacity = true;
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return op;
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final boolean isStateful() {
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveStateful) {
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mStateful;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean stateful = false;
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mNum;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mChildren[i].mDrawable.isStateful()) {
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    stateful = true;
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mStateful = stateful;
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveStateful = true;
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return stateful;
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
74326e35fca60426ce375a4a0534dbc9964123c76eeAdam Powell        public boolean canConstantState() {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mCheckedConstantState && mChildren != null) {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCanConstantState = true;
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int N = mNum;
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i=0; i<N; i++) {
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mChildren[i].mDrawable.getConstantState() == null) {
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCanConstantState = false;
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCheckedConstantState = true;
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCanConstantState;
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
761