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