HC05AC-CTRL/src/main/java/io/gitlab/jfronny/hc05ac/InputActivity.kt

78 lines
2.7 KiB
Kotlin

package io.gitlab.jfronny.hc05ac
import android.os.Bundle
import android.view.MotionEvent
import android.widget.TextView
import androidx.appcompat.widget.LinearLayoutCompat
import io.gitlab.jfronny.hc05ac.util.BaseActivity
import io.gitlab.jfronny.hc05ac.util.clamp
import io.gitlab.jfronny.hc05ac.util.putIfMissing
import java.util.*
/**
* Activity that divides the screen into two halves, each serving as an input controller.
* Implementations define a send function which is called for every update.
*/
abstract class InputActivity : BaseActivity() {
private var root: LinearLayoutCompat? = null
private var leftView: TextView? = null
private var rightView: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
root = findViewById(R.id.root)
leftView = findViewById(R.id.left)
rightView = findViewById(R.id.right)
}
private var left: Byte = 0
private var right: Byte = 0
private val sides: MutableMap<Int, Side> = TreeMap()
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.actionMasked) {
MotionEvent.ACTION_UP -> {
left = 0
right = 0
sides.clear()
}
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
val side = sides.putIfMissing(event.getPointerId(event.actionIndex)) {
if (event.getX(event.actionIndex) > root!!.width / 2) Side.RIGHT
else Side.LEFT
}
val mapped = screenToByte(event.getY(event.actionIndex))
if (side == Side.LEFT) left = mapped
else right = mapped
}
MotionEvent.ACTION_MOVE -> {
for ((id, side) in sides) {
val index = event.findPointerIndex(id)
val mapped = screenToByte(event.getY(index))
if (side == Side.LEFT) left = mapped
else right = mapped
}
}
MotionEvent.ACTION_POINTER_UP -> {
val side = sides.remove(event.getPointerId(event.actionIndex))
if (side != Side.LEFT) right = 0
if (side != Side.RIGHT) left = 0
}
else -> return false
}
leftView!!.text = left.toString()
rightView!!.text = right.toString()
send(left, right)
return false
}
private fun screenToByte(y: Float): Byte {
return (127 - (y * 255f / root!!.height).toInt().clamp(0, 255)).toByte()
}
private enum class Side {
LEFT, RIGHT
}
protected abstract fun send(left: Byte, right: Byte)
}