Skip to content

Commit

Permalink
Refactors drag, adds partially working multi-touch
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Aug 4, 2024
1 parent aa06095 commit c59f597
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 77 deletions.
110 changes: 70 additions & 40 deletions app/src/main/java/app/jerboa/spp/ui/view/SPPRenderer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,14 @@ class SPPRenderer(
private var arTime = 0
private var contTime = 0

private var draggedToy: Pair<TOY, Int>? = null
private var dragDelta: Vec2 = Vec2(0f,0f)
private var dragStartTime: Long = 0L
private var dragPlacedToy: Boolean = false
data class TouchEvent(
var draggedToy: Pair<TOY, Int>? = null,
var dragDelta: Vec2 = Vec2(0f,0f),
var dragStartTime: Long = 0L,
var dragPlacedToy: Boolean = false
)

private var touchEvents: MutableMap<UInt, TouchEvent> = mutableMapOf()

data class TapDelta (val distance: Float, val timeMillis: Long)
private val tapDelta = TapDelta(arScale*0.5f, 100L)
Expand Down Expand Up @@ -378,87 +382,104 @@ class SPPRenderer(
}

// drag event
fun drag(x: Float, y: Float, state: DRAG, toyType: TOY){
fun handleTouchEvent(x: Float, y: Float, state: DRAG, toyType: TOY, pointer: UInt){
if (DEMO_REAL){return}

if (pointer !in touchEvents)
{
touchEvents[pointer] = TouchEvent()
}
val touchEvent = touchEvents[pointer]!!

val w = screenToWorld(x,resolution.second-y)
val wx = w[0]
val wy = w[1]

when (state){
when (state) {
DRAG.START -> {
dragStartTime = System.currentTimeMillis()
touchEvent.dragStartTime = System.currentTimeMillis()
val toy = toySelected(wx, wy)
if (toy != null){
draggedToy = toy
if (toy != null) {
touchEvent.draggedToy = toy
onToyChanged(toy.first)
dragPlacedToy = false
}
else {
when (toyType)
{
touchEvent.dragPlacedToy = false
} else {
when (toyType) {
TOY.ATTRACTOR -> {
if (attractors.sizeBack < maxAorR){
if (attractors.sizeBack < maxAorR) {
attractors.add(Pair(wx, wy))
}
draggedToy = Pair(TOY.ATTRACTOR, attractors.sizeBack-1)
touchEvent.draggedToy = Pair(TOY.ATTRACTOR, attractors.sizeBack - 1)
onToyChanged(TOY.ATTRACTOR)
dragPlacedToy = true
touchEvent.dragPlacedToy = true
}

TOY.REPELLOR -> {
if (repellors.sizeBack < maxAorR) {
repellors.add(Pair(wx, wy))
}
draggedToy = Pair(TOY.REPELLOR, repellors.sizeBack-1)
touchEvent.draggedToy = Pair(TOY.REPELLOR, repellors.sizeBack - 1)
onToyChanged(TOY.REPELLOR)
dragPlacedToy = true
touchEvent.dragPlacedToy = true
}

TOY.SPINNER -> {
if (spinners.sizeBack < maxAorR){
if (spinners.sizeBack < maxAorR) {
spinners.add(Pair(wx, wy))
}
draggedToy = Pair(TOY.SPINNER, spinners.sizeBack-1)
touchEvent.draggedToy = Pair(TOY.SPINNER, spinners.sizeBack - 1)
onToyChanged(TOY.SPINNER)
dragPlacedToy = true
touchEvent.dragPlacedToy = true
}

TOY.FREEZER -> {
if (freezers.sizeBack < maxAorR){
if (freezers.sizeBack < maxAorR) {
freezers.add(Pair(wx, wy))
}
draggedToy = Pair(TOY.FREEZER, freezers.sizeBack-1)
touchEvent.draggedToy = Pair(TOY.FREEZER, freezers.sizeBack - 1)
onToyChanged(TOY.FREEZER)
dragPlacedToy = true
touchEvent.dragPlacedToy = true
}

TOY.ORBITER -> {
if (orbiters.sizeBack < maxAorR){
if (orbiters.sizeBack < maxAorR) {
orbiters.add(Pair(wx, wy))
}
draggedToy = Pair(TOY.ORBITER, orbiters.sizeBack-1)
touchEvent.draggedToy = Pair(TOY.ORBITER, orbiters.sizeBack - 1)
onToyChanged(TOY.ORBITER)
dragPlacedToy = true
touchEvent.dragPlacedToy = true
}

TOY.NOTHING -> {
touchEvent.dragPlacedToy = false
}
TOY.NOTHING -> {dragPlacedToy = false}
}
}
dragDelta = Vec2(0f,0f)
touchEvent.dragDelta = Vec2(0f, 0f)
touchEvents[pointer] = touchEvent
}

DRAG.STOP -> {
draggedToy = null
touchEvent.draggedToy = null

if (dragPlacedToy){dragPlacedToy = false; return}
if (touchEvent.dragPlacedToy) {
touchEvent.dragPlacedToy = false; return
}

val dragDistance2 = dragDelta.x*dragDelta.x + dragDelta.y*dragDelta.y
val dragTime = System.currentTimeMillis() - dragStartTime
dragStartTime = 0L
if (dragDistance2 < tapDelta.distance*tapDelta.distance || dragTime < tapDelta.timeMillis)
{
val d = touchEvent.dragDelta
val dragDistance2 = d.x * d.x + d.y * d.y
val dragTime = System.currentTimeMillis() - touchEvent.dragStartTime
touchEvent.dragStartTime = 0L
if (dragDistance2 < tapDelta.distance * tapDelta.distance || dragTime < tapDelta.timeMillis) {
touchEvents.remove(pointer)
tap(x, y, toyType)
}

}

DRAG.CONTINUE -> {
var dx: Float = 0f
var dy: Float = 0f
val toy = draggedToy
val toy = touchEvent.draggedToy
if (toy != null) {
when (toy.first) {
TOY.ATTRACTOR -> {
Expand All @@ -468,38 +489,47 @@ class SPPRenderer(
attractors[toy.second] = Pair(wx, wy)
}
}

TOY.REPELLOR -> {
if (toy.second in repellors.indicesBack) {
dx = wx - repellors.getBack(toy.second).first
dy = wy - repellors.getBack(toy.second).second
repellors[toy.second] = Pair(wx, wy)
}
}

TOY.SPINNER -> {
if (toy.second in spinners.indicesBack) {
dx = wx - spinners.getBack(toy.second).first
dy = wy - spinners.getBack(toy.second).second
spinners[toy.second] = Pair(wx, wy)
}
}

TOY.FREEZER -> {
if (toy.second in freezers.indicesBack) {
dx = wx - freezers.getBack(toy.second).first
dy = wy - freezers.getBack(toy.second).second
freezers[toy.second] = Pair(wx, wy)
}
}

TOY.ORBITER -> {
if (toy.second in orbiters.indicesBack) {
dx = wx - orbiters.getBack(toy.second).first
dy = wy - orbiters.getBack(toy.second).second
orbiters[toy.second] = Pair(wx, wy)
}
}

TOY.NOTHING -> {}
}
}
dragDelta = Vec2(dragDelta.x + sqrt(dx*dx), dragDelta.y + sqrt(dy*dy))
touchEvent.dragDelta = Vec2(
touchEvent.dragDelta.x + sqrt(dx * dx),
touchEvent.dragDelta.y + sqrt(dy * dy)
)
touchEvents[pointer] = touchEvent
}
}
}
Expand Down
66 changes: 29 additions & 37 deletions app/src/main/java/app/jerboa/spp/ui/view/SPPView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app.jerboa.spp.ui.view
import android.content.Context
import android.opengl.GLSurfaceView
import android.util.AttributeSet
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import androidx.core.view.GestureDetectorCompat
Expand Down Expand Up @@ -37,15 +38,9 @@ class SPPView (
allowAdapt,
colourMap
)
private val gestures: GestureDetectorCompat = GestureDetectorCompat(context,this)
private val gestures: GestureDetector = GestureDetector(context,this)
var isDisplayingMenuChanged: Boolean = false

private var lastTouchX: Float = 0f
private var lastTouchY: Float = 0f
private var posX: Float = 0f
private var posY: Float = 0f
private var pointerId: Int = 0

init {
setEGLContextClientVersion(3)
preserveEGLContextOnPause = true
Expand Down Expand Up @@ -90,46 +85,43 @@ class SPPView (
}

override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
Log.d("event", "${event.action}")
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
event.actionIndex.also { pointer ->
lastTouchX = event.getX(pointer)
lastTouchY = event.getY(pointer)
renderer.handleTouchEvent(
event.getX(pointer),
event.getY(pointer),
DRAG.START,
placingToy,
0U
)
}
renderer.drag(lastTouchX,lastTouchY,DRAG.START, placingToy)
pointerId = event.getPointerId(0)
}
MotionEvent.ACTION_MOVE -> {
val pointer = event.findPointerIndex(pointerId)
if (pointer in 0..event.pointerCount) {

val (x: Float, y: Float) = pointer.let {
event.getX(pointer) to event.getY(pointer)
}

posX += x - lastTouchX
posY += y - lastTouchY

invalidate()

lastTouchX = x
lastTouchY = y

renderer.drag(x, y, DRAG.CONTINUE, placingToy)
}
MotionEvent.ACTION_POINTER_DOWN -> {
event.actionIndex.also { pointer ->
renderer.handleTouchEvent(
event.getX(pointer),
event.getY(pointer),
DRAG.START,
placingToy,
event.actionIndex.toUInt()
)
}
}
MotionEvent.ACTION_MOVE -> {
val pointer = event.findPointerIndex(event.actionIndex)
renderer.handleTouchEvent(event.getX(pointer), event.getY(pointer), DRAG.CONTINUE, placingToy, event.actionIndex.toUInt())
}
MotionEvent.ACTION_UP -> {
pointerId = MotionEvent.INVALID_POINTER_ID
renderer.drag(lastTouchX,lastTouchY,DRAG.STOP, placingToy)
renderer.handleTouchEvent(event.getX(0),event.getY(0),DRAG.STOP, placingToy, event.actionIndex.toUInt())
}
MotionEvent.ACTION_POINTER_UP -> {
event.actionIndex.also { pointer ->
event.getPointerId(pointer).takeIf { it == pointerId }
?.run {
val newPointerIndex = if (pointer == 0) 1 else 0
lastTouchX = event.getX(newPointerIndex)
lastTouchY = event.getY(newPointerIndex)
renderer.drag(lastTouchX,lastTouchY,DRAG.STOP, placingToy)
event.getPointerId(pointer)
.run {
renderer.handleTouchEvent(event.getX(pointer),event.getY(pointer),DRAG.STOP, placingToy, event.actionIndex.toUInt())
}
}
}
Expand Down

0 comments on commit c59f597

Please sign in to comment.