1a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes/*
2a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * Copyright (C) 2015 The Android Open Source Project
3a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes *
4a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
5a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * you may not use this file except in compliance with the License.
6a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * You may obtain a copy of the License at
7a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes *
8a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
9a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes *
10a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * Unless required by applicable law or agreed to in writing, software
11a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
12a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * See the License for the specific language governing permissions and
14a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes * limitations under the License.
15a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes */
16a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
1766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banespackage android.support.v7.widget;
18a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
19a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banesimport android.content.Context;
20a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banesimport android.content.res.ColorStateList;
21a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banesimport android.graphics.Color;
22711c3df64595e2404ff6aa642ee5303f510e1dcbChris Banesimport android.support.v4.graphics.ColorUtils;
23a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banesimport android.util.TypedValue;
24a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
2566698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesclass ThemeUtils {
26a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
27a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes    private static final ThreadLocal<TypedValue> TL_TYPED_VALUE = new ThreadLocal<>();
28a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
29bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
30bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
31bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] ACTIVATED_STATE_SET = new int[]{android.R.attr.state_activated};
32bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
33bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] CHECKED_STATE_SET = new int[]{android.R.attr.state_checked};
34bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] SELECTED_STATE_SET = new int[]{android.R.attr.state_selected};
35bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] NOT_PRESSED_OR_FOCUSED_STATE_SET = new int[]{
36bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes            -android.R.attr.state_pressed, -android.R.attr.state_focused};
37bb1a62b3eed874aa47ea4763ac972902c77e988fChris Banes    static final int[] EMPTY_STATE_SET = new int[0];
38a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
392aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes    private static final int[] TEMP_ARRAY = new int[1];
40a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
412cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public static ColorStateList createDisabledStateList(int textColor, int disabledTextColor) {
422aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        // Now create a new ColorStateList with the default color, and the new disabled
432aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        // color
442aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        final int[][] states = new int[2][];
452aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        final int[] colors = new int[2];
462aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        int i = 0;
47a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
482aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        // Disabled state
492aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        states[i] = DISABLED_STATE_SET;
502aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        colors[i] = disabledTextColor;
512aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        i++;
52a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
532aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        // Default state
542aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        states[i] = EMPTY_STATE_SET;
552aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        colors[i] = textColor;
562aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        i++;
57a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
582aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        return new ColorStateList(states, colors);
592aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes    }
602aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes
612cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public static int getThemeAttrColor(Context context, int attr) {
622aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        TEMP_ARRAY[0] = attr;
639d5f84f33353a42e837c6b465412d1a6f2fc6eaaChris Banes        TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, null, TEMP_ARRAY);
642aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        try {
652aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            return a.getColor(0, 0);
662aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        } finally {
672aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            a.recycle();
682aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        }
692aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes    }
70a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
712cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public static ColorStateList getThemeAttrColorStateList(Context context, int attr) {
722aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        TEMP_ARRAY[0] = attr;
739d5f84f33353a42e837c6b465412d1a6f2fc6eaaChris Banes        TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, null, TEMP_ARRAY);
742aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        try {
752aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            return a.getColorStateList(0);
762aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        } finally {
772aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            a.recycle();
782aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        }
792aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes    }
802aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes
812cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public static int getDisabledThemeAttrColor(Context context, int attr) {
822aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        final ColorStateList csl = getThemeAttrColorStateList(context, attr);
832aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        if (csl != null && csl.isStateful()) {
842aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            // If the CSL is stateful, we'll assume it has a disabled state and use it
852aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            return csl.getColorForState(DISABLED_STATE_SET, csl.getDefaultColor());
862aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        } else {
872aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            // Else, we'll generate the color using disabledAlpha from the theme
882aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes
892aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            final TypedValue tv = getTypedValue();
902aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            // Now retrieve the disabledAlpha value from the theme
912aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, tv, true);
922aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            final float disabledAlpha = tv.getFloat();
932aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes
942aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes            return getThemeAttrColor(context, attr, disabledAlpha);
95a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes        }
96a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes    }
97a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
98a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes    private static TypedValue getTypedValue() {
99a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes        TypedValue typedValue = TL_TYPED_VALUE.get();
100a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes        if (typedValue == null) {
101a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes            typedValue = new TypedValue();
102a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes            TL_TYPED_VALUE.set(typedValue);
103a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes        }
104a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes        return typedValue;
105a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes    }
106a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
1072aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes    static int getThemeAttrColor(Context context, int attr, float alpha) {
1082aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        final int color = getThemeAttrColor(context, attr);
1092aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        final int originalAlpha = Color.alpha(color);
1102aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes        return ColorUtils.setAlphaComponent(color, Math.round(originalAlpha * alpha));
1112aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes    }
1122aeb0f4237bca35d7f650c3145354416306d4f7bChris Banes
113a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes}
114