FocusOverlay.java revision c0fe0b6915004303a550047e68a2124edae9fdb2
1482de029dc20e0a577388a602985fb31c3200309Doris Liu/*
2482de029dc20e0a577388a602985fb31c3200309Doris Liu * Copyright (C) 2013 The Android Open Source Project
3482de029dc20e0a577388a602985fb31c3200309Doris Liu *
4482de029dc20e0a577388a602985fb31c3200309Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
5482de029dc20e0a577388a602985fb31c3200309Doris Liu * you may not use this file except in compliance with the License.
6482de029dc20e0a577388a602985fb31c3200309Doris Liu * You may obtain a copy of the License at
7482de029dc20e0a577388a602985fb31c3200309Doris Liu *
8482de029dc20e0a577388a602985fb31c3200309Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
9482de029dc20e0a577388a602985fb31c3200309Doris Liu *
10482de029dc20e0a577388a602985fb31c3200309Doris Liu * Unless required by applicable law or agreed to in writing, software
11482de029dc20e0a577388a602985fb31c3200309Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
12482de029dc20e0a577388a602985fb31c3200309Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13482de029dc20e0a577388a602985fb31c3200309Doris Liu * See the License for the specific language governing permissions and
14482de029dc20e0a577388a602985fb31c3200309Doris Liu * limitations under the License.
15482de029dc20e0a577388a602985fb31c3200309Doris Liu */
16482de029dc20e0a577388a602985fb31c3200309Doris Liu
17482de029dc20e0a577388a602985fb31c3200309Doris Liupackage com.android.camera.ui;
18482de029dc20e0a577388a602985fb31c3200309Doris Liu
19482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.animation.ValueAnimator;
20482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.content.Context;
21482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.graphics.Canvas;
22482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.graphics.Rect;
23482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.graphics.drawable.Drawable;
24482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.util.AttributeSet;
25482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.view.View;
26482de029dc20e0a577388a602985fb31c3200309Doris Liu
27482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera.FocusOverlayManager;
2810c5816e1ff3d30e4c4996643ba05d63d522b81aAndy Huibersimport com.android.camera.debug.Log;
29482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera2.R;
30482de029dc20e0a577388a602985fb31c3200309Doris Liu
31482de029dc20e0a577388a602985fb31c3200309Doris Liu/**
3215b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu * Displays a focus indicator.
33482de029dc20e0a577388a602985fb31c3200309Doris Liu */
34482de029dc20e0a577388a602985fb31c3200309Doris Liupublic class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
3510c5816e1ff3d30e4c4996643ba05d63d522b81aAndy Huibers    private static final Log.Tag TAG = new Log.Tag("FocusOverlay");
36482de029dc20e0a577388a602985fb31c3200309Doris Liu
37482de029dc20e0a577388a602985fb31c3200309Doris Liu    private final static int FOCUS_DURATION_MS = 500;
38482de029dc20e0a577388a602985fb31c3200309Doris Liu    private final static int FOCUS_INDICATOR_ROTATION_DEGREES = 50;
3915b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu
4015b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu    private final Drawable mFocusIndicator;
41dfe96eac810876659f831d2c9054f33b698916e7Doris Liu    private final Drawable mFocusOuterRing;
4215b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu    private final Rect mBounds = new Rect();
4315b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu    private final ValueAnimator mFocusAnimation = new ValueAnimator();
4415b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu
45482de029dc20e0a577388a602985fb31c3200309Doris Liu    private int mPositionX;
46482de029dc20e0a577388a602985fb31c3200309Doris Liu    private int mPositionY;
47482de029dc20e0a577388a602985fb31c3200309Doris Liu    private int mAngle;
48dfe96eac810876659f831d2c9054f33b698916e7Doris Liu    private final int mFocusIndicatorSize;
49482de029dc20e0a577388a602985fb31c3200309Doris Liu    private boolean mShowIndicator;
50dfe96eac810876659f831d2c9054f33b698916e7Doris Liu    private final int mFocusOuterRingSize;
51482de029dc20e0a577388a602985fb31c3200309Doris Liu
52482de029dc20e0a577388a602985fb31c3200309Doris Liu    public FocusOverlay(Context context, AttributeSet attrs) {
53482de029dc20e0a577388a602985fb31c3200309Doris Liu        super(context, attrs);
54c5d230b407a4e8cbc029f1eaeb5f759f8ae2d0a9Doris Liu        mFocusIndicator = getResources().getDrawable(R.drawable.focus_ring_touch_inner);
55dfe96eac810876659f831d2c9054f33b698916e7Doris Liu        mFocusIndicatorSize = getResources().getDimensionPixelSize(R.dimen.focus_inner_ring_size);
56c5d230b407a4e8cbc029f1eaeb5f759f8ae2d0a9Doris Liu        mFocusOuterRing = getResources().getDrawable(R.drawable.focus_ring_touch_outer);
57dfe96eac810876659f831d2c9054f33b698916e7Doris Liu        mFocusOuterRingSize = getResources().getDimensionPixelSize(R.dimen.focus_outer_ring_size);
58482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
59482de029dc20e0a577388a602985fb31c3200309Doris Liu
60482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
61482de029dc20e0a577388a602985fb31c3200309Doris Liu    public boolean hasFaces() {
6215b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu        // TODO: Add face detection support.
63482de029dc20e0a577388a602985fb31c3200309Doris Liu        return false;
64482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
65482de029dc20e0a577388a602985fb31c3200309Doris Liu
66482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
67482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void clearFocus() {
68482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = false;
69482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
70482de029dc20e0a577388a602985fb31c3200309Doris Liu
71482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
72c0fe0b6915004303a550047e68a2124edae9fdb2Andy Huibers    public void setFocusPosition(int x, int y, boolean isPassiveScan) {
73482de029dc20e0a577388a602985fb31c3200309Doris Liu        mPositionX = x;
74482de029dc20e0a577388a602985fb31c3200309Doris Liu        mPositionY = y;
75482de029dc20e0a577388a602985fb31c3200309Doris Liu        mBounds.set(x - mFocusIndicatorSize / 2, y - mFocusIndicatorSize / 2,
76482de029dc20e0a577388a602985fb31c3200309Doris Liu                x + mFocusIndicatorSize / 2, y + mFocusIndicatorSize / 2);
77482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusIndicator.setBounds(mBounds);
78dfe96eac810876659f831d2c9054f33b698916e7Doris Liu        mFocusOuterRing.setBounds(x - mFocusOuterRingSize / 2, y - mFocusOuterRingSize / 2,
79dfe96eac810876659f831d2c9054f33b698916e7Doris Liu                x + mFocusOuterRingSize / 2, y + mFocusOuterRingSize / 2);
80af65683681dbbb98063363ee776f5d357a7b5de5Doris Liu        if (getVisibility() != VISIBLE) {
81af65683681dbbb98063363ee776f5d357a7b5de5Doris Liu            setVisibility(VISIBLE);
82af65683681dbbb98063363ee776f5d357a7b5de5Doris Liu        }
83482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
84482de029dc20e0a577388a602985fb31c3200309Doris Liu
85482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
86482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void onFocusStarted() {
87482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = true;
88482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.setIntValues(0, FOCUS_INDICATOR_ROTATION_DEGREES);
89482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.setDuration(FOCUS_DURATION_MS);
90482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
91482de029dc20e0a577388a602985fb31c3200309Doris Liu            @Override
92482de029dc20e0a577388a602985fb31c3200309Doris Liu            public void onAnimationUpdate(ValueAnimator animation) {
93482de029dc20e0a577388a602985fb31c3200309Doris Liu                mAngle = (Integer) animation.getAnimatedValue();
94482de029dc20e0a577388a602985fb31c3200309Doris Liu                invalidate();
95482de029dc20e0a577388a602985fb31c3200309Doris Liu            }
96482de029dc20e0a577388a602985fb31c3200309Doris Liu        });
97482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.start();
98482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
99482de029dc20e0a577388a602985fb31c3200309Doris Liu
100482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
101e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling    public void onFocusSucceeded() {
102482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.cancel();
103482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = false;
104482de029dc20e0a577388a602985fb31c3200309Doris Liu        invalidate();
105482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
106482de029dc20e0a577388a602985fb31c3200309Doris Liu
107482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
108e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling    public void onFocusFailed() {
109482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.cancel();
110482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = false;
111482de029dc20e0a577388a602985fb31c3200309Doris Liu        invalidate();
112482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
113482de029dc20e0a577388a602985fb31c3200309Doris Liu
114482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
115482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void pauseFaceDetection() {
11615b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu        // TODO: Add face detection support.
117482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
118482de029dc20e0a577388a602985fb31c3200309Doris Liu
119482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
120482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void resumeFaceDetection() {
12115b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu        // TODO: Add face detection support.
122482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
123482de029dc20e0a577388a602985fb31c3200309Doris Liu
124e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling    @Override
125482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void onDraw(Canvas canvas) {
126482de029dc20e0a577388a602985fb31c3200309Doris Liu        super.onDraw(canvas);
127482de029dc20e0a577388a602985fb31c3200309Doris Liu
128c0fe0b6915004303a550047e68a2124edae9fdb2Andy Huibers        if (mShowIndicator) {
129dfe96eac810876659f831d2c9054f33b698916e7Doris Liu            mFocusOuterRing.draw(canvas);
130482de029dc20e0a577388a602985fb31c3200309Doris Liu            canvas.save();
131482de029dc20e0a577388a602985fb31c3200309Doris Liu            canvas.rotate(mAngle, mPositionX, mPositionY);
132482de029dc20e0a577388a602985fb31c3200309Doris Liu            mFocusIndicator.draw(canvas);
133482de029dc20e0a577388a602985fb31c3200309Doris Liu            canvas.restore();
134482de029dc20e0a577388a602985fb31c3200309Doris Liu        }
135482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
136482de029dc20e0a577388a602985fb31c3200309Doris Liu}
137