• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.bubbles
17 
18 import android.graphics.Canvas
19 import android.graphics.Color
20 import android.graphics.ColorFilter
21 import android.graphics.Paint
22 import android.graphics.drawable.Drawable
23 import android.graphics.drawable.ShapeDrawable
24 import com.android.app.animation.Interpolators
25 import com.android.launcher3.R
26 import com.android.launcher3.Utilities
27 import com.android.launcher3.Utilities.mapToRange
28 import com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound
29 import com.android.launcher3.taskbar.TaskbarActivityContext
30 import com.android.wm.shell.common.TriangleShape
31 
32 /** Drawable for the background of the bubble bar. */
33 class BubbleBarBackground(context: TaskbarActivityContext, private val backgroundHeight: Float) :
34     Drawable() {
35 
36     private val DARK_THEME_SHADOW_ALPHA = 51f
37     private val LIGHT_THEME_SHADOW_ALPHA = 25f
38 
39     private val paint: Paint = Paint()
40     private val pointerSize: Float
41 
42     private val shadowAlpha: Float
43     private var shadowBlur = 0f
44     private var keyShadowDistance = 0f
45 
46     var arrowPositionX: Float = 0f
47         private set
48     private var showingArrow: Boolean = false
49     private var arrowDrawable: ShapeDrawable
50 
51     var width: Float = 0f
52 
53     init {
54         paint.color = context.getColor(R.color.taskbar_background)
55         paint.flags = Paint.ANTI_ALIAS_FLAG
56         paint.style = Paint.Style.FILL
57 
58         val res = context.resources
59         shadowBlur = res.getDimension(R.dimen.transient_taskbar_shadow_blur)
60         keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance)
61         pointerSize = res.getDimension(R.dimen.bubblebar_pointer_size)
62 
63         shadowAlpha =
64             if (Utilities.isDarkTheme(context)) {
65                 DARK_THEME_SHADOW_ALPHA
66             } else {
67                 LIGHT_THEME_SHADOW_ALPHA
68             }
69 
70         arrowDrawable =
71             ShapeDrawable(TriangleShape.create(pointerSize, pointerSize, /* pointUp= */ true))
72         arrowDrawable.setBounds(0, 0, pointerSize.toInt(), pointerSize.toInt())
73         arrowDrawable.paint.flags = Paint.ANTI_ALIAS_FLAG
74         arrowDrawable.paint.style = Paint.Style.FILL
75         arrowDrawable.paint.color = context.getColor(R.color.taskbar_background)
76     }
77 
showArrownull78     fun showArrow(show: Boolean) {
79         showingArrow = show
80     }
81 
setArrowPositionnull82     fun setArrowPosition(x: Float) {
83         arrowPositionX = x
84     }
85 
86     /** Draws the background with the given paint and height, on the provided canvas. */
drawnull87     override fun draw(canvas: Canvas) {
88         canvas.save()
89 
90         // TODO (b/277359345): Should animate the alpha similar to taskbar (see TaskbarDragLayer)
91         // Draw shadows.
92         val newShadowAlpha =
93             mapToRange(paint.alpha.toFloat(), 0f, 255f, 0f, shadowAlpha, Interpolators.LINEAR)
94         paint.setShadowLayer(
95             shadowBlur,
96             0f,
97             keyShadowDistance,
98             setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
99         )
100         arrowDrawable.paint.setShadowLayer(
101             shadowBlur,
102             0f,
103             keyShadowDistance,
104             setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
105         )
106 
107         // Draw background.
108         val radius = backgroundHeight / 2f
109         canvas.drawRoundRect(
110             canvas.width.toFloat() - width,
111             0f,
112             canvas.width.toFloat(),
113             canvas.height.toFloat(),
114             radius,
115             radius,
116             paint
117         )
118 
119         if (showingArrow) {
120             // Draw arrow.
121             val transX = arrowPositionX - pointerSize / 2f
122             canvas.translate(transX, -pointerSize)
123             arrowDrawable.draw(canvas)
124         }
125 
126         canvas.restore()
127     }
128 
getOpacitynull129     override fun getOpacity(): Int {
130         return paint.alpha
131     }
132 
setAlphanull133     override fun setAlpha(alpha: Int) {
134         paint.alpha = alpha
135     }
136 
setColorFilternull137     override fun setColorFilter(colorFilter: ColorFilter?) {
138         paint.colorFilter = colorFilter
139     }
140 
setArrowAlphanull141     fun setArrowAlpha(alpha: Int) {
142         arrowDrawable.paint.alpha = alpha
143     }
144 }
145