1 /*
2  * Copyright (C) 2020 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.wallpaper.widget;
17 
18 import android.graphics.Canvas;
19 import android.graphics.ColorFilter;
20 import android.graphics.Paint;
21 import android.graphics.PixelFormat;
22 import android.graphics.PorterDuff;
23 import android.graphics.PorterDuffXfermode;
24 import android.graphics.Rect;
25 import android.graphics.RectF;
26 import android.graphics.drawable.Drawable;
27 import android.view.ViewOverlay;
28 
29 import androidx.annotation.Nullable;
30 
31 /**
32  * Translucent Drawable to be rendered on a {@link ViewOverlay} to allow the window background
33  * to be seen through it.
34  */
35 public class LiveTileOverlay extends Drawable {
36 
37     public static final LiveTileOverlay INSTANCE = new LiveTileOverlay();
38 
39     private final Paint mPaint = new Paint();
40     private final Rect mBoundsRect = new Rect();
41 
42     private RectF mCurrentRect;
43     private float mCornerRadius;
44 
45     private boolean mIsAttached;
46 
47     private Drawable mForegroundDrawable;
48 
LiveTileOverlay()49     private LiveTileOverlay() {
50         mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
51     }
52 
53     /**
54      * Update the position and radius of the overlay.
55      */
update(RectF currentRect, float cornerRadius)56     public void update(RectF currentRect, float cornerRadius) {
57         invalidateSelf();
58 
59         mCurrentRect = currentRect;
60         mCornerRadius = cornerRadius;
61 
62         mCurrentRect.roundOut(mBoundsRect);
63         setBounds(mBoundsRect);
64         invalidateSelf();
65     }
66 
67     @Override
draw(Canvas canvas)68     public void draw(Canvas canvas) {
69         if (mCurrentRect != null) {
70             canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint);
71             if (mForegroundDrawable != null) {
72                 mForegroundDrawable.draw(canvas);
73             }
74         }
75     }
76 
77     @Override
setAlpha(int i)78     public void setAlpha(int i) { }
79 
80     @Override
setColorFilter(ColorFilter colorFilter)81     public void setColorFilter(ColorFilter colorFilter) { }
82 
83     @Override
getOpacity()84     public int getOpacity() {
85         return PixelFormat.TRANSLUCENT;
86     }
87 
88     /**
89      * Attach this drawable to a given {@link ViewOverlay}
90      * @return true if the drawable was newly attached, false if it was already attached or it
91      *          couldn't be attached
92      */
attach(ViewOverlay overlay)93     public boolean attach(ViewOverlay overlay) {
94         if (overlay != null && !mIsAttached) {
95             overlay.add(this);
96             mIsAttached = true;
97             return true;
98         }
99 
100         return false;
101     }
102 
103     /**
104      * Detach this drawable from the given overlay
105      * @param overlay
106      */
detach(ViewOverlay overlay)107     public void detach(ViewOverlay overlay) {
108         if (overlay != null) {
109             overlay.remove(this);
110             mIsAttached = false;
111         }
112     }
113 
114     /**
115      * Set a drawable to be drawn on top of this one.
116      */
setForegroundDrawable(@ullable Drawable foregroundDrawable)117     public void setForegroundDrawable(@Nullable Drawable foregroundDrawable) {
118         mForegroundDrawable = foregroundDrawable;
119         invalidateSelf();
120     }
121 }
122