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.deskclock.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      */
     59     public TargetDrawable(Resources res, int resId, int count) {
     60         mResourceId = resId;
     61         setDrawable(res, resId);
     62         mNumDrawables = count;
     63     }
     64 
     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 
     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 
     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      */
     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      */
    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      */
    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 
    153     public void setX(float x) {
    154         mTranslationX = x;
    155     }
    156 
    157     public void setY(float y) {
    158         mTranslationY = y;
    159     }
    160 
    161     public void setScaleX(float x) {
    162         mScaleX = x;
    163     }
    164 
    165     public void setScaleY(float y) {
    166         mScaleY = y;
    167     }
    168 
    169     public void setAlpha(float alpha) {
    170         mAlpha = alpha;
    171     }
    172 
    173     public float getX() {
    174         return mTranslationX;
    175     }
    176 
    177     public float getY() {
    178         return mTranslationY;
    179     }
    180 
    181     public float getScaleX() {
    182         return mScaleX;
    183     }
    184 
    185     public float getScaleY() {
    186         return mScaleY;
    187     }
    188 
    189     public float getAlpha() {
    190         return mAlpha;
    191     }
    192 
    193     public void setPositionX(float x) {
    194         mPositionX = x;
    195     }
    196 
    197     public void setPositionY(float y) {
    198         mPositionY = y;
    199     }
    200 
    201     public float getPositionX() {
    202         return mPositionX;
    203     }
    204 
    205     public float getPositionY() {
    206         return mPositionY;
    207     }
    208 
    209     public int getWidth() {
    210         return mDrawable != null ? mDrawable.getIntrinsicWidth() : 0;
    211     }
    212 
    213     public int getHeight() {
    214         return mDrawable != null ? mDrawable.getIntrinsicHeight() : 0;
    215     }
    216 
    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 
    230     public void setEnabled(boolean enabled) {
    231         mEnabled  = enabled;
    232     }
    233 
    234     public int getResourceId() {
    235         return mResourceId;
    236     }
    237 }
    238