1cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu/*
2cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Copyright (C) 2014 The Android Open Source Project
3cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu *
4cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * in compliance with the License. You may obtain a copy of the License at
6cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu *
7cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * http://www.apache.org/licenses/LICENSE-2.0
8cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu *
9cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License
10cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * or implied. See the License for the specific language governing permissions and limitations under
12cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu * the License.
13cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */
14cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gupackage android.support.v17.leanback.graphics;
15cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
16cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.content.Context;
17131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbournimport android.content.res.TypedArray;
18cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.graphics.ColorFilter;
19cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.graphics.Paint;
20cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.view.View;
21cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Guimport android.support.v17.leanback.R;
22cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
23cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu/**
247cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn * Helper class for applying a dim level to a View.  The ColorFilterDimmer
257cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn * uses a ColorFilter in a Paint object to dim the view according to the
267cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn * currently active level.
27cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu */
28cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gupublic final class ColorFilterDimmer {
29cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
30cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    private final ColorFilterCache mColorDimmer;
31cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
32cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    private final float mActiveLevel;
33cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    private final float mDimmedLevel;
34cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
35cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    private final Paint mPaint;
36cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    private ColorFilter mFilter;
37cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
38cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
397cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * Creates a default ColorFilterDimmer. Uses the default color and level for
407cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * the dimmer.
417cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *
427cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @param context A Context used to retrieve Resources.
437cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @return A ColorFilterDimmer with the default dim color and levels.
44cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
45cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public static ColorFilterDimmer createDefault(Context context) {
46131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn        TypedArray a = context.obtainStyledAttributes(R.styleable.LeanbackTheme);
47131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn
48131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn        int dimColor = a.getColor(R.styleable.LeanbackTheme_overlayDimMaskColor,
49131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn                context.getResources().getColor(R.color.lb_view_dim_mask_color));
50131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn        float activeLevel = a.getFraction(R.styleable.LeanbackTheme_overlayDimActiveLevel, 1, 1,
51131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn                context.getResources().getFraction(R.fraction.lb_view_active_level, 1, 0));
52131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn        float dimmedLevel = a.getFraction(R.styleable.LeanbackTheme_overlayDimDimmedLevel, 1, 1,
53131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn                context.getResources().getFraction(R.fraction.lb_view_dimmed_level, 1, 1));
54131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn        a.recycle();
55cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return new ColorFilterDimmer(ColorFilterCache.getColorFilterCache(
56131ea1bf320a60591383cc6d8831c38e13b31b2bTim Kilbourn                    dimColor), activeLevel, dimmedLevel);
57cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
58cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
59cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
607cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * Creates a ColorFilterDimmer for the given color and levels..
61cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     *
62cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     * @param dimmer      The ColorFilterCache for dim color.
637cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @param activeLevel The level of dimming when the View is in its active
647cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *                    state. Must be a float value between 0.0 and 1.0.
657cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @param dimmedLevel The level of dimming when the View is in its dimmed
667cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *                    state. Must be a float value between 0.0 and 1.0.
67cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
68cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public static ColorFilterDimmer create(ColorFilterCache dimmer,
69cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu            float activeLevel, float dimmedLevel) {
70cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return new ColorFilterDimmer(dimmer, activeLevel, dimmedLevel);
71cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
72cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
73cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    private ColorFilterDimmer(ColorFilterCache dimmer, float activeLevel, float dimmedLevel) {
74cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        mColorDimmer = dimmer;
757cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn        if (activeLevel > 1.0f) activeLevel = 1.0f;
767cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn        if (activeLevel < 0.0f) activeLevel = 0.0f;
777cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn        if (dimmedLevel > 1.0f) dimmedLevel = 1.0f;
787cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn        if (dimmedLevel < 0.0f) dimmedLevel = 0.0f;
79cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        mActiveLevel = activeLevel;
80cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        mDimmedLevel = dimmedLevel;
81cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        mPaint = new Paint();
82cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
83cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
84cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
857cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * Apply current the ColorFilter to a View. This method will set the
867cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * hardware layer of the view when applying a filter, and remove it when not
877cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * applying a filter.
887cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *
897cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @param view The View to apply the ColorFilter to.
90cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
91cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public void applyFilterToView(View view) {
92cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        if (mFilter != null) {
93cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu            view.setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
94cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        } else {
95cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu            view.setLayerType(View.LAYER_TYPE_NONE, null);
96cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        }
97cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        // FIXME: Current framework has bug that not triggering invalidate when change layer
98cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        // paint.  Will add conditional sdk version check once bug is fixed in released
99cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        // framework.
100cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        view.invalidate();
101cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
102cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
103cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
1047cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * Sets the active level of the dimmer. Updates the ColorFilter based on the
1057cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * level.
1067cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *
1077cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @param level A float between 0 (fully dim) and 1 (fully active).
108cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
109cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public void setActiveLevel(float level) {
1107cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn        if (level < 0.0f) level = 0.0f;
1117cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn        if (level > 1.0f) level = 1.0f;
112cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        mFilter = mColorDimmer.getFilterForLevel(
113cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu                mDimmedLevel + level * (mActiveLevel - mDimmedLevel));
114cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        mPaint.setColorFilter(mFilter);
115cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
116cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
117cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
1187cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * Gets the ColorFilter set to the current dim level.
1197cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *
1207cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @return The current ColorFilter.
121cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
122cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public ColorFilter getColorFilter() {
123cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return mFilter;
124cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
125cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu
126cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    /**
1277cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * Gets the Paint object set to the current dim level.
1287cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     *
1297cc1c375d3bbfeacfcc3259e77671ae24f610d33Tim Kilbourn     * @return The current Paint object.
130cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu     */
131cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    public Paint getPaint() {
132cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu        return mPaint;
133cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu    }
134cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu}
135