• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.launcher3.util;
18 
19 import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT;
20 import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME;
21 
22 import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
23 
24 import android.app.WallpaperColors;
25 import android.app.WallpaperManager;
26 import android.content.Context;
27 import android.content.res.TypedArray;
28 import android.graphics.Color;
29 import android.graphics.ColorMatrix;
30 import android.graphics.drawable.Drawable;
31 import android.util.AttributeSet;
32 import android.util.SparseArray;
33 import android.util.TypedValue;
34 
35 import com.android.launcher3.LauncherPrefs;
36 import com.android.launcher3.R;
37 import com.android.launcher3.Utilities;
38 import com.android.launcher3.icons.GraphicsUtils;
39 
40 /**
41  * Various utility methods associated with theming.
42  */
43 @SuppressWarnings("NewApi")
44 public class Themes {
45 
46     public static final String KEY_THEMED_ICONS = "themed_icons";
47 
getActivityThemeRes(Context context)48     public static int getActivityThemeRes(Context context) {
49         final int colorHints;
50         if (Utilities.ATLEAST_P) {
51             WallpaperColors colors = context.getSystemService(WallpaperManager.class)
52                     .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
53             colorHints = colors == null ? 0 : colors.getColorHints();
54         } else {
55             colorHints = 0;
56         }
57         return getActivityThemeRes(context, colorHints);
58     }
59 
getActivityThemeRes(Context context, int wallpaperColorHints)60     public static int getActivityThemeRes(Context context, int wallpaperColorHints) {
61         boolean supportsDarkText = Utilities.ATLEAST_S
62                 && (wallpaperColorHints & HINT_SUPPORTS_DARK_TEXT) != 0;
63         boolean isMainColorDark = Utilities.ATLEAST_S
64                 && (wallpaperColorHints & HINT_SUPPORTS_DARK_THEME) != 0;
65 
66         if (Utilities.isDarkTheme(context)) {
67             return supportsDarkText ? R.style.AppTheme_Dark_DarkText
68                     : isMainColorDark ? R.style.AppTheme_Dark_DarkMainColor : R.style.AppTheme_Dark;
69         } else {
70             return supportsDarkText ? R.style.AppTheme_DarkText
71                     : isMainColorDark ? R.style.AppTheme_DarkMainColor : R.style.AppTheme;
72         }
73     }
74 
75     /**
76      * Returns true if workspace icon theming is enabled
77      */
isThemedIconEnabled(Context context)78     public static boolean isThemedIconEnabled(Context context) {
79         return LauncherPrefs.get(context).get(THEMED_ICONS);
80     }
81 
getDefaultBodyFont(Context context)82     public static String getDefaultBodyFont(Context context) {
83         TypedArray ta = context.obtainStyledAttributes(android.R.style.TextAppearance_DeviceDefault,
84                 new int[]{android.R.attr.fontFamily});
85         String value = ta.getString(0);
86         ta.recycle();
87         return value;
88     }
89 
getDialogCornerRadius(Context context)90     public static float getDialogCornerRadius(Context context) {
91         return getDimension(context, android.R.attr.dialogCornerRadius,
92                 context.getResources().getDimension(R.dimen.default_dialog_corner_radius));
93     }
94 
getDimension(Context context, int attr, float defaultValue)95     public static float getDimension(Context context, int attr, float defaultValue) {
96         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
97         float value = ta.getDimension(0, defaultValue);
98         ta.recycle();
99         return value;
100     }
101 
getColorAccent(Context context)102     public static int getColorAccent(Context context) {
103         return getAttrColor(context, android.R.attr.colorAccent);
104     }
105 
106     /** Returns the background color attribute. */
getColorBackground(Context context)107     public static int getColorBackground(Context context) {
108         return getAttrColor(context, android.R.attr.colorBackground);
109     }
110 
111     /** Returns the floating background color attribute. */
getColorBackgroundFloating(Context context)112     public static int getColorBackgroundFloating(Context context) {
113         return getAttrColor(context, android.R.attr.colorBackgroundFloating);
114     }
115 
getAttrColor(Context context, int attr)116     public static int getAttrColor(Context context, int attr) {
117         return GraphicsUtils.getAttrColor(context, attr);
118     }
119 
getAttrBoolean(Context context, int attr)120     public static boolean getAttrBoolean(Context context, int attr) {
121         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
122         boolean value = ta.getBoolean(0, false);
123         ta.recycle();
124         return value;
125     }
126 
getAttrDrawable(Context context, int attr)127     public static Drawable getAttrDrawable(Context context, int attr) {
128         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
129         Drawable value = ta.getDrawable(0);
130         ta.recycle();
131         return value;
132     }
133 
getAttrInteger(Context context, int attr)134     public static int getAttrInteger(Context context, int attr) {
135         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
136         int value = ta.getInteger(0, 0);
137         ta.recycle();
138         return value;
139     }
140 
141     /**
142      * Scales a color matrix such that, when applied to color R G B A, it produces R' G' B' A' where
143      * R' = r * R
144      * G' = g * G
145      * B' = b * B
146      * A' = a * A
147      *
148      * The matrix will, for instance, turn white into r g b a, and black will remain black.
149      *
150      * @param color The color r g b a
151      * @param target The ColorMatrix to scale
152      */
setColorScaleOnMatrix(int color, ColorMatrix target)153     public static void setColorScaleOnMatrix(int color, ColorMatrix target) {
154         target.setScale(Color.red(color) / 255f, Color.green(color) / 255f,
155                 Color.blue(color) / 255f, Color.alpha(color) / 255f);
156     }
157 
158     /**
159      * Changes a color matrix such that, when applied to srcColor, it produces dstColor.
160      *
161      * Note that values on the last column of target ColorMatrix can be negative, and may result in
162      * negative values when applied on a color. Such negative values will be automatically shifted
163      * up to 0 by the framework.
164      *
165      * @param srcColor The color to start from
166      * @param dstColor The color to create by applying target on srcColor
167      * @param target The ColorMatrix to transform the color
168      */
setColorChangeOnMatrix(int srcColor, int dstColor, ColorMatrix target)169     public static void setColorChangeOnMatrix(int srcColor, int dstColor, ColorMatrix target) {
170         target.reset();
171         target.getArray()[4] = Color.red(dstColor) - Color.red(srcColor);
172         target.getArray()[9] = Color.green(dstColor) - Color.green(srcColor);
173         target.getArray()[14] = Color.blue(dstColor) - Color.blue(srcColor);
174         target.getArray()[19] = Color.alpha(dstColor) - Color.alpha(srcColor);
175     }
176 
177     /**
178      * Creates a map for attribute-name to value for all the values in {@param attrs} which can be
179      * held in memory for later use.
180      */
createValueMap(Context context, AttributeSet attrSet, IntArray keysToIgnore)181     public static SparseArray<TypedValue> createValueMap(Context context, AttributeSet attrSet,
182             IntArray keysToIgnore) {
183         int count = attrSet.getAttributeCount();
184         IntArray attrNameArray = new IntArray(count);
185         for (int i = 0; i < count; i++) {
186             attrNameArray.add(attrSet.getAttributeNameResource(i));
187         }
188         attrNameArray.removeAllValues(keysToIgnore);
189 
190         int[] attrNames = attrNameArray.toArray();
191         SparseArray<TypedValue> result = new SparseArray<>(attrNames.length);
192         TypedArray ta = context.obtainStyledAttributes(attrSet, attrNames);
193         for (int i = 0; i < attrNames.length; i++) {
194             TypedValue tv = new TypedValue();
195             ta.getValue(i, tv);
196             result.put(attrNames[i], tv);
197         }
198 
199         return result;
200     }
201 }
202