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