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         invalidateSelf();
     79         return true;
     80     }
     81 
     82     public void animateToSmallRadius() {
     83         int smallLevel = map(mSmallRadiusTarget,
     84                 0, diagonalLength(mCanvasWidth, mCanvasHeight)/2,
     85                 0, DRAWABLE_MAX_LEVEL);
     86         final ValueAnimator animator =
     87             ValueAnimator.ofInt(getLevel(), smallLevel);
     88         animator.setDuration(CIRCLE_ANIM_DURATION_MS);
     89         animator.setInterpolator(Gusterpolator.INSTANCE);
     90         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     91             @Override
     92             public void onAnimationUpdate(ValueAnimator animation) {
     93                 setLevel((Integer) animation.getAnimatedValue());
     94             }
     95         });
     96         animator.start();
     97     }
     98 
     99     public void animateToFullSize() {
    100         final ValueAnimator animator =
    101             ValueAnimator.ofInt(getLevel(), DRAWABLE_MAX_LEVEL);
    102         animator.setDuration(CIRCLE_ANIM_DURATION_MS);
    103         animator.setInterpolator(Gusterpolator.INSTANCE);
    104         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    105             @Override
    106             public void onAnimationUpdate(ValueAnimator animation) {
    107                 setLevel((Integer) animation.getAnimatedValue());
    108             }
    109         });
    110         animator.start();
    111     }
    112 
    113     @Override
    114     public void draw(Canvas canvas) {
    115         mCanvasWidth = canvas.getWidth();
    116         mCanvasHeight = canvas.getHeight();
    117 
    118         mRadius = map(getLevel(), 0, DRAWABLE_MAX_LEVEL,
    119                 0, diagonalLength(canvas.getWidth(), canvas.getHeight())/2);
    120         canvas.drawCircle(canvas.getWidth()/2.0f, canvas.getHeight()/2.0f,
    121                 mRadius, mPaint);
    122     }
    123 
    124     /**
    125      * Maps a given value x from one input range [in_min, in_max] to
    126      * another output range [out_min, out-max].
    127      * @param x Value to be mapped.
    128      * @param in_min Input range minimum.
    129      * @param in_max Input range maximum.
    130      * @param out_min Output range minimum.
    131      * @param out_max Output range maximum.
    132      * @return The mapped value.
    133      */
    134     private static int map(int x, int in_min, int in_max, int out_min, int out_max) {
    135         return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    136     }
    137 
    138     private static int diagonalLength(int w, int h) {
    139         return (int) Math.sqrt((w*w) + (h*h));
    140     }
    141 }