• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.statusbar;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorListenerAdapter;
21 import android.animation.ValueAnimator;
22 import android.content.Context;
23 import android.graphics.Canvas;
24 import android.graphics.Color;
25 import android.graphics.Paint;
26 import android.graphics.PorterDuff;
27 import android.graphics.PorterDuffXfermode;
28 import android.graphics.Rect;
29 import android.util.AttributeSet;
30 import android.view.View;
31 import android.view.animation.Interpolator;
32 
33 /**
34  * A view which can draw a scrim
35  */
36 public class ScrimView extends View
37 {
38     private final Paint mPaint = new Paint();
39     private int mScrimColor;
40     private boolean mIsEmpty = true;
41     private boolean mDrawAsSrc;
42     private float mViewAlpha = 1.0f;
43     private ValueAnimator mAlphaAnimator;
44     private Rect mExcludedRect = new Rect();
45     private int mLeftInset = 0;
46     private boolean mHasExcludedArea;
47     private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
48             = new ValueAnimator.AnimatorUpdateListener() {
49         @Override
50         public void onAnimationUpdate(ValueAnimator animation) {
51             mViewAlpha = (float) animation.getAnimatedValue();
52             invalidate();
53         }
54     };
55     private AnimatorListenerAdapter mClearAnimatorListener = new AnimatorListenerAdapter() {
56         @Override
57         public void onAnimationEnd(Animator animation) {
58             mAlphaAnimator = null;
59         }
60     };
61     private Runnable mChangeRunnable;
62 
ScrimView(Context context)63     public ScrimView(Context context) {
64         this(context, null);
65     }
66 
ScrimView(Context context, AttributeSet attrs)67     public ScrimView(Context context, AttributeSet attrs) {
68         this(context, attrs, 0);
69     }
70 
ScrimView(Context context, AttributeSet attrs, int defStyleAttr)71     public ScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
72         this(context, attrs, defStyleAttr, 0);
73     }
74 
ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)75     public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
76         super(context, attrs, defStyleAttr, defStyleRes);
77     }
78 
79     @Override
onDraw(Canvas canvas)80     protected void onDraw(Canvas canvas) {
81         if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
82             PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
83             int color = getScrimColorWithAlpha();
84             if (!mHasExcludedArea) {
85                 canvas.drawColor(color, mode);
86             } else {
87                 mPaint.setColor(color);
88                 if (mExcludedRect.top > 0) {
89                     canvas.drawRect(0, 0, getWidth(), mExcludedRect.top, mPaint);
90                 }
91                 if (mExcludedRect.left + mLeftInset > 0) {
92                     canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left + mLeftInset,
93                             mExcludedRect.bottom, mPaint);
94                 }
95                 if (mExcludedRect.right + mLeftInset < getWidth()) {
96                     canvas.drawRect(mExcludedRect.right + mLeftInset,
97                             mExcludedRect.top,
98                             getWidth(),
99                             mExcludedRect.bottom,
100                             mPaint);
101                 }
102                 if (mExcludedRect.bottom < getHeight()) {
103                     canvas.drawRect(0,  mExcludedRect.bottom, getWidth(), getHeight(), mPaint);
104                 }
105             }
106         }
107     }
108 
getScrimColorWithAlpha()109     public int getScrimColorWithAlpha() {
110         int color = mScrimColor;
111         color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
112                 Color.green(color), Color.blue(color));
113         return color;
114     }
115 
setDrawAsSrc(boolean asSrc)116     public void setDrawAsSrc(boolean asSrc) {
117         mDrawAsSrc = asSrc;
118         mPaint.setXfermode(new PorterDuffXfermode(mDrawAsSrc ? PorterDuff.Mode.SRC
119                 : PorterDuff.Mode.SRC_OVER));
120         invalidate();
121     }
122 
setScrimColor(int color)123     public void setScrimColor(int color) {
124         if (color != mScrimColor) {
125             mIsEmpty = Color.alpha(color) == 0;
126             mScrimColor = color;
127             invalidate();
128             if (mChangeRunnable != null) {
129                 mChangeRunnable.run();
130             }
131         }
132     }
133 
getScrimColor()134     public int getScrimColor() {
135         return mScrimColor;
136     }
137 
138     @Override
hasOverlappingRendering()139     public boolean hasOverlappingRendering() {
140         return false;
141     }
142 
setViewAlpha(float alpha)143     public void setViewAlpha(float alpha) {
144         if (mAlphaAnimator != null) {
145             mAlphaAnimator.cancel();
146         }
147         if (alpha != mViewAlpha) {
148             mViewAlpha = alpha;
149             invalidate();
150             if (mChangeRunnable != null) {
151                 mChangeRunnable.run();
152             }
153         }
154     }
155 
animateViewAlpha(float alpha, long durationOut, Interpolator interpolator)156     public void animateViewAlpha(float alpha, long durationOut, Interpolator interpolator) {
157         if (mAlphaAnimator != null) {
158             mAlphaAnimator.cancel();
159         }
160         mAlphaAnimator = ValueAnimator.ofFloat(mViewAlpha, alpha);
161         mAlphaAnimator.addUpdateListener(mAlphaUpdateListener);
162         mAlphaAnimator.addListener(mClearAnimatorListener);
163         mAlphaAnimator.setInterpolator(interpolator);
164         mAlphaAnimator.setDuration(durationOut);
165         mAlphaAnimator.start();
166     }
167 
setExcludedArea(Rect area)168     public void setExcludedArea(Rect area) {
169         if (area == null) {
170             mHasExcludedArea = false;
171             invalidate();
172             return;
173         }
174 
175         int left = Math.max(area.left, 0);
176         int top = Math.max(area.top, 0);
177         int right = Math.min(area.right, getWidth());
178         int bottom = Math.min(area.bottom, getHeight());
179         mExcludedRect.set(left, top, right, bottom);
180         mHasExcludedArea = left < right && top < bottom;
181         invalidate();
182     }
183 
184     public void setChangeRunnable(Runnable changeRunnable) {
185         mChangeRunnable = changeRunnable;
186     }
187 
188     public void setLeftInset(int leftInset) {
189         if (mLeftInset != leftInset) {
190             mLeftInset = leftInset;
191 
192             if (mHasExcludedArea) {
193                 invalidate();
194             }
195         }
196     }
197 }
198