DrawableWrapper.java revision 860126b78aa4d6e8db5208c7f96764a8556cf95f
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics.drawable;
18
19import android.content.res.Resources;
20import android.graphics.Canvas;
21import android.graphics.ColorFilter;
22import android.graphics.Rect;
23import android.graphics.Xfermode;
24
25/**
26 * A Drawable that wraps another Drawable.
27 */
28public class DrawableWrapper extends Drawable implements Drawable.Callback {
29    private WrapperState mWrapperState;
30
31    /** Local drawable backed by its own constant state. */
32    private Drawable mWrappedDrawable;
33
34    private boolean mMutated;
35
36    /** @hide */
37    @Override
38    public boolean isProjected() {
39        return mWrappedDrawable.isProjected();
40    }
41
42    @Override
43    public void setAutoMirrored(boolean mirrored) {
44        mWrappedDrawable.setAutoMirrored(mirrored);
45    }
46
47    @Override
48    public boolean isAutoMirrored() {
49        return mWrappedDrawable.isAutoMirrored();
50    }
51
52    @Override
53    public int getMinimumWidth() {
54        return mWrappedDrawable.getMinimumWidth();
55    }
56
57    @Override
58    public int getMinimumHeight() {
59        return mWrappedDrawable.getMinimumHeight();
60    }
61
62    @Override
63    public int getIntrinsicWidth() {
64        return mWrappedDrawable.getIntrinsicWidth();
65    }
66
67    @Override
68    public int getIntrinsicHeight() {
69        return mWrappedDrawable.getIntrinsicHeight();
70    }
71
72    @Override
73    public Drawable getCurrent() {
74        return mWrappedDrawable.getCurrent();
75    }
76
77    @Override
78    public void invalidateDrawable(Drawable who) {
79        final Callback callback = getCallback();
80        if (callback != null) {
81            callback.invalidateDrawable(this);
82        }
83    }
84
85    @Override
86    public void scheduleDrawable(Drawable who, Runnable what, long when) {
87        final Callback callback = getCallback();
88        if (callback != null) {
89            callback.scheduleDrawable(this, what, when);
90        }
91    }
92
93    @Override
94    public void unscheduleDrawable(Drawable who, Runnable what) {
95        final Callback callback = getCallback();
96        if (callback != null) {
97            callback.unscheduleDrawable(this, what);
98        }
99    }
100
101    @Override
102    public void draw(Canvas canvas) {
103        mWrappedDrawable.draw(canvas);
104    }
105
106    @Override
107    public int getChangingConfigurations() {
108        return mWrappedDrawable.getChangingConfigurations();
109    }
110
111    @Override
112    public boolean getPadding(Rect padding) {
113        return mWrappedDrawable.getPadding(padding);
114    }
115
116    @Override
117    public Rect getDirtyBounds() {
118        return mWrappedDrawable.getDirtyBounds();
119    }
120
121    @Override
122    public boolean supportsHotspots() {
123        return mWrappedDrawable.supportsHotspots();
124    }
125
126    @Override
127    public void setHotspot(int id, float x, float y) {
128        mWrappedDrawable.setHotspot(id, x, y);
129    }
130
131    @Override
132    public void removeHotspot(int id) {
133        mWrappedDrawable.removeHotspot(id);
134    }
135
136    @Override
137    public void clearHotspots() {
138        mWrappedDrawable.clearHotspots();
139    }
140
141    @Override
142    public boolean setVisible(boolean visible, boolean restart) {
143        // Must call through to super().
144        super.setVisible(visible, restart);
145        return mWrappedDrawable.setVisible(visible, restart);
146    }
147
148    @Override
149    public void setAlpha(int alpha) {
150        mWrappedDrawable.setAlpha(alpha);
151    }
152
153    @Override
154    public int getAlpha() {
155        return mWrappedDrawable.getAlpha();
156    }
157
158    /** {@hide} */
159    @Override
160    public void setLayoutDirection(int layoutDirection) {
161        mWrappedDrawable.setLayoutDirection(layoutDirection);
162    }
163
164    /** {@hide} */
165    @Override
166    public int getLayoutDirection() {
167        return mWrappedDrawable.getLayoutDirection();
168    }
169
170    @Override
171    public void setColorFilter(ColorFilter cf) {
172        mWrappedDrawable.setColorFilter(cf);
173    }
174
175    @Override
176    public ColorFilter getColorFilter() {
177        return mWrappedDrawable.getColorFilter();
178    }
179
180    @Override
181    public void setFilterBitmap(boolean filter) {
182        mWrappedDrawable.setFilterBitmap(filter);
183    }
184
185    @Override
186    public void setXfermode(Xfermode mode) {
187        mWrappedDrawable.setXfermode(mode);
188    }
189
190    @Override
191    public int getOpacity() {
192        return mWrappedDrawable.getOpacity();
193    }
194
195    @Override
196    public boolean isStateful() {
197        return mWrappedDrawable.isStateful();
198    }
199
200    @Override
201    public final boolean setState(int[] stateSet) {
202        return super.setState(stateSet);
203    }
204
205    @Override
206    public final int[] getState() {
207        return super.getState();
208    }
209
210    @Override
211    protected boolean onStateChange(int[] state) {
212        // Don't override setState(), getState().
213        return mWrappedDrawable.setState(state);
214    }
215
216    @Override
217    protected boolean onLevelChange(int level) {
218        // Don't override setLevel(), getLevel().
219        return mWrappedDrawable.setLevel(level);
220    }
221
222    @Override
223    public final void setBounds(int left, int top, int right, int bottom) {
224        super.setBounds(left, top, right, bottom);
225    }
226
227    @Override
228    public final void setBounds(Rect bounds) {
229        super.setBounds(bounds);
230    }
231
232    @Override
233    protected void onBoundsChange(Rect bounds) {
234        // Don't override setBounds(), getBounds().
235        mWrappedDrawable.setBounds(bounds);
236    }
237
238    protected void setConstantState(WrapperState wrapperState, Resources res) {
239        mWrapperState = wrapperState;
240
241        // Load a new drawable from the constant state.
242        if (wrapperState == null || wrapperState.mWrappedConstantState == null) {
243            mWrappedDrawable = null;
244        } else if (res != null) {
245            mWrappedDrawable = wrapperState.mWrappedConstantState.newDrawable(res);
246        } else {
247            mWrappedDrawable = wrapperState.mWrappedConstantState.newDrawable();
248        }
249    }
250
251    @Override
252    public ConstantState getConstantState() {
253        return mWrapperState;
254    }
255
256    @Override
257    public Drawable mutate() {
258        if (!mMutated) {
259            mWrappedDrawable = mWrappedDrawable.mutate();
260            mMutated = true;
261        }
262        return this;
263    }
264
265    /**
266     * Sets the wrapped drawable and update the constant state.
267     *
268     * @param drawable
269     * @param res
270     */
271    protected final void setDrawable(Drawable drawable, Resources res) {
272        if (mWrappedDrawable != null) {
273            mWrappedDrawable.setCallback(null);
274        }
275
276        mWrappedDrawable = drawable;
277
278        if (drawable != null) {
279            drawable.setCallback(this);
280
281            mWrapperState.mWrappedConstantState = drawable.getConstantState();
282        } else {
283            mWrapperState.mWrappedConstantState = null;
284        }
285    }
286
287    protected final Drawable getDrawable() {
288        return mWrappedDrawable;
289    }
290
291    public static abstract class WrapperState extends ConstantState {
292        ConstantState mWrappedConstantState;
293
294        WrapperState(WrapperState orig) {
295            if (orig != null) {
296                mWrappedConstantState = orig.mWrappedConstantState;
297            }
298        }
299
300        @Override
301        public int getChangingConfigurations() {
302            return mWrappedConstantState.getChangingConfigurations();
303        }
304    }
305}
306