1 /* 2 * Copyright (C) 2019 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 18 19 import android.animation.ArgbEvaluator 20 import android.content.Context 21 import android.view.ContextThemeWrapper 22 import com.android.settingslib.Utils 23 24 /** 25 * A color blender for `Theme.SystemUI` and other themes. 26 * 27 * This class is used to handle colors from themes in [Context] in the following fashion: 28 * * The theme associated has a `darkIconTheme` and a `lightIconTheme` 29 * * Each of these themes define colors for the items `singleToneColor`, `backgroundColor`, 30 * and `fillColor`. 31 * 32 * In particular, `Theme.SystemUI` is a valid [Context]. If the provided [Context] does not have 33 * the correct themes, the colors that are not found will default to black. 34 * 35 * It provides a way to obtain these colors and blends for a given background intensity. 36 */ 37 class DualToneHandler(context: Context) { 38 private lateinit var darkColor: Color 39 private lateinit var lightColor: Color 40 41 init { 42 setColorsFromContext(context) 43 } 44 45 /** 46 * Sets the colors in this object from the given [Context] 47 * 48 * @param[context] A context with the appropriate themes to extract the colors from. 49 */ setColorsFromContextnull50 fun setColorsFromContext(context: Context) { 51 val dualToneDarkTheme = ContextThemeWrapper(context, 52 Utils.getThemeAttr(context, R.attr.darkIconTheme)) 53 val dualToneLightTheme = ContextThemeWrapper(context, 54 Utils.getThemeAttr(context, R.attr.lightIconTheme)) 55 darkColor = Color( 56 Utils.getColorAttrDefaultColor(dualToneDarkTheme, R.attr.singleToneColor), 57 Utils.getColorAttrDefaultColor(dualToneDarkTheme, R.attr.backgroundColor), 58 Utils.getColorAttrDefaultColor(dualToneDarkTheme, R.attr.fillColor)) 59 lightColor = Color( 60 Utils.getColorAttrDefaultColor(dualToneLightTheme, R.attr.singleToneColor), 61 Utils.getColorAttrDefaultColor(dualToneLightTheme, R.attr.backgroundColor), 62 Utils.getColorAttrDefaultColor(dualToneLightTheme, R.attr.fillColor)) 63 } 64 getColorForDarkIntensitynull65 private fun getColorForDarkIntensity(darkIntensity: Float, lightColor: Int, darkColor: Int) = 66 ArgbEvaluator.getInstance().evaluate(darkIntensity, lightColor, darkColor) as Int 67 68 /** 69 * Blends the single color associated with the light and dark theme 70 * 71 * @param[intensity] Intensity of the background. Correspond with the "percentage" of color 72 * from `darkIconTheme` to use 73 * @return The blended color 74 */ 75 fun getSingleColor(intensity: Float) = 76 getColorForDarkIntensity(intensity, lightColor.single, darkColor.single) 77 78 /** 79 * Blends the background color associated with the light and dark theme 80 * 81 * @param[intensity] Intensity of the background. Correspond with the "percentage" of color 82 * from `darkIconTheme` to use 83 * @return The blended color 84 */ 85 fun getBackgroundColor(intensity: Float) = 86 getColorForDarkIntensity(intensity, lightColor.background, darkColor.background) 87 88 /** 89 * Blends the fill color associated with the light and dark theme 90 * 91 * @param[intensity] Intensity of the background. Correspond with the "percentage" of color 92 * from `darkIconTheme` to use 93 * @return The blended color 94 */ 95 fun getFillColor(intensity: Float) = 96 getColorForDarkIntensity(intensity, lightColor.fill, darkColor.fill) 97 98 private data class Color(val single: Int, val background: Int, val fill: Int) 99 }