• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 
17 package com.android.internal.widget.multiwaveview;
18 
19 import android.content.res.Resources;
20 import android.graphics.Canvas;
21 import android.graphics.ColorFilter;
22 import android.graphics.drawable.Drawable;
23 import android.graphics.drawable.StateListDrawable;
24 import android.util.Log;
25 
26 public class TargetDrawable {
27     private static final String TAG = "TargetDrawable";
28     private static final boolean DEBUG = false;
29 
30     public static final int[] STATE_ACTIVE =
31             { android.R.attr.state_enabled, android.R.attr.state_active };
32     public static final int[] STATE_INACTIVE =
33             { android.R.attr.state_enabled, -android.R.attr.state_active };
34     public static final int[] STATE_FOCUSED =
35             { android.R.attr.state_enabled, -android.R.attr.state_active,
36                 android.R.attr.state_focused };
37 
38     private float mTranslationX = 0.0f;
39     private float mTranslationY = 0.0f;
40     private float mPositionX = 0.0f;
41     private float mPositionY = 0.0f;
42     private float mScaleX = 1.0f;
43     private float mScaleY = 1.0f;
44     private float mAlpha = 1.0f;
45     private Drawable mDrawable;
46     private boolean mEnabled = true;
47     private final int mResourceId;
48 
49     /* package */ static class DrawableWithAlpha extends Drawable {
50         private float mAlpha = 1.0f;
51         private Drawable mRealDrawable;
DrawableWithAlpha(Drawable realDrawable)52         public DrawableWithAlpha(Drawable realDrawable) {
53             mRealDrawable = realDrawable;
54         }
setAlpha(float alpha)55         public void setAlpha(float alpha) {
56             mAlpha = alpha;
57         }
getAlpha()58         public float getAlpha() {
59             return mAlpha;
60         }
draw(Canvas canvas)61         public void draw(Canvas canvas) {
62             mRealDrawable.setAlpha((int) Math.round(mAlpha * 255f));
63             mRealDrawable.draw(canvas);
64         }
65         @Override
setAlpha(int alpha)66         public void setAlpha(int alpha) {
67             mRealDrawable.setAlpha(alpha);
68         }
69         @Override
setColorFilter(ColorFilter cf)70         public void setColorFilter(ColorFilter cf) {
71             mRealDrawable.setColorFilter(cf);
72         }
73         @Override
getOpacity()74         public int getOpacity() {
75             return mRealDrawable.getOpacity();
76         }
77     }
78 
TargetDrawable(Resources res, int resId)79     public TargetDrawable(Resources res, int resId) {
80         mResourceId = resId;
81         setDrawable(res, resId);
82     }
83 
setDrawable(Resources res, int resId)84     public void setDrawable(Resources res, int resId) {
85         // Note we explicitly don't set mResourceId to resId since we allow the drawable to be
86         // swapped at runtime and want to re-use the existing resource id for identification.
87         Drawable drawable = resId == 0 ? null : res.getDrawable(resId);
88         // Mutate the drawable so we can animate shared drawable properties.
89         mDrawable = drawable != null ? drawable.mutate() : null;
90         resizeDrawables();
91         setState(STATE_INACTIVE);
92     }
93 
TargetDrawable(TargetDrawable other)94     public TargetDrawable(TargetDrawable other) {
95         mResourceId = other.mResourceId;
96         // Mutate the drawable so we can animate shared drawable properties.
97         mDrawable = other.mDrawable != null ? other.mDrawable.mutate() : null;
98         resizeDrawables();
99         setState(STATE_INACTIVE);
100     }
101 
setState(int [] state)102     public void setState(int [] state) {
103         if (mDrawable instanceof StateListDrawable) {
104             StateListDrawable d = (StateListDrawable) mDrawable;
105             d.setState(state);
106         }
107     }
108 
hasState(int [] state)109     public boolean hasState(int [] state) {
110         if (mDrawable instanceof StateListDrawable) {
111             StateListDrawable d = (StateListDrawable) mDrawable;
112             // TODO: this doesn't seem to work
113             return d.getStateDrawableIndex(state) != -1;
114         }
115         return false;
116     }
117 
118     /**
119      * Returns true if the drawable is a StateListDrawable and is in the focused state.
120      *
121      * @return
122      */
isActive()123     public boolean isActive() {
124         if (mDrawable instanceof StateListDrawable) {
125             StateListDrawable d = (StateListDrawable) mDrawable;
126             int[] states = d.getState();
127             for (int i = 0; i < states.length; i++) {
128                 if (states[i] == android.R.attr.state_focused) {
129                     return true;
130                 }
131             }
132         }
133         return false;
134     }
135 
136     /**
137      * Returns true if this target is enabled. Typically an enabled target contains a valid
138      * drawable in a valid state. Currently all targets with valid drawables are valid.
139      *
140      * @return
141      */
isEnabled()142     public boolean isEnabled() {
143         return mDrawable != null && mEnabled;
144     }
145 
146     /**
147      * Makes drawables in a StateListDrawable all the same dimensions.
148      * If not a StateListDrawable, then justs sets the bounds to the intrinsic size of the
149      * drawable.
150      */
resizeDrawables()151     private void resizeDrawables() {
152         if (mDrawable instanceof StateListDrawable) {
153             StateListDrawable d = (StateListDrawable) mDrawable;
154             int maxWidth = 0;
155             int maxHeight = 0;
156             for (int i = 0; i < d.getStateCount(); i++) {
157                 Drawable childDrawable = d.getStateDrawable(i);
158                 maxWidth = Math.max(maxWidth, childDrawable.getIntrinsicWidth());
159                 maxHeight = Math.max(maxHeight, childDrawable.getIntrinsicHeight());
160             }
161             if (DEBUG) Log.v(TAG, "union of childDrawable rects " + d + " to: "
162                         + maxWidth + "x" + maxHeight);
163             d.setBounds(0, 0, maxWidth, maxHeight);
164             for (int i = 0; i < d.getStateCount(); i++) {
165                 Drawable childDrawable = d.getStateDrawable(i);
166                 if (DEBUG) Log.v(TAG, "sizing drawable " + childDrawable + " to: "
167                             + maxWidth + "x" + maxHeight);
168                 childDrawable.setBounds(0, 0, maxWidth, maxHeight);
169             }
170         } else if (mDrawable != null) {
171             mDrawable.setBounds(0, 0,
172                     mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
173         }
174     }
175 
setX(float x)176     public void setX(float x) {
177         mTranslationX = x;
178     }
179 
setY(float y)180     public void setY(float y) {
181         mTranslationY = y;
182     }
183 
setScaleX(float x)184     public void setScaleX(float x) {
185         mScaleX = x;
186     }
187 
setScaleY(float y)188     public void setScaleY(float y) {
189         mScaleY = y;
190     }
191 
setAlpha(float alpha)192     public void setAlpha(float alpha) {
193         mAlpha = alpha;
194     }
195 
getX()196     public float getX() {
197         return mTranslationX;
198     }
199 
getY()200     public float getY() {
201         return mTranslationY;
202     }
203 
getScaleX()204     public float getScaleX() {
205         return mScaleX;
206     }
207 
getScaleY()208     public float getScaleY() {
209         return mScaleY;
210     }
211 
getAlpha()212     public float getAlpha() {
213         return mAlpha;
214     }
215 
setPositionX(float x)216     public void setPositionX(float x) {
217         mPositionX = x;
218     }
219 
setPositionY(float y)220     public void setPositionY(float y) {
221         mPositionY = y;
222     }
223 
getPositionX()224     public float getPositionX() {
225         return mPositionX;
226     }
227 
getPositionY()228     public float getPositionY() {
229         return mPositionY;
230     }
231 
getWidth()232     public int getWidth() {
233         return mDrawable != null ? mDrawable.getIntrinsicWidth() : 0;
234     }
235 
getHeight()236     public int getHeight() {
237         return mDrawable != null ? mDrawable.getIntrinsicHeight() : 0;
238     }
239 
draw(Canvas canvas)240     public void draw(Canvas canvas) {
241         if (mDrawable == null || !mEnabled) {
242             return;
243         }
244         canvas.save(Canvas.MATRIX_SAVE_FLAG);
245         canvas.scale(mScaleX, mScaleY, mPositionX, mPositionY);
246         canvas.translate(mTranslationX + mPositionX, mTranslationY + mPositionY);
247         canvas.translate(-0.5f * getWidth(), -0.5f * getHeight());
248         mDrawable.setAlpha((int) Math.round(mAlpha * 255f));
249         mDrawable.draw(canvas);
250         canvas.restore();
251     }
252 
setEnabled(boolean enabled)253     public void setEnabled(boolean enabled) {
254         mEnabled  = enabled;
255     }
256 
getResourceId()257     public int getResourceId() {
258         return mResourceId;
259     }
260 }
261