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.camera;
18 
19 import android.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Paint;
22 import android.graphics.RectF;
23 import android.util.AttributeSet;
24 import android.widget.ImageView;
25 
26 import com.android.camera.debug.Log;
27 
28 class PanoProgressBar extends ImageView {
29     @SuppressWarnings("unused")
30     private static final Log.Tag TAG = new Log.Tag("PanoProgressBar");
31     public static final int DIRECTION_NONE = 0;
32     public static final int DIRECTION_LEFT = 1;
33     public static final int DIRECTION_RIGHT = 2;
34     private float mProgress = 0;
35     private float mMaxProgress = 0;
36     private float mLeftMostProgress = 0;
37     private float mRightMostProgress = 0;
38     private float mProgressOffset = 0;
39     private float mIndicatorWidth = 0;
40     private int mDirection = 0;
41     private final Paint mBackgroundPaint = new Paint();
42     private final Paint mDoneAreaPaint = new Paint();
43     private final Paint mIndicatorPaint = new Paint();
44     private float mWidth;
45     private float mHeight;
46     private RectF mDrawBounds;
47     private OnDirectionChangeListener mListener = null;
48 
49     public interface OnDirectionChangeListener {
onDirectionChange(int direction)50         public void onDirectionChange(int direction);
51     }
52 
PanoProgressBar(Context context, AttributeSet attrs)53     public PanoProgressBar(Context context, AttributeSet attrs) {
54         super(context, attrs);
55         mDoneAreaPaint.setStyle(Paint.Style.FILL);
56         mDoneAreaPaint.setAlpha(0xff);
57 
58         mBackgroundPaint.setStyle(Paint.Style.FILL);
59         mBackgroundPaint.setAlpha(0xff);
60 
61         mIndicatorPaint.setStyle(Paint.Style.FILL);
62         mIndicatorPaint.setAlpha(0xff);
63 
64         mDrawBounds = new RectF();
65     }
66 
setOnDirectionChangeListener(OnDirectionChangeListener l)67     public void setOnDirectionChangeListener(OnDirectionChangeListener l) {
68         mListener = l;
69     }
70 
setDirection(int direction)71     private void setDirection(int direction) {
72         if (mDirection != direction) {
73             mDirection = direction;
74             if (mListener != null) {
75                 mListener.onDirectionChange(mDirection);
76             }
77             invalidate();
78         }
79     }
80 
getDirection()81     public int getDirection() {
82         return mDirection;
83     }
84 
85     @Override
setBackgroundColor(int color)86     public void setBackgroundColor(int color) {
87         mBackgroundPaint.setColor(color);
88         invalidate();
89     }
90 
setDoneColor(int color)91     public void setDoneColor(int color) {
92         mDoneAreaPaint.setColor(color);
93         invalidate();
94     }
95 
setIndicatorColor(int color)96     public void setIndicatorColor(int color) {
97         mIndicatorPaint.setColor(color);
98         invalidate();
99     }
100 
101     @Override
onSizeChanged(int w, int h, int oldw, int oldh)102     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
103         mWidth = w;
104         mHeight = h;
105         mDrawBounds.set(0, 0, mWidth, mHeight);
106     }
107 
setMaxProgress(int progress)108     public void setMaxProgress(int progress) {
109         mMaxProgress = progress;
110     }
111 
setIndicatorWidth(float w)112     public void setIndicatorWidth(float w) {
113         mIndicatorWidth = w;
114         invalidate();
115     }
116 
setRightIncreasing(boolean rightIncreasing)117     public void setRightIncreasing(boolean rightIncreasing) {
118         if (rightIncreasing) {
119             mLeftMostProgress = 0;
120             mRightMostProgress = 0;
121             mProgressOffset = 0;
122             setDirection(DIRECTION_RIGHT);
123         } else {
124             mLeftMostProgress = mWidth;
125             mRightMostProgress = mWidth;
126             mProgressOffset = mWidth;
127             setDirection(DIRECTION_LEFT);
128         }
129         invalidate();
130     }
131 
setProgress(int progress)132     public void setProgress(int progress) {
133         // The panning direction will be decided after user pan more than 10 degrees in one
134         // direction.
135         if (mDirection == DIRECTION_NONE) {
136             if (progress > 10) {
137                 setRightIncreasing(true);
138             } else if (progress < -10) {
139                 setRightIncreasing(false);
140             }
141         }
142         // mDirection might be modified by setRightIncreasing() above. Need to check again.
143         if (mDirection != DIRECTION_NONE) {
144             mProgress = progress * mWidth / mMaxProgress + mProgressOffset;
145             // value bounds.
146             mProgress = Math.min(mWidth, Math.max(0, mProgress));
147             if (mDirection == DIRECTION_RIGHT) {
148                 // The right most progress is adjusted.
149                 mRightMostProgress = Math.max(mRightMostProgress, mProgress);
150             }
151             if (mDirection == DIRECTION_LEFT) {
152                 // The left most progress is adjusted.
153                 mLeftMostProgress = Math.min(mLeftMostProgress, mProgress);
154             }
155             invalidate();
156         }
157     }
158 
reset()159     public void reset() {
160         mProgress = 0;
161         mProgressOffset = 0;
162         setDirection(DIRECTION_NONE);
163         invalidate();
164     }
165 
166     @Override
onDraw(Canvas canvas)167     protected void onDraw(Canvas canvas) {
168         // the background
169         canvas.drawRect(mDrawBounds, mBackgroundPaint);
170         if (mDirection != DIRECTION_NONE) {
171             // the progress area
172             canvas.drawRect(mLeftMostProgress, mDrawBounds.top, mRightMostProgress,
173                     mDrawBounds.bottom, mDoneAreaPaint);
174             // the indication bar
175             float l;
176             float r;
177             if (mDirection == DIRECTION_RIGHT) {
178                 l = Math.max(mProgress - mIndicatorWidth, 0f);
179                 r = mProgress;
180             } else {
181                 l = mProgress;
182                 r = Math.min(mProgress + mIndicatorWidth, mWidth);
183             }
184             canvas.drawRect(l, mDrawBounds.top, r, mDrawBounds.bottom, mIndicatorPaint);
185         }
186 
187         // draw the mask image on the top for shaping.
188         super.onDraw(canvas);
189     }
190 }
191