1 /*
2  * Copyright (C) 2022 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 package com.android.systemui.shared.shadow
17 
18 import android.content.Context
19 import android.graphics.Canvas
20 import android.graphics.drawable.Drawable
21 import android.util.AttributeSet
22 import android.widget.TextView
23 import com.android.systemui.shared.R
24 import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo
25 import com.android.systemui.shared.shadow.DoubleShadowTextHelper.applyShadows
26 
27 /** Extension of [TextView] which draws two shadows on the text (ambient and key shadows} */
28 open class DoubleShadowTextView
29 @JvmOverloads
30 constructor(
31     context: Context,
32     attrs: AttributeSet? = null,
33     defStyleAttr: Int = 0,
34     defStyleRes: Int = 0
35 ) : TextView(context, attrs, defStyleAttr, defStyleRes) {
36     private val mKeyShadowInfo: ShadowInfo
37     private val mAmbientShadowInfo: ShadowInfo
38 
39     init {
40         val attributes =
41             context.obtainStyledAttributes(
42                 attrs,
43                 R.styleable.DoubleShadowTextView,
44                 defStyleAttr,
45                 defStyleRes
46             )
47         val drawableSize: Int
48         val drawableInsetSize: Int
49         try {
50             val keyShadowBlur =
51                 attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowBlur, 0f)
52             val keyShadowOffsetX =
53                 attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowOffsetX, 0f)
54             val keyShadowOffsetY =
55                 attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowOffsetY, 0f)
56             val keyShadowAlpha =
57                 attributes.getFloat(R.styleable.DoubleShadowTextView_keyShadowAlpha, 0f)
58             mKeyShadowInfo =
59                 ShadowInfo(keyShadowBlur, keyShadowOffsetX, keyShadowOffsetY, keyShadowAlpha)
60             val ambientShadowBlur =
61                 attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowBlur, 0f)
62             val ambientShadowOffsetX =
63                 attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowOffsetX, 0f)
64             val ambientShadowOffsetY =
65                 attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowOffsetY, 0f)
66             val ambientShadowAlpha =
67                 attributes.getFloat(R.styleable.DoubleShadowTextView_ambientShadowAlpha, 0f)
68             mAmbientShadowInfo =
69                 ShadowInfo(
70                     ambientShadowBlur,
71                     ambientShadowOffsetX,
72                     ambientShadowOffsetY,
73                     ambientShadowAlpha
74                 )
75             drawableSize =
76                 attributes.getDimensionPixelSize(
77                     R.styleable.DoubleShadowTextView_drawableIconSize,
78                     0
79                 )
80             drawableInsetSize =
81                 attributes.getDimensionPixelSize(
82                     R.styleable.DoubleShadowTextView_drawableIconInsetSize,
83                     0
84                 )
85         } finally {
86             attributes.recycle()
87         }
88 
89         val drawables = arrayOf<Drawable?>(null, null, null, null)
90         for ((index, drawable) in compoundDrawablesRelative.withIndex()) {
91             if (drawable == null) continue
92             drawables[index] =
93                 DoubleShadowIconDrawable(
94                     mKeyShadowInfo,
95                     mAmbientShadowInfo,
96                     drawable,
97                     drawableSize,
98                     drawableInsetSize
99                 )
100         }
101         setCompoundDrawablesRelative(drawables[0], drawables[1], drawables[2], drawables[3])
102     }
103 
onDrawnull104     public override fun onDraw(canvas: Canvas) {
105         applyShadows(mKeyShadowInfo, mAmbientShadowInfo, this, canvas) { super.onDraw(canvas) }
106     }
107 }
108