oleksandrbalan/minabox

ScrollbarAdapter

Closed this issue · 1 comments

Hi,
Is there any ScrollbarAdapter for MinaBox / LazyTable states?

Hi 👋

I am not sure what do you mean by "adapters", but you could fairly easy draw some scrollbars on canvas using translate state property of the MinaBoxState.

For example it could be something like this:

@Composable
private fun Scrollbars(
    translate: MinaBoxState.Translate,
    modifier: Modifier = Modifier
) {
    val scrollbarsWidth = 4.dp
    val scrollbarsColor = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f)
    Canvas(modifier) {
        val scrollbarsWidthPx = scrollbarsWidth.roundToPx()

        val totalHeight = translate.maxY + size.height
        val verticalRatio = totalHeight / size.height
        val startY = translate.y / verticalRatio
        val endY = (translate.y + size.height) / verticalRatio

        drawLine(
            color = scrollbarsColor,
            start = Offset(size.width - scrollbarsWidthPx / 2, startY),
            end = Offset(size.width - scrollbarsWidthPx / 2, endY),
            strokeWidth = scrollbarsWidthPx.toFloat(),
            cap = StrokeCap.Round,
        )

        val totalWidth = translate.maxX + size.width
        val horizontalRatio = totalWidth / size.width
        val startX = translate.x / horizontalRatio
        val endX = (translate.x + size.width) / horizontalRatio

        drawLine(
            color = scrollbarsColor,
            start = Offset(startX, size.height - scrollbarsWidthPx / 2),
            end = Offset(endX, size.height - scrollbarsWidthPx / 2),
            strokeWidth = scrollbarsWidthPx.toFloat(),
            cap = StrokeCap.Round,
        )
    }
}

With a usage inside a Box over the MinaBox layout:

Box {
    val state = rememberMinaBoxState()

    MinaBox(
        state = state,
        modifier = Modifier.fillMaxSize()
    ) { ... }

    val translate = state.translate
    if (translate != null) {
        Scrollbars(
            translate = translate,
            modifier = Modifier.fillMaxSize()
        )
    }
}
Screen.Recording.2023-09-08.at.19.57.04.mov

In the LazyTable you could do the same, as you could reach for Translate through minaBoxState property.

val state = rememberLazyTableState()
val translate = state.minaBoxState.translate

If you want some interactive scrollbars (for desktop) I guess it could be achieved with the same math, but applied to the .offset() and .size() modifiers of some draggable composable elements.