1 /*
2  * Copyright (C) 2021 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 package com.android.launcher3.taskbar;
17 
18 import android.content.Context;
19 import android.graphics.Canvas;
20 import android.graphics.Paint;
21 import android.graphics.Path;
22 import android.util.AttributeSet;
23 import android.view.View;
24 
25 /**
26  * View that handles scrimming the taskbar and the inverted corners it draws. The scrim is used
27  * when bubbles is expanded.
28  */
29 public class TaskbarScrimView extends View {
30     private final Paint mTaskbarScrimPaint;
31     private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath;
32 
33     private boolean mShowScrim;
34     private float mLeftCornerRadius, mRightCornerRadius;
35     private float mBackgroundHeight;
36 
TaskbarScrimView(Context context)37     public TaskbarScrimView(Context context) {
38         this(context, null);
39     }
40 
TaskbarScrimView(Context context, AttributeSet attrs)41     public TaskbarScrimView(Context context, AttributeSet attrs) {
42         this(context, attrs, 0);
43     }
44 
TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr)45     public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
46         this(context, attrs, defStyleAttr, 0);
47     }
48 
TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)49     public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr,
50             int defStyleRes) {
51         super(context, attrs, defStyleAttr, defStyleRes);
52 
53         mTaskbarScrimPaint = new Paint();
54         mTaskbarScrimPaint.setColor(getResources().getColor(android.R.color.system_neutral1_1000));
55         mTaskbarScrimPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
56         mTaskbarScrimPaint.setStyle(Paint.Style.FILL);
57 
58         mInvertedLeftCornerPath = new Path();
59         mInvertedRightCornerPath = new Path();
60     }
61 
62     @Override
onDraw(Canvas canvas)63     protected void onDraw(Canvas canvas) {
64         super.onDraw(canvas);
65 
66         if (mShowScrim) {
67             canvas.save();
68             canvas.translate(0, canvas.getHeight() - mBackgroundHeight);
69 
70             // Scrim the taskbar itself.
71             canvas.drawRect(0, 0, canvas.getWidth(), mBackgroundHeight, mTaskbarScrimPaint);
72 
73             // Scrim the inverted rounded corners above the taskbar.
74             canvas.translate(0, -mLeftCornerRadius);
75             canvas.drawPath(mInvertedLeftCornerPath, mTaskbarScrimPaint);
76             canvas.translate(0, mLeftCornerRadius);
77             canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius);
78             canvas.drawPath(mInvertedRightCornerPath, mTaskbarScrimPaint);
79 
80             canvas.restore();
81         }
82     }
83 
84     /**
85      * Sets the height of the taskbar background.
86      * @param height the height of the background.
87      */
setBackgroundHeight(float height)88     protected void setBackgroundHeight(float height) {
89         mBackgroundHeight = height;
90         if (mShowScrim) {
91             invalidate();
92         }
93     }
94 
95     /**
96      * Sets the alpha of the taskbar scrim.
97      * @param alpha the alpha of the scrim.
98      */
setScrimAlpha(float alpha)99     protected void setScrimAlpha(float alpha) {
100         mShowScrim = alpha > 0f;
101         mTaskbarScrimPaint.setAlpha((int) (alpha * 255));
102         invalidate();
103     }
104 
105     /**
106      * Sets the radius of the left and right corners above the taskbar.
107      * @param leftCornerRadius the radius of the left corner.
108      * @param rightCornerRadius the radius of the right corner.
109      */
setCornerSizes(float leftCornerRadius, float rightCornerRadius)110     protected void setCornerSizes(float leftCornerRadius, float rightCornerRadius) {
111         mLeftCornerRadius = leftCornerRadius;
112         mRightCornerRadius = rightCornerRadius;
113 
114         Path square = new Path();
115         square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW);
116         Path circle = new Path();
117         circle.addCircle(mLeftCornerRadius, 0, mLeftCornerRadius, Path.Direction.CW);
118         mInvertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE);
119         square.reset();
120         square.addRect(0, 0, mRightCornerRadius, mRightCornerRadius, Path.Direction.CW);
121         circle.reset();
122         circle.addCircle(0, 0, mRightCornerRadius, Path.Direction.CW);
123         mInvertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE);
124 
125         if (mShowScrim) {
126             invalidate();
127         }
128     }
129 }
130