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.icons.mono
17 
18 import android.content.Context
19 import android.graphics.Bitmap
20 import android.graphics.BlendMode.SRC_IN
21 import android.graphics.BlendModeColorFilter
22 import android.graphics.Canvas
23 import android.graphics.Paint
24 import android.graphics.Rect
25 import com.android.launcher3.icons.BitmapInfo
26 import com.android.launcher3.icons.FastBitmapDrawable
27 import com.android.launcher3.icons.R
28 
29 /** Class to handle monochrome themed app icons */
30 class ThemedIconDrawable(constantState: ThemedConstantState) :
31     FastBitmapDrawable(constantState.getBitmap(), constantState.colorFg) {
32     val bitmapInfo = constantState.bitmapInfo
33     private val colorFg = constantState.colorFg
34     private val colorBg = constantState.colorBg
35 
36     // The foreground/monochrome icon for the app
37     private val monoIcon = constantState.mono
38     private val monoFilter = BlendModeColorFilter(colorFg, SRC_IN)
39     private val monoPaint =
<lambda>null40         Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).apply { colorFilter = monoFilter }
41 
42     private val bgBitmap = constantState.whiteShadowLayer
43     private val bgFilter = BlendModeColorFilter(colorBg, SRC_IN)
44     private val mBgPaint =
<lambda>null45         Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).apply { colorFilter = bgFilter }
46 
drawInternalnull47     override fun drawInternal(canvas: Canvas, bounds: Rect) {
48         canvas.drawBitmap(bgBitmap, null, bounds, mBgPaint)
49         canvas.drawBitmap(monoIcon, null, bounds, monoPaint)
50     }
51 
updateFilternull52     override fun updateFilter() {
53         super.updateFilter()
54         val alpha = if (mIsDisabled) (mDisabledAlpha * FULLY_OPAQUE).toInt() else FULLY_OPAQUE
55         mBgPaint.alpha = alpha
56         mBgPaint.setColorFilter(
57             if (mIsDisabled) BlendModeColorFilter(getDisabledColor(colorBg), SRC_IN) else bgFilter
58         )
59 
60         monoPaint.alpha = alpha
61         monoPaint.setColorFilter(
62             if (mIsDisabled) BlendModeColorFilter(getDisabledColor(colorFg), SRC_IN) else monoFilter
63         )
64     }
65 
isThemednull66     override fun isThemed() = true
67 
68     override fun newConstantState() =
69         ThemedConstantState(bitmapInfo, monoIcon, bgBitmap, colorBg, colorFg)
70 
71     override fun getIconColor() = colorFg
72 
73     class ThemedConstantState(
74         val bitmapInfo: BitmapInfo,
75         val mono: Bitmap,
76         val whiteShadowLayer: Bitmap,
77         val colorBg: Int,
78         val colorFg: Int,
79     ) : FastBitmapConstantState(bitmapInfo.icon, bitmapInfo.color) {
80 
81         public override fun createDrawable() = ThemedIconDrawable(this)
82 
83         fun getBitmap(): Bitmap = mBitmap
84     }
85 
86     companion object {
87         const val TAG: String = "ThemedIconDrawable"
88 
89         /** Get an int array representing background and foreground colors for themed icons */
90         @JvmStatic
getColorsnull91         fun getColors(context: Context): IntArray {
92             val res = context.resources
93             return intArrayOf(
94                 res.getColor(R.color.themed_icon_background_color),
95                 res.getColor(R.color.themed_icon_color),
96             )
97         }
98     }
99 }
100