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