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