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 { 47 public void onDirectionChange(int direction); 48 } 49 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 64 public void setOnDirectionChangeListener(OnDirectionChangeListener l) { 65 mListener = l; 66 } 67 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 78 public int getDirection() { 79 return mDirection; 80 } 81 82 public void setBackgroundColor(int color) { 83 mBackgroundPaint.setColor(color); 84 invalidate(); 85 } 86 87 public void setDoneColor(int color) { 88 mDoneAreaPaint.setColor(color); 89 invalidate(); 90 } 91 92 public void setIndicatorColor(int color) { 93 mIndicatorPaint.setColor(color); 94 invalidate(); 95 } 96 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 103 public void setMaxProgress(int progress) { 104 mMaxProgress = progress; 105 } 106 107 public void setIndicatorWidth(float w) { 108 mIndicatorWidth = w; 109 invalidate(); 110 } 111 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 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 154 public void reset() { 155 mProgress = 0; 156 mProgressOffset = 0; 157 setDirection(DIRECTION_NONE); 158 invalidate(); 159 } 160 161 @Override 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