1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.graphics; 15 16import android.content.Context; 17import android.content.res.TypedArray; 18import android.graphics.ColorFilter; 19import android.graphics.Paint; 20import android.view.View; 21import android.support.v17.leanback.R; 22 23/** 24 * Helper class for applying a dim level to a View. The ColorFilterDimmer 25 * uses a ColorFilter in a Paint object to dim the view according to the 26 * currently active level. 27 */ 28public final class ColorFilterDimmer { 29 30 private final ColorFilterCache mColorDimmer; 31 32 private final float mActiveLevel; 33 private final float mDimmedLevel; 34 35 private final Paint mPaint; 36 private ColorFilter mFilter; 37 38 /** 39 * Creates a default ColorFilterDimmer. Uses the default color and level for 40 * the dimmer. 41 * 42 * @param context A Context used to retrieve Resources. 43 * @return A ColorFilterDimmer with the default dim color and levels. 44 */ 45 public static ColorFilterDimmer createDefault(Context context) { 46 TypedArray a = context.obtainStyledAttributes(R.styleable.LeanbackTheme); 47 48 int dimColor = a.getColor(R.styleable.LeanbackTheme_overlayDimMaskColor, 49 context.getResources().getColor(R.color.lb_view_dim_mask_color)); 50 float activeLevel = a.getFraction(R.styleable.LeanbackTheme_overlayDimActiveLevel, 1, 1, 51 context.getResources().getFraction(R.fraction.lb_view_active_level, 1, 0)); 52 float dimmedLevel = a.getFraction(R.styleable.LeanbackTheme_overlayDimDimmedLevel, 1, 1, 53 context.getResources().getFraction(R.fraction.lb_view_dimmed_level, 1, 1)); 54 a.recycle(); 55 return new ColorFilterDimmer(ColorFilterCache.getColorFilterCache( 56 dimColor), activeLevel, dimmedLevel); 57 } 58 59 /** 60 * Creates a ColorFilterDimmer for the given color and levels.. 61 * 62 * @param dimmer The ColorFilterCache for dim color. 63 * @param activeLevel The level of dimming when the View is in its active 64 * state. Must be a float value between 0.0 and 1.0. 65 * @param dimmedLevel The level of dimming when the View is in its dimmed 66 * state. Must be a float value between 0.0 and 1.0. 67 */ 68 public static ColorFilterDimmer create(ColorFilterCache dimmer, 69 float activeLevel, float dimmedLevel) { 70 return new ColorFilterDimmer(dimmer, activeLevel, dimmedLevel); 71 } 72 73 private ColorFilterDimmer(ColorFilterCache dimmer, float activeLevel, float dimmedLevel) { 74 mColorDimmer = dimmer; 75 if (activeLevel > 1.0f) activeLevel = 1.0f; 76 if (activeLevel < 0.0f) activeLevel = 0.0f; 77 if (dimmedLevel > 1.0f) dimmedLevel = 1.0f; 78 if (dimmedLevel < 0.0f) dimmedLevel = 0.0f; 79 mActiveLevel = activeLevel; 80 mDimmedLevel = dimmedLevel; 81 mPaint = new Paint(); 82 } 83 84 /** 85 * Apply current the ColorFilter to a View. This method will set the 86 * hardware layer of the view when applying a filter, and remove it when not 87 * applying a filter. 88 * 89 * @param view The View to apply the ColorFilter to. 90 */ 91 public void applyFilterToView(View view) { 92 if (mFilter != null) { 93 view.setLayerType(View.LAYER_TYPE_HARDWARE, mPaint); 94 } else { 95 view.setLayerType(View.LAYER_TYPE_NONE, null); 96 } 97 // FIXME: Current framework has bug that not triggering invalidate when change layer 98 // paint. Will add conditional sdk version check once bug is fixed in released 99 // framework. 100 view.invalidate(); 101 } 102 103 /** 104 * Sets the active level of the dimmer. Updates the ColorFilter based on the 105 * level. 106 * 107 * @param level A float between 0 (fully dim) and 1 (fully active). 108 */ 109 public void setActiveLevel(float level) { 110 if (level < 0.0f) level = 0.0f; 111 if (level > 1.0f) level = 1.0f; 112 mFilter = mColorDimmer.getFilterForLevel( 113 mDimmedLevel + level * (mActiveLevel - mDimmedLevel)); 114 mPaint.setColorFilter(mFilter); 115 } 116 117 /** 118 * Gets the ColorFilter set to the current dim level. 119 * 120 * @return The current ColorFilter. 121 */ 122 public ColorFilter getColorFilter() { 123 return mFilter; 124 } 125 126 /** 127 * Gets the Paint object set to the current dim level. 128 * 129 * @return The current Paint object. 130 */ 131 public Paint getPaint() { 132 return mPaint; 133 } 134} 135