• 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                 canvas.drawRect(left, top, right, top + length, mFadePaint);
146 
147                 if (mBlackPaint == null) {
148                     // Draw under the status bar at the top
149                     mBlackPaint = new Paint();
150                     mBlackPaint.setColor(0xFF000000);
151                 }
152                 canvas.drawRect(left, top - mPaddingTop, right, top, mBlackPaint);
153             }
154 
155             if (drawBottom) {
156                 mFadeMatrix.setScale(1, fadeHeight * bottomFadeStrength);
157                 mFadeMatrix.postRotate(180);
158                 mFadeMatrix.postTranslate(left, bottom);
159                 mFade.setLocalMatrix(mFadeMatrix);
160                 canvas.drawRect(left, bottom - length, right, bottom, mFadePaint);
161             }
162 
163             if (drawLeft) {
164                 mFadeMatrix.setScale(1, fadeHeight * leftFadeStrength);
165                 mFadeMatrix.postRotate(-90);
166                 mFadeMatrix.postTranslate(left, top);
167                 mFade.setLocalMatrix(mFadeMatrix);
168                 canvas.drawRect(left, top, left + length, bottom, mFadePaint);
169             }
170 
171             if (drawRight) {
172                 mFadeMatrix.setScale(1, fadeHeight * rightFadeStrength);
173                 mFadeMatrix.postRotate(90);
174                 mFadeMatrix.postTranslate(right, top);
175                 mFade.setLocalMatrix(mFadeMatrix);
176                 canvas.drawRect(right - length, top, right, bottom, mFadePaint);
177             }
178         }
179     }
180 
getVerticalFadingEdgeLength()181     public int getVerticalFadingEdgeLength() {
182         return mFadingEdgeLength;
183     }
184 
getHorizontalFadingEdgeLength()185     public int getHorizontalFadingEdgeLength() {
186         return mFadingEdgeLength;
187     }
188 
189 }
190