ShaderBlurDrawable.kt 4.12 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package foundation.e.blisslauncher.core.blur

import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PixelFormat
import android.graphics.RectF
import android.graphics.Shader
import android.graphics.drawable.Drawable
import foundation.e.blisslauncher.core.DeviceProfile

class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider: BlurWallpaperProvider) :
    Drawable(), BlurWallpaperProvider.Listener {

    private var blurAlpha = 255
    private val blurPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG)
    private var blurBitmap: Bitmap? = null
        set(value) {
            if (field != value) {
                field = value
                blurPaint.shader =
                    value?.let { BitmapShader(it, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) }
            }
        }

    private val blurBounds = RectF()
Amit Kumar's avatar
Amit Kumar committed
30
    var canvasOffset: Float = 0f
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    private val blurPath = Path()
    private var blurPathValid = false
        set(value) {
            if (field != value) {
                field = value
                if (!value) {
                    invalidateSelf()
                }
            }
        }

    var noRadius = true

    override fun draw(canvas: Canvas) = draw(canvas, noRadius)

    fun draw(canvas: Canvas, noRadius: Boolean = false) {
        if (blurAlpha == 0) return
Amit Kumar's avatar
Amit Kumar committed
48
        if (blurBounds.right.toInt() - blurBounds.left.toInt() == 0) return
49
50
        blurBitmap = blurWallpaperProvider.wallpaper

51
        if (blurBitmap == null) {
52
53
54
            blurBitmap = blurWallpaperProvider.placeholder
        }
        blurBitmap =
55
56
57
            if (blurBitmap!!.height >= blurBounds.bottom &&
                blurBitmap!!.width >= blurBounds.right
            ) {
58
59
60
61
62
63
64
65
66
67
                Bitmap.createBitmap(
                    blurBitmap!!,
                    blurBounds.left.toInt(), blurBounds.top.toInt(),
                    blurBounds.right.toInt() - blurBounds.left.toInt(),
                    blurBounds.bottom.toInt() - blurBounds.top.toInt()
                )
            } else {
                blurBitmap
            }

68
        // setupBlurPath()
69

Amit Kumar's avatar
Amit Kumar committed
70
71
72
73
74
        // We check the offset just to make sure we don't translate it incorrectly
        // when moving back to home screen from widget page.
        if (canvasOffset > 0) {
            canvas.translate(canvasOffset, 0f)
        }
75
76
77
78
79
80
81
82
83
        if (noRadius) {
            canvas.drawRect(
                0f, 0f,
                blurBounds.right - blurBounds.left, blurBounds.bottom - blurBounds.top,
                blurPaint
            )
        } else {
            canvas.drawPath(DeviceProfile.path, blurPaint)
        }
Amit Kumar's avatar
Amit Kumar committed
84
85
86

        if (canvasOffset > 0)
            canvas.translate(-canvasOffset, 0f)
87
    }
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
    override fun setAlpha(alpha: Int) {
        blurAlpha = alpha
        blurPaint.alpha = alpha
    }

    override fun getAlpha(): Int {
        return blurAlpha
    }

    private fun setupBlurPath() {
        if (blurPathValid) return

        blurPath.reset()
        blurPath.addRect(
103
104
105
106
107
            0f,
            0f,
            blurBounds.right - blurBounds.left,
            blurBounds.bottom - blurBounds.top,
            Path.Direction.CW
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
        )
    }

    override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) =
        setBlurBounds(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())

    fun setBlurBounds(left: Float, top: Float, right: Float, bottom: Float) {
        if (blurBounds.left != left ||
            blurBounds.top != top ||
            blurBounds.right != right ||
            blurBounds.bottom != bottom
        ) {
            blurBounds.set(left, top, right, bottom)
            blurPathValid = false
        }
    }

    override fun getOpacity(): Int = PixelFormat.TRANSLUCENT

    override fun onWallpaperChanged() {
        invalidateSelf()
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
    }

    fun startListening() = blurWallpaperProvider.addListener(this)

    fun stopListening() = blurWallpaperProvider.removeListener(this)
137
}