Styling up the LocationDetail
This commit is contained in:
		
							parent
							
								
									e3cd0bdd4b
								
							
						
					
					
						commit
						b9d14d12ff
					
				
					 11 changed files with 156 additions and 55 deletions
				
			
		| 
						 | 
				
			
			@ -100,7 +100,7 @@ fun LexiconItem(
 | 
			
		|||
                            true -> emptyList()
 | 
			
		||||
                            else -> listOf(
 | 
			
		||||
                                AnnotatedString.Range(
 | 
			
		||||
                                    item = typography.dropCapMediumSpan,
 | 
			
		||||
                                    item = typography.bodyDropCapSpan,
 | 
			
		||||
                                    start = 0,
 | 
			
		||||
                                    end = 1,
 | 
			
		||||
                                )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,6 @@ 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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,12 +38,13 @@ import com.skydoves.landscapist.ImageOptions
 | 
			
		|||
fun FantasyMap(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    state: FantasyMapState,
 | 
			
		||||
    model: () -> Any?,
 | 
			
		||||
    imageOptions: ImageOptions = ImageOptions(),
 | 
			
		||||
    @DrawableRes previewPlaceholder: Int,
 | 
			
		||||
    item: State<LocationDetailUio>,
 | 
			
		||||
    items: State<List<AnnotatedMarqueeUio>>,
 | 
			
		||||
    highlight: State<Offset>,
 | 
			
		||||
    selectedItem: State<Int>,
 | 
			
		||||
    onMarquee: (MarqueeUio) -> Unit,
 | 
			
		||||
    onMarquee: (AnnotatedMarqueeUio) -> Unit,
 | 
			
		||||
    onTap: (Offset) -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val lexiconTheme = MaterialTheme.lexicon
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ fun FantasyMap(
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    LaunchedEffect(key1 = "CenterOnMarquee:${selectedItem.value}") {
 | 
			
		||||
        item.value.marquees.getOrNull(selectedItem.value)?.position
 | 
			
		||||
        items.value.getOrNull(selectedItem.value)?.position
 | 
			
		||||
            ?.let { state.pan(state.computeMarqueeOffset(it)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ fun FantasyMap(
 | 
			
		|||
                .drawWithContent {
 | 
			
		||||
                    drawContent()
 | 
			
		||||
                    if (animatedMarqueeAlpha.value > 0f) {
 | 
			
		||||
                        item.value.marquees.forEachIndexed { index, item ->
 | 
			
		||||
                        items.value.forEachIndexed { index, item ->
 | 
			
		||||
                            if (item.position != Offset.Unspecified) {
 | 
			
		||||
                                drawMarque(
 | 
			
		||||
                                    theme = lexiconTheme,
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ fun FantasyMap(
 | 
			
		|||
                                    )
 | 
			
		||||
                                )
 | 
			
		||||
                            } else {
 | 
			
		||||
                                val marquee = item.value.marquees
 | 
			
		||||
                                val marquee = items.value
 | 
			
		||||
                                    .asReversed()
 | 
			
		||||
                                    .firstOrNull { item ->
 | 
			
		||||
                                        if (item.position != Offset.Unspecified) {
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ fun FantasyMap(
 | 
			
		|||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
            imageModel = { item.value.map },
 | 
			
		||||
            imageModel = model,
 | 
			
		||||
            imageOptions = imageOptions,
 | 
			
		||||
            previewPlaceholder = previewPlaceholder,
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package com.pixelized.rplexicon.ui.screens.location.detail
 | 
			
		|||
import android.content.res.Configuration
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import androidx.compose.foundation.ExperimentalFoundationApi
 | 
			
		||||
import androidx.compose.foundation.Image
 | 
			
		||||
import androidx.compose.foundation.ScrollState
 | 
			
		||||
import androidx.compose.foundation.gestures.scrollBy
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +37,7 @@ import androidx.compose.runtime.Composable
 | 
			
		|||
import androidx.compose.runtime.LaunchedEffect
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.derivedStateOf
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.runtime.rememberCoroutineScope
 | 
			
		||||
| 
						 | 
				
			
			@ -43,13 +45,18 @@ import androidx.compose.ui.Alignment
 | 
			
		|||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.draw.clip
 | 
			
		||||
import androidx.compose.ui.geometry.Offset
 | 
			
		||||
import androidx.compose.ui.graphics.ColorFilter
 | 
			
		||||
import androidx.compose.ui.graphics.RectangleShape
 | 
			
		||||
import androidx.compose.ui.graphics.graphicsLayer
 | 
			
		||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 | 
			
		||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
 | 
			
		||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
 | 
			
		||||
import androidx.compose.ui.layout.ContentScale
 | 
			
		||||
import androidx.compose.ui.layout.onSizeChanged
 | 
			
		||||
import androidx.compose.ui.platform.LocalDensity
 | 
			
		||||
import androidx.compose.ui.res.painterResource
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.text.AnnotatedString
 | 
			
		||||
import androidx.compose.ui.text.style.TextAlign
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.IntOffset
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +69,6 @@ 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
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +83,13 @@ data class LocationDetailUio(
 | 
			
		|||
    val marquees: List<MarqueeUio>,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
data class AnnotatedLocationDetailUio(
 | 
			
		||||
    val name: AnnotatedString,
 | 
			
		||||
    val map: Uri,
 | 
			
		||||
    val marquees: List<AnnotatedMarqueeUio>,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@OptIn(ExperimentalFoundationApi::class)
 | 
			
		||||
@Composable
 | 
			
		||||
fun LocationDetail(
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +107,7 @@ fun LocationDetail(
 | 
			
		|||
 | 
			
		||||
    val ok = stringResource(id = android.R.string.ok)
 | 
			
		||||
 | 
			
		||||
    val location = rememberAnnotation(item = viewModel.location)
 | 
			
		||||
    val snackJob = remember { mutableStateOf<Job?>(null) }
 | 
			
		||||
    val mapHighlight = remember { mutableStateOf(Offset.Unspecified) }
 | 
			
		||||
    val selectedIndex = remember { mutableStateOf(0) }
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +121,7 @@ fun LocationDetail(
 | 
			
		|||
            scrollState = scroll,
 | 
			
		||||
            pagerState = pager,
 | 
			
		||||
            fantasyMapState = fantasy,
 | 
			
		||||
            item = viewModel.location,
 | 
			
		||||
            item = location,
 | 
			
		||||
            selectedIndex = selectedIndex,
 | 
			
		||||
            mapHighlight = mapHighlight,
 | 
			
		||||
            onBack = {
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +129,7 @@ fun LocationDetail(
 | 
			
		|||
            },
 | 
			
		||||
            onMarquee = {
 | 
			
		||||
                scope.launch {
 | 
			
		||||
                    val index = max(viewModel.location.value.marquees.indexOf(it), 0)
 | 
			
		||||
                    val index = max(location.value.marquees.indexOf(it), 0)
 | 
			
		||||
                    selectedIndex.value = index
 | 
			
		||||
                    pager.animateScrollToPage(page = index)
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -195,18 +209,19 @@ private fun LocationContent(
 | 
			
		|||
    scrollState: ScrollState,
 | 
			
		||||
    pagerState: PagerState,
 | 
			
		||||
    fantasyMapState: FantasyMapState,
 | 
			
		||||
    item: State<LocationDetailUio>,
 | 
			
		||||
    item: State<AnnotatedLocationDetailUio>,
 | 
			
		||||
    selectedIndex: State<Int>,
 | 
			
		||||
    mapHighlight: State<Offset>,
 | 
			
		||||
    onBack: () -> Unit,
 | 
			
		||||
    onMarquee: (MarqueeUio) -> Unit,
 | 
			
		||||
    onMarquee: (AnnotatedMarqueeUio) -> Unit,
 | 
			
		||||
    onMapTap: (Offset) -> Unit,
 | 
			
		||||
    onTouch: (Boolean) -> Unit,
 | 
			
		||||
    onCenter: () -> Unit,
 | 
			
		||||
    onZoomIn: () -> Unit,
 | 
			
		||||
    onZoomOut: () -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val itemNameSize = rememberTextSize(style = MaterialTheme.typography.headlineSmall)
 | 
			
		||||
    val density = LocalDensity.current
 | 
			
		||||
    val itemNameSize = remember { mutableStateOf(0.dp) }
 | 
			
		||||
 | 
			
		||||
    val filledIconButtonColors = IconButtonDefaults.filledIconButtonColors(
 | 
			
		||||
        containerColor = MaterialTheme.colorScheme.surface,
 | 
			
		||||
| 
						 | 
				
			
			@ -261,9 +276,10 @@ private fun LocationContent(
 | 
			
		|||
                                .align(alignment = Alignment.Center)
 | 
			
		||||
                                .offset { IntOffset(x = 0, y = scrollState.value / 2) },
 | 
			
		||||
                            state = fantasyMapState,
 | 
			
		||||
                            model = { item.value.map },
 | 
			
		||||
                            previewPlaceholder = R.drawable.im_brulkhai,
 | 
			
		||||
                            imageOptions = ImageOptions(contentScale = ContentScale.Fit),
 | 
			
		||||
                            item = item,
 | 
			
		||||
                            items = remember { derivedStateOf { item.value.marquees } },
 | 
			
		||||
                            selectedItem = selectedIndex,
 | 
			
		||||
                            highlight = mapHighlight,
 | 
			
		||||
                            onMarquee = onMarquee,
 | 
			
		||||
| 
						 | 
				
			
			@ -323,18 +339,32 @@ private fun LocationContent(
 | 
			
		|||
                Handle(
 | 
			
		||||
                    modifier = Modifier
 | 
			
		||||
                        .align(alignment = Alignment.CenterHorizontally)
 | 
			
		||||
                        .padding(top = 16.dp)
 | 
			
		||||
                        .padding(vertical = 16.dp)
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
                Text(
 | 
			
		||||
                Column(
 | 
			
		||||
                    modifier = Modifier
 | 
			
		||||
                        .align(alignment = Alignment.CenterHorizontally)
 | 
			
		||||
                        .onSizeChanged { itemNameSize.value = with(density) { it.height.toDp() } }
 | 
			
		||||
                        .padding(horizontal = 16.dp)
 | 
			
		||||
                        .padding(top = 16.dp),
 | 
			
		||||
                    textAlign = TextAlign.Center,
 | 
			
		||||
                    style = MaterialTheme.typography.headlineSmall,
 | 
			
		||||
                    text = item.value.name,
 | 
			
		||||
                )
 | 
			
		||||
                        .fillMaxWidth(),
 | 
			
		||||
                    horizontalAlignment = Alignment.CenterHorizontally,
 | 
			
		||||
                ) {
 | 
			
		||||
                    Text(
 | 
			
		||||
                        textAlign = TextAlign.Center,
 | 
			
		||||
                        style = MaterialTheme.typography.headlineSmall,
 | 
			
		||||
                        text = item.value.name,
 | 
			
		||||
                    )
 | 
			
		||||
                    Image(
 | 
			
		||||
                        modifier = Modifier
 | 
			
		||||
                            .height(24.dp)
 | 
			
		||||
                            .graphicsLayer { rotationZ = 180f },
 | 
			
		||||
                        painter = painterResource(id = R.drawable.art_divider_1),
 | 
			
		||||
                        contentScale = ContentScale.FillWidth,
 | 
			
		||||
                        alignment = Alignment.Center,
 | 
			
		||||
                        colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface),
 | 
			
		||||
                        contentDescription = null,
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                HorizontalPager(
 | 
			
		||||
                    modifier = Modifier
 | 
			
		||||
| 
						 | 
				
			
			@ -350,7 +380,7 @@ private fun LocationContent(
 | 
			
		|||
                        MarqueeItem(
 | 
			
		||||
                            modifier = Modifier
 | 
			
		||||
                                .fillMaxWidth()
 | 
			
		||||
                                .height(this@constraint.maxHeight - 32.dp - itemNameSize.height),
 | 
			
		||||
                                .height(this@constraint.maxHeight - 32.dp - itemNameSize.value),
 | 
			
		||||
                            marquee = marquee,
 | 
			
		||||
                        )
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -378,6 +408,31 @@ private fun HandlePagerScroll(
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Stable
 | 
			
		||||
fun rememberAnnotation(item: State<LocationDetailUio>): State<AnnotatedLocationDetailUio> {
 | 
			
		||||
    val typography = MaterialTheme.lexicon.typography
 | 
			
		||||
 | 
			
		||||
    return remember(item) {
 | 
			
		||||
        derivedStateOf {
 | 
			
		||||
            AnnotatedLocationDetailUio(
 | 
			
		||||
                name = AnnotatedString(
 | 
			
		||||
                    text = item.value.name,
 | 
			
		||||
                    spanStyles = listOf(
 | 
			
		||||
                        AnnotatedString.Range(
 | 
			
		||||
                            item = typography.titleDropCapSpan,
 | 
			
		||||
                            start = 0,
 | 
			
		||||
                            end = Integer.min(1, item.value.name.length),
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                ),
 | 
			
		||||
                map = item.value.map,
 | 
			
		||||
                marquees = item.value.marquees.map { it.annotate(typography) },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@Stable
 | 
			
		||||
private fun rememberSnapConnection(
 | 
			
		||||
| 
						 | 
				
			
			@ -437,7 +492,7 @@ private fun LocationPreview() {
 | 
			
		|||
                scrollState = rememberScrollState(),
 | 
			
		||||
                pagerState = rememberPagerState(),
 | 
			
		||||
                fantasyMapState = rememberFantasyMapState(),
 | 
			
		||||
                item = remember {
 | 
			
		||||
                item = rememberAnnotation(item = remember {
 | 
			
		||||
                    mutableStateOf(
 | 
			
		||||
                        LocationDetailUio(
 | 
			
		||||
                            name = "Daggerfall",
 | 
			
		||||
| 
						 | 
				
			
			@ -456,7 +511,7 @@ private fun LocationPreview() {
 | 
			
		|||
                            ),
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
                }),
 | 
			
		||||
                selectedIndex = remember { mutableStateOf(0) },
 | 
			
		||||
                mapHighlight = remember { mutableStateOf(Offset(0.5f, 0.5f)) },
 | 
			
		||||
                onBack = { },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ package com.pixelized.rplexicon.ui.screens.location.detail
 | 
			
		|||
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import androidx.compose.ui.geometry.Offset
 | 
			
		||||
import androidx.lifecycle.SavedStateHandle
 | 
			
		||||
import androidx.lifecycle.ViewModel
 | 
			
		||||
import com.pixelized.rplexicon.repository.LocationRepository
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,7 @@ package com.pixelized.rplexicon.ui.screens.location.detail
 | 
			
		|||
 | 
			
		||||
import androidx.compose.foundation.layout.Arrangement
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.Row
 | 
			
		||||
import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.rememberScrollState
 | 
			
		||||
import androidx.compose.foundation.verticalScroll
 | 
			
		||||
| 
						 | 
				
			
			@ -14,11 +13,16 @@ import androidx.compose.runtime.Composable
 | 
			
		|||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.geometry.Offset
 | 
			
		||||
import androidx.compose.ui.text.AnnotatedString
 | 
			
		||||
import androidx.compose.ui.text.style.TextAlign
 | 
			
		||||
import androidx.compose.ui.text.style.TextOverflow
 | 
			
		||||
import androidx.compose.ui.tooling.preview.Preview
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
 | 
			
		||||
import com.pixelized.rplexicon.ui.theme.typography.LexiconTypography
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.LOS_HOLLOW
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.extentions.annotateWithDropCap
 | 
			
		||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
data class MarqueeUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -27,23 +31,49 @@ data class MarqueeUio(
 | 
			
		|||
    val description: String?,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
data class AnnotatedMarqueeUio(
 | 
			
		||||
    val name: AnnotatedString,
 | 
			
		||||
    val position: Offset,
 | 
			
		||||
    val description: AnnotatedString?,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
fun MarqueeUio.annotate(
 | 
			
		||||
    typography: LexiconTypography
 | 
			
		||||
): AnnotatedMarqueeUio {
 | 
			
		||||
    return AnnotatedMarqueeUio(
 | 
			
		||||
        name = name.annotateWithDropCap(style = typography.bodyDropCapSpan),
 | 
			
		||||
        position = position,
 | 
			
		||||
        description = description?.annotateWithDropCap(style = typography.bodyDropCapSpan),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun MarqueeItem(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    marquee: MarqueeUio,
 | 
			
		||||
    marquee: AnnotatedMarqueeUio,
 | 
			
		||||
) {
 | 
			
		||||
    Column(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        verticalArrangement = Arrangement.spacedBy(space = 8.dp)
 | 
			
		||||
    ) {
 | 
			
		||||
        Text(
 | 
			
		||||
            modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
            textAlign = TextAlign.Center,
 | 
			
		||||
            overflow = TextOverflow.Ellipsis,
 | 
			
		||||
            maxLines = 1,
 | 
			
		||||
            style = MaterialTheme.typography.titleMedium,
 | 
			
		||||
            text = marquee.name,
 | 
			
		||||
        )
 | 
			
		||||
        Row(
 | 
			
		||||
            horizontalArrangement = Arrangement.spacedBy(8.dp),
 | 
			
		||||
        ) {
 | 
			
		||||
            Text(
 | 
			
		||||
                modifier = Modifier.alignByBaseline(),
 | 
			
		||||
                text = LOS_HOLLOW,
 | 
			
		||||
            )
 | 
			
		||||
            Text(
 | 
			
		||||
                modifier = Modifier.alignByBaseline(),
 | 
			
		||||
                style = MaterialTheme.typography.titleMedium,
 | 
			
		||||
                textAlign = TextAlign.Center,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                maxLines = 3,
 | 
			
		||||
                text = marquee.name,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        marquee.description?.let {
 | 
			
		||||
            Text(
 | 
			
		||||
                modifier = Modifier.verticalScroll(rememberScrollState()),
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +95,8 @@ private fun MarqueeItemPreview() {
 | 
			
		|||
                    name = "Name",
 | 
			
		||||
                    position = Offset.Zero,
 | 
			
		||||
                    description = "description",
 | 
			
		||||
                ).annotate(
 | 
			
		||||
                    typography = MaterialTheme.lexicon.typography,
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ fun LocationItem(
 | 
			
		|||
                            true -> emptyList()
 | 
			
		||||
                            else -> listOf(
 | 
			
		||||
                                AnnotatedString.Range(
 | 
			
		||||
                                    item = typography.dropCapMediumSpan,
 | 
			
		||||
                                    item = typography.bodyDropCapSpan,
 | 
			
		||||
                                    start = 0,
 | 
			
		||||
                                    end = 1,
 | 
			
		||||
                                )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ import androidx.compose.ui.Modifier
 | 
			
		|||
import androidx.compose.ui.draw.rotate
 | 
			
		||||
import androidx.compose.ui.graphics.Color
 | 
			
		||||
import androidx.compose.ui.graphics.ColorFilter
 | 
			
		||||
import androidx.compose.ui.graphics.ColorMatrix
 | 
			
		||||
import androidx.compose.ui.graphics.graphicsLayer
 | 
			
		||||
import androidx.compose.ui.layout.ContentScale
 | 
			
		||||
import androidx.compose.ui.res.painterResource
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +128,7 @@ private fun QuestDetailUio.QuestStep.annotate(): AnnotatedQuestDetailUio.Annotat
 | 
			
		|||
                text = description,
 | 
			
		||||
                spanStyles = listOf(
 | 
			
		||||
                    AnnotatedString.Range(
 | 
			
		||||
                        item = typography.dropCapLargeSpan,
 | 
			
		||||
                        item = typography.bodyDropCapSpan,
 | 
			
		||||
                        start = 0,
 | 
			
		||||
                        end = min(1, description.length),
 | 
			
		||||
                    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ fun QuestItem(
 | 
			
		|||
                            true -> emptyList()
 | 
			
		||||
                            else -> listOf(
 | 
			
		||||
                                AnnotatedString.Range(
 | 
			
		||||
                                    item = typography.dropCapMediumSpan,
 | 
			
		||||
                                    item = typography.bodyDropCapSpan,
 | 
			
		||||
                                    start = 0,
 | 
			
		||||
                                    end = 1,
 | 
			
		||||
                                )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ fun lexiconDimen(
 | 
			
		|||
        thickness = 4.dp,
 | 
			
		||||
    ),
 | 
			
		||||
    map: LexiconDimens.Map = LexiconDimens.Map(
 | 
			
		||||
        mapSnapPx = with(density) { 64.dp.roundToPx() },
 | 
			
		||||
        mapSnapPx = with(density) { 128.dp.roundToPx() },
 | 
			
		||||
        marqueeRadiusPx = with(density) { 12.dp.roundToPx() },
 | 
			
		||||
        marqueeStrokePx = with(density) { 2.dp.roundToPx() },
 | 
			
		||||
        crossRadiusPx = with(density) { 12.dp.roundToPx() / sqrt(2f) }.toInt(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,22 +24,19 @@ val stampFontFamily = FontFamily(
 | 
			
		|||
@Stable
 | 
			
		||||
class LexiconTypography(
 | 
			
		||||
    val base: Typography = Typography(),
 | 
			
		||||
    val dropCapMedium: TextStyle = base.displaySmall.copy(
 | 
			
		||||
    val stamp: TextStyle = base.headlineLarge.copy(
 | 
			
		||||
        fontFamily = stampFontFamily,
 | 
			
		||||
    ),
 | 
			
		||||
    val bodyDropCapSpan: SpanStyle = base.displaySmall.copy(
 | 
			
		||||
        fontFamily = regalFontFamily,
 | 
			
		||||
        baselineShift = BaselineShift(-0.3f),
 | 
			
		||||
        letterSpacing = (-6).sp
 | 
			
		||||
    ),
 | 
			
		||||
    val dropCapLarge: TextStyle = base.displayMedium.copy(
 | 
			
		||||
    ).toSpanStyle(),
 | 
			
		||||
    val titleDropCapSpan: SpanStyle = base.displayLarge.copy(
 | 
			
		||||
        fontFamily = regalFontFamily,
 | 
			
		||||
        baselineShift = BaselineShift.Subscript,
 | 
			
		||||
        baselineShift = BaselineShift(-0.3f),
 | 
			
		||||
        letterSpacing = (-8).sp
 | 
			
		||||
    ),
 | 
			
		||||
    val stamp: TextStyle = base.headlineLarge.copy(
 | 
			
		||||
        fontFamily = stampFontFamily,
 | 
			
		||||
    )
 | 
			
		||||
) {
 | 
			
		||||
    val dropCapMediumSpan: SpanStyle = dropCapMedium.toSpanStyle()
 | 
			
		||||
    val dropCapLargeSpan: SpanStyle = dropCapLarge.toSpanStyle()
 | 
			
		||||
}
 | 
			
		||||
    ).toSpanStyle()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
fun lexiconTypography() = LexiconTypography()
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,10 @@
 | 
			
		|||
package com.pixelized.rplexicon.utilitary.extentions
 | 
			
		||||
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.view.accessibility.AccessibilityNodeInfo
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.ui.text.AnnotatedString
 | 
			
		||||
import androidx.compose.ui.text.SpanStyle
 | 
			
		||||
import androidx.core.net.toUri
 | 
			
		||||
 | 
			
		||||
val String.ARG: String get() = "$this={$this}"
 | 
			
		||||
| 
						 | 
				
			
			@ -24,3 +28,18 @@ fun String?.toUriOrNull(): Uri? = try {
 | 
			
		|||
    null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private val dropCapRegex = Regex("(?:\n\n)(.)")
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
fun String.annotateWithDropCap(
 | 
			
		||||
    style: SpanStyle,
 | 
			
		||||
) = AnnotatedString(
 | 
			
		||||
    text = this,
 | 
			
		||||
    spanStyles = listOf(
 | 
			
		||||
        AnnotatedString.Range(
 | 
			
		||||
            item = style,
 | 
			
		||||
            start = 0,
 | 
			
		||||
            end = Integer.min(1, this.length),
 | 
			
		||||
        ),
 | 
			
		||||
    ) + dropCapRegex.annotatedSpan(input = this, spanStyle = style)
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue