Fix shadows, padding, and scroll on characterSheetScreen.

This commit is contained in:
Thomas Andres Gomez 2023-09-19 10:53:26 +02:00
parent 9e5655c7d7
commit bd4de62841
4 changed files with 317 additions and 279 deletions

View file

@ -3,7 +3,6 @@ package com.pixelized.rplexicon.ui.screens.character
import android.content.res.Configuration import android.content.res.Configuration
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -57,6 +56,9 @@ import com.pixelized.rplexicon.ui.screens.character.composable.LabelPoint
import com.pixelized.rplexicon.ui.screens.character.composable.LabelPointUio import com.pixelized.rplexicon.ui.screens.character.composable.LabelPointUio
import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
import com.pixelized.rplexicon.ui.screens.character.composable.StatUio import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
import com.pixelized.rplexicon.ui.screens.character.pages.ActionsPages
import com.pixelized.rplexicon.ui.screens.character.pages.ProficiencyPage
import com.pixelized.rplexicon.ui.screens.character.preview.rememberCharacterSheetPreview
import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.pixelized.rplexicon.ui.theme.LexiconTheme
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -93,7 +95,6 @@ fun CharacterSheetScreen(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.systemBarsPadding(), .systemBarsPadding(),
state = rememberScrollState(),
pagerState = rememberPagerState { pagerState = rememberPagerState {
if (viewModel.actions.value.isNotEmpty() || viewModel.counter.value.isNotEmpty()) { if (viewModel.actions.value.isNotEmpty() || viewModel.counter.value.isNotEmpty()) {
2 2
@ -185,7 +186,6 @@ fun CharacterSheetScreen(
@Composable @Composable
private fun CharacterSheetContent( private fun CharacterSheetContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
state: ScrollState,
pagerState: PagerState, pagerState: PagerState,
refreshState: PullRefreshState, refreshState: PullRefreshState,
refreshing: State<Boolean>, refreshing: State<Boolean>,
@ -254,49 +254,52 @@ private fun CharacterSheetContent(
} }
} }
HorizontalPager( Box(
modifier = Modifier modifier = Modifier.fillMaxWidth(),
.fillMaxWidth()
.pullRefresh(refreshState)
.verticalScroll(state = state),
state = pagerState,
contentPadding = PaddingValues(all = 16.dp),
pageSpacing = 8.dp,
verticalAlignment = Alignment.Top,
) { ) {
when (it) { HorizontalPager(
0 -> ProficiencyPage( modifier = Modifier
modifier = Modifier.fillMaxWidth(), .fillMaxWidth()
sheet = sheet, .pullRefresh(refreshState),
onInitiative = onInitiative, state = pagerState,
onStats = onStats, contentPadding = PaddingValues(horizontal = 16.dp),
onProficiencies = onProficiencies, pageSpacing = 8.dp,
) verticalAlignment = Alignment.Top,
) {
when (it) {
0 -> ProficiencyPage(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(state = rememberScrollState())
.padding(vertical = 16.dp),
sheet = sheet,
onInitiative = onInitiative,
onStats = onStats,
onProficiencies = onProficiencies,
)
1 -> ActionsPages( 1 -> ActionsPages(
modifier = Modifier.fillMaxWidth(), modifier = Modifier
actions = actions, .fillMaxWidth()
counter = counter, .verticalScroll(state = rememberScrollState())
alterations = alterations, .padding(vertical = 16.dp),
onHit = onHit, actions = actions,
onDamage = onDamage, counter = counter,
) alterations = alterations,
onHit = onHit,
onDamage = onDamage,
)
}
} }
Loader(
modifier = Modifier.align(Alignment.TopCenter),
refreshState = refreshState,
refreshing = refreshing,
)
} }
} }
} }
Box(
modifier = Modifier
.padding(paddingValues = paddingValues)
.fillMaxWidth(),
) {
Loader(
modifier = Modifier.align(Alignment.TopCenter),
refreshState = refreshState,
refreshing = refreshing,
)
}
} }
} }
@ -306,194 +309,14 @@ private fun CharacterSheetContent(
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun CharacterScreenPreview() { private fun CharacterScreenPreview() {
LexiconTheme { LexiconTheme {
val bru = remember {
CharacterSheetUio(
armorClass = LabelPointUio(
label = R.string.character_sheet_title_ca,
value = "15",
),
hitPoint = LabelPointUio(
label = R.string.character_sheet_title_hp,
value = "125",
max = "/ 150",
),
speed = LabelPointUio(
label = R.string.character_sheet_title_speed,
value = "30",
max = "m",
),
initiative = LabelPointUio(
label = R.string.character_sheet_title_initiative,
value = "+2",
),
stats = listOf(
StatUio(
id = StatUio.ID.STRENGTH,
value = 16,
modifier = 3,
),
StatUio(
id = StatUio.ID.DEXTERITY,
value = 10,
modifier = 0,
),
StatUio(
id = StatUio.ID.CONSTITUTION,
value = 16,
modifier = 3,
),
StatUio(
id = StatUio.ID.INTELLIGENCE,
value = 8,
modifier = 1,
),
StatUio(
id = StatUio.ID.WISDOM,
value = 14,
modifier = 2,
),
StatUio(
id = StatUio.ID.CHARISMA,
value = 10,
modifier = 0,
),
),
savingThrows = listOf(
ProficiencyUio(
id = ProficiencyUio.ID.STRENGTH_SAVING_THROW,
multiplier = 1,
modifier = 5,
),
ProficiencyUio(
id = ProficiencyUio.ID.DEXTERITY_SAVING_THROW,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.CONSTITUTION_SAVING_THROW,
multiplier = 1,
modifier = +5,
),
ProficiencyUio(
id = ProficiencyUio.ID.INTELLIGENCE_SAVING_THROW,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.WISDOM_SAVING_THROW,
multiplier = 0,
modifier = +2,
),
ProficiencyUio(
id = ProficiencyUio.ID.CHARISMA_SAVING_THROW,
multiplier = 0,
modifier = +0,
),
),
proficiencies = listOf(
ProficiencyUio(
id = ProficiencyUio.ID.ACROBATICS,
multiplier = 0,
modifier = +0,
),
ProficiencyUio(
id = ProficiencyUio.ID.ANIMAL_HANDLING,
multiplier = 0,
modifier = 2,
),
ProficiencyUio(
id = ProficiencyUio.ID.ARCANA,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.ATHLETICS,
multiplier = 1,
modifier = 5,
),
ProficiencyUio(
id = ProficiencyUio.ID.DECEPTION,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.HISTORY,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.INSIGHT,
multiplier = 1,
modifier = 4,
),
ProficiencyUio(
id = ProficiencyUio.ID.INTIMIDATION,
multiplier = 1,
modifier = 2,
),
ProficiencyUio(
id = ProficiencyUio.ID.INVESTIGATION,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.MEDICINE,
multiplier = 0,
modifier = 2,
),
ProficiencyUio(
id = ProficiencyUio.ID.NATURE,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.PERCEPTION,
multiplier = 1,
modifier = 4,
),
ProficiencyUio(
id = ProficiencyUio.ID.PERFORMANCE,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.PERSUASION,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.RELIGION,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.SLEIGHT_OF_HAND,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.STEALTH,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.SURVIVAL,
multiplier = 1,
modifier = 4,
),
),
)
}
Surface { Surface {
CharacterSheetContent( CharacterSheetContent(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
state = rememberScrollState(),
pagerState = rememberPagerState { 1 }, pagerState = rememberPagerState { 1 },
refreshState = rememberPullRefreshState(refreshing = false, onRefresh = { }), refreshState = rememberPullRefreshState(refreshing = false, onRefresh = { }),
refreshing = remember { mutableStateOf(false) }, refreshing = remember { mutableStateOf(false) },
onRefresh = { }, onRefresh = { },
sheet = bru, sheet = rememberCharacterSheetPreview(),
actions = remember { actions = remember {
mutableStateOf( mutableStateOf(
listOf( listOf(

View file

@ -1,4 +1,4 @@
package com.pixelized.rplexicon.ui.screens.character package com.pixelized.rplexicon.ui.screens.character.pages
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column

View file

@ -1,7 +1,10 @@
package com.pixelized.rplexicon.ui.screens.character package com.pixelized.rplexicon.ui.screens.character.pages
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -9,6 +12,7 @@ import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.shape.CutCornerShape import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -20,13 +24,17 @@ import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.layoutId import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
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 com.pixelized.rplexicon.R import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.screens.character.CharacterSheetUio
import com.pixelized.rplexicon.ui.screens.character.composable.Proficiency import com.pixelized.rplexicon.ui.screens.character.composable.Proficiency
import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
import com.pixelized.rplexicon.ui.screens.character.composable.Stat import com.pixelized.rplexicon.ui.screens.character.composable.Stat
import com.pixelized.rplexicon.ui.screens.character.composable.StatUio import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
import com.pixelized.rplexicon.ui.screens.character.preview.rememberCharacterSheetPreview
import com.pixelized.rplexicon.ui.theme.LexiconTheme
import com.pixelized.rplexicon.utilitary.extentions.ddBorder import com.pixelized.rplexicon.utilitary.extentions.ddBorder
@Composable @Composable
@ -39,69 +47,69 @@ fun ProficiencyPage(
onStats: (StatUio) -> Unit, onStats: (StatUio) -> Unit,
onProficiencies: (ProficiencyUio) -> Unit, onProficiencies: (ProficiencyUio) -> Unit,
) { ) {
ProficiencyLayout( Box(modifier = modifier) {
modifier = modifier, ProficiencyLayout(
inner = inner, inner = inner,
outline = outline, outline = outline,
stats = { stats = {
Column( Column(
modifier = Modifier modifier = Modifier
.sizeIn(minWidth = 100.dp, minHeight = 116.dp) .sizeIn(minWidth = 100.dp, minHeight = 116.dp)
.ddBorder(outline = outline, inner = inner) .ddBorder(outline = outline, inner = inner)
.clickable(onClick = onInitiative) .clickable(onClick = onInitiative)
.padding(all = 8.dp), .padding(all = 8.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(4.dp), verticalArrangement = Arrangement.spacedBy(4.dp),
) { ) {
Text(
style = MaterialTheme.typography.labelSmall,
text = sheet.initiative.label?.let { stringResource(id = it) } ?: ""
)
Text(
style = MaterialTheme.typography.displayMedium,
text = sheet.initiative.value ?: ""
)
}
sheet.stats.forEach {
Stat(
modifier = Modifier.ddBorder(inner = inner, outline = outline),
stat = it,
onClick = onStats,
)
}
},
savingThrows = {
sheet.savingThrows.forEach {
Proficiency(
proficiency = it,
onClick = onProficiencies,
)
}
Text( Text(
modifier = Modifier.padding(vertical = 4.dp),
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
text = sheet.initiative.label?.let { stringResource(id = it) } ?: "" text = stringResource(id = R.string.character_sheet_title_saving_throws)
) )
},
proficiencies = {
sheet.proficiencies.forEach {
Proficiency(
proficiency = it,
onClick = onProficiencies,
)
}
Text( Text(
style = MaterialTheme.typography.displayMedium, modifier = Modifier.padding(vertical = 4.dp),
text = sheet.initiative.value ?: "" style = MaterialTheme.typography.labelSmall,
text = stringResource(id = R.string.character_sheet_title_proficiencies)
) )
} },
sheet.stats.forEach { )
Stat( }
modifier = Modifier.ddBorder(inner = inner, outline = outline),
stat = it,
onClick = onStats,
)
}
},
savingThrows = {
sheet.savingThrows.forEach {
Proficiency(
proficiency = it,
onClick = onProficiencies,
)
}
Text(
modifier = Modifier.padding(vertical = 4.dp),
style = MaterialTheme.typography.labelSmall,
text = stringResource(id = R.string.character_sheet_title_saving_throws)
)
},
proficiencies = {
sheet.proficiencies.forEach {
Proficiency(
proficiency = it,
onClick = onProficiencies,
)
}
Text(
modifier = Modifier.padding(vertical = 4.dp),
style = MaterialTheme.typography.labelSmall,
text = stringResource(id = R.string.character_sheet_title_proficiencies)
)
},
)
} }
@Composable @Composable
private fun ProficiencyLayout( private fun ProficiencyLayout(
modifier: Modifier = Modifier,
spacing: Dp = 16.dp, spacing: Dp = 16.dp,
inner: Shape, inner: Shape,
outline: Shape, outline: Shape,
@ -111,7 +119,6 @@ private fun ProficiencyLayout(
) { ) {
val density = LocalDensity.current val density = LocalDensity.current
Layout( Layout(
modifier = modifier,
content = { content = {
Column( Column(
modifier = Modifier.layoutId("StatsId"), modifier = Modifier.layoutId("StatsId"),
@ -182,4 +189,21 @@ private fun ProficiencyLayout(
val List<Measurable>.stats get() = first { it.layoutId == "StatsId" } val List<Measurable>.stats get() = first { it.layoutId == "StatsId" }
val List<Measurable>.savingThrows get() = first { it.layoutId == "SavingThrowsId" } val List<Measurable>.savingThrows get() = first { it.layoutId == "SavingThrowsId" }
val List<Measurable>.proficiencies get() = first { it.layoutId == "ProficienciesId" } val List<Measurable>.proficiencies get() = first { it.layoutId == "ProficienciesId" }
@Composable
@Preview(uiMode = UI_MODE_NIGHT_NO, heightDp = 1060)
@Preview(uiMode = UI_MODE_NIGHT_YES, heightDp = 1060)
private fun ProficiencyPreview() {
LexiconTheme {
Surface {
ProficiencyPage(
modifier = Modifier.padding(all = 16.dp),
sheet = rememberCharacterSheetPreview(),
onInitiative = { },
onStats = { },
onProficiencies = { },
)
}
}
}

View file

@ -0,0 +1,191 @@
package com.pixelized.rplexicon.ui.screens.character.preview
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.screens.character.CharacterSheetUio
import com.pixelized.rplexicon.ui.screens.character.composable.LabelPointUio
import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
@Stable
@Composable
fun rememberCharacterSheetPreview() = remember {
CharacterSheetUio(
armorClass = LabelPointUio(
label = R.string.character_sheet_title_ca,
value = "15",
),
hitPoint = LabelPointUio(
label = R.string.character_sheet_title_hp,
value = "125",
max = "/ 150",
),
speed = LabelPointUio(
label = R.string.character_sheet_title_speed,
value = "30",
max = "m",
),
initiative = LabelPointUio(
label = R.string.character_sheet_title_initiative,
value = "+2",
),
stats = listOf(
StatUio(
id = StatUio.ID.STRENGTH,
value = 16,
modifier = 3,
),
StatUio(
id = StatUio.ID.DEXTERITY,
value = 10,
modifier = 0,
),
StatUio(
id = StatUio.ID.CONSTITUTION,
value = 16,
modifier = 3,
),
StatUio(
id = StatUio.ID.INTELLIGENCE,
value = 8,
modifier = 1,
),
StatUio(
id = StatUio.ID.WISDOM,
value = 14,
modifier = 2,
),
StatUio(
id = StatUio.ID.CHARISMA,
value = 10,
modifier = 0,
),
),
savingThrows = listOf(
ProficiencyUio(
id = ProficiencyUio.ID.STRENGTH_SAVING_THROW,
multiplier = 1,
modifier = 5,
),
ProficiencyUio(
id = ProficiencyUio.ID.DEXTERITY_SAVING_THROW,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.CONSTITUTION_SAVING_THROW,
multiplier = 1,
modifier = +5,
),
ProficiencyUio(
id = ProficiencyUio.ID.INTELLIGENCE_SAVING_THROW,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.WISDOM_SAVING_THROW,
multiplier = 0,
modifier = +2,
),
ProficiencyUio(
id = ProficiencyUio.ID.CHARISMA_SAVING_THROW,
multiplier = 0,
modifier = +0,
),
),
proficiencies = listOf(
ProficiencyUio(
id = ProficiencyUio.ID.ACROBATICS,
multiplier = 0,
modifier = +0,
),
ProficiencyUio(
id = ProficiencyUio.ID.ANIMAL_HANDLING,
multiplier = 0,
modifier = 2,
),
ProficiencyUio(
id = ProficiencyUio.ID.ARCANA,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.ATHLETICS,
multiplier = 1,
modifier = 5,
),
ProficiencyUio(
id = ProficiencyUio.ID.DECEPTION,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.HISTORY,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.INSIGHT,
multiplier = 1,
modifier = 4,
),
ProficiencyUio(
id = ProficiencyUio.ID.INTIMIDATION,
multiplier = 1,
modifier = 2,
),
ProficiencyUio(
id = ProficiencyUio.ID.INVESTIGATION,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.MEDICINE,
multiplier = 0,
modifier = 2,
),
ProficiencyUio(
id = ProficiencyUio.ID.NATURE,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.PERCEPTION,
multiplier = 1,
modifier = 4,
),
ProficiencyUio(
id = ProficiencyUio.ID.PERFORMANCE,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.PERSUASION,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.RELIGION,
multiplier = 0,
modifier = -1,
),
ProficiencyUio(
id = ProficiencyUio.ID.SLEIGHT_OF_HAND,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.STEALTH,
multiplier = 0,
modifier = 0,
),
ProficiencyUio(
id = ProficiencyUio.ID.SURVIVAL,
multiplier = 1,
modifier = 4,
),
),
)
}