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