1 /*
2  * Copyright (C) 2018 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.quickstep.views;
17 
18 import android.content.Context;
19 import android.graphics.Canvas;
20 import android.graphics.Rect;
21 import android.graphics.drawable.Drawable;
22 import android.util.AttributeSet;
23 import android.view.Gravity;
24 import android.view.View;
25 
26 import androidx.annotation.Nullable;
27 
28 import com.android.launcher3.Utilities;
29 
30 /**
31  * A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
32  * when the drawable changes.
33  */
34 public class IconView extends View {
35 
36     @Nullable
37     private Drawable mDrawable;
38     private int mDrawableWidth, mDrawableHeight;
39 
IconView(Context context)40     public IconView(Context context) {
41         super(context);
42     }
43 
IconView(Context context, AttributeSet attrs)44     public IconView(Context context, AttributeSet attrs) {
45         super(context, attrs);
46     }
47 
IconView(Context context, AttributeSet attrs, int defStyleAttr)48     public IconView(Context context, AttributeSet attrs, int defStyleAttr) {
49         super(context, attrs, defStyleAttr);
50     }
51 
52     /**
53      * Sets a {@link Drawable} to be displayed.
54      */
setDrawable(@ullable Drawable d)55     public void setDrawable(@Nullable Drawable d) {
56         if (mDrawable != null) {
57             mDrawable.setCallback(null);
58         }
59         mDrawable = d;
60         if (mDrawable != null) {
61             mDrawable.setCallback(this);
62             setDrawableSizeInternal(getWidth(), getHeight());
63         }
64         invalidate();
65     }
66 
67     /**
68      * Sets the size of the icon drawable.
69      */
setDrawableSize(int iconWidth, int iconHeight)70     public void setDrawableSize(int iconWidth, int iconHeight) {
71         mDrawableWidth = iconWidth;
72         mDrawableHeight = iconHeight;
73         if (mDrawable != null) {
74             setDrawableSizeInternal(getWidth(), getHeight());
75         }
76     }
77 
setDrawableSizeInternal(int selfWidth, int selfHeight)78     private void setDrawableSizeInternal(int selfWidth, int selfHeight) {
79         Rect selfRect = new Rect(0, 0, selfWidth, selfHeight);
80         Rect drawableRect = new Rect();
81         Gravity.apply(Gravity.CENTER, mDrawableWidth, mDrawableHeight, selfRect, drawableRect);
82         mDrawable.setBounds(drawableRect);
83     }
84 
85     @Nullable
getDrawable()86     public Drawable getDrawable() {
87         return mDrawable;
88     }
89 
getDrawableWidth()90     public int getDrawableWidth() {
91         return mDrawableWidth;
92     }
93 
getDrawableHeight()94     public int getDrawableHeight() {
95         return mDrawableHeight;
96     }
97 
98     @Override
onSizeChanged(int w, int h, int oldw, int oldh)99     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
100         super.onSizeChanged(w, h, oldw, oldh);
101         if (mDrawable != null) {
102             setDrawableSizeInternal(w, h);
103         }
104     }
105 
106     @Override
verifyDrawable(Drawable who)107     protected boolean verifyDrawable(Drawable who) {
108         return super.verifyDrawable(who) || who == mDrawable;
109     }
110 
111     @Override
drawableStateChanged()112     protected void drawableStateChanged() {
113         super.drawableStateChanged();
114 
115         final Drawable drawable = mDrawable;
116         if (drawable != null && drawable.isStateful()
117                 && drawable.setState(getDrawableState())) {
118             invalidateDrawable(drawable);
119         }
120     }
121 
122     @Override
onDraw(Canvas canvas)123     protected void onDraw(Canvas canvas) {
124         if (mDrawable != null) {
125             mDrawable.draw(canvas);
126         }
127     }
128 
129     @Override
hasOverlappingRendering()130     public boolean hasOverlappingRendering() {
131         return false;
132     }
133 
134     @Override
setAlpha(float alpha)135     public void setAlpha(float alpha) {
136         super.setAlpha(alpha);
137         if (alpha > 0) {
138             setVisibility(VISIBLE);
139         } else {
140             setVisibility(INVISIBLE);
141         }
142     }
143 
144     /**
145      * Set the tint color of the icon, useful for scrimming or dimming.
146      *
147      * @param color to blend in.
148      * @param amount [0,1] 0 no tint, 1 full tint
149      */
setIconColorTint(int color, float amount)150     public void setIconColorTint(int color, float amount) {
151         if (mDrawable != null) {
152             mDrawable.setColorFilter(Utilities.makeColorTintingColorFilter(color, amount));
153         }
154     }
155 }
156