1ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong/* 2ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * Copyright (C) 2011 The Android Open Source Project 3ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * 4ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * Licensed under the Apache License, Version 2.0 (the "License"); 5ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * you may not use this file except in compliance with the License. 6ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * You may obtain a copy of the License at 7ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * 8ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * http://www.apache.org/licenses/LICENSE-2.0 9ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * 10ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * Unless required by applicable law or agreed to in writing, software 11ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * distributed under the License is distributed on an "AS IS" BASIS, 12ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * See the License for the specific language governing permissions and 14ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong * limitations under the License. 15ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong */ 16ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 17ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongpackage com.android.camera; 18ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 19ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.content.Context; 20ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Canvas; 21ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.Paint; 22ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.graphics.RectF; 23ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.util.AttributeSet; 24ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport android.widget.ImageView; 25ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 26ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongclass PanoProgressBar extends ImageView { 27ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong @SuppressWarnings("unused") 28ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private static final String TAG = "PanoProgressBar"; 29ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public static final int DIRECTION_NONE = 0; 30ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public static final int DIRECTION_LEFT = 1; 31ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public static final int DIRECTION_RIGHT = 2; 32ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mProgress = 0; 33ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mMaxProgress = 0; 34ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mLeftMostProgress = 0; 35ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mRightMostProgress = 0; 36ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mProgressOffset = 0; 37ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mIndicatorWidth = 0; 38ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private int mDirection = 0; 39ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private final Paint mBackgroundPaint = new Paint(); 40ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private final Paint mDoneAreaPaint = new Paint(); 41ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private final Paint mIndicatorPaint = new Paint(); 42ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mWidth; 43ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private float mHeight; 44ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private RectF mDrawBounds; 45ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private OnDirectionChangeListener mListener = null; 46ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 47ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public interface OnDirectionChangeListener { 48ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void onDirectionChange(int direction); 49ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 50ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 51ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public PanoProgressBar(Context context, AttributeSet attrs) { 52ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong super(context, attrs); 53ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDoneAreaPaint.setStyle(Paint.Style.FILL); 54ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDoneAreaPaint.setAlpha(0xff); 55ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 56ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mBackgroundPaint.setStyle(Paint.Style.FILL); 57ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mBackgroundPaint.setAlpha(0xff); 58ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 59ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mIndicatorPaint.setStyle(Paint.Style.FILL); 60ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mIndicatorPaint.setAlpha(0xff); 61ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 62ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDrawBounds = new RectF(); 63ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 64ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 65ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setOnDirectionChangeListener(OnDirectionChangeListener l) { 66ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mListener = l; 67ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 68ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 69ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong private void setDirection(int direction) { 70ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection != direction) { 71ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDirection = direction; 72ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mListener != null) { 73ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mListener.onDirectionChange(mDirection); 74ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 75ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 76ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 77ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 78ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 79ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public int getDirection() { 80ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong return mDirection; 81ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 82ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 83ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong @Override 84ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setBackgroundColor(int color) { 85ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mBackgroundPaint.setColor(color); 86ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 87ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 88ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 89ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setDoneColor(int color) { 90ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDoneAreaPaint.setColor(color); 91ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 92ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 93ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 94ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setIndicatorColor(int color) { 95ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mIndicatorPaint.setColor(color); 96ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 97ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 98ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 99ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong @Override 100ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong protected void onSizeChanged(int w, int h, int oldw, int oldh) { 101ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mWidth = w; 102ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mHeight = h; 103ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDrawBounds.set(0, 0, mWidth, mHeight); 104ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 105ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 106ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setMaxProgress(int progress) { 107ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mMaxProgress = progress; 108ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 109ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 110ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setIndicatorWidth(float w) { 111ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mIndicatorWidth = w; 112ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 113ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 114ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 115ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setRightIncreasing(boolean rightIncreasing) { 116ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (rightIncreasing) { 117ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mLeftMostProgress = 0; 118ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mRightMostProgress = 0; 119ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mProgressOffset = 0; 120ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong setDirection(DIRECTION_RIGHT); 121ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } else { 122ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mLeftMostProgress = mWidth; 123ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mRightMostProgress = mWidth; 124ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mProgressOffset = mWidth; 125ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong setDirection(DIRECTION_LEFT); 126ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 127ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 128ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 129ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 130ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void setProgress(int progress) { 131ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // The panning direction will be decided after user pan more than 10 degrees in one 132ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // direction. 133ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection == DIRECTION_NONE) { 134ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (progress > 10) { 135ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong setRightIncreasing(true); 136ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } else if (progress < -10) { 137ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong setRightIncreasing(false); 138ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 139ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 140ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // mDirection might be modified by setRightIncreasing() above. Need to check again. 141ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection != DIRECTION_NONE) { 142ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mProgress = progress * mWidth / mMaxProgress + mProgressOffset; 143ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // value bounds. 144ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mProgress = Math.min(mWidth, Math.max(0, mProgress)); 145ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection == DIRECTION_RIGHT) { 146ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // The right most progress is adjusted. 147ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mRightMostProgress = Math.max(mRightMostProgress, mProgress); 148ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 149ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection == DIRECTION_LEFT) { 150ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // The left most progress is adjusted. 151ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mLeftMostProgress = Math.min(mLeftMostProgress, mProgress); 152ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 153ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 154ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 155ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 156ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 157ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong public void reset() { 158ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mProgress = 0; 159ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mProgressOffset = 0; 160ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong setDirection(DIRECTION_NONE); 161ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong invalidate(); 162ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 163ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 164ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong @Override 165ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong protected void onDraw(Canvas canvas) { 166ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // the background 167ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong canvas.drawRect(mDrawBounds, mBackgroundPaint); 168ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection != DIRECTION_NONE) { 169ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // the progress area 170ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong canvas.drawRect(mLeftMostProgress, mDrawBounds.top, mRightMostProgress, 171ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong mDrawBounds.bottom, mDoneAreaPaint); 172ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // the indication bar 173ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong float l; 174ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong float r; 175ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong if (mDirection == DIRECTION_RIGHT) { 176ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong l = Math.max(mProgress - mIndicatorWidth, 0f); 177ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong r = mProgress; 178ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } else { 179ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong l = mProgress; 180ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong r = Math.min(mProgress + mIndicatorWidth, mWidth); 181ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 182ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong canvas.drawRect(l, mDrawBounds.top, r, mDrawBounds.bottom, mIndicatorPaint); 183ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 184ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong 185ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong // draw the mask image on the top for shaping. 186ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong super.onDraw(canvas); 187ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong } 188ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong} 189