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