From a359a5e191f4d46240052a7afec358124779bf31 Mon Sep 17 00:00:00 2001 From: Tretzi Date: Fri, 20 Mar 2026 00:01:24 -0500 Subject: [PATCH] Auto commit Fri Mar 20 12:01:19 AM CDT 2026 --- .../mvp/session/TimelineEditorScreen.kt | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/mindmachine/mvp/session/TimelineEditorScreen.kt b/app/src/main/java/com/mindmachine/mvp/session/TimelineEditorScreen.kt index e901433..ec97bbd 100644 --- a/app/src/main/java/com/mindmachine/mvp/session/TimelineEditorScreen.kt +++ b/app/src/main/java/com/mindmachine/mvp/session/TimelineEditorScreen.kt @@ -4,9 +4,11 @@ import android.view.HapticFeedbackConstants import androidx.activity.compose.BackHandler import androidx.compose.foundation.Canvas import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.calculateCentroid +import androidx.compose.foundation.gestures.calculatePan +import androidx.compose.foundation.gestures.calculateZoom import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.gestures.detectTransformGestures import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -31,6 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path +import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign @@ -255,6 +258,36 @@ internal fun TimelineGraph( .fillMaxWidth() .height(190.dp) .background(Color(0xFF0A0E18), RoundedCornerShape(10.dp)) + .pointerInput(activeCurve, viewport, curveLeft, curveRight) { + awaitPointerEventScope { + while (true) { + val event = awaitPointerEvent(pass = PointerEventPass.Initial) + val pressedCount = event.changes.count { it.pressed } + if (pressedCount < 2) continue + + val zoom = event.calculateZoom() + val pan = event.calculatePan() + val centroid = event.calculateCentroid(useCurrent = true) + + if (zoom != 1f || pan.x != 0f || pan.y != 0f) { + val newViewport = viewport.applyZoomPan( + zoomChange = zoom, + panPx = pan.x, + widthPx = size.width.toFloat(), + centroidPx = centroid.x, + ) + onViewportChanged(newViewport) + } + + // Reserve all 2+ finger gestures for transform handling so they don't + // compete with one-finger point/handle drags. + event.changes.forEach { it.consume() } + draggingPointIndex = null + draggingCurveId = null + dragMode = HandleDrag.NONE + } + } + } .pointerInput(viewport, selection, curveLeft, curveRight, activeCurve) { detectDragGestures( onDragStart = { start -> @@ -340,17 +373,6 @@ internal fun TimelineGraph( } ) } - .pointerInput(activeCurve, viewport, curveLeft, curveRight) { - detectTransformGestures { centroid, pan, zoom, _ -> - val newViewport = viewport.applyZoomPan( - zoomChange = zoom, - panPx = pan.x, - widthPx = size.width.toFloat(), - centroidPx = centroid.x, - ) - onViewportChanged(newViewport) - } - } .pointerInput(activeCurve) { detectTapGestures( onTap = { offset ->