• 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.views;
18 
19 import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
20 
21 import android.content.Context;
22 import android.content.res.TypedArray;
23 import android.graphics.Canvas;
24 import android.graphics.Color;
25 import android.util.AttributeSet;
26 import android.widget.TextView;
27 
28 import com.android.launcher3.BubbleTextView;
29 import com.android.launcher3.R;
30 
31 /**
32  * Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
33  */
34 public class DoubleShadowBubbleTextView extends BubbleTextView {
35 
36     private final ShadowInfo mShadowInfo;
37 
DoubleShadowBubbleTextView(Context context)38     public DoubleShadowBubbleTextView(Context context) {
39         this(context, null);
40     }
41 
DoubleShadowBubbleTextView(Context context, AttributeSet attrs)42     public DoubleShadowBubbleTextView(Context context, AttributeSet attrs) {
43         this(context, attrs, 0);
44     }
45 
DoubleShadowBubbleTextView(Context context, AttributeSet attrs, int defStyle)46     public DoubleShadowBubbleTextView(Context context, AttributeSet attrs, int defStyle) {
47         super(context, attrs, defStyle);
48         mShadowInfo = new ShadowInfo(context, attrs, defStyle);
49         setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0, mShadowInfo.ambientShadowColor);
50     }
51 
52     @Override
onDraw(Canvas canvas)53     public void onDraw(Canvas canvas) {
54         // If text is transparent or shadow alpha is 0, don't draw any shadow
55         if (mShadowInfo.skipDoubleShadow(this)) {
56             super.onDraw(canvas);
57             return;
58         }
59         int alpha = Color.alpha(getCurrentTextColor());
60 
61         // We enhance the shadow by drawing the shadow twice
62         getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
63                 getTextShadowColor(mShadowInfo.ambientShadowColor, alpha));
64 
65         drawWithoutDot(canvas);
66         canvas.save();
67         canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
68                 getScrollX() + getWidth(),
69                 getScrollY() + getHeight());
70 
71         getPaint().setShadowLayer(
72                 mShadowInfo.keyShadowBlur,
73                 mShadowInfo.keyShadowOffsetX,
74                 mShadowInfo.keyShadowOffsetY,
75                 getTextShadowColor(mShadowInfo.keyShadowColor, alpha));
76         drawWithoutDot(canvas);
77         canvas.restore();
78 
79         drawDotIfNecessary(canvas);
80     }
81 
82     public static class ShadowInfo {
83         public final float ambientShadowBlur;
84         public final int ambientShadowColor;
85 
86         public final float keyShadowBlur;
87         public final float keyShadowOffsetX;
88         public final float keyShadowOffsetY;
89         public final int keyShadowColor;
90 
ShadowInfo(Context c, AttributeSet attrs, int defStyle)91         public ShadowInfo(Context c, AttributeSet attrs, int defStyle) {
92 
93             TypedArray a = c.obtainStyledAttributes(
94                     attrs, R.styleable.ShadowInfo, defStyle, 0);
95 
96             ambientShadowBlur = a.getDimensionPixelSize(
97                     R.styleable.ShadowInfo_ambientShadowBlur, 0);
98             ambientShadowColor = a.getColor(R.styleable.ShadowInfo_ambientShadowColor, 0);
99 
100             keyShadowBlur = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowBlur, 0);
101             keyShadowOffsetX = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowOffsetX, 0);
102             keyShadowOffsetY = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowOffsetY, 0);
103             keyShadowColor = a.getColor(R.styleable.ShadowInfo_keyShadowColor, 0);
104             a.recycle();
105         }
106 
skipDoubleShadow(TextView textView)107         public boolean skipDoubleShadow(TextView textView) {
108             int textAlpha = Color.alpha(textView.getCurrentTextColor());
109             int keyShadowAlpha = Color.alpha(keyShadowColor);
110             int ambientShadowAlpha = Color.alpha(ambientShadowColor);
111             if (textAlpha == 0 || (keyShadowAlpha == 0 && ambientShadowAlpha == 0)) {
112                 textView.getPaint().clearShadowLayer();
113                 return true;
114             } else if (ambientShadowAlpha > 0 && keyShadowAlpha == 0) {
115                 textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
116                         getTextShadowColor(ambientShadowColor, textAlpha));
117                 return true;
118             } else if (keyShadowAlpha > 0 && ambientShadowAlpha == 0) {
119                 textView.getPaint().setShadowLayer(
120                         keyShadowBlur,
121                         keyShadowOffsetX,
122                         keyShadowOffsetY,
123                         getTextShadowColor(keyShadowColor, textAlpha));
124                 return true;
125             } else {
126                 return false;
127             }
128         }
129     }
130 
131     // Multiplies the alpha of shadowColor by textAlpha.
getTextShadowColor(int shadowColor, int textAlpha)132     private static int getTextShadowColor(int shadowColor, int textAlpha) {
133         return setColorAlphaBound(shadowColor,
134                 Math.round(Color.alpha(shadowColor) * textAlpha / 255f));
135     }
136 }
137