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