Change a bit the UI on the alteration drawer menu.

This commit is contained in:
Thomas Andres Gomez 2023-09-27 18:28:20 +02:00
parent 03dd4939b4
commit 255ad7aed8
6 changed files with 209 additions and 77 deletions

View file

@ -37,10 +37,12 @@ fun IndicatorStep(
selectedIndex: Int?,
defaultSize: Dp = 4.dp,
selectedWidth: Dp = 16.dp,
indicatorSpacing: Dp = 8.dp,
defaultColor: Color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.35f),
selectedColor: Color = MaterialTheme.colorScheme.primary,
indicatorSpacing: Dp = 4.dp,
) {
val colorScheme = MaterialTheme.colorScheme
val defaultColor = remember { colorScheme.onSurface.copy(alpha = 0.35f) }
val selectedColor = remember { colorScheme.primary }
Row(modifier = modifier) {
repeat(count) { index ->
val transition = rememberIndicatorTransition(

View file

@ -0,0 +1,51 @@
package com.pixelized.rplexicon.ui.composable
import androidx.compose.material3.DrawerDefaults
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.LayoutDirection
@Composable
fun ModalNavigationDrawer(
drawerContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
gesturesEnabled: Boolean = true,
scrimColor: Color = DrawerDefaults.scrimColor,
layoutDirection: LayoutDirection = LayoutDirection.Ltr,
content: @Composable () -> Unit
) {
val currentLayoutDirection = LocalLayoutDirection.current
CompositionLocalProvider(
LocalLayoutDirection provides layoutDirection,
) {
androidx.compose.material3.ModalNavigationDrawer(
modifier = modifier,
drawerState = drawerState,
gesturesEnabled = gesturesEnabled,
scrimColor = scrimColor,
drawerContent = {
CompositionLocalProvider(
LocalLayoutDirection provides currentLayoutDirection,
) {
drawerContent()
}
},
content = {
CompositionLocalProvider(
LocalLayoutDirection provides currentLayoutDirection,
) {
content()
}
},
)
}
}

View file

@ -108,12 +108,11 @@ fun ActionsPageContent(
LazyColumn(
modifier = modifier,
state = lazyListState,
contentPadding = PaddingValues(vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
contentPadding = PaddingValues(vertical = 8.dp),
) {
items(items = attacks.value) {
Attack(
modifier = Modifier.padding(horizontal = 16.dp),
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
weapon = it,
onHit = onAttackHit,
onDamage = onAttackDamage,
@ -123,13 +122,14 @@ fun ActionsPageContent(
spells.value.forEach { entry ->
stickyHeader {
SpellHeader(
modifier = Modifier.padding(top = 8.dp, bottom = 4.dp),
header = entry.first,
)
}
items(items = entry.second) {
Spell(
modifier = Modifier.padding(horizontal = 16.dp),
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
spell = it,
onClick = onSpell,
onHit = onSpellHit,

View file

@ -12,7 +12,7 @@ import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@ -20,15 +20,16 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Menu
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberDrawerState
@ -47,9 +48,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.pixelized.rplexicon.LocalRollOverlay
@ -57,6 +61,7 @@ import com.pixelized.rplexicon.NO_WINDOW_INSETS
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.model.Roll
import com.pixelized.rplexicon.ui.composable.BlurredOverlayHostState
import com.pixelized.rplexicon.ui.composable.ModalNavigationDrawer
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollAlteration
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollAlterationUio
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDice
@ -64,6 +69,7 @@ import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCard
import com.pixelized.rplexicon.ui.screens.rolls.composable.ThrowsCardUio
import com.pixelized.rplexicon.ui.theme.LexiconTheme
import com.pixelized.rplexicon.utilitary.extentions.lexicon
import kotlinx.coroutines.launch
@Composable
@ -84,6 +90,9 @@ fun RollOverlay(
onMenu = {
scope.launch { drawer.open() }
},
onMenuClose = {
scope.launch { drawer.close() }
},
onClose = {
overlay.hideOverlay()
},
@ -113,6 +122,7 @@ private fun RollOverlayContent(
alterations: State<List<RollAlterationUio>>,
showDetail: State<Boolean>,
onMenu: () -> Unit,
onMenuClose: () -> Unit,
onClose: () -> Unit,
onDice: () -> Unit,
onCard: () -> Unit,
@ -129,18 +139,48 @@ private fun RollOverlayContent(
modifier = modifier,
drawerState = drawer,
gesturesEnabled = enableDrawer.value,
layoutDirection = LayoutDirection.Rtl,
drawerContent = {
Surface {
LazyColumn(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(4f / 5f),
) {
items(items = alterations.value) {
RollAlteration(
modifier = Modifier.fillMaxWidth(),
alteration = it,
onClick = onAlteration,
Column {
Text(
modifier = Modifier.padding(horizontal = 16.dp),
style = MaterialTheme.typography.titleMedium,
text = stringResource(id = R.string.dice_roll_alteraton_action).let {
AnnotatedString(
text = it,
spanStyles = listOf(
AnnotatedString.Range(
item = MaterialTheme.lexicon.typography.bodyDropCapSpan,
start = 0,
end = Integer.min(1, it.length),
)
)
)
},
)
LazyColumn(
modifier = Modifier
.weight(weight = 1f)
.fillMaxWidth(4f / 5f),
) {
items(items = alterations.value) {
RollAlteration(
modifier = Modifier.fillMaxWidth(),
alteration = it,
onClick = onAlteration,
)
}
}
TextButton(
modifier = Modifier.align(alignment = Alignment.End),
onClick = onMenuClose,
) {
Text(
modifier = Modifier.padding(horizontal = 8.dp),
text = stringResource(id = R.string.action_close),
)
}
}
@ -154,16 +194,6 @@ private fun RollOverlayContent(
TopAppBar(
colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
title = { },
navigationIcon = {
if (enableDrawer.value) {
IconButton(onClick = onMenu) {
Icon(
imageVector = Icons.Outlined.Menu,
contentDescription = null,
)
}
}
},
actions = {
IconButton(onClick = onClose) {
Icon(
@ -191,8 +221,7 @@ private fun RollOverlayContent(
AnimatedContent(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.padding(all = 16.dp),
.align(Alignment.BottomCenter),
targetState = card.value,
transitionSpec = {
val enter =
@ -207,11 +236,24 @@ private fun RollOverlayContent(
when (it) {
null -> Box(
modifier = Modifier.fillMaxWidth(),
)
contentAlignment = Alignment.BottomEnd,
) {
if (enableDrawer.value) {
TextButton(
onClick = onMenu,
) {
Text(
modifier = Modifier.padding(horizontal = 8.dp),
text = stringResource(id = R.string.dice_roll_alteraton_action),
)
}
}
}
else -> ThrowsCard(
modifier = Modifier
.fillMaxWidth()
.padding(all = 16.dp)
.clickable(onClick = onCard),
throws = it,
showDetail = showDetail,
@ -229,56 +271,19 @@ private fun RollOverlayContent(
@Preview(uiMode = UI_MODE_NIGHT_NO)
@Preview(uiMode = UI_MODE_NIGHT_YES)
private fun RollOverlayPreview(
@PreviewParameter(RollOverlayPreviewProvider::class) preview: DrawerValue
@PreviewParameter(RollOverlayPreviewProvider::class) preview: RollOverlayPreviewUio
) {
LexiconTheme {
Surface {
RollOverlayContent(
modifier = Modifier.fillMaxSize(),
drawer = rememberDrawerState(initialValue = preview),
dice = remember {
mutableStateOf(
RollDiceUio(
icon = R.drawable.ic_d20_24,
isCriticalSuccess = true,
result = "20",
)
)
},
card = remember {
mutableStateOf<ThrowsCardUio?>(
ThrowsCardUio(
title = "PERCEPTION CHECK",
highlight = "CHECK",
dice = R.drawable.ic_d20_24,
roll = "$20 + 2 + 2",
result = "20",
isCriticalSuccess = true,
details = listOf(
ThrowsCardUio.Detail(
throws = ThrowsCardUio.Throw(
dice = R.drawable.ic_d20_24,
roll = "1d20",
result = "20"
),
result = "20"
),
ThrowsCardUio.Detail(
title = "Wisdom bonus",
result = "2",
),
ThrowsCardUio.Detail(
title = "Proficiency bonus",
result = "2",
),
),
)
)
},
drawer = rememberDrawerState(initialValue = preview.drawer),
dice = preview.dice,
card = preview.card,
alterations = remember {
mutableStateOf(
listOf(
RollAlterationUio(label = "Critique", checked = false),
RollAlterationUio(label = "Critique", checked = true),
)
)
},
@ -286,6 +291,7 @@ private fun RollOverlayPreview(
mutableStateOf(true)
},
onMenu = { },
onMenuClose = { },
onClose = { },
onDice = { },
onCard = { },
@ -295,8 +301,75 @@ private fun RollOverlayPreview(
}
}
private class RollOverlayPreviewProvider : PreviewParameterProvider<DrawerValue> {
override val values: Sequence<DrawerValue> = sequenceOf(DrawerValue.Closed, DrawerValue.Open)
@Stable
private data class RollOverlayPreviewUio(
val drawer: DrawerValue,
val dice: State<RollDiceUio>,
val card: State<ThrowsCardUio?>,
)
private class RollOverlayPreviewProvider : PreviewParameterProvider<RollOverlayPreviewUio> {
override val values: Sequence<RollOverlayPreviewUio> = sequenceOf(
RollOverlayPreviewUio(
drawer = DrawerValue.Closed,
dice = mutableStateOf(
RollDiceUio(
icon = R.drawable.ic_d20_24,
result = null,
)
),
card = mutableStateOf(null),
),
RollOverlayPreviewUio(
drawer = DrawerValue.Closed,
dice = mutableStateOf(
RollDiceUio(
icon = R.drawable.ic_d20_24,
isCriticalSuccess = true,
result = "20",
)
),
card = mutableStateOf(
ThrowsCardUio(
title = "PERCEPTION CHECK",
highlight = "CHECK",
dice = R.drawable.ic_d20_24,
roll = "$20 + 2 + 2",
result = "20",
isCriticalSuccess = true,
details = listOf(
ThrowsCardUio.Detail(
throws = ThrowsCardUio.Throw(
dice = R.drawable.ic_d20_24,
roll = "1d20",
result = "20"
),
result = "20"
),
ThrowsCardUio.Detail(
title = "Wisdom bonus",
result = "2",
),
ThrowsCardUio.Detail(
title = "Proficiency bonus",
result = "2",
),
),
)
)
),
RollOverlayPreviewUio(
drawer = DrawerValue.Open,
dice = mutableStateOf(
RollDiceUio(
icon = R.drawable.ic_d20_24,
isCriticalSuccess = true,
result = "20",
)
),
card = mutableStateOf(null),
),
)
}
@Stable

View file

@ -1,6 +1,8 @@
<resources>
<string name="app_name">Rp-Compagnon</string>
<string name="action_close">Fermer</string>
<string name="error_generic">Une erreur s\'est produite.</string>
<string name="error_structure">La structure du fichier semble avoir changé et n\'est plus compatible avec cette application.</string>
@ -128,6 +130,7 @@
<string name="dice_roll_spell_hit_title">Jet de sort : \"%1$s"</string>
<string name="dice_roll_spell_damage_title">Jet de dommage : \"%1$s\"</string>
<string name="dice_roll_critical_label">Critique</string>
<string name="dice_roll_alteraton_action">Alterations</string>
<string name="dice_roll_saving_throw_title">JET DE SAUVEGARDE : %1$s</string>
<string name="dice_roll_saving_throw_detail">Sauvegarde de \"%1$s\"</string>

View file

@ -1,6 +1,8 @@
<resources>
<string name="app_name">Rp-Companion</string>
<string name="action_close">Close</string>
<string name="error_generic">An error occur.</string>
<string name="error_structure">The file structure appears to have changed and is no longer compatible with this application</string>
@ -128,6 +130,7 @@
<string name="dice_roll_spell_hit_title">%1$s HIT</string>
<string name="dice_roll_spell_damage_title">%1$s DAMAGE</string>
<string name="dice_roll_critical_label">Critical</string>
<string name="dice_roll_alteraton_action">Altérations</string>
<string name="dice_roll_saving_throw_title">%1$s SAVING THROW</string>
<string name="dice_roll_saving_throw_detail">%1$s save</string>