1057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong/* 2057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * Copyright (C) 2011 The Android Open Source Project 3057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * 4057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * Licensed under the Apache License, Version 2.0 (the "License"); 5057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * you may not use this file except in compliance with the License. 6057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * You may obtain a copy of the License at 7057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * 8057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * http://www.apache.org/licenses/LICENSE-2.0 9057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * 10057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * Unless required by applicable law or agreed to in writing, software 11057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * distributed under the License is distributed on an "AS IS" BASIS, 12057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * See the License for the specific language governing permissions and 14057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong * limitations under the License. 15057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong */ 16057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 17057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongpackage com.android.camera.panorama; 18057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 19057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongimport android.content.Context; 20057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongimport android.graphics.Canvas; 21057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongimport android.graphics.Paint; 22057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongimport android.graphics.RectF; 23057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongimport android.util.AttributeSet; 24057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongimport android.widget.ImageView; 25057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 26057040c0e19834d98719143c2627a9f0df3e4c35Angus Kongclass PanoProgressBar extends ImageView { 27057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private static final String TAG = "PanoProgressBar"; 286108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public static final int DIRECTION_NONE = 0; 296108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public static final int DIRECTION_LEFT = 1; 306108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public static final int DIRECTION_RIGHT = 2; 31057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mProgress = 0; 32057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mMaxProgress = 0; 33057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mLeftMostProgress = 0; 34057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mRightMostProgress = 0; 35057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mProgressOffset = 0; 36057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mIndicatorWidth = 0; 376108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong private int mDirection = 0; 38057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private final Paint mBackgroundPaint = new Paint(); 39057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private final Paint mDoneAreaPaint = new Paint(); 40057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private final Paint mIndicatorPaint = new Paint(); 41057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mWidth; 42057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private float mHeight; 43057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong private RectF mDrawBounds; 446108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong private OnDirectionChangeListener mListener = null; 456108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong 466108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public interface OnDirectionChangeListener { 476108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public void onDirectionChange(int direction); 486108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong } 49057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 50057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public PanoProgressBar(Context context, AttributeSet attrs) { 51057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong super(context, attrs); 52057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mDoneAreaPaint.setStyle(Paint.Style.FILL); 53057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mDoneAreaPaint.setAlpha(0xff); 54057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 55057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mBackgroundPaint.setStyle(Paint.Style.FILL); 56057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mBackgroundPaint.setAlpha(0xff); 57057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 58057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mIndicatorPaint.setStyle(Paint.Style.FILL); 59057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mIndicatorPaint.setAlpha(0xff); 60057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 61057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mDrawBounds = new RectF(); 62057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 63057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 646108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public void setOnDirectionChangeListener(OnDirectionChangeListener l) { 656108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong mListener = l; 666108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong } 676108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong 686108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong private void setDirection(int direction) { 69fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong if (mDirection != direction) { 70fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong mDirection = direction; 71fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong if (mListener != null) { 72fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong mListener.onDirectionChange(mDirection); 73fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong } 74fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong invalidate(); 756108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong } 766108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong } 776108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong 786108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong public int getDirection() { 796108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong return mDirection; 806108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong } 816108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong 82057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setBackgroundColor(int color) { 83057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mBackgroundPaint.setColor(color); 84fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong invalidate(); 85057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 86057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 87057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setDoneColor(int color) { 88057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mDoneAreaPaint.setColor(color); 89fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong invalidate(); 90057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 91057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 92057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setIndicatorColor(int color) { 93057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mIndicatorPaint.setColor(color); 94fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong invalidate(); 95057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 96057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 97057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong protected void onSizeChanged(int w, int h, int oldw, int oldh) { 98057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mWidth = w; 99057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mHeight = h; 100057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mDrawBounds.set(0, 0, mWidth, mHeight); 101057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 102057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 103057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setMaxProgress(int progress) { 104057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mMaxProgress = progress; 105057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 106057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 107057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setIndicatorWidth(float w) { 108057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mIndicatorWidth = w; 109fa959aede9b1fe9d510108e883a2f16cf28c9033Angus Kong invalidate(); 110057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 111057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 112057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setRightIncreasing(boolean rightIncreasing) { 113057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (rightIncreasing) { 114057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mLeftMostProgress = 0; 115057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mRightMostProgress = 0; 116057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mProgressOffset = 0; 1176108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong setDirection(DIRECTION_RIGHT); 118057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } else { 119057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mLeftMostProgress = mWidth; 120057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mRightMostProgress = mWidth; 121057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mProgressOffset = mWidth; 1226108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong setDirection(DIRECTION_LEFT); 123057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 124215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong invalidate(); 125057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 126057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 127057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void setProgress(int progress) { 128057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // The panning direction will be decided after user pan more than 10 degrees in one 129057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // direction. 130057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (mDirection == DIRECTION_NONE) { 131057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (progress > 10) { 132057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong setRightIncreasing(true); 133215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong } else if (progress < -10) { 134057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong setRightIncreasing(false); 135057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 136215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong } 137215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong // mDirection might be modified by setRightIncreasing() above. Need to check again. 138215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong if (mDirection != DIRECTION_NONE) { 139057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mProgress = progress * mWidth / mMaxProgress + mProgressOffset; 140057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // value bounds. 141057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mProgress = Math.min(mWidth, Math.max(0, mProgress)); 142057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (mDirection == DIRECTION_RIGHT) { 143057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // The right most progress is adjusted. 144057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mRightMostProgress = Math.max(mRightMostProgress, mProgress); 145057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 146057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (mDirection == DIRECTION_LEFT) { 147057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // The left most progress is adjusted. 148057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mLeftMostProgress = Math.min(mLeftMostProgress, mProgress); 149057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 150215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong invalidate(); 151057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 152057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 153057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 154057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong public void reset() { 155057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mProgress = 0; 156057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mProgressOffset = 0; 1576108e0ed3a6b03deed2a8586d98607a6756637b1Angus Kong setDirection(DIRECTION_NONE); 158215f7ecf1fcc861986397fdf6724602d4775ab2cAngus Kong invalidate(); 159057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 160057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 161057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong @Override 162057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong protected void onDraw(Canvas canvas) { 163057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // the background 164057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong canvas.drawRect(mDrawBounds, mBackgroundPaint); 165057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (mDirection != DIRECTION_NONE) { 166057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // the progress area 167057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong canvas.drawRect(mLeftMostProgress, mDrawBounds.top, mRightMostProgress, 168057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong mDrawBounds.bottom, mDoneAreaPaint); 169057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // the indication bar 170057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong float l; 171057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong float r; 172057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong if (mDirection == DIRECTION_RIGHT) { 173057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong l = Math.max(mProgress - mIndicatorWidth, 0f); 174057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong r = mProgress; 175057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } else { 176057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong l = mProgress; 177057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong r = Math.min(mProgress + mIndicatorWidth, mWidth); 178057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 179057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong canvas.drawRect(l, mDrawBounds.top, r, mDrawBounds.bottom, mIndicatorPaint); 180057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 181057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong 182057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong // draw the mask image on the top for shaping. 183057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong super.onDraw(canvas); 184057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong } 185057040c0e19834d98719143c2627a9f0df3e4c35Angus Kong} 186