Refactor showSelectItemWithIcon layout

This commit is contained in:
tarsin committed 2023-07-03 10:24:31 +08:00
1 parent 174e899ead
commit 8c0e217117
2 files changed
+66 -16

No files matched your search

@@ -0,0 +1,46 @@
package com.hippo.ehviewer.ui.tools
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.unit.Dp
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.roundToInt
import kotlin.math.sin
private const val FullCircle: Float = (PI * 2).toFloat()
private const val QuarterCircle = PI / 2
@Composable
fun CircularLayout(
modifier: Modifier = Modifier,
radius: Dp,
content: @Composable () -> Unit,
) {
Layout(
modifier = modifier,
content = content,
) { measurables, constraints ->
val radiusPx = radius.toPx()
val itemConstraints = constraints.copy(minWidth = 0, minHeight = 0)
val placeables = measurables.map { measurable -> measurable.measure(itemConstraints) }
val theta = FullCircle / (placeables.count())
layout(
width = constraints.minWidth,
height = constraints.minHeight,
) {
placeables.forEachIndexed { i, it ->
val centerOffsetX = constraints.maxWidth / 2 - it.width / 2
val centerOffsetY = constraints.maxHeight / 2 - it.height / 2
val offsetX = radiusPx * cos(theta * i - QuarterCircle) + centerOffsetX
val offsetY = radiusPx * sin(theta * i - QuarterCircle) + centerOffsetY
it.place(
x = offsetX.roundToInt(),
y = offsetY.roundToInt(),
)
}
}
}
}
@@ -4,6 +4,8 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -25,6 +27,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
@@ -115,7 +118,7 @@ class DialogState {
}
}
private suspend fun <R> showNoButton(block: @Composable DismissDialogScope<R>.() -> Unit): R {
private suspend fun <R> showNoButton(respectDefaultWidth: Boolean = true, block: @Composable DismissDialogScope<R>.() -> Unit): R {
return suspendCancellableCoroutine { cont ->
cont.invokeOnCancellation { dismiss() }
content = {
@@ -132,7 +135,7 @@ class DialogState {
},
content = {
Surface(
modifier = Modifier.width(280.dp),
modifier = with(Modifier) { if (!respectDefaultWidth) defaultMinSize(280.dp) else width(280.dp) },
shape = AlertDialogDefaults.shape,
color = AlertDialogDefaults.containerColor,
tonalElevation = AlertDialogDefaults.TonalElevation,
@@ -184,21 +187,22 @@ class DialogState {
suspend fun showSelectItemWithIcon(
vararg items: Pair<ImageVector, String>,
@StringRes title: Int,
): Int = showNoButton {
LazyColumn {
stickyHeader {
Text(text = stringResource(id = title), modifier = Modifier.padding(horizontal = 16.dp).padding(top = 16.dp), style = MaterialTheme.typography.titleMedium)
}
itemsIndexed(items) { index, (icon, text) ->
ListItem(
headlineContent = {
Text(text = text, style = MaterialTheme.typography.titleMedium)
},
modifier = Modifier.clickable { dismissWith(index) },
leadingContent = {
): Int = showNoButton(false) {
Column {
Text(text = stringResource(id = title), modifier = Modifier.padding(horizontal = 16.dp).padding(top = 16.dp), style = MaterialTheme.typography.titleMedium)
CircularLayout(
radius = 112.dp,
modifier = Modifier.fillMaxWidth().aspectRatio(1F),
) {
items.forEachIndexed { index, (icon, text) ->
Column(
modifier = Modifier.clickable { dismissWith(index) },
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(imageVector = icon, contentDescription = null, tint = AlertDialogDefaults.iconContentColor)
},
)
Text(text = text, style = MaterialTheme.typography.bodySmall)
}
}
}
}
}