Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2014 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.camera.ui;
     18 
     19 import android.animation.ValueAnimator;
     20 import android.graphics.Canvas;
     21 import android.graphics.ColorFilter;
     22 import android.graphics.Paint;
     23 import android.graphics.PixelFormat;
     24 import android.graphics.drawable.Drawable;
     25 
     26 import com.android.camera.util.Gusterpolator;
     27 
     28 public class AnimatedCircleDrawable extends Drawable {
     29     private static final int CIRCLE_ANIM_DURATION_MS = 300;
     30     private static int DRAWABLE_MAX_LEVEL = 10000;
     31 
     32     private int mCanvasWidth;
     33     private int mCanvasHeight;
     34 
     35     private int mAlpha = 0xff;
     36     private int mColor;
     37     private Paint mPaint;
     38     private int mRadius;
     39     private int mSmallRadiusTarget;
     40 
     41     public AnimatedCircleDrawable(int smallRadiusTarget) {
     42         mPaint = new Paint();
     43         mPaint.setAntiAlias(true);
     44         mSmallRadiusTarget = smallRadiusTarget;
     45     }
     46 
     47     public void setColor(int color) {
     48         mColor = color;
     49         updatePaintColor();
     50     }
     51 
     52     private void updatePaintColor() {
     53         int paintColor = (mAlpha << 24) | (mColor & 0x00ffffff);
     54         mPaint.setColor(paintColor);
     55         invalidateSelf();
     56     }
     57 
     58     // abstract overrides
     59     @Override
     60     public int getOpacity() {
     61         return PixelFormat.TRANSLUCENT;
     62     }
     63 
     64     @Override
     65     public void setAlpha(int alpha) {
     66         mAlpha = alpha;
     67         updatePaintColor();
     68     }
     69 
     70     @Override
     71     public void setColorFilter(ColorFilter cf) {
     72         //TODO support this?
     73     }
     74     // end abstract overrides
     75 
     76     @Override
     77     public boolean onLevelChange(int level) {
     78         if (level != getLevel()) {
     79             invalidateSelf();
     80             return true;
     81         }
     82         return false;
     83     }
     84 
     85     public void animateToSmallRadius() {
     86         int smallLevel = map(mSmallRadiusTarget,
     87                 0, diagonalLength(mCanvasWidth, mCanvasHeight)/2,
     88                 0, DRAWABLE_MAX_LEVEL);
     89         final ValueAnimator animator =
     90             ValueAnimator.ofInt(getLevel(), smallLevel);
     91         animator.setDuration(CIRCLE_ANIM_DURATION_MS);
     92         animator.setInterpolator(Gusterpolator.INSTANCE);
     93         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     94             @Override
     95             public void onAnimationUpdate(ValueAnimator animation) {
     96                 setLevel((Integer) animation.getAnimatedValue());
     97             }
     98         });
     99         animator.start();
    100     }
    101 
    102     public void animateToFullSize() {
    103         final ValueAnimator animator =
    104             ValueAnimator.ofInt(getLevel(), DRAWABLE_MAX_LEVEL);
    105         animator.setDuration(CIRCLE_ANIM_DURATION_MS);
    106         animator.setInterpolator(Gusterpolator.INSTANCE);
    107         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    108             @Override
    109             public void onAnimationUpdate(ValueAnimator animation) {
    110                 setLevel((Integer) animation.getAnimatedValue());
    111             }
    112         });
    113         animator.start();
    114     }
    115 
    116     @Override
    117     public void draw(Canvas canvas) {
    118         mCanvasWidth = canvas.getWidth();
    119         mCanvasHeight = canvas.getHeight();
    120 
    121         mRadius = map(getLevel(), 0, DRAWABLE_MAX_LEVEL,
    122                 0, diagonalLength(canvas.getWidth(), canvas.getHeight())/2);
    123         canvas.drawCircle(canvas.getWidth()/2.0f, canvas.getHeight()/2.0f,
    124                 mRadius, mPaint);
    125     }
    126 
    127     /**
    128      * Maps a given value x from one input range [in_min, in_max] to
    129      * another output range [out_min, out-max].
    130      * @param x Value to be mapped.
    131      * @param in_min Input range minimum.
    132      * @param in_max Input range maximum.
    133      * @param out_min Output range minimum.
    134      * @param out_max Output range maximum.
    135      * @return The mapped value.
    136      */
    137     private static int map(int x, int in_min, int in_max, int out_min, int out_max) {
    138         return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    139     }
    140 
    141     private static int diagonalLength(int w, int h) {
    142         return (int) Math.sqrt((w*w) + (h*h));
    143     }
    144 }