in lets-plot-compose/src/desktopMain/kotlin/org/jetbrains/letsPlot/compose/desktop/SvgViewPanel.kt [24:103]
fun SvgViewPanel(
svgView: SvgView,
modifier: Modifier = Modifier
) {
val density = LocalDensity.current.density
var clickCount by remember { mutableStateOf(0) }
var lastClickTime by remember { mutableStateOf(0L) }
var canvasSize by remember { mutableStateOf(IntSize.Zero) }
var redrawTrigger by remember { mutableStateOf(0) }
// Set up the redraw callback
DisposableEffect(svgView) {
svgView.onRedrawRequested = {
redrawTrigger++
}
onDispose {
svgView.onRedrawRequested = null
}
}
// Force recomposition when SVG content or canvas size changes
val svg = svgView.svg
LaunchedEffect(svg, canvasSize) {
if (canvasSize.width > 0 && canvasSize.height > 0) {
redrawTrigger++
}
}
Canvas(
modifier = modifier
.pointerHoverIcon(PointerIcon(Cursor(Cursor.CROSSHAIR_CURSOR)))
.onSizeChanged { size ->
// Convert canvas logical pixels (from Compose layout) to physical pixels (plot SVG pixels)
val width = (size.width / density).toInt()
val height = (size.height / density).toInt()
canvasSize = IntSize(width, height)
}
.pointerInput(Unit) {
awaitPointerEventScope {
while (true) {
val event = awaitPointerEvent()
when (event.type) {
PointerEventType.Press -> {
val currentTime = System.currentTimeMillis()
clickCount = if (currentTime - lastClickTime < 300) {
clickCount + 1
} else {
1
}
lastClickTime = currentTime
svgView.handlePointerEvent(event)
}
PointerEventType.Release -> {
if (clickCount > 0) {
val position = event.changes.first().position
svgView.handleClick(position, clickCount)
if (clickCount > 1) {
clickCount = 0 // Reset after a double click
}
}
svgView.handlePointerEvent(event)
}
PointerEventType.Move,
PointerEventType.Enter,
PointerEventType.Exit,
PointerEventType.Scroll -> {
svgView.handlePointerEvent(event)
}
}
}
}
}
) {
drawSvgContent(svgView, this, canvasSize, redrawTrigger)
}
}