fun SvgViewPanel()

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)
    }
}