|
|
@@ -5,7 +5,7 @@
|
|
|
* e: mj@mjdev.org
|
|
|
* w: https://mjdev.org
|
|
|
*/
|
|
|
-package org.mjdev.tvlib.ui
|
|
|
+package org.mjdev.tvlib.ui.components.special
|
|
|
|
|
|
import android.content.Context
|
|
|
import android.graphics.Bitmap
|
|
|
@@ -13,9 +13,14 @@ import android.graphics.Canvas
|
|
|
import android.graphics.Color
|
|
|
import android.util.AttributeSet
|
|
|
import android.view.View
|
|
|
+import androidx.compose.runtime.Composable
|
|
|
+import androidx.compose.ui.Modifier
|
|
|
+import androidx.compose.ui.viewinterop.AndroidView
|
|
|
+import org.mjdev.tvlib.annotations.Previews
|
|
|
import java.util.Random
|
|
|
import java.util.Timer
|
|
|
import java.util.TimerTask
|
|
|
+import kotlin.math.max
|
|
|
|
|
|
class AnalogTvNoise @JvmOverloads constructor(
|
|
|
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
|
|
@@ -23,22 +28,22 @@ class AnalogTvNoise @JvmOverloads constructor(
|
|
|
private val mRandom = Random(System.currentTimeMillis())
|
|
|
private var mTileWidth = 0
|
|
|
private var mTileHeight = 0
|
|
|
- private var mScalledBitmap: Bitmap? = null
|
|
|
+ private var mScaledBitmap: Bitmap? = null
|
|
|
private var mBitmap: Bitmap? = null
|
|
|
private var mPixels: IntArray? = null
|
|
|
private var mTimer: Timer? = null
|
|
|
|
|
|
override fun onDraw(canvas: Canvas) {
|
|
|
- if (mScalledBitmap == null) return
|
|
|
- for (i in 0 until DIVIDER_WIDTH_SCALLED) {
|
|
|
- canvas.drawBitmap(mScalledBitmap!!, (i * mScalledBitmap!!.width).toFloat(), 0f, null)
|
|
|
+ if (mScaledBitmap == null) return
|
|
|
+ for (i in 0 until DIVIDER_WIDTH_SCALED) {
|
|
|
+ canvas.drawBitmap(mScaledBitmap!!, (i * mScaledBitmap!!.width).toFloat(), 0f, null)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
|
super.onLayout(changed, left, top, right, bottom)
|
|
|
- val tileWidth = width / DIVIDER_WIDTH
|
|
|
- val tileHeight = height / DIVIDER_HEIGHT
|
|
|
+ val tileWidth = max(1, width / DIVIDER_WIDTH)
|
|
|
+ val tileHeight = max(1, height / DIVIDER_HEIGHT)
|
|
|
if (mTileWidth != tileWidth || mTileHeight != tileHeight || mPixels == null) {
|
|
|
mPixels = IntArray(tileWidth * tileHeight)
|
|
|
mBitmap = Bitmap.createBitmap(tileWidth, tileHeight, Bitmap.Config.RGB_565)
|
|
|
@@ -85,19 +90,37 @@ class AnalogTvNoise @JvmOverloads constructor(
|
|
|
private fun generateNoise() {
|
|
|
if (mPixels == null || mBitmap == null) return
|
|
|
for (i in 0 until mTileWidth * mTileHeight) {
|
|
|
- val pix = Math.max(40, mRandom.nextInt(255))
|
|
|
+ val pix = max(40, mRandom.nextInt(255))
|
|
|
mPixels!![i] = Color.rgb(pix, pix, pix)
|
|
|
}
|
|
|
- val width = width / DIVIDER_WIDTH_SCALLED
|
|
|
+ val width = width / DIVIDER_WIDTH_SCALED
|
|
|
mBitmap?.setPixels(mPixels!!, 0, mTileWidth, 0, 0, mTileWidth, mTileHeight)
|
|
|
- mScalledBitmap = Bitmap.createScaledBitmap(mBitmap!!, width, height, false)
|
|
|
+ mScaledBitmap = Bitmap.createScaledBitmap(
|
|
|
+ mBitmap!!,
|
|
|
+ max(1, width),
|
|
|
+ max(1, height),
|
|
|
+ false
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
companion object {
|
|
|
private const val DIVIDER_WIDTH = 8
|
|
|
private const val DIVIDER_HEIGHT = 4
|
|
|
- private const val DIVIDER_WIDTH_SCALLED = 2
|
|
|
+ private const val DIVIDER_WIDTH_SCALED = 2
|
|
|
private const val ANIM_INTERVAL = 50
|
|
|
}
|
|
|
|
|
|
+}
|
|
|
+
|
|
|
+@Previews
|
|
|
+@Composable
|
|
|
+fun AnalogTvNoise(
|
|
|
+ modifier: Modifier = Modifier
|
|
|
+) {
|
|
|
+ AndroidView(
|
|
|
+ modifier = modifier,
|
|
|
+ factory = { context ->
|
|
|
+ AnalogTvNoise(context)
|
|
|
+ }
|
|
|
+ )
|
|
|
}
|