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