• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.recent;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.Canvas;
22 import android.graphics.LinearGradient;
23 import android.graphics.Matrix;
24 import android.graphics.Paint;
25 import android.graphics.Shader;
26 import android.util.AttributeSet;
27 import android.view.View;
28 import android.view.ViewConfiguration;
29 import android.widget.LinearLayout;
30 
31 import com.android.systemui.R;
32 
33 public class FadedEdgeDrawHelper {
34     public static final boolean OPTIMIZE_SW_RENDERED_RECENTS = true;
35     public static final boolean USE_DARK_FADE_IN_HW_ACCELERATED_MODE = true;
36     private View mScrollView;
37 
38     private int mFadingEdgeLength;
39     private boolean mIsVertical;
40     private boolean mSoftwareRendered = false;
41     private Paint mBlackPaint;
42     private Paint mFadePaint;
43     private Matrix mFadeMatrix;
44     private LinearGradient mFade;
45 
create(Context context, AttributeSet attrs, View scrollView, boolean isVertical)46     public static FadedEdgeDrawHelper create(Context context,
47             AttributeSet attrs, View scrollView, boolean isVertical) {
48         boolean isTablet = context.getResources().
49                 getBoolean(R.bool.config_recents_interface_for_tablets);
50         if (!isTablet && (OPTIMIZE_SW_RENDERED_RECENTS || USE_DARK_FADE_IN_HW_ACCELERATED_MODE)) {
51             return new FadedEdgeDrawHelper(context, attrs, scrollView, isVertical);
52         } else {
53             return null;
54         }
55     }
56 
FadedEdgeDrawHelper(Context context, AttributeSet attrs, View scrollView, boolean isVertical)57     public FadedEdgeDrawHelper(Context context,
58             AttributeSet attrs, View scrollView, boolean isVertical) {
59         mScrollView = scrollView;
60         TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View);
61         mFadingEdgeLength = a.getDimensionPixelSize(android.R.styleable.View_fadingEdgeLength,
62                 ViewConfiguration.get(context).getScaledFadingEdgeLength());
63         mIsVertical = isVertical;
64     }
65 
onAttachedToWindowCallback( LinearLayout layout, boolean hardwareAccelerated)66     public void onAttachedToWindowCallback(
67             LinearLayout layout, boolean hardwareAccelerated) {
68         mSoftwareRendered = !hardwareAccelerated;
69         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
70                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
71             mScrollView.setVerticalFadingEdgeEnabled(false);
72             mScrollView.setHorizontalFadingEdgeEnabled(false);
73         }
74     }
75 
addViewCallback(View newLinearLayoutChild)76     public void addViewCallback(View newLinearLayoutChild) {
77         if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
78             final RecentsPanelView.ViewHolder holder =
79                     (RecentsPanelView.ViewHolder) newLinearLayoutChild.getTag();
80             holder.labelView.setDrawingCacheEnabled(true);
81             holder.labelView.buildDrawingCache();
82         }
83     }
84 
drawCallback(Canvas canvas, int left, int right, int top, int bottom, int scrollX, int scrollY, float topFadingEdgeStrength, float bottomFadingEdgeStrength, float leftFadingEdgeStrength, float rightFadingEdgeStrength, int mPaddingTop)85     public void drawCallback(Canvas canvas,
86             int left, int right, int top, int bottom, int scrollX, int scrollY,
87             float topFadingEdgeStrength, float bottomFadingEdgeStrength,
88             float leftFadingEdgeStrength, float rightFadingEdgeStrength, int mPaddingTop) {
89 
90         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
91                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
92             if (mFadePaint == null) {
93                 mFadePaint = new Paint();
94                 mFadeMatrix = new Matrix();
95                 // use use a height of 1, and then wack the matrix each time we
96                 // actually use it.
97                 mFade = new LinearGradient(0, 0, 0, 1, 0xCC000000, 0, Shader.TileMode.CLAMP);
98                 // PULL OUT THIS CONSTANT
99                 mFadePaint.setShader(mFade);
100             }
101 
102             // draw the fade effect
103             boolean drawTop = false;
104             boolean drawBottom = false;
105             boolean drawLeft = false;
106             boolean drawRight = false;
107 
108             float topFadeStrength = 0.0f;
109             float bottomFadeStrength = 0.0f;
110             float leftFadeStrength = 0.0f;
111             float rightFadeStrength = 0.0f;
112 
113             final float fadeHeight = mFadingEdgeLength;
114             int length = (int) fadeHeight;
115 
116             // clip the fade length if top and bottom fades overlap
117             // overlapping fades produce odd-looking artifacts
118             if (mIsVertical && (top + length > bottom - length)) {
119                 length = (bottom - top) / 2;
120             }
121 
122             // also clip horizontal fades if necessary
123             if (!mIsVertical && (left + length > right - length)) {
124                 length = (right - left) / 2;
125             }
126 
127             if (mIsVertical) {
128                 topFadeStrength = Math.max(0.0f, Math.min(1.0f, topFadingEdgeStrength));
129                 drawTop = topFadeStrength * fadeHeight > 1.0f;
130                 bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, bottomFadingEdgeStrength));
131                 drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
132             }
133 
134             if (!mIsVertical) {
135                 leftFadeStrength = Math.max(0.0f, Math.min(1.0f, leftFadingEdgeStrength));
136                 drawLeft = leftFadeStrength * fadeHeight > 1.0f;
137                 rightFadeStrength = Math.max(0.0f, Math.min(1.0f, rightFadingEdgeStrength));
138                 drawRight = rightFadeStrength * fadeHeight > 1.0f;
139             }
140 
141             if (drawTop) {
142                 mFadeMatrix.setScale(1, fadeHeight * topFadeStrength);
143                 mFadeMatrix.postTranslate(left, top);
144                 mFade.setLocalMatrix(mFadeMatrix);
145                 mFadePaint.setShader(mFade);
146                 canvas.drawRect(left, top, right, top + length, mFadePaint);
147 
148                 if (mBlackPaint == null) {
149                     // Draw under the status bar at the top
150                     mBlackPaint = new Paint();
151                     mBlackPaint.setColor(0xFF000000);
152                 }
153                 canvas.drawRect(left, top - mPaddingTop, right, top, mBlackPaint);
154             }
155 
156             if (drawBottom) {
157                 mFadeMatrix.setScale(1, fadeHeight * bottomFadeStrength);
158                 mFadeMatrix.postRotate(180);
159                 mFadeMatrix.postTranslate(left, bottom);
160                 mFade.setLocalMatrix(mFadeMatrix);
161                 mFadePaint.setShader(mFade);
162                 canvas.drawRect(left, bottom - length, right, bottom, mFadePaint);
163             }
164 
165             if (drawLeft) {
166                 mFadeMatrix.setScale(1, fadeHeight * leftFadeStrength);
167                 mFadeMatrix.postRotate(-90);
168                 mFadeMatrix.postTranslate(left, top);
169                 mFade.setLocalMatrix(mFadeMatrix);
170                 mFadePaint.setShader(mFade);
171                 canvas.drawRect(left, top, left + length, bottom, mFadePaint);
172             }
173 
174             if (drawRight) {
175                 mFadeMatrix.setScale(1, fadeHeight * rightFadeStrength);
176                 mFadeMatrix.postRotate(90);
177                 mFadeMatrix.postTranslate(right, top);
178                 mFade.setLocalMatrix(mFadeMatrix);
179                 mFadePaint.setShader(mFade);
180                 canvas.drawRect(right - length, top, right, bottom, mFadePaint);
181             }
182         }
183     }
184 
getVerticalFadingEdgeLength()185     public int getVerticalFadingEdgeLength() {
186         return mFadingEdgeLength;
187     }
188 
getHorizontalFadingEdgeLength()189     public int getHorizontalFadingEdgeLength() {
190         return mFadingEdgeLength;
191     }
192 
193 }
194