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