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
1958945975b256739fdfe78435d7846d1e2fd29da1Chris Craikimport android.annotation.NonNull;
20b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
2252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
24021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.Canvas;
25021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.ColorFilter;
2658945975b256739fdfe78435d7846d1e2fd29da1Chris Craikimport android.graphics.Outline;
27021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.PixelFormat;
28b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode;
29021aad952bee3ac9ee4a98c09f1a012359088dd2Adam Powellimport android.graphics.Rect;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport com.android.internal.R;
3452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
3552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport org.xmlpull.v1.XmlPullParser;
3652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport org.xmlpull.v1.XmlPullParserException;
3752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
405b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette/**
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Drawable that manages an array of other Drawables. These are drawn in array
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * order, so the element with the largest index will be drawn on top.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It can be defined in an XML file with the <code>&lt;layer-list></code> element.
45e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * Each Drawable in the layer is defined in a nested <code>&lt;item></code>.
46e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * <p>
47e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * For more information, see the guide to
48e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
50e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#LayerDrawable_paddingMode
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_left
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_top
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_right
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_bottom
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_drawable
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#LayerDrawableItem_id
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class LayerDrawable extends Drawable implements Drawable.Callback {
595b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    /**
605b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * Padding mode used to nest each layer inside the padding of the previous
615b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * layer.
62e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *
63e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     * @see #setPaddingMode(int)
645b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     */
655b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    public static final int PADDING_MODE_NEST = 0;
665b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
67e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette    /**
68e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     * Padding mode used to stack each layer directly atop the previous layer.
69e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *
70e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     * @see #setPaddingMode(int)
71e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     */
725b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    public static final int PADDING_MODE_STACK = 1;
735b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayerState mLayerState;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
76e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    private int mOpacityOverride = PixelFormat.UNKNOWN;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingL;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingT;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingR;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mPaddingB;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Rect mTmpRect = new Rect();
837068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette    private Rect mHotspotBounds;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMutated;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new layer drawable with the list of specified layers.
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layers A list of drawables to use as layers in this new drawable.
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public LayerDrawable(Drawable[] layers) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(layers, null);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
961c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette     * Create a new layer drawable with the specified list of layers and the
971c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette     * specified constant state.
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layers The list of layers to add to this drawable.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param state The constant drawable state.
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayerDrawable(Drawable[] layers, LayerState state) {
10352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        this(state, null, null);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = layers.length;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ChildDrawable[] r = new ChildDrawable[length];
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < length; i++) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r[i] = new ChildDrawable();
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r[i].mDrawable = layers[i];
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            layers[i].setCallback(this);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLayerState.mChildrenChangingConfigurations |= layers[i].getChangingConfigurations();
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mNum = length;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mChildren = r;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensurePadding();
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1185b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayerDrawable() {
12052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        this((LayerState) null, null, null);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    LayerDrawable(LayerState state, Resources res, Theme theme) {
12452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final LayerState as = createConstantState(state, res);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState = as;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (as.mNum > 0) {
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ensurePadding();
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (theme != null && canApplyTheme()) {
13052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            applyTheme(theme);
13152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
134c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn    LayerState createConstantState(LayerState state, Resources res) {
135c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        return new LayerState(state, this, res);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
13952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
14152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        super.inflate(r, parser, attrs, theme);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
143e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawable);
144e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        updateStateFromTypedArray(a);
14552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        a.recycle();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        inflateLayers(r, parser, attrs, theme);
148e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
14952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        ensurePadding();
15052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        onStateChange(getState());
15152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
15252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
15352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    /**
15452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * Initializes the constant state from the values in the typed array.
15552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     */
156e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette    private void updateStateFromTypedArray(TypedArray a) {
15752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final LayerState state = mLayerState;
158e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
1598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
1608e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mChangingConfigurations |= a.getChangingConfigurations();
1618e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
16252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        // Extract the theme attributes, if any.
1638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mThemeAttrs = a.extractThemeAttrs();
1643f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
165e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        mOpacityOverride = a.getInt(R.styleable.LayerDrawable_opacity, mOpacityOverride);
166e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
167e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        state.mAutoMirrored = a.getBoolean(R.styleable.LayerDrawable_autoMirrored,
168e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette                state.mAutoMirrored);
169e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        state.mPaddingMode = a.getInteger(R.styleable.LayerDrawable_paddingMode,
170e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette                state.mPaddingMode);
17152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
17252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
17352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    /**
17452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * Inflates child layers using the specified parser.
17552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     */
17652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private void inflateLayers(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
17752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            throws XmlPullParserException, IOException {
1788e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final LayerState state = mLayerState;
1798e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int innerDepth = parser.getDepth() + 1;
18152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int type;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int depth;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (type != XmlPullParser.START_TAG) {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (depth > innerDepth || !parser.getName().equals("item")) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1938e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final ChildDrawable layer = new ChildDrawable();
1948e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawableItem);
1958e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateLayerFromTypedArray(layer, a);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            a.recycle();
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            if (layer.mDrawable == null) {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while ((type = parser.next()) == XmlPullParser.TEXT) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (type != XmlPullParser.START_TAG) {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new XmlPullParserException(parser.getPositionDescription()
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + ": <item> tag requires a 'drawable' attribute or "
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + "child tag defining a drawable");
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                layer.mDrawable = Drawable.createFromXmlInner(r, parser, attrs, theme);
2078e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            }
2088e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
2098e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            if (layer.mDrawable != null) {
2108e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                state.mChildrenChangingConfigurations |=
2118e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                        layer.mDrawable.getChangingConfigurations();
2128e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                layer.mDrawable.setCallback(this);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2149e6f9924c421d801f28b773673511cd59859d843Alan Viverette
2159e6f9924c421d801f28b773673511cd59859d843Alan Viverette            addLayer(layer);
2168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
2178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    }
2188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
2198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    private void updateLayerFromTypedArray(ChildDrawable layer, TypedArray a) {
2208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final LayerState state = mLayerState;
2218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
2228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
2238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mChildrenChangingConfigurations |= a.getChangingConfigurations();
2248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
2258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Extract the theme attributes, if any.
2268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        layer.mThemeAttrs = a.extractThemeAttrs();
2278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
2288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        layer.mInsetL = a.getDimensionPixelOffset(
2298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                R.styleable.LayerDrawableItem_left, layer.mInsetL);
2308e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        layer.mInsetT = a.getDimensionPixelOffset(
2318e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                R.styleable.LayerDrawableItem_top, layer.mInsetT);
2328e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        layer.mInsetR = a.getDimensionPixelOffset(
2338e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                R.styleable.LayerDrawableItem_right, layer.mInsetR);
2348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        layer.mInsetB = a.getDimensionPixelOffset(
2358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                R.styleable.LayerDrawableItem_bottom, layer.mInsetB);
2368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        layer.mId = a.getResourceId(R.styleable.LayerDrawableItem_id, layer.mId);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2388e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final Drawable dr = a.getDrawable(R.styleable.LayerDrawableItem_drawable);
2398e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        if (dr != null) {
2408e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            layer.mDrawable = dr;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
24352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
24452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
24552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void applyTheme(Theme t) {
24652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        super.applyTheme(t);
24752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
24852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final LayerState state = mLayerState;
24952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (state == null) {
250e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette            return;
25152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
25252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
2538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        if (state.mThemeAttrs != null) {
2548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.LayerDrawable);
25552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            updateStateFromTypedArray(a);
25652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            a.recycle();
25752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
25852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
25952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
26052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int N = mLayerState.mNum;
26152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        for (int i = 0; i < N; i++) {
262e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette            final ChildDrawable layer = array[i];
2638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            if (layer.mThemeAttrs != null) {
2648e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                final TypedArray a = t.resolveAttributes(layer.mThemeAttrs,
2658e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                        R.styleable.LayerDrawableItem);
2668e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                updateLayerFromTypedArray(layer, a);
2678e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                a.recycle();
2688e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            }
2698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
270e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette            final Drawable d = layer.mDrawable;
271e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette            if (d.canApplyTheme()) {
272e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette                d.applyTheme(t);
27352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
27452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ensurePadding();
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onStateChange(getState());
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
28152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public boolean canApplyTheme() {
28252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final LayerState state = mLayerState;
28352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (state == null) {
28452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return false;
28552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
28652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
28752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (state.mThemeAttrs != null) {
28852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return true;
28952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
29052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
29152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final ChildDrawable[] array = state.mChildren;
29252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int N = state.mNum;
29352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        for (int i = 0; i < N; i++) {
294e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette            final ChildDrawable layer = array[i];
295e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette            if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) {
29652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                return true;
29752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
29852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
29952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
30052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return false;
30152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
302e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette
30361956606818918194a38e045a8e35e7108480e5eAlan Viverette    /**
30461956606818918194a38e045a8e35e7108480e5eAlan Viverette     * @hide
30561956606818918194a38e045a8e35e7108480e5eAlan Viverette     */
30661956606818918194a38e045a8e35e7108480e5eAlan Viverette    @Override
30761956606818918194a38e045a8e35e7108480e5eAlan Viverette    public boolean isProjected() {
30861956606818918194a38e045a8e35e7108480e5eAlan Viverette        if (super.isProjected()) {
30961956606818918194a38e045a8e35e7108480e5eAlan Viverette            return true;
31061956606818918194a38e045a8e35e7108480e5eAlan Viverette        }
31161956606818918194a38e045a8e35e7108480e5eAlan Viverette
31261956606818918194a38e045a8e35e7108480e5eAlan Viverette        final ChildDrawable[] layers = mLayerState.mChildren;
31361956606818918194a38e045a8e35e7108480e5eAlan Viverette        final int N = mLayerState.mNum;
31461956606818918194a38e045a8e35e7108480e5eAlan Viverette        for (int i = 0; i < N; i++) {
31561956606818918194a38e045a8e35e7108480e5eAlan Viverette            if (layers[i].mDrawable.isProjected()) {
31661956606818918194a38e045a8e35e7108480e5eAlan Viverette                return true;
31761956606818918194a38e045a8e35e7108480e5eAlan Viverette            }
31861956606818918194a38e045a8e35e7108480e5eAlan Viverette        }
31961956606818918194a38e045a8e35e7108480e5eAlan Viverette
32061956606818918194a38e045a8e35e7108480e5eAlan Viverette        return false;
32161956606818918194a38e045a8e35e7108480e5eAlan Viverette    }
32252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
3238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    void addLayer(ChildDrawable layer) {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final LayerState st = mLayerState;
3255b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final int N = st.mChildren != null ? st.mChildren.length : 0;
3265b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final int i = st.mNum;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (i >= N) {
3285b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            final ChildDrawable[] nu = new ChildDrawable[N + 10];
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i > 0) {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.arraycopy(st.mChildren, 0, nu, 0, i);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3325b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            st.mChildren = nu;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mChildren[i] = layer;
3378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.mNum++;
3388e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        st.invalidateCache();
3398e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    }
3405b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
3418e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    /**
3428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * Add a new layer to this drawable. The new layer is identified by an id.
3438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     *
3448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param layer The drawable to add as a layer.
3458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param themeAttrs Theme attributes extracted from the layer.
3468e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param id The id of the new layer.
3478e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param left The left padding of the new layer.
3488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param top The top padding of the new layer.
3498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param right The right padding of the new layer.
3508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * @param bottom The bottom padding of the new layer.
3518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     */
3528e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    ChildDrawable addLayer(Drawable layer, int[] themeAttrs, int id, int left, int top, int right,
3538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            int bottom) {
3545b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final ChildDrawable childDrawable = new ChildDrawable();
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mId = id;
356e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        childDrawable.mThemeAttrs = themeAttrs;
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mDrawable = layer;
3583f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        childDrawable.mDrawable.setAutoMirrored(isAutoMirrored());
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetL = left;
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetT = top;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetR = right;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetB = bottom;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3648e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        addLayer(childDrawable);
3658e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
3668e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations();
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        layer.setCallback(this);
3688e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
3698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        return childDrawable;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
373ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette     * Looks for a layer with the given ID and returns its {@link Drawable}.
374ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette     * <p>
375ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette     * If multiple layers are found for the given ID, returns the
376ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette     * {@link Drawable} for the matching layer at the highest index.
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The layer ID to search for.
379ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette     * @return The {@link Drawable} for the highest-indexed layer that has the
380ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette     *         given ID, or null if not found.
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable findDrawableByLayerId(int id) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] layers = mLayerState.mChildren;
384ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette        for (int i = mLayerState.mNum - 1; i >= 0; i--) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (layers[i].mId == id) {
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return layers[i].mDrawable;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3895b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3925b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the ID of a layer.
3955b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *
3965b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param index The index of the layer which will received the ID.
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The ID to assign to the layer.
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setId(int index, int id) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayerState.mChildren[index].mId = id;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4025b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the number of layers contained within this.
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of layers.
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getNumberOfLayers() {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.mNum;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the drawable at the specified layer index.
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The layer index of the drawable to retrieve.
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The {@link android.graphics.drawable.Drawable} at the specified layer index.
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getDrawable(int index) {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.mChildren[index].mDrawable;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the id of the specified layer.
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The index of the layer.
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4275b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id.
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getId(int index) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.mChildren[index].mId;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4325b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets (or replaces) the {@link Drawable} for the layer with the given id.
4355b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id The layer ID to search for.
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param drawable The replacement {@link Drawable}.
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether the {@link Drawable} was replaced (could return false if
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the id was not found).
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setDrawableByLayerId(int id, Drawable drawable) {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] layers = mLayerState.mChildren;
4435b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final int N = mLayerState.mNum;
4445b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
4455b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            final ChildDrawable childDrawable = layers[i];
4465b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            if (childDrawable.mId == id) {
4475b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                if (childDrawable.mDrawable != null) {
448fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    if (drawable != null) {
4495b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                        final Rect bounds = childDrawable.mDrawable.getBounds();
450fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                        drawable.setBounds(bounds);
451fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    }
4525b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
4535b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                    childDrawable.mDrawable.setCallback(null);
454fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                }
4555b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
456fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                if (drawable != null) {
457fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                    drawable.setCallback(this);
458fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                }
4595b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
4605b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                childDrawable.mDrawable = drawable;
4611c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                mLayerState.invalidateCache();
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4655b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4685b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
4695b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    /**
4705b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * Specifies the insets in pixels for the drawable at the specified index.
4715b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *
4725b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param index the index of the drawable to adjust
4735b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param l number of pixels to add to the left bound
4745b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param t number of pixels to add to the top bound
4755b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param r number of pixels to subtract from the right bound
4765b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param b number of pixels to subtract from the bottom bound
4775b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     */
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLayerInset(int index, int l, int t, int r, int b) {
4795b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final ChildDrawable childDrawable = mLayerState.mChildren[index];
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetL = l;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetT = t;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetR = r;
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        childDrawable.mInsetB = b;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4865b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    /**
4875b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * Specifies how layer padding should affect the bounds of subsequent
4885b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * layers. The default value is {@link #PADDING_MODE_NEST}.
4895b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *
4905b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @param mode padding mode, one of:
4915b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *            <ul>
492e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *            <li>{@link #PADDING_MODE_NEST} to nest each layer inside the
493e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *            padding of the previous layer
494e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *            <li>{@link #PADDING_MODE_STACK} to stack each layer directly
495e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *            atop the previous layer
4965b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *            </ul>
497e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *
498e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     * @see #getPaddingMode()
499e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     * @attr ref android.R.styleable#LayerDrawable_paddingMode
5005b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     */
5015b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    public void setPaddingMode(int mode) {
5025b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        if (mLayerState.mPaddingMode != mode) {
5035b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            mLayerState.mPaddingMode = mode;
5045b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        }
5055b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    }
5065b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5075b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    /**
5085b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @return the current padding mode
509e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     *
5105b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @see #setPaddingMode(int)
511e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette     * @attr ref android.R.styleable#LayerDrawable_paddingMode
5125b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     */
5135b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    public int getPaddingMode() {
5145b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette      return mLayerState.mPaddingMode;
5155b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    }
5165b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5175b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    @Override
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void invalidateDrawable(Drawable who) {
519ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette        invalidateSelf();
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5225b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    @Override
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void scheduleDrawable(Drawable who, Runnable what, long when) {
524ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette        scheduleSelf(what, when);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5275b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    @Override
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unscheduleDrawable(Drawable who, Runnable what) {
529ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette        unscheduleSelf(what);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
5365b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.draw(canvas);
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.getChangingConfigurations()
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mLayerState.mChangingConfigurations
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mLayerState.mChildrenChangingConfigurations;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5475b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getPadding(Rect padding) {
550ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette        if (mLayerState.mPaddingMode == PADDING_MODE_NEST) {
551ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette            computeNestedPadding(padding);
552ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette        } else {
553ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette            computeStackedPadding(padding);
5545b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        }
5555b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5565b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        return padding.left != 0 || padding.top != 0 || padding.right != 0 || padding.bottom != 0;
5575b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    }
5585b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5595b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    private void computeNestedPadding(Rect padding) {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.left = 0;
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.top = 0;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.right = 0;
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        padding.bottom = 0;
5645b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5655b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        // Add all the padding.
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
5685b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
5695b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            refreshChildPadding(i, array[i]);
5705b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.left += mPaddingL[i];
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.top += mPaddingT[i];
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.right += mPaddingR[i];
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.bottom += mPaddingB[i];
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5765b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    }
57787980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette
5781c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette    private void computeStackedPadding(Rect padding) {
5791c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        padding.left = 0;
5801c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        padding.top = 0;
5811c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        padding.right = 0;
5821c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        padding.bottom = 0;
5831c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette
5841c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        // Take the max padding.
5851c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
5861c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        final int N = mLayerState.mNum;
5871c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        for (int i = 0; i < N; i++) {
5881c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            refreshChildPadding(i, array[i]);
5891c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette
5901c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            padding.left = Math.max(padding.left, mPaddingL[i]);
5911c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            padding.top = Math.max(padding.top, mPaddingT[i]);
5921c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            padding.right = Math.max(padding.right, mPaddingR[i]);
5931c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            padding.bottom = Math.max(padding.bottom, mPaddingB[i]);
5941c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        }
5951c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette    }
5961c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette
59758945975b256739fdfe78435d7846d1e2fd29da1Chris Craik    /**
59877b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik     * Populates <code>outline</code> with the first available (non-empty) layer outline.
5997c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette     *
6007c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette     * @param outline Outline in which to place the first available layer outline
60158945975b256739fdfe78435d7846d1e2fd29da1Chris Craik     */
60258945975b256739fdfe78435d7846d1e2fd29da1Chris Craik    @Override
60331ba192dd201df2cad96a8c503f730130ab0d80fChris Craik    public void getOutline(@NonNull Outline outline) {
6047c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette        final LayerState state = mLayerState;
6057c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette        final ChildDrawable[] children = state.mChildren;
6067c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette        final int N = state.mNum;
6077c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette        for (int i = 0; i < N; i++) {
60831ba192dd201df2cad96a8c503f730130ab0d80fChris Craik            children[i].mDrawable.getOutline(outline);
60931ba192dd201df2cad96a8c503f730130ab0d80fChris Craik            if (!outline.isEmpty()) {
61031ba192dd201df2cad96a8c503f730130ab0d80fChris Craik                return;
6117c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette            }
6127c0517272ba2d97084739a14fea78641b265eb5dAlan Viverette        }
61358945975b256739fdfe78435d7846d1e2fd29da1Chris Craik    }
61458945975b256739fdfe78435d7846d1e2fd29da1Chris Craik
61587980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette    @Override
616c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette    public void setHotspot(float x, float y) {
61787980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
61887980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette        final int N = mLayerState.mNum;
61987980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette        for (int i = 0; i < N; i++) {
620c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette            array[i].mDrawable.setHotspot(x, y);
62187980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette        }
62287980f9a7383fa4150f9c037ed34c37677f97f97Alan Viverette    }
6235b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
62553a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette    public void setHotspotBounds(int left, int top, int right, int bottom) {
62653a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
62753a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette        final int N = mLayerState.mNum;
62853a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette        for (int i = 0; i < N; i++) {
62953a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette            array[i].mDrawable.setHotspotBounds(left, top, right, bottom);
63053a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette        }
6317068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette
6327068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette        if (mHotspotBounds == null) {
6337068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette            mHotspotBounds = new Rect(left, top, right, bottom);
6347068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette        } else {
6357068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette            mHotspotBounds.set(left, top, right, bottom);
6367068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette        }
6377068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette    }
6387068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette
6397068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette    /** @hide */
6407068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette    @Override
6417068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette    public void getHotspotBounds(Rect outRect) {
6427068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette        if (mHotspotBounds != null) {
6437068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette            outRect.set(mHotspotBounds);
6447068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette        } else {
6457068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette            super.getHotspotBounds(outRect);
6467068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette        }
64753a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette    }
64853a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette
64953a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette    @Override
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setVisible(boolean visible, boolean restart) {
6515b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final boolean changed = super.setVisible(visible, restart);
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
6545b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setVisible(visible, restart);
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6575b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
6655b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setDither(dither);
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
6745b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setAlpha(alpha);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
678b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
679b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
680b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    public int getAlpha() {
681b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        final ChildDrawable[] array = mLayerState.mChildren;
682b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        if (mLayerState.mNum > 0) {
6831c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            // All layers should have the same alpha set on them - just return
6841c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            // the first one
685b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase            return array[0].mDrawable.getAlpha();
686b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        } else {
687b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase            return super.getAlpha();
688b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        }
689b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    }
690b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(ColorFilter cf) {
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
6955b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            array[i].mDrawable.setColorFilter(cf);
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
699e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato
700b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
701a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    public void setTintList(ColorStateList tint) {
702b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
703b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final int N = mLayerState.mNum;
704b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        for (int i = 0; i < N; i++) {
705a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            array[i].mDrawable.setTintList(tint);
706a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        }
707a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    }
708a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette
709a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    @Override
710a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    public void setTintMode(Mode tintMode) {
711a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
712a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        final int N = mLayerState.mNum;
713a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        for (int i = 0; i < N; i++) {
714a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            array[i].mDrawable.setTintMode(tintMode);
715b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
716b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
717b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
718e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    /**
7191c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette     * Sets the opacity of this drawable directly, instead of collecting the
7201c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette     * states from the layers
721e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     *
7221c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette     * @param opacity The opacity to use, or {@link PixelFormat#UNKNOWN
7231c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette     *            PixelFormat.UNKNOWN} for the default behavior
724e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#UNKNOWN
725e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#TRANSLUCENT
726e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#TRANSPARENT
727e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     * @see PixelFormat#OPAQUE
728e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato     */
729e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    public void setOpacity(int opacity) {
730e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        mOpacityOverride = opacity;
731e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato    }
7325b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
735e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        if (mOpacityOverride != PixelFormat.UNKNOWN) {
736e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato            return mOpacityOverride;
737e70b375c4b9d73d1165a21a421cfd73170cd06ccJoe Onorato        }
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.getOpacity();
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7423f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public void setAutoMirrored(boolean mirrored) {
7433f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        mLayerState.mAutoMirrored = mirrored;
7445b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7453f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        final ChildDrawable[] array = mLayerState.mChildren;
7463f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        final int N = mLayerState.mNum;
7475b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
7483f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio            array[i].mDrawable.setAutoMirrored(mirrored);
7493f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        }
7503f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
7513f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
7523f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
7533f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public boolean isAutoMirrored() {
7543f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        return mLayerState.mAutoMirrored;
7553f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
7563f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
7573f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isStateful() {
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayerState.isStateful();
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7615b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onStateChange(int[] state) {
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean paddingChanged = false;
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = false;
7665b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7675b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
7685b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final int N = mLayerState.mNum;
7695b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
7711c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            if (r.mDrawable.isStateful() && r.mDrawable.setState(state)) {
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                changed = true;
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7745b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7755b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            if (refreshChildPadding(i, r)) {
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paddingChanged = true;
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7795b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (paddingChanged) {
781ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette            onBoundsChange(getBounds());
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7835b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7865b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean paddingChanged = false;
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = false;
7915b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
7925b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final ChildDrawable[] array = mLayerState.mChildren;
7935b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final int N = mLayerState.mNum;
7945b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (r.mDrawable.setLevel(level)) {
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                changed = true;
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7995b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8005b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            if (refreshChildPadding(i, r)) {
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paddingChanged = true;
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8045b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (paddingChanged) {
806ee779ea446dd1161ba2fc50356edd5722454f141Alan Viverette            onBoundsChange(getBounds());
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8085b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect bounds) {
8145b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padL = 0;
8155b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padT = 0;
8165b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padR = 0;
8175b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padB = 0;
8185b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8195b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
8225b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
8245b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            r.mDrawable.setBounds(bounds.left + r.mInsetL + padL, bounds.top + r.mInsetT + padT,
8255b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                    bounds.right - r.mInsetR - padR, bounds.bottom - r.mInsetB - padB);
8265b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8275b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            if (nest) {
8285b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padL += mPaddingL[i];
8295b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padR += mPaddingR[i];
8305b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padT += mPaddingT[i];
8315b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padB += mPaddingB[i];
8325b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int width = -1;
8395b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padL = 0;
8405b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padR = 0;
8415b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8425b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
8455b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
8475b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            final int w = r.mDrawable.getIntrinsicWidth() + r.mInsetL + r.mInsetR + padL + padR;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (w > width) {
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                width = w;
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8515b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8525b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            if (nest) {
8535b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padL += mPaddingL[i];
8545b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padR += mPaddingR[i];
8555b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8575b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return width;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int height = -1;
8645b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padT = 0;
8655b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        int padB = 0;
8665b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8675b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ChildDrawable[] array = mLayerState.mChildren;
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
8705b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        for (int i = 0; i < N; i++) {
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable r = array[i];
8725b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + padT + padB;
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (h > height) {
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                height = h;
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8765b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8775b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            if (nest) {
8785b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padT += mPaddingT[i];
8795b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                padB += mPaddingB[i];
8805b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette            }
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8825b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return height;
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8865b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    /**
8875b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * Refreshes the cached padding values for the specified child.
8885b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     *
8895b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * @return true if the child's padding has changed
8905b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     */
8915b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    private boolean refreshChildPadding(int i, ChildDrawable r) {
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect rect = mTmpRect;
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        r.mDrawable.getPadding(rect);
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingL[i] = rect.left;
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingT[i] = rect.top;
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingR[i] = rect.right;
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPaddingB[i] = rect.bottom;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9055b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette    /**
9065b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     * Ensures the child padding caches are large enough.
9075b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette     */
90847bf0d95ef6c9ac68773567d503749c874a07f2fAlan Viverette    void ensurePadding() {
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = mLayerState.mNum;
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mPaddingL != null && mPaddingL.length >= N) {
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9135b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingL = new int[N];
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingT = new int[N];
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingR = new int[N];
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaddingB = new int[N];
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLayerState.canConstantState()) {
9236efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais            mLayerState.mChangingConfigurations = getChangingConfigurations();
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mLayerState;
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mMutated && super.mutate() == this) {
93290e10cc58690678937575b54e1b20b899445d0e4Romain Guy            mLayerState = createConstantState(mLayerState, null);
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ChildDrawable[] array = mLayerState.mChildren;
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mLayerState.mNum;
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                array[i].mDrawable.mutate();
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMutated = true;
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
943fc4947491f785600b8770112fa1d19ece06d42f9Dianne Hackborn    /** @hide */
9440af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    @Override
9450af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    public void setLayoutDirection(int layoutDirection) {
946731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio        final ChildDrawable[] array = mLayerState.mChildren;
947731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio        final int N = mLayerState.mNum;
948731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio        for (int i = 0; i < N; i++) {
949731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio            array[i].mDrawable.setLayoutDirection(layoutDirection);
9500af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        }
9510af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        super.setLayoutDirection(layoutDirection);
9520af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    }
9530af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class ChildDrawable {
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Drawable mDrawable;
95652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public int[] mThemeAttrs;
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mInsetL, mInsetT, mInsetR, mInsetB;
9588e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        public int mId = View.NO_ID;
9591c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette
96052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        ChildDrawable() {
96152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // Default empty constructor.
96252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
96352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
964d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette        ChildDrawable(ChildDrawable orig, LayerDrawable owner, Resources res) {
96552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            if (res != null) {
966d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette                mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
96752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            } else {
968d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette                mDrawable = orig.mDrawable.getConstantState().newDrawable();
96952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
97052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mDrawable.setCallback(owner);
971d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
972d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mDrawable.setBounds(orig.mDrawable.getBounds());
973d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mDrawable.setLevel(orig.mDrawable.getLevel());
974d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mThemeAttrs = orig.mThemeAttrs;
975d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mInsetL = orig.mInsetL;
976d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mInsetT = orig.mInsetT;
977d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mInsetR = orig.mInsetR;
978d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mInsetB = orig.mInsetB;
979d7853e576301bf68e96148a0b9e52085bfc7cf95Alan Viverette            mId = orig.mId;
98052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class LayerState extends ConstantState {
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mNum;
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ChildDrawable[] mChildren;
98652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        int[] mThemeAttrs;
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mChangingConfigurations;
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mChildrenChangingConfigurations;
9905b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
9911c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        private boolean mHaveOpacity;
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int mOpacity;
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9941c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        private boolean mHaveIsStateful;
9951c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        private boolean mIsStateful;
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
997e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette        private boolean mAutoMirrored = false;
9983f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
9995b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette        private int mPaddingMode = PADDING_MODE_NEST;
10005b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
1001c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        LayerState(LayerState orig, LayerDrawable owner, Resources res) {
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (orig != null) {
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final ChildDrawable[] origChildDrawable = orig.mChildren;
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int N = orig.mNum;
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNum = N;
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildren = new ChildDrawable[N];
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChangingConfigurations = orig.mChangingConfigurations;
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
10115b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < N; i++) {
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    final ChildDrawable or = origChildDrawable[i];
101452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    mChildren[i] = new ChildDrawable(or, owner, res);
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHaveOpacity = orig.mHaveOpacity;
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOpacity = orig.mOpacity;
10191c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                mHaveIsStateful = orig.mHaveIsStateful;
10201c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                mIsStateful = orig.mIsStateful;
10213f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                mAutoMirrored = orig.mAutoMirrored;
10225b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette                mPaddingMode = orig.mPaddingMode;
102352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                mThemeAttrs = orig.mThemeAttrs;
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNum = 0;
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildren = null;
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
103152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public boolean canApplyTheme() {
103252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return mThemeAttrs != null;
103352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
103452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
103552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Drawable newDrawable() {
103752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return new LayerDrawable(this, null, null);
1038c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        }
10395b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
1040c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        @Override
1041c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        public Drawable newDrawable(Resources res) {
104252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return new LayerDrawable(this, res, null);
104352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
104452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
104552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
104652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public Drawable newDrawable(Resources res, Theme theme) {
104752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return new LayerDrawable(this, res, theme);
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10495b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mChangingConfigurations;
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final int getOpacity() {
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveOpacity) {
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mOpacity;
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10601c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            final ChildDrawable[] array = mChildren;
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mNum;
10621c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            int op = N > 0 ? array[0].mDrawable.getOpacity() : PixelFormat.TRANSPARENT;
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 1; i < N; i++) {
10641c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                op = Drawable.resolveOpacity(op, array[i].mDrawable.getOpacity());
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10661c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOpacity = op;
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveOpacity = true;
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return op;
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10715b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final boolean isStateful() {
10731c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            if (mHaveIsStateful) {
10741c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                return mIsStateful;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10765b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
10771c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            final ChildDrawable[] array = mChildren;
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mNum;
10791c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            boolean isStateful = false;
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
10811c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                if (array[i].mDrawable.isStateful()) {
10821c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                    isStateful = true;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10865b10a723b0aa2eddf37262a30bb5cc9fb6fbbd9cAlan Viverette
10871c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            mIsStateful = isStateful;
10881c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            mHaveIsStateful = true;
10891c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            return isStateful;
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10921c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        public final boolean canConstantState() {
10931c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            final ChildDrawable[] array = mChildren;
10941c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            final int N = mNum;
10951c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            for (int i = 0; i < N; i++) {
10961c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                if (array[i].mDrawable.getConstantState() == null) {
10971c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette                    return false;
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11011c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            // Don't cache the result, this method is not called very often.
11021c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            return true;
11031c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        }
11041c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette
11051c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette        public void invalidateCache() {
11061c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            mHaveOpacity = false;
11071c4e36c973ae89b1793bd557405bab958fffeea8Alan Viverette            mHaveIsStateful = false;
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1112