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.systemui.recents.views; 18 19 import android.graphics.Outline; 20 import android.graphics.Rect; 21 import android.view.View; 22 import android.view.ViewDebug; 23 import android.view.ViewOutlineProvider; 24 25 import com.android.systemui.recents.misc.Utilities; 26 27 /* An outline provider that has a clip and outline that can be animated. */ 28 public class AnimateableViewBounds extends ViewOutlineProvider { 29 30 private static final float MIN_ALPHA = 0.1f; 31 private static final float MAX_ALPHA = 0.8f; 32 33 View mSourceView; 34 @ViewDebug.ExportedProperty(category="recents") 35 Rect mClipRect = new Rect(); 36 @ViewDebug.ExportedProperty(category="recents") 37 Rect mClipBounds = new Rect(); 38 @ViewDebug.ExportedProperty(category="recents") 39 Rect mLastClipBounds = new Rect(); 40 @ViewDebug.ExportedProperty(category="recents") 41 int mCornerRadius; 42 @ViewDebug.ExportedProperty(category="recents") 43 float mAlpha = 1f; 44 AnimateableViewBounds(View source, int cornerRadius)45 public AnimateableViewBounds(View source, int cornerRadius) { 46 mSourceView = source; 47 mCornerRadius = cornerRadius; 48 } 49 50 /** 51 * Resets the right and bottom clip for this view. 52 */ reset()53 public void reset() { 54 mClipRect.set(-1, -1, -1, -1); 55 updateClipBounds(); 56 } 57 58 @Override getOutline(View view, Outline outline)59 public void getOutline(View view, Outline outline) { 60 outline.setAlpha(Utilities.mapRange(mAlpha, MIN_ALPHA, MAX_ALPHA)); 61 if (mCornerRadius > 0) { 62 outline.setRoundRect(mClipRect.left, mClipRect.top, 63 mSourceView.getWidth() - mClipRect.right, 64 mSourceView.getHeight() - mClipRect.bottom, 65 mCornerRadius); 66 } else { 67 outline.setRect(mClipRect.left, mClipRect.top, 68 mSourceView.getWidth() - mClipRect.right, 69 mSourceView.getHeight() - mClipRect.bottom); 70 } 71 } 72 73 /** 74 * Sets the view outline alpha. 75 */ setAlpha(float alpha)76 void setAlpha(float alpha) { 77 if (Float.compare(alpha, mAlpha) != 0) { 78 mAlpha = alpha; 79 // TODO, If both clip and alpha change in the same frame, only invalidate once 80 mSourceView.invalidateOutline(); 81 } 82 } 83 84 /** 85 * @return the outline alpha. 86 */ getAlpha()87 public float getAlpha() { 88 return mAlpha; 89 } 90 91 /** Sets the top clip. */ setClipTop(int top)92 public void setClipTop(int top) { 93 mClipRect.top = top; 94 updateClipBounds(); 95 } 96 97 /** Returns the top clip. */ getClipTop()98 public int getClipTop() { 99 return mClipRect.top; 100 } 101 102 /** Sets the bottom clip. */ setClipBottom(int bottom)103 public void setClipBottom(int bottom) { 104 mClipRect.bottom = bottom; 105 updateClipBounds(); 106 } 107 108 /** Returns the bottom clip. */ getClipBottom()109 public int getClipBottom() { 110 return mClipRect.bottom; 111 } 112 updateClipBounds()113 private void updateClipBounds() { 114 mClipBounds.set(Math.max(0, mClipRect.left), Math.max(0, mClipRect.top), 115 mSourceView.getWidth() - Math.max(0, mClipRect.right), 116 mSourceView.getHeight() - Math.max(0, mClipRect.bottom)); 117 if (!mLastClipBounds.equals(mClipBounds)) { 118 mSourceView.setClipBounds(mClipBounds); 119 // TODO, If both clip and alpha change in the same frame, only invalidate once 120 mSourceView.invalidateOutline(); 121 mLastClipBounds.set(mClipBounds); 122 } 123 } 124 } 125