1 /*
2  * Copyright (C) 2013 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.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Color;
22 import android.graphics.Paint;
23 import android.graphics.RectF;
24 import android.view.View;
25 
26 import com.android.camera2.R;
27 
28 /**
29  * Renders a circular progress bar on the screen.
30  */
31 public class ProgressRenderer {
32     private final int mProgressRadius;
33     private final Paint mProgressBasePaint;
34     private final Paint mProgressPaint;
35 
36     private RectF mArcBounds = new RectF(0, 0, 1, 1);
37     private int mProgressAngleDegrees = 270;
38     private boolean mVisible = false;
39     private final View mParentView;
40     private final Runnable mInvalidateParentViewRunnable = new Runnable() {
41         @Override
42         public void run() {
43             mParentView.invalidate();
44         }
45     };
46 
47     /**
48      * After we reach 100%, keep on painting the progress for another x milliseconds
49      * before hiding it.
50      */
51     private static final int SHOW_PROGRESS_X_ADDITIONAL_MS = 100;
52 
ProgressRenderer(Context context, View parent)53     public ProgressRenderer(Context context, View parent) {
54         mParentView = parent;
55         mProgressRadius = context.getResources().getDimensionPixelSize(R.dimen.pie_progress_radius);
56         int pieProgressWidth = context.getResources().getDimensionPixelSize(
57                 R.dimen.pie_progress_width);
58         mProgressBasePaint = createProgressPaint(pieProgressWidth, 0.2f);
59         mProgressPaint = createProgressPaint(pieProgressWidth, 1.0f);
60     }
61 
62     /**
63      * Shows a progress indicator. If the progress is '100', the progress
64      * indicator will be hidden.
65      * <p>
66      * Can be called from any thread.
67      *
68      * @param percent the progress in percent (0-100).
69      */
setProgress(int percent)70     public void setProgress(int percent) {
71         // Clamp the value.
72         percent = Math.min(100, Math.max(percent, 0));
73         mProgressAngleDegrees = (int) ((360f / 100) * percent);
74 
75         // We hide the progress once we drew the 100% state once.
76         if (percent < 100) {
77             mVisible = true;
78         }
79         mParentView.post(mInvalidateParentViewRunnable);
80     }
81 
82     /**
83      * Draw the current progress (if < 100%) centered at the given location.
84      */
onDraw(Canvas canvas, int centerX, int centerY)85     public void onDraw(Canvas canvas, int centerX, int centerY) {
86         if (!mVisible) {
87             return;
88         }
89         mArcBounds = new RectF(centerX - mProgressRadius, centerY - mProgressRadius, centerX
90                 + mProgressRadius,
91                 centerY + mProgressRadius);
92 
93         canvas.drawCircle(centerX, centerY, mProgressRadius, mProgressBasePaint);
94         canvas.drawArc(mArcBounds, -90, mProgressAngleDegrees, false, mProgressPaint);
95 
96         // After we reached 100%, we paint the progress renderer for another x
97         // milliseconds until we hide it.
98         if (mProgressAngleDegrees == 360) {
99             mVisible = false;
100             mParentView.postDelayed(
101                 new Runnable() {
102                     @Override
103                     public void run() {
104                         mParentView.invalidate();
105                     }
106                 }, SHOW_PROGRESS_X_ADDITIONAL_MS);
107         }
108     }
109 
110     /**
111      * @return Whether the progress renderer is visible.
112      */
isVisible()113     public boolean isVisible() {
114         return mVisible;
115     }
116 
createProgressPaint(int width, float alpha)117     private static Paint createProgressPaint(int width, float alpha) {
118         Paint paint = new Paint();
119         paint.setAntiAlias(true);
120         // 20% alpha.
121         paint.setColor(Color.argb((int) (alpha * 255), 255, 255, 255));
122         paint.setStrokeWidth(width);
123         paint.setStyle(Paint.Style.STROKE);
124         return paint;
125     }
126 }
127