Add snaping beavior to the LocationDetail
This commit is contained in:
		
							parent
							
								
									85cdd69570
								
							
						
					
					
						commit
						e3cd0bdd4b
					
				
					 4 changed files with 133 additions and 72 deletions
				
			
		| 
						 | 
				
			
			@ -30,14 +30,10 @@ import androidx.compose.ui.layout.onSizeChanged
 | 
			
		|||
import androidx.compose.ui.unit.IntSize
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import com.pixelized.rplexicon.ui.composable.AsyncImage
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.colors.LexiconColors
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
 | 
			
		||||
import com.skydoves.landscapist.ImageOptions
 | 
			
		||||
import kotlin.math.sqrt
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private val RADIUS = 12.dp
 | 
			
		||||
private val SQUARE = (RADIUS / sqrt(2f))
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun FantasyMap(
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +47,7 @@ fun FantasyMap(
 | 
			
		|||
    onMarquee: (MarqueeUio) -> Unit,
 | 
			
		||||
    onTap: (Offset) -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val colorScheme = MaterialTheme.lexicon.colorScheme
 | 
			
		||||
    val lexiconTheme = MaterialTheme.lexicon
 | 
			
		||||
 | 
			
		||||
    val animatedScale = animateFloatAsState(
 | 
			
		||||
        targetValue = state.scale,
 | 
			
		||||
| 
						 | 
				
			
			@ -118,12 +114,11 @@ fun FantasyMap(
 | 
			
		|||
                .onSizeChanged { state.imageSize = it }
 | 
			
		||||
                .drawWithContent {
 | 
			
		||||
                    drawContent()
 | 
			
		||||
 | 
			
		||||
                    if (animatedMarqueeAlpha.value > 0f) {
 | 
			
		||||
                        item.value.marquees.forEachIndexed { index, item ->
 | 
			
		||||
                            if (item.position != Offset.Unspecified) {
 | 
			
		||||
                                drawMarque(
 | 
			
		||||
                                    colorScheme = colorScheme,
 | 
			
		||||
                                    theme = lexiconTheme,
 | 
			
		||||
                                    alpha = animatedMarqueeAlpha,
 | 
			
		||||
                                    scale = animatedScale,
 | 
			
		||||
                                    position = item.position,
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +129,7 @@ fun FantasyMap(
 | 
			
		|||
                    }
 | 
			
		||||
                    if (highlight.value != Offset.Unspecified && animatedCrossAlpha.value > 0f) {
 | 
			
		||||
                        drawCross(
 | 
			
		||||
                            colorScheme = colorScheme,
 | 
			
		||||
                            theme = lexiconTheme,
 | 
			
		||||
                            alpha = animatedCrossAlpha,
 | 
			
		||||
                            scale = animatedScale,
 | 
			
		||||
                            position = highlight.value,
 | 
			
		||||
| 
						 | 
				
			
			@ -257,34 +252,34 @@ class FantasyMapState(
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
private fun DrawScope.drawMarque(
 | 
			
		||||
    colorScheme: LexiconColors,
 | 
			
		||||
    theme: LexiconTheme,
 | 
			
		||||
    alpha: State<Float>,
 | 
			
		||||
    scale: State<Float>,
 | 
			
		||||
    position: Offset,
 | 
			
		||||
    selected: Boolean,
 | 
			
		||||
) {
 | 
			
		||||
    val scaledRadius = theme.dimens.map.marqueeRadiusPx / scale.value
 | 
			
		||||
    val scaledStroke = theme.dimens.map.marqueeStrokePx / scale.value
 | 
			
		||||
    val scaledShadowDrop = theme.dimens.map.shadowDropPx / scale.value
 | 
			
		||||
 | 
			
		||||
    drawCircle(
 | 
			
		||||
        color = colorScheme.shadow,
 | 
			
		||||
        color = theme.colorScheme.shadow,
 | 
			
		||||
        alpha = alpha.value,
 | 
			
		||||
        radius = 12.dp.toPx() / scale.value,
 | 
			
		||||
        style = Stroke(
 | 
			
		||||
            width = 2.dp.toPx() / scale.value,
 | 
			
		||||
        ),
 | 
			
		||||
        radius = scaledRadius,
 | 
			
		||||
        style = Stroke(width = scaledStroke),
 | 
			
		||||
        center = Offset(
 | 
			
		||||
            x = size.width * position.x,
 | 
			
		||||
            y = size.height * position.y + 2.dp.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y + scaledShadowDrop,
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    drawCircle(
 | 
			
		||||
        color = when (selected) {
 | 
			
		||||
            true -> colorScheme.base.primary
 | 
			
		||||
            true -> theme.colorScheme.base.primary
 | 
			
		||||
            else -> Color.White
 | 
			
		||||
        },
 | 
			
		||||
        alpha = alpha.value,
 | 
			
		||||
        radius = 12.dp.toPx() / scale.value,
 | 
			
		||||
        style = Stroke(
 | 
			
		||||
            width = 2.dp.toPx() / scale.value,
 | 
			
		||||
        ),
 | 
			
		||||
        radius = scaledRadius,
 | 
			
		||||
        style = Stroke(width = scaledStroke),
 | 
			
		||||
        center = Offset(
 | 
			
		||||
            x = size.width * position.x,
 | 
			
		||||
            y = size.height * position.y,
 | 
			
		||||
| 
						 | 
				
			
			@ -293,61 +288,65 @@ private fun DrawScope.drawMarque(
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
private fun DrawScope.drawCross(
 | 
			
		||||
    colorScheme: LexiconColors,
 | 
			
		||||
    theme: LexiconTheme,
 | 
			
		||||
    alpha: State<Float>,
 | 
			
		||||
    scale: State<Float>,
 | 
			
		||||
    position: Offset,
 | 
			
		||||
) {
 | 
			
		||||
    val scaledRadius = theme.dimens.map.crossRadiusPx / scale.value
 | 
			
		||||
    val scaledStroke = theme.dimens.map.crossStrokePx / scale.value
 | 
			
		||||
    val scaledShadowDrop = theme.dimens.map.shadowDropPx / scale.value
 | 
			
		||||
 | 
			
		||||
    drawLine(
 | 
			
		||||
        color = colorScheme.shadow,
 | 
			
		||||
        color = theme.colorScheme.shadow,
 | 
			
		||||
        alpha = alpha.value,
 | 
			
		||||
        strokeWidth = 2.dp.toPx() / scale.value,
 | 
			
		||||
        strokeWidth = scaledStroke,
 | 
			
		||||
        start = Offset(
 | 
			
		||||
            x = size.width * position.x - SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y - SQUARE.toPx() / scale.value + 2.dp.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x - scaledRadius,
 | 
			
		||||
            y = size.height * position.y - scaledRadius + scaledShadowDrop,
 | 
			
		||||
        ),
 | 
			
		||||
        end = Offset(
 | 
			
		||||
            x = size.width * position.x + SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y + SQUARE.toPx() / scale.value + 2.dp.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x + scaledRadius,
 | 
			
		||||
            y = size.height * position.y + scaledRadius + scaledShadowDrop,
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    drawLine(
 | 
			
		||||
        color = colorScheme.shadow,
 | 
			
		||||
        color = theme.colorScheme.shadow,
 | 
			
		||||
        alpha = alpha.value,
 | 
			
		||||
        strokeWidth = 2.dp.toPx() / scale.value,
 | 
			
		||||
        strokeWidth = scaledStroke,
 | 
			
		||||
        start = Offset(
 | 
			
		||||
            x = size.width * position.x + SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y - SQUARE.toPx() / scale.value + 2.dp.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x + scaledRadius,
 | 
			
		||||
            y = size.height * position.y - scaledRadius + scaledShadowDrop,
 | 
			
		||||
        ),
 | 
			
		||||
        end = Offset(
 | 
			
		||||
            x = size.width * position.x - SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y + SQUARE.toPx() / scale.value + 2.dp.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x - scaledRadius,
 | 
			
		||||
            y = size.height * position.y + scaledRadius + scaledShadowDrop,
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    drawLine(
 | 
			
		||||
        color = colorScheme.base.primary,
 | 
			
		||||
        color = theme.colorScheme.base.primary,
 | 
			
		||||
        alpha = alpha.value,
 | 
			
		||||
        strokeWidth = 2.dp.toPx() / scale.value,
 | 
			
		||||
        strokeWidth = scaledStroke,
 | 
			
		||||
        start = Offset(
 | 
			
		||||
            x = size.width * position.x - SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y - SQUARE.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x - scaledRadius,
 | 
			
		||||
            y = size.height * position.y - scaledRadius,
 | 
			
		||||
        ),
 | 
			
		||||
        end = Offset(
 | 
			
		||||
            x = size.width * position.x + SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y + SQUARE.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x + scaledRadius,
 | 
			
		||||
            y = size.height * position.y + scaledRadius,
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    drawLine(
 | 
			
		||||
        color = colorScheme.base.primary,
 | 
			
		||||
        color = theme.colorScheme.base.primary,
 | 
			
		||||
        alpha = alpha.value,
 | 
			
		||||
        strokeWidth = 2.dp.toPx() / scale.value,
 | 
			
		||||
        strokeWidth = scaledStroke,
 | 
			
		||||
        start = Offset(
 | 
			
		||||
            x = size.width * position.x + SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y - SQUARE.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x + scaledRadius,
 | 
			
		||||
            y = size.height * position.y - scaledRadius,
 | 
			
		||||
        ),
 | 
			
		||||
        end = Offset(
 | 
			
		||||
            x = size.width * position.x - SQUARE.toPx() / scale.value,
 | 
			
		||||
            y = size.height * position.y + SQUARE.toPx() / scale.value,
 | 
			
		||||
            x = size.width * position.x - scaledRadius,
 | 
			
		||||
            y = size.height * position.y + scaledRadius,
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +53,7 @@ import androidx.compose.ui.res.stringResource
 | 
			
		|||
import androidx.compose.ui.text.style.TextAlign
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.IntOffset
 | 
			
		||||
import androidx.compose.ui.unit.Velocity
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import androidx.hilt.navigation.compose.hiltViewModel
 | 
			
		||||
import com.pixelized.rplexicon.LocalSnack
 | 
			
		||||
| 
						 | 
				
			
			@ -60,8 +61,10 @@ import com.pixelized.rplexicon.R
 | 
			
		|||
import com.pixelized.rplexicon.ui.composable.Handle
 | 
			
		||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.rememberTextSize
 | 
			
		||||
import com.skydoves.landscapist.ImageOptions
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
| 
						 | 
				
			
			@ -86,34 +89,21 @@ fun LocationDetail(
 | 
			
		|||
    val scroll = rememberScrollState()
 | 
			
		||||
    val pager = rememberPagerState()
 | 
			
		||||
    val fantasy = rememberFantasyMapState()
 | 
			
		||||
    val snapBehavior = rememberSnapConnection(scrollState = scroll)
 | 
			
		||||
    val scrollBehavior = rememberScrollConnection(scrollState = scroll)
 | 
			
		||||
 | 
			
		||||
    val ok = stringResource(id = android.R.string.ok)
 | 
			
		||||
    val job = remember { mutableStateOf<Job?>(null) }
 | 
			
		||||
 | 
			
		||||
    val connection = remember {
 | 
			
		||||
        object : NestedScrollConnection {
 | 
			
		||||
            override fun onPreScroll(
 | 
			
		||||
                available: Offset,
 | 
			
		||||
                source: NestedScrollSource
 | 
			
		||||
            ): Offset = runBlocking {
 | 
			
		||||
                Offset(
 | 
			
		||||
                    x = 0f,
 | 
			
		||||
                    y = when (scroll.canScrollForward) {
 | 
			
		||||
                        true -> -scroll.scrollBy(-available.y)
 | 
			
		||||
                        else -> 0f
 | 
			
		||||
                    },
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val snackJob = remember { mutableStateOf<Job?>(null) }
 | 
			
		||||
    val mapHighlight = remember { mutableStateOf(Offset.Unspecified) }
 | 
			
		||||
    val selectedIndex = remember { mutableStateOf(0) }
 | 
			
		||||
 | 
			
		||||
    Surface {
 | 
			
		||||
        LocationContent(
 | 
			
		||||
            modifier = Modifier.fillMaxSize(),
 | 
			
		||||
            connection = connection,
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .fillMaxSize()
 | 
			
		||||
                .nestedScroll(connection = snapBehavior),
 | 
			
		||||
            connection = scrollBehavior,
 | 
			
		||||
            scrollState = scroll,
 | 
			
		||||
            pagerState = pager,
 | 
			
		||||
            fantasyMapState = fantasy,
 | 
			
		||||
| 
						 | 
				
			
			@ -131,8 +121,8 @@ fun LocationDetail(
 | 
			
		|||
                }
 | 
			
		||||
            },
 | 
			
		||||
            onMapTap = {
 | 
			
		||||
                job.value?.cancel()
 | 
			
		||||
                job.value = scope.launch {
 | 
			
		||||
                snackJob.value?.cancel()
 | 
			
		||||
                snackJob.value = scope.launch {
 | 
			
		||||
                    snack.showSnackbar(
 | 
			
		||||
                        message = "x:${it.x}, y:${it.y}",
 | 
			
		||||
                        actionLabel = ok,
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +136,7 @@ fun LocationDetail(
 | 
			
		|||
                if (it) {
 | 
			
		||||
                    mapHighlight.value = Offset.Unspecified
 | 
			
		||||
                } else {
 | 
			
		||||
                    job.value?.cancel()
 | 
			
		||||
                    snackJob.value?.cancel()
 | 
			
		||||
                }
 | 
			
		||||
                fantasy.toggleFreeHand(it)
 | 
			
		||||
            },
 | 
			
		||||
| 
						 | 
				
			
			@ -388,6 +378,52 @@ private fun HandlePagerScroll(
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Stable
 | 
			
		||||
private fun rememberSnapConnection(
 | 
			
		||||
    scope: CoroutineScope = rememberCoroutineScope(),
 | 
			
		||||
    scrollState: ScrollState,
 | 
			
		||||
): NestedScrollConnection {
 | 
			
		||||
    val dimens = MaterialTheme.lexicon.dimens
 | 
			
		||||
 | 
			
		||||
    return remember(scope, scrollState) {
 | 
			
		||||
        object : NestedScrollConnection {
 | 
			
		||||
            override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
 | 
			
		||||
                if (scrollState.value < dimens.map.mapSnapPx) {
 | 
			
		||||
                    scope.launch { scrollState.animateScrollTo(0) }
 | 
			
		||||
                }
 | 
			
		||||
                if ((scrollState.maxValue - scrollState.value) < dimens.map.mapSnapPx) {
 | 
			
		||||
                    scope.launch { scrollState.animateScrollTo(scrollState.maxValue) }
 | 
			
		||||
                }
 | 
			
		||||
                return super.onPostFling(consumed, available)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Stable
 | 
			
		||||
private fun rememberScrollConnection(
 | 
			
		||||
    scrollState: ScrollState,
 | 
			
		||||
): NestedScrollConnection {
 | 
			
		||||
    return remember(scrollState) {
 | 
			
		||||
        object : NestedScrollConnection {
 | 
			
		||||
            override fun onPreScroll(
 | 
			
		||||
                available: Offset,
 | 
			
		||||
                source: NestedScrollSource
 | 
			
		||||
            ): Offset = runBlocking {
 | 
			
		||||
                Offset(
 | 
			
		||||
                    x = 0f,
 | 
			
		||||
                    y = when (scrollState.canScrollForward) {
 | 
			
		||||
                        true -> -scrollState.scrollBy(-available.y)
 | 
			
		||||
                        else -> 0f
 | 
			
		||||
                    },
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@OptIn(ExperimentalFoundationApi::class)
 | 
			
		||||
@Composable
 | 
			
		||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ import androidx.compose.runtime.Stable
 | 
			
		|||
import androidx.compose.runtime.compositionLocalOf
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.ui.graphics.toArgb
 | 
			
		||||
import androidx.compose.ui.platform.LocalDensity
 | 
			
		||||
import androidx.compose.ui.platform.LocalView
 | 
			
		||||
import androidx.core.view.WindowCompat
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.animation.LexiconAnimation
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +43,8 @@ fun LexiconTheme(
 | 
			
		|||
    darkTheme: Boolean = isSystemInDarkTheme(),
 | 
			
		||||
    content: @Composable () -> Unit
 | 
			
		||||
) {
 | 
			
		||||
    val lexiconTheme = remember {
 | 
			
		||||
    val density = LocalDensity.current
 | 
			
		||||
    val lexiconTheme = remember(density) {
 | 
			
		||||
        LexiconTheme(
 | 
			
		||||
            animation = lexiconAnimation(),
 | 
			
		||||
            colorScheme = when (darkTheme) {
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +52,7 @@ fun LexiconTheme(
 | 
			
		|||
                else -> lightColorScheme()
 | 
			
		||||
            },
 | 
			
		||||
            shapes = lexiconShapes(),
 | 
			
		||||
            dimens = lexiconDimen(),
 | 
			
		||||
            dimens = lexiconDimen(density = density),
 | 
			
		||||
            typography = lexiconTypography(),
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,10 @@ package com.pixelized.rplexicon.ui.theme.dimen
 | 
			
		|||
import androidx.compose.foundation.layout.PaddingValues
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.ui.unit.Density
 | 
			
		||||
import androidx.compose.ui.unit.Dp
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import kotlin.math.sqrt
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
@Immutable
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +14,8 @@ data class LexiconDimens(
 | 
			
		|||
    val item: Dp,
 | 
			
		||||
    val detailPadding: Dp,
 | 
			
		||||
    val itemListPadding: PaddingValues,
 | 
			
		||||
    val handle: Handle
 | 
			
		||||
    val handle: Handle,
 | 
			
		||||
    val map: Map,
 | 
			
		||||
) {
 | 
			
		||||
    @Stable
 | 
			
		||||
    @Immutable
 | 
			
		||||
| 
						 | 
				
			
			@ -20,9 +23,21 @@ data class LexiconDimens(
 | 
			
		|||
        val width: Dp,
 | 
			
		||||
        val thickness: Dp,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @Stable
 | 
			
		||||
    @Immutable
 | 
			
		||||
    data class Map(
 | 
			
		||||
        val mapSnapPx: Int,
 | 
			
		||||
        val marqueeRadiusPx: Int,
 | 
			
		||||
        val marqueeStrokePx: Int,
 | 
			
		||||
        val crossRadiusPx: Int,
 | 
			
		||||
        val crossStrokePx: Int,
 | 
			
		||||
        val shadowDropPx: Int,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun lexiconDimen(
 | 
			
		||||
    density: Density,
 | 
			
		||||
    itemHeight: Dp = 52.dp,
 | 
			
		||||
    detailPadding: Dp = 248.dp,
 | 
			
		||||
    itemListPadding: PaddingValues = PaddingValues(
 | 
			
		||||
| 
						 | 
				
			
			@ -33,9 +48,18 @@ fun lexiconDimen(
 | 
			
		|||
        width = 32.dp,
 | 
			
		||||
        thickness = 4.dp,
 | 
			
		||||
    ),
 | 
			
		||||
    map: LexiconDimens.Map = LexiconDimens.Map(
 | 
			
		||||
        mapSnapPx = with(density) { 64.dp.roundToPx() },
 | 
			
		||||
        marqueeRadiusPx = with(density) { 12.dp.roundToPx() },
 | 
			
		||||
        marqueeStrokePx = with(density) { 2.dp.roundToPx() },
 | 
			
		||||
        crossRadiusPx = with(density) { 12.dp.roundToPx() / sqrt(2f) }.toInt(),
 | 
			
		||||
        crossStrokePx = with(density) { 2.dp.roundToPx() },
 | 
			
		||||
        shadowDropPx = with(density) { 2.dp.roundToPx() },
 | 
			
		||||
    ),
 | 
			
		||||
) = LexiconDimens(
 | 
			
		||||
    item = itemHeight,
 | 
			
		||||
    detailPadding = detailPadding,
 | 
			
		||||
    itemListPadding = itemListPadding,
 | 
			
		||||
    handle = handle,
 | 
			
		||||
    map = map,
 | 
			
		||||
)
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue