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