package com.suno.android.common_ui.components.radial import androidx.compose.foundation.layout.Box import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.Layout import androidx.compose.ui.tooling.preview.Preview import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @Composable fun RadialLayout( modifier: Modifier = Modifier, items: List<@Composable () -> Unit>, radius: Float, angle: Float, originX: Float, originY: Float, ) { Layout( content = { items.forEach { item -> Box( contentAlignment = Alignment.CenterStart, modifier = Modifier.graphicsLayer { val itemAngle = angle + items.indexOf(item) * (360f / items.size) this.rotationZ = itemAngle // Adjust the rotation to be tangent plus 90 degrees }, ) { item() } } }, modifier = modifier, ) { measurableList, constraints -> val screenBoundConstraints = constraints.copy( maxWidth = 3000, ) val placeableList = measurableList.map { measurable -> measurable.measure(screenBoundConstraints) } layout(constraints.maxWidth, constraints.maxHeight) { val centerX = originX.toInt() val centerY = originY.toInt() placeableList.forEachIndexed { index, placeable -> val itemAngle = angle + index * (360f / items.size) val radians = itemAngle * PI / 180f val x = (centerX + radius * cos(radians)).toInt() - placeable.width / 2 val y = (centerY + radius * sin(radians)).toInt() - placeable.height / 2 placeable.placeRelative(x, y) } } } } @Preview( showSystemUi = true, ) @Composable private fun RadialLayout_Preview() { val testItems: List<@Composable () -> Unit> = (0..100).map { return Text(text = "$it") } RadialLayout( items = testItems, radius = 1000f, angle = 100f, originX = 100f, originY = 100f, ) }