1 /* 2 * Copyright (C) 2014 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.focus; 18 19 import android.graphics.Canvas; 20 import android.graphics.Paint; 21 22 import com.android.camera.ui.motion.InterpolateUtils; 23 import com.android.camera.ui.motion.Invalidator; 24 25 /** 26 * Manual focus ring animation renderer. 27 */ 28 class ManualFocusRing extends FocusRingRenderer { 29 /** 30 * The manual focus ring encapsulates the animation logic for visualizing 31 * a focus event when triggered by a physical screen touch. 32 * 33 * @param invalidator the object to invalidate while running. 34 * @param ringPaint the paint to draw the ring with. 35 * @param exitDurationMillis the fade out time in milliseconds. 36 */ ManualFocusRing(Invalidator invalidator, Paint ringPaint, float exitDurationMillis)37 public ManualFocusRing(Invalidator invalidator, Paint ringPaint, 38 float exitDurationMillis) { 39 super(invalidator, ringPaint, 0.0f, exitDurationMillis); 40 } 41 42 @Override draw(long t, long dt, Canvas canvas)43 public void draw(long t, long dt, Canvas canvas) { 44 float ringRadius = mRingRadius.update(dt); 45 processStates(t); 46 47 if (!isActive()) { 48 return; 49 } 50 51 mInvalidator.invalidate(); 52 int ringAlpha = 255; 53 54 if (mFocusState == FocusState.STATE_FADE_OUT) { 55 float rFade = InterpolateUtils.unitRatio(t, mExitStartMillis, mExitDurationMillis); 56 ringAlpha = (int) InterpolateUtils.lerp(255, 0, mExitOpacityCurve.valueAt(rFade)); 57 } else if (mFocusState == FocusState.STATE_HARD_STOP) { 58 float rFade = InterpolateUtils.unitRatio(t, mHardExitStartMillis, 59 mHardExitDurationMillis); 60 ringAlpha = (int) InterpolateUtils.lerp(255, 0, mExitOpacityCurve.valueAt(rFade)); 61 } else if (mFocusState == FocusState.STATE_INACTIVE) { 62 ringAlpha = 0; 63 } 64 65 mRingPaint.setAlpha(ringAlpha); 66 canvas.drawCircle(getCenterX(), getCenterY(), ringRadius, mRingPaint); 67 } 68 processStates(long t)69 private void processStates(long t) { 70 if (mFocusState == FocusState.STATE_INACTIVE) { 71 return; 72 } 73 74 if (mFocusState == FocusState.STATE_ENTER 75 && (t > mEnterStartMillis + mEnterDurationMillis)) { 76 mFocusState = FocusState.STATE_ACTIVE; 77 } 78 79 if (mFocusState == FocusState.STATE_ACTIVE && !mRingRadius.isActive()) { 80 mFocusState = FocusState.STATE_FADE_OUT; 81 mExitStartMillis = t; 82 } 83 84 if (mFocusState == FocusState.STATE_FADE_OUT && t > mExitStartMillis + mExitDurationMillis) { 85 mFocusState = FocusState.STATE_INACTIVE; 86 } 87 88 if (mFocusState == FocusState.STATE_HARD_STOP 89 && t > mHardExitStartMillis + mHardExitDurationMillis) { 90 mFocusState = FocusState.STATE_INACTIVE; 91 } 92 } 93 } 94