1 /* 2 * Copyright (C) 2012 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.ui; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.graphics.Canvas; 22 import android.graphics.Color; 23 import android.graphics.Paint; 24 import android.graphics.Rect; 25 import android.view.ScaleGestureDetector; 26 27 import com.android.camera.R; 28 29 public class ZoomRenderer extends OverlayRenderer 30 implements ScaleGestureDetector.OnScaleGestureListener { 31 32 private static final String TAG = "CAM_Zoom"; 33 34 private int mMaxZoom; 35 private int mMinZoom; 36 private OnZoomChangedListener mListener; 37 38 private ScaleGestureDetector mDetector; 39 private Paint mPaint; 40 private Paint mTextPaint; 41 private int mCircleSize; 42 private int mCenterX; 43 private int mCenterY; 44 private float mMaxCircle; 45 private float mMinCircle; 46 private int mInnerStroke; 47 private int mOuterStroke; 48 private int mZoomSig; 49 private int mZoomFraction; 50 private Rect mTextBounds; 51 52 public interface OnZoomChangedListener { 53 void onZoomStart(); 54 void onZoomEnd(); 55 void onZoomValueChanged(int index); // only for immediate zoom 56 } 57 58 public ZoomRenderer(Context ctx) { 59 Resources res = ctx.getResources(); 60 mPaint = new Paint(); 61 mPaint.setAntiAlias(true); 62 mPaint.setColor(Color.WHITE); 63 mPaint.setStyle(Paint.Style.STROKE); 64 mTextPaint = new Paint(mPaint); 65 mTextPaint.setStyle(Paint.Style.FILL); 66 mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.zoom_font_size)); 67 mTextPaint.setTextAlign(Paint.Align.LEFT); 68 mTextPaint.setAlpha(192); 69 mInnerStroke = res.getDimensionPixelSize(R.dimen.focus_inner_stroke); 70 mOuterStroke = res.getDimensionPixelSize(R.dimen.focus_outer_stroke); 71 mDetector = new ScaleGestureDetector(ctx, this); 72 mMinCircle = res.getDimensionPixelSize(R.dimen.zoom_ring_min); 73 mTextBounds = new Rect(); 74 setVisible(false); 75 } 76 77 // set from module 78 public void setZoomMax(int zoomMaxIndex) { 79 mMaxZoom = zoomMaxIndex; 80 mMinZoom = 0; 81 } 82 83 public void setZoom(int index) { 84 mCircleSize = (int) (mMinCircle + index * (mMaxCircle - mMinCircle) / (mMaxZoom - mMinZoom)); 85 } 86 87 public void setZoomValue(int value) { 88 value = value / 10; 89 mZoomSig = value / 10; 90 mZoomFraction = value % 10; 91 } 92 93 public void setOnZoomChangeListener(OnZoomChangedListener listener) { 94 mListener = listener; 95 } 96 97 @Override 98 public void layout(int l, int t, int r, int b) { 99 super.layout(l, t, r, b); 100 mCenterX = (r - l) / 2; 101 mCenterY = (b - t) / 2; 102 mMaxCircle = Math.min(getWidth(), getHeight()); 103 mMaxCircle = (mMaxCircle - mMinCircle) / 2; 104 } 105 106 public boolean isScaling() { 107 return mDetector.isInProgress(); 108 } 109 110 @Override 111 public void onDraw(Canvas canvas) { 112 mPaint.setStrokeWidth(mInnerStroke); 113 canvas.drawCircle(mCenterX, mCenterY, mMinCircle, mPaint); 114 canvas.drawCircle(mCenterX, mCenterY, mMaxCircle, mPaint); 115 canvas.drawLine(mCenterX - mMinCircle, mCenterY, 116 mCenterX - mMaxCircle - 4, mCenterY, mPaint); 117 mPaint.setStrokeWidth(mOuterStroke); 118 canvas.drawCircle((float) mCenterX, (float) mCenterY, 119 (float) mCircleSize, mPaint); 120 String txt = mZoomSig+"."+mZoomFraction+"x"; 121 mTextPaint.getTextBounds(txt, 0, txt.length(), mTextBounds); 122 canvas.drawText(txt, mCenterX - mTextBounds.centerX(), mCenterY - mTextBounds.centerY(), 123 mTextPaint); 124 } 125 126 @Override 127 public boolean onScale(ScaleGestureDetector detector) { 128 final float sf = detector.getScaleFactor(); 129 float circle = (int) (mCircleSize * sf * sf); 130 circle = Math.max(mMinCircle, circle); 131 circle = Math.min(mMaxCircle, circle); 132 if (mListener != null && (int) circle != mCircleSize) { 133 mCircleSize = (int) circle; 134 int zoom = mMinZoom + (int) ((mCircleSize - mMinCircle) * (mMaxZoom - mMinZoom) / (mMaxCircle - mMinCircle)); 135 mListener.onZoomValueChanged(zoom); 136 } 137 return true; 138 } 139 140 @Override 141 public boolean onScaleBegin(ScaleGestureDetector detector) { 142 setVisible(true); 143 if (mListener != null) { 144 mListener.onZoomStart(); 145 } 146 update(); 147 return true; 148 } 149 150 @Override 151 public void onScaleEnd(ScaleGestureDetector detector) { 152 setVisible(false); 153 if (mListener != null) { 154 mListener.onZoomEnd(); 155 } 156 } 157 158 } 159