Skip to content

Instantly share code, notes, and snippets.

@VizGhar
Created April 18, 2024 06:29
Show Gist options
  • Save VizGhar/982297c2d9ec705ba127e6f8d453dc07 to your computer and use it in GitHub Desktop.
Save VizGhar/982297c2d9ec705ba127e6f8d453dc07 to your computer and use it in GitHub Desktop.
package xyz.kandrac.u
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Composable
fun GroupBox(
modifier: Modifier = Modifier,
borderColor: Color,
borderWidth: Dp,
cornerRadius: Dp,
header: @Composable () -> Unit,
content: @Composable () -> Unit
) {
val headerHeightPx = remember { mutableStateOf(0f) }
val headerWidthPx = remember { mutableStateOf(0f) }
val cornerRadiusPx = with(LocalDensity.current) { cornerRadius.toPx() }
val borderWidthPx = with(LocalDensity.current) { borderWidth.toPx() }
Box(modifier = modifier) {
Box(modifier = Modifier
// TODO add padding from top based on headerHeightPx
.drawBehind {
// ramcek treba nakreslit rucne, kedze v nom ma byt vyrez pre header
drawLine(borderColor, Offset(cornerRadiusPx + headerWidthPx.value, 0f), Offset(size.width - cornerRadiusPx, 0f), borderWidthPx) // horna ciara koniec
drawLine(borderColor, Offset(0f, cornerRadiusPx), Offset(0f, size.height - cornerRadiusPx), borderWidthPx) // lava ciara
drawLine(borderColor, Offset(size.width, cornerRadiusPx), Offset(size.width, size.height - cornerRadiusPx), borderWidthPx) // prava ciara
drawLine(borderColor, Offset(cornerRadiusPx, size.height), Offset(size.width - cornerRadiusPx, size.height), borderWidthPx) // dolna ciara
drawArc(borderColor, 180f, 90f, false, Offset(0f, 0f), Size(cornerRadiusPx * 2, cornerRadiusPx * 2), 1f, Stroke(borderWidthPx)) // lavy horny roh
drawArc(borderColor, 270f, 90f, false, Offset(size.width - cornerRadiusPx * 2, 0f), Size(cornerRadiusPx * 2, cornerRadiusPx * 2), 1f, Stroke(borderWidthPx)) // pravy horny roh
drawArc(borderColor, 90f, 90f, false, Offset(0f, size.height - cornerRadiusPx * 2), Size(cornerRadiusPx * 2, cornerRadiusPx * 2), 1f, Stroke(borderWidthPx)) // lavy dolny roh
drawArc(borderColor, 0f, 90f, false, Offset(size.width - cornerRadiusPx * 2, size.height - cornerRadiusPx * 2), Size(cornerRadiusPx * 2, cornerRadiusPx * 2), 1f, Stroke(borderWidthPx)) // pravy dolny roh
}
) {
Column(Modifier.padding(12.dp)) {
content()
}
// TODO: dynamically compute offset based on headerHeightPx
BoxWithConstraints(modifier = Modifier.offset(y = -10.dp).padding(start = cornerRadius).onGloballyPositioned {
headerWidthPx.value = it.size.width.toFloat()
headerHeightPx.value = it.size.height.toFloat()
}) {
header()
}
}
}
}
@Composable
@Preview
fun GroupBoxPreview() {
GroupBox(
modifier = Modifier.padding(8.dp),
borderColor = Color.Black,
borderWidth = 4.dp,
cornerRadius = 20.dp,
header = { Text("GroupBox Sample") },
content = {
Column {
Text(text = "First Namef adsfdas fasdf asdfa ")
Text(text = "Last Name")
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment