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 {
onZoomStart()53         void onZoomStart();
onZoomEnd()54         void onZoomEnd();
onZoomValueChanged(int index)55         void onZoomValueChanged(int index);  // only for immediate zoom
56     }
57 
ZoomRenderer(Context ctx)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
setZoomMax(int zoomMaxIndex)78     public void setZoomMax(int zoomMaxIndex) {
79         mMaxZoom = zoomMaxIndex;
80         mMinZoom = 0;
81     }
82 
setZoom(int index)83     public void setZoom(int index) {
84         mCircleSize = (int) (mMinCircle + index * (mMaxCircle - mMinCircle) / (mMaxZoom - mMinZoom));
85     }
86 
setZoomValue(int value)87     public void setZoomValue(int value) {
88         value = value / 10;
89         mZoomSig = value / 10;
90         mZoomFraction = value % 10;
91     }
92 
setOnZoomChangeListener(OnZoomChangedListener listener)93     public void setOnZoomChangeListener(OnZoomChangedListener listener) {
94         mListener = listener;
95     }
96 
97     @Override
layout(int l, int t, int r, int b)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 
isScaling()106     public boolean isScaling() {
107         return mDetector.isInProgress();
108     }
109 
110     @Override
onDraw(Canvas canvas)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
onScale(ScaleGestureDetector detector)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
onScaleBegin(ScaleGestureDetector detector)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
onScaleEnd(ScaleGestureDetector detector)151     public void onScaleEnd(ScaleGestureDetector detector) {
152         setVisible(false);
153         if (mListener != null) {
154             mListener.onZoomEnd();
155         }
156     }
157 
158 }
159