SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/drawable/MediaBackgroundDrawable.kt

101 lines
3.0 KiB
Kotlin

package jp.juggler.subwaytooter.drawable
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
import jp.juggler.subwaytooter.R
import jp.juggler.util.ui.attrColor
import kotlin.math.min
class MediaBackgroundDrawable(
private val context: Context,
private val tileStep: Int,
private val kind: Kind,
) : Drawable() {
enum class Kind(
val c1: Context.() -> Int,
val c2: Context.() -> Int,
val isMediaBackground: Boolean = true,
) {
Black({ Color.BLACK }, { 0 }),
BlackTile({ Color.BLACK }, { Color.BLACK or 0x202020 }),
Grey({ Color.BLACK or 0x787878 }, { 0 }),
GreyTile({ Color.BLACK or 0x707070 }, { Color.BLACK or 0x808080 }),
White({ Color.WHITE }, { 0 }),
WhiteTile({ Color.WHITE }, { Color.BLACK or 0xe0e0e0 }),
EmojiPickerBg(
{ attrColor(R.attr.colorWindowBackground) },
{ attrColor(R.attr.colorTimeSmall) },
isMediaBackground = false
),
;
fun toIndex() = entries.indexOf(this)
companion object {
fun fromIndex(idx: Int) = entries.elementAtOrNull(idx) ?: BlackTile
}
}
private val rect = Rect()
private val paint = Paint().apply {
style = Paint.Style.FILL
}
override fun setAlpha(alpha: Int) {
paint.alpha = alpha
}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
}
@Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated("deprecated in API level 29.")
override fun getOpacity() = when (paint.alpha) {
255 -> PixelFormat.OPAQUE
0 -> PixelFormat.TRANSPARENT
else -> PixelFormat.TRANSLUCENT
}
override fun draw(canvas: Canvas) {
val bounds = this.bounds
val c1 = kind.c1.invoke(context)
val c2 = kind.c2.invoke(context)
if (c2 == 0) {
paint.color = c1
canvas.drawRect(bounds, paint)
return
}
val xStart = bounds.left
val xRepeat = (bounds.right - bounds.left + tileStep - 1) / tileStep
val yStart = bounds.top
val yRepeat = (bounds.bottom - bounds.top + tileStep - 1) / tileStep
for (y in 0 until yRepeat) {
val ys = yStart + y * tileStep
rect.top = ys
rect.bottom = min(bounds.bottom, ys + tileStep)
for (x in 0 until xRepeat) {
paint.color = when ((x + y).and(1)) {
0 -> c1
else -> c2
}
val xs = xStart + x * tileStep
rect.left = xs
rect.right = min(bounds.right, xs + tileStep)
canvas.drawRect(rect, paint)
}
}
}
}