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