Skip to content

Instantly share code, notes, and snippets.

@AlexKGwyn
Created April 23, 2023 14:51
Show Gist options
  • Save AlexKGwyn/bd404385ef659a94e18d35599bf7798e to your computer and use it in GitHub Desktop.
Save AlexKGwyn/bd404385ef659a94e18d35599bf7798e to your computer and use it in GitHub Desktop.
Jetpack Compose MacOS Pinch to Zoom modifier
@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE")
package com.lottieworks.app.ui
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.onGloballyPositioned
import com.apple.eawt.event.GestureUtilities
import com.apple.eawt.event.MagnificationListener
import com.lottieworks.app.ui.component.SwingWindow
import javax.swing.SwingUtilities
fun Modifier.pinchZoom(key: Any, onPinchZoom: (magnification: Float, focal: Offset) -> Unit) = composed {
val window = SwingWindow.current
val rootPane = remember(key, window) { SwingUtilities.getRootPane(window) }
var lastPointer: Offset? by remember(key) { mutableStateOf(null) }
var layoutCoordinates: LayoutCoordinates? by remember(key) { mutableStateOf(null) }
DisposableEffect(key, rootPane) {
val listener = MagnificationListener { e ->
if (e != null) {
lastPointer?.let { lastPointer -> onPinchZoom(1 + e.magnification.toFloat(), lastPointer) }
e.consume()
}
}
GestureUtilities.addGestureListenerTo(rootPane, listener)
onDispose {
GestureUtilities.removeGestureListenerFrom(rootPane, listener)
}
}
pointerInput(key) {
awaitPointerEventScope {
while (true) {
val event = awaitPointerEvent()
lastPointer = if (event.type == PointerEventType.Exit) {
null
} else {
layoutCoordinates?.windowToLocal(event.changes.first().position)
}
}
}
}.onGloballyPositioned {
layoutCoordinates = it
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment