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.drawable.Drawable;
     22 import android.graphics.drawable.StateListDrawable;
     23 import android.util.Log;
     24 
     25 public 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