blob: fdc3229ab8d74e37f7fbfeac454639ad3040396c [file] [log] [blame]
Fabian Kozynskif86df992019-04-22 14:23:47 -04001/*
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
17package com.android.systemui
18
19import android.animation.ArgbEvaluator
20import android.content.Context
21import android.view.ContextThemeWrapper
22import 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 */
37class 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 */
50 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
65 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}