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