0

I'm trying to make a composable with a line shape. These lines will be connecting any two coordinates together, meaning it won't be a straight horizontal/vertical line, I know I can use divider for that.

I can do a line in drawWithCache (compose desktop's equivalent of Canvas), but these lines are neither hoverable nor clickable.

Afaik clipping a box with a custom shape won't be helping here because hover and click events will still work with a rectangle shape.

Is there any way at all that I can do this?

P.S. I would love it if I could extend a solution to make other shapes, such as a line with Bezier's curve applied.

Shazniq
  • 423
  • 4
  • 16

1 Answers1

0

I've found the solution. Modifier.clipToBounds won't work, but Modifier.clip(shape) does.

@Composable
fun Line() {
    var top by remember { mutableStateOf(false) }
    val shape = if (top) {
        LineShapeTop
    } else {
        LineShapeBottom
    }
    Box(
        Modifier
            .background(color = Color.Blue, shape = shape)
            .clip(shape)
            .fillMaxSize()
            .clickable { top = !top }
    )
}
object LineShapeTop : Shape {
    const val strokeWidth = 16.0f
    override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
        val path = Path().apply {
            moveTo(0f, 0f)
            lineTo(size.width/2 + strokeWidth, 0f)
            lineTo(size.width/2 + strokeWidth, size.height- strokeWidth)
            lineTo(size.width, size.height- strokeWidth)

            lineTo(size.width, size.height)
            lineTo(size.width/2, size.height)
            lineTo(size.width/2, strokeWidth)
            lineTo(0f, strokeWidth)
            close()
        }
        return Outline.Generic(path)
    }
}
object LineShapeBottom : Shape {
    const val strokeWidth = 16.0f
    override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
        val path = Path().apply {
            moveTo(0f, size.height)

            lineTo(size.width/2 + strokeWidth, size.height)
            lineTo(size.width/2 + strokeWidth, strokeWidth)
            lineTo(size.width, strokeWidth)
            lineTo(size.width, 0f)
            lineTo(size.width/2, 0f)
            lineTo(size.width/2, size.height- strokeWidth)
            lineTo(0f, size.height- strokeWidth)
            close()
        }
        return Outline.Generic(path)
    }
}

FirstSecond

Shazniq
  • 423
  • 4
  • 16