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 androidx.leanback.graphics; 15 16import android.content.Context; 17import android.content.res.TypedArray; 18import android.graphics.Canvas; 19import android.graphics.Color; 20import android.graphics.Paint; 21import android.view.View; 22 23import androidx.leanback.R; 24 25/** 26 * Helper class for assigning a dim color to Paint. It holds the alpha value for 27 * the current active level. 28 */ 29public final class ColorOverlayDimmer { 30 31 private final float mActiveLevel; 32 private final float mDimmedLevel; 33 34 private final Paint mPaint; 35 36 private int mAlpha; 37 private float mAlphaFloat; 38 39 /** 40 * Creates a default ColorOverlayDimmer. 41 */ 42 public static ColorOverlayDimmer createDefault(Context context) { 43 TypedArray a = context.obtainStyledAttributes(R.styleable.LeanbackTheme); 44 45 int dimColor = a.getColor(R.styleable.LeanbackTheme_overlayDimMaskColor, 46 context.getResources().getColor(R.color.lb_view_dim_mask_color)); 47 float activeLevel = a.getFraction(R.styleable.LeanbackTheme_overlayDimActiveLevel, 1, 1, 48 context.getResources().getFraction(R.fraction.lb_view_active_level, 1, 0)); 49 float dimmedLevel = a.getFraction(R.styleable.LeanbackTheme_overlayDimDimmedLevel, 1, 1, 50 context.getResources().getFraction(R.fraction.lb_view_dimmed_level, 1, 1)); 51 a.recycle(); 52 return new ColorOverlayDimmer(dimColor, activeLevel, dimmedLevel); 53 } 54 55 /** 56 * Creates a ColorOverlayDimmer for the given color and levels. 57 * 58 * @param dimColor The color for fully dimmed. Only the RGB values are 59 * used; the alpha channel is ignored. 60 * @param activeLevel The level of dimming when the View is in its active 61 * state. Must be a float value between 0.0 and 1.0. 62 * @param dimmedLevel The level of dimming when the View is in its dimmed 63 * state. Must be a float value between 0.0 and 1.0. 64 */ 65 public static ColorOverlayDimmer createColorOverlayDimmer(int dimColor, float activeLevel, 66 float dimmedLevel) { 67 return new ColorOverlayDimmer(dimColor, activeLevel, dimmedLevel); 68 } 69 70 private ColorOverlayDimmer(int dimColor, float activeLevel, float dimmedLevel) { 71 if (activeLevel > 1.0f) activeLevel = 1.0f; 72 if (activeLevel < 0.0f) activeLevel = 0.0f; 73 if (dimmedLevel > 1.0f) dimmedLevel = 1.0f; 74 if (dimmedLevel < 0.0f) dimmedLevel = 0.0f; 75 mPaint = new Paint(); 76 dimColor = Color.rgb(Color.red(dimColor), Color.green(dimColor), Color.blue(dimColor)); 77 mPaint.setColor(dimColor); 78 mActiveLevel = activeLevel; 79 mDimmedLevel = dimmedLevel; 80 setActiveLevel(1); 81 } 82 83 /** 84 * Sets the active level of the dimmer. Updates the alpha value based on the 85 * level. 86 * 87 * @param level A float between 0 (fully dim) and 1 (fully active). 88 */ 89 public void setActiveLevel(float level) { 90 mAlphaFloat = (mDimmedLevel + level * (mActiveLevel - mDimmedLevel)); 91 mAlpha = (int) (255 * mAlphaFloat); 92 mPaint.setAlpha(mAlpha); 93 } 94 95 /** 96 * Returns whether the dimmer needs to draw. 97 */ 98 public boolean needsDraw() { 99 return mAlpha != 0; 100 } 101 102 /** 103 * Returns the alpha value for the dimmer. 104 */ 105 public int getAlpha() { 106 return mAlpha; 107 } 108 109 /** 110 * Returns the float value between 0 and 1 corresponding to alpha between 111 * 0 and 255. 112 */ 113 public float getAlphaFloat() { 114 return mAlphaFloat; 115 } 116 117 /** 118 * Returns the Paint object set to the current alpha value. 119 */ 120 public Paint getPaint() { 121 return mPaint; 122 } 123 124 /** 125 * Change the RGB of the color according to current dim level. Maintains the 126 * alpha value of the color. 127 * 128 * @param color The color to apply the dim level to. 129 * @return A color with the RGB values adjusted by the alpha of the current 130 * dim level. 131 */ 132 public int applyToColor(int color) { 133 float f = 1 - mAlphaFloat; 134 return Color.argb(Color.alpha(color), 135 (int)(Color.red(color) * f), 136 (int)(Color.green(color) * f), 137 (int)(Color.blue(color) * f)); 138 } 139 140 /** 141 * Draw a dim color overlay on top of a child View inside the canvas of 142 * the parent View. 143 * 144 * @param c Canvas of the parent View. 145 * @param v A child of the parent View. 146 * @param includePadding Set to true to draw overlay on padding area of the 147 * View. 148 */ 149 public void drawColorOverlay(Canvas c, View v, boolean includePadding) { 150 c.save(); 151 float dx = v.getLeft() + v.getTranslationX(); 152 float dy = v.getTop() + v.getTranslationY(); 153 c.translate(dx, dy); 154 c.concat(v.getMatrix()); 155 c.translate(-dx, -dy); 156 if (includePadding) { 157 c.drawRect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom(), mPaint); 158 } else { 159 c.drawRect(v.getLeft() + v.getPaddingLeft(), 160 v.getTop() + v.getPaddingTop(), 161 v.getRight() - v.getPaddingRight(), 162 v.getBottom() - v.getPaddingBottom(), mPaint); 163 } 164 c.restore(); 165 } 166} 167