GameMaster summary screen
This commit is contained in:
parent
805bdc65bc
commit
ff105e2f81
35 changed files with 2770 additions and 74 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package com.pixelized.rplexicon.data.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.pixelized.rplexicon.R
|
||||
|
||||
data class CharacterSheet(
|
||||
|
|
@ -61,30 +62,34 @@ data class CharacterSheet(
|
|||
val value: String,
|
||||
val resource: String? = null,
|
||||
val label: Int? = null,
|
||||
@DrawableRes val icon: Int,
|
||||
) {
|
||||
BARBARIAN(
|
||||
value = "Barbare",
|
||||
resource = "Rage",
|
||||
label = R.string.character_sheet_title_rage
|
||||
label = R.string.character_sheet_title_rage,
|
||||
icon = R.drawable.ic_class_barbarian_24
|
||||
),
|
||||
BARD(
|
||||
value = "Barde",
|
||||
resource = "Inspiration bardique",
|
||||
label = R.string.character_sheet_title_inspiration
|
||||
label = R.string.character_sheet_title_inspiration,
|
||||
icon = R.drawable.ic_class_bard_24
|
||||
),
|
||||
CLERIC(
|
||||
value = "Clerc",
|
||||
resource = "Conduit divin",
|
||||
label = R.string.character_sheet_title_conduit
|
||||
label = R.string.character_sheet_title_conduit,
|
||||
icon = R.drawable.ic_class_cleric_24
|
||||
),
|
||||
DRUID(value = "Druide"),
|
||||
FIGHTER(value = "Guerrier"),
|
||||
MONK(value = "Moine"),
|
||||
PALADIN(value = "Paladin"),
|
||||
RANGER(value = "Rodeur"),
|
||||
ROGUE(value = "Roublard"),
|
||||
SORCERER(value = "Ensorceleur"),
|
||||
WARLOCK(value = "Occultiste"),
|
||||
WIZARD(value = "Magicien"),
|
||||
DRUID(value = "Druide", icon = R.drawable.ic_class_druid_24),
|
||||
FIGHTER(value = "Guerrier", icon = R.drawable.ic_class_fighter_24),
|
||||
MONK(value = "Moine", icon = R.drawable.ic_class_monk_24),
|
||||
PALADIN(value = "Paladin", icon = R.drawable.ic_class_paladin_24),
|
||||
RANGER(value = "Rodeur", icon = R.drawable.ic_class_ranger_24),
|
||||
ROGUE(value = "Roublard", icon = R.drawable.ic_class_rogue_24),
|
||||
SORCERER(value = "Ensorceleur", icon = R.drawable.ic_class_sorcerer_24),
|
||||
WARLOCK(value = "Occultiste", icon = R.drawable.ic_class_warlock_24),
|
||||
WIZARD(value = "Magicien", icon = R.drawable.ic_class_wizard_24),
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.pixelized.rplexicon.data.model
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.firebase.database.IgnoreExtraProperties
|
||||
import com.google.firebase.database.PropertyName
|
||||
|
||||
@Keep
|
||||
@IgnoreExtraProperties
|
||||
data class CharacterSheetFireMap(
|
||||
@get:PropertyName(CHARACTERS)
|
||||
@set:PropertyName(CHARACTERS)
|
||||
var characters: Map<String, CharacterSheetFire> = emptyMap(),
|
||||
) {
|
||||
companion object {
|
||||
private const val CHARACTERS = "Characters"
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.google.firebase.database.ktx.database
|
|||
import com.google.firebase.ktx.Firebase
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.data.model.CharacterSheetFire
|
||||
import com.pixelized.rplexicon.data.model.CharacterSheetFireMap
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -33,6 +34,36 @@ class FirebaseRepository @Inject constructor(
|
|||
Firebase.database.setPersistenceEnabled(true)
|
||||
}
|
||||
|
||||
fun getCharacter(): Flow<CharacterSheetFireMap> {
|
||||
return callbackFlow {
|
||||
// reference to the node
|
||||
val reference = database.getReference("/")
|
||||
// build a register the callback
|
||||
val listener = reference.addValueEventListener(object : ValueEventListener {
|
||||
override fun onDataChange(dataSnapshot: DataSnapshot) {
|
||||
val value = try {
|
||||
dataSnapshot.getValue(CharacterSheetFireMap::class.java)
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed to parse value.", exception)
|
||||
_error.tryEmit(exception)
|
||||
null
|
||||
}
|
||||
if (value != null) {
|
||||
trySend(value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancelled(error: DatabaseError) {
|
||||
Log.e(TAG, "Failed to read value.", error.toException())
|
||||
cancel()
|
||||
}
|
||||
})
|
||||
awaitClose {
|
||||
reference.removeEventListener(listener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getCharacter(character: String): Flow<CharacterSheetFire> {
|
||||
return callbackFlow {
|
||||
// reference to the node
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package com.pixelized.rplexicon.ui.navigation
|
|||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.material3.BottomAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
|
|
@ -43,6 +43,7 @@ import com.pixelized.rplexicon.ui.navigation.pages.composableQuests
|
|||
import com.pixelized.rplexicon.ui.navigation.pages.navigateToLexicon
|
||||
import com.pixelized.rplexicon.ui.navigation.pages.navigateToLocation
|
||||
import com.pixelized.rplexicon.ui.navigation.pages.navigateToQuestList
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToSummary
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
val LocalPageNavHost = staticCompositionLocalOf<NavHostController> {
|
||||
|
|
@ -59,7 +60,9 @@ fun HomeNavHost(
|
|||
questListState: LazyListState,
|
||||
locationListState: LazyListState,
|
||||
) {
|
||||
val screen = LocalScreenNavHost.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalSnack provides remember { SnackbarHostState() },
|
||||
) {
|
||||
|
|
@ -72,6 +75,14 @@ fun HomeNavHost(
|
|||
title = {
|
||||
Text(text = stringResource(id = R.string.app_name))
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { screen.navigateToSummary() }) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_d20_24),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
snackbarHost = {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.pixelized.rplexicon.ui.navigation.screens.composableSearch
|
|||
import com.pixelized.rplexicon.ui.navigation.screens.composableLocationDetail
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableQuestDetail
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableSpellDetail
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableSummary
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToHome
|
||||
|
||||
val LocalScreenNavHost = staticCompositionLocalOf<NavHostController> {
|
||||
|
|
@ -58,6 +59,8 @@ fun ScreenNavHost(
|
|||
composableLocationDetail()
|
||||
composableCharacterSheet()
|
||||
composableSpellDetail()
|
||||
|
||||
composableSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package com.pixelized.rplexicon.ui.navigation.screens
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptionsBuilder
|
||||
import com.pixelized.rplexicon.ui.navigation.NavigationAnimation
|
||||
import com.pixelized.rplexicon.ui.navigation.animatedComposable
|
||||
import com.pixelized.rplexicon.ui.screens.summary.SummaryScreen
|
||||
|
||||
private const val ROUTE = "summary"
|
||||
const val SUMMARY_ROUTE = ROUTE
|
||||
|
||||
fun NavGraphBuilder.composableSummary() {
|
||||
animatedComposable(
|
||||
route = SUMMARY_ROUTE,
|
||||
animation = NavigationAnimation.Push,
|
||||
) {
|
||||
SummaryScreen()
|
||||
}
|
||||
}
|
||||
|
||||
fun NavHostController.navigateToSummary(
|
||||
option: NavOptionsBuilder.() -> Unit = {},
|
||||
) {
|
||||
val route = ROUTE
|
||||
navigate(route = route, builder = option)
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.composable.character
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
|
@ -7,10 +8,15 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
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.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.dashedBorder
|
||||
|
||||
@Composable
|
||||
|
|
@ -18,13 +24,14 @@ fun MasteryCircle(
|
|||
modifier: Modifier = Modifier,
|
||||
multiplier: Int,
|
||||
size: Dp = 12.dp,
|
||||
borderWidth: Dp = 1.dp
|
||||
) {
|
||||
when (multiplier) {
|
||||
0 -> Box(
|
||||
modifier = modifier
|
||||
.size(size = size)
|
||||
.dashedBorder(
|
||||
width = 1.dp,
|
||||
width = borderWidth,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
shape = CircleShape,
|
||||
on = 2.dp,
|
||||
|
|
@ -43,14 +50,35 @@ fun MasteryCircle(
|
|||
|
||||
else -> Box(
|
||||
modifier = modifier
|
||||
.size(size = size)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
width = borderWidth,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
shape = CircleShape
|
||||
)
|
||||
.padding(2.dp)
|
||||
.padding(all = 2.dp)
|
||||
) {
|
||||
MasteryCircle(multiplier = multiplier - 1)
|
||||
MasteryCircle(
|
||||
multiplier = multiplier - 1,
|
||||
size = size - borderWidth * 2,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun MasteryCirclePreview(
|
||||
@PreviewParameter(MasteryCircleProvider::class) preview: Int,
|
||||
) {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
MasteryCircle(multiplier = preview)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MasteryCircleProvider : PreviewParameterProvider<Int> {
|
||||
override val values: Sequence<Int> = sequenceOf(0, 1, 2, 3)
|
||||
}
|
||||
|
|
@ -10,8 +10,7 @@ import com.pixelized.rplexicon.ui.screens.character.composable.character.Passive
|
|||
import com.pixelized.rplexicon.ui.screens.character.composable.character.ProficiencyUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.StatUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.proficiency.CharacterSheetUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.advantage
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.disadvantage
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.passivesBonus
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.sum
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier
|
||||
import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
||||
|
|
@ -21,194 +20,188 @@ class CharacterSheetUioFactory @Inject constructor() {
|
|||
|
||||
fun convert(
|
||||
sheet: CharacterSheet,
|
||||
alterations: Map<Property, List<Alteration.Status>>,
|
||||
status: Map<Property, List<Alteration.Status>>,
|
||||
): CharacterSheetUio {
|
||||
val proficiency = (sheet.proficiency + alterations[Property.PROFICIENCY].sum)
|
||||
val strength = sheet.strength + alterations[Property.STRENGTH].sum
|
||||
val dexterity = sheet.dexterity + alterations[Property.DEXTERITY].sum
|
||||
val constitution = sheet.constitution + alterations[Property.CONSTITUTION].sum
|
||||
val intelligence = sheet.intelligence + alterations[Property.INTELLIGENCE].sum
|
||||
val wisdom = sheet.wisdom + alterations[Property.WISDOM].sum
|
||||
val charisma = sheet.charisma + alterations[Property.CHARISMA].sum
|
||||
val proficiency = (sheet.proficiency + status[Property.PROFICIENCY].sum)
|
||||
val strength = sheet.strength + status[Property.STRENGTH].sum
|
||||
val dexterity = sheet.dexterity + status[Property.DEXTERITY].sum
|
||||
val constitution = sheet.constitution + status[Property.CONSTITUTION].sum
|
||||
val intelligence = sheet.intelligence + status[Property.INTELLIGENCE].sum
|
||||
val wisdom = sheet.wisdom + status[Property.WISDOM].sum
|
||||
val charisma = sheet.charisma + status[Property.CHARISMA].sum
|
||||
|
||||
return CharacterSheetUio(
|
||||
initiative = LabelPointUio(
|
||||
label = R.string.character_sheet_title_initiative,
|
||||
value = (dexterity.modifier + alterations[Property.INITIATIVE].sum).toLabel(),
|
||||
value = (dexterity.modifier + status[Property.INITIATIVE].sum).toLabel(),
|
||||
max = null,
|
||||
),
|
||||
stats = listOf(
|
||||
StatUio(
|
||||
id = StatUio.ID.STRENGTH,
|
||||
value = strength,
|
||||
modifier = strength.modifier + alterations[Property.STRENGTH_THROW].sum,
|
||||
modifier = strength.modifier + status[Property.STRENGTH_THROW].sum,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.DEXTERITY,
|
||||
value = dexterity,
|
||||
modifier = dexterity.modifier + alterations[Property.DEXTERITY_THROW].sum,
|
||||
modifier = dexterity.modifier + status[Property.DEXTERITY_THROW].sum,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.CONSTITUTION,
|
||||
value = constitution,
|
||||
modifier = constitution.modifier + alterations[Property.CONSTITUTION_THROW].sum,
|
||||
modifier = constitution.modifier + status[Property.CONSTITUTION_THROW].sum,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.INTELLIGENCE,
|
||||
value = intelligence,
|
||||
modifier = intelligence.modifier + alterations[Property.INTELLIGENCE_THROW].sum,
|
||||
modifier = intelligence.modifier + status[Property.INTELLIGENCE_THROW].sum,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.WISDOM,
|
||||
value = wisdom,
|
||||
modifier = wisdom.modifier + alterations[Property.WISDOM_THROW].sum,
|
||||
modifier = wisdom.modifier + status[Property.WISDOM_THROW].sum,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.CHARISMA,
|
||||
value = charisma,
|
||||
modifier = charisma.modifier + alterations[Property.CHARISMA_THROW].sum,
|
||||
modifier = charisma.modifier + status[Property.CHARISMA_THROW].sum,
|
||||
),
|
||||
),
|
||||
savingThrows = listOf(
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.STRENGTH_SAVING_THROW,
|
||||
multiplier = sheet.strengthSavingThrows,
|
||||
modifier = strength.modifier + alterations[Property.STRENGTH_SAVING_THROW].sum + sheet.strengthSavingThrows * proficiency,
|
||||
modifier = strength.modifier + status[Property.STRENGTH_SAVING_THROW].sum + sheet.strengthSavingThrows * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.DEXTERITY_SAVING_THROW,
|
||||
multiplier = sheet.dexteritySavingThrows,
|
||||
modifier = dexterity.modifier + alterations[Property.DEXTERITY_SAVING_THROW].sum + sheet.dexteritySavingThrows * proficiency,
|
||||
modifier = dexterity.modifier + status[Property.DEXTERITY_SAVING_THROW].sum + sheet.dexteritySavingThrows * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.CONSTITUTION_SAVING_THROW,
|
||||
multiplier = sheet.constitutionSavingThrows,
|
||||
modifier = constitution.modifier + alterations[Property.CONSTITUTION_SAVING_THROW].sum + sheet.constitutionSavingThrows * proficiency,
|
||||
modifier = constitution.modifier + status[Property.CONSTITUTION_SAVING_THROW].sum + sheet.constitutionSavingThrows * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INTELLIGENCE_SAVING_THROW,
|
||||
multiplier = sheet.intelligenceSavingThrows,
|
||||
modifier = intelligence.modifier + alterations[Property.INTELLIGENCE_SAVING_THROW].sum + sheet.intelligenceSavingThrows * proficiency,
|
||||
modifier = intelligence.modifier + status[Property.INTELLIGENCE_SAVING_THROW].sum + sheet.intelligenceSavingThrows * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.WISDOM_SAVING_THROW,
|
||||
multiplier = sheet.wisdomSavingThrows,
|
||||
modifier = wisdom.modifier + alterations[Property.WISDOM_SAVING_THROW].sum + sheet.wisdomSavingThrows * proficiency,
|
||||
modifier = wisdom.modifier + status[Property.WISDOM_SAVING_THROW].sum + sheet.wisdomSavingThrows * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.CHARISMA_SAVING_THROW,
|
||||
multiplier = sheet.charismaSavingThrows,
|
||||
modifier = charisma.modifier + alterations[Property.CHARISMA_SAVING_THROW].sum + sheet.charismaSavingThrows * proficiency,
|
||||
modifier = charisma.modifier + status[Property.CHARISMA_SAVING_THROW].sum + sheet.charismaSavingThrows * proficiency,
|
||||
),
|
||||
),
|
||||
proficiencies = listOf(
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ACROBATICS,
|
||||
multiplier = sheet.acrobatics,
|
||||
modifier = dexterity.modifier + alterations[Property.ACROBATICS].sum + sheet.acrobatics * proficiency,
|
||||
modifier = dexterity.modifier + status[Property.ACROBATICS].sum + sheet.acrobatics * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ARCANA,
|
||||
multiplier = sheet.arcana,
|
||||
modifier = intelligence.modifier + alterations[Property.ARCANA].sum + sheet.arcana * proficiency,
|
||||
modifier = intelligence.modifier + status[Property.ARCANA].sum + sheet.arcana * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ATHLETICS,
|
||||
multiplier = sheet.athletics,
|
||||
modifier = strength.modifier + alterations[Property.ATHLETICS].sum + sheet.athletics * proficiency,
|
||||
modifier = strength.modifier + status[Property.ATHLETICS].sum + sheet.athletics * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.STEALTH,
|
||||
multiplier = sheet.stealth,
|
||||
modifier = dexterity.modifier + alterations[Property.STEALTH].sum + sheet.stealth * proficiency,
|
||||
modifier = dexterity.modifier + status[Property.STEALTH].sum + sheet.stealth * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ANIMAL_HANDLING,
|
||||
multiplier = sheet.animalHandling,
|
||||
modifier = wisdom.modifier + alterations[Property.ANIMAL_HANDLING].sum + sheet.animalHandling * proficiency,
|
||||
modifier = wisdom.modifier + status[Property.ANIMAL_HANDLING].sum + sheet.animalHandling * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.SLEIGHT_OF_HAND,
|
||||
multiplier = sheet.sleightOfHand,
|
||||
modifier = dexterity.modifier + alterations[Property.SLEIGHT_OF_HAND].sum + sheet.sleightOfHand * proficiency,
|
||||
modifier = dexterity.modifier + status[Property.SLEIGHT_OF_HAND].sum + sheet.sleightOfHand * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.HISTORY,
|
||||
multiplier = sheet.history,
|
||||
modifier = intelligence.modifier + alterations[Property.HISTORY].sum + sheet.history * proficiency,
|
||||
modifier = intelligence.modifier + status[Property.HISTORY].sum + sheet.history * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INTIMIDATION,
|
||||
multiplier = sheet.intimidation,
|
||||
modifier = charisma.modifier + alterations[Property.INTIMIDATION].sum + sheet.intimidation * proficiency,
|
||||
modifier = charisma.modifier + status[Property.INTIMIDATION].sum + sheet.intimidation * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INSIGHT,
|
||||
multiplier = sheet.insight,
|
||||
modifier = wisdom.modifier + alterations[Property.INSIGHT].sum + sheet.insight * proficiency,
|
||||
modifier = wisdom.modifier + status[Property.INSIGHT].sum + sheet.insight * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INVESTIGATION,
|
||||
multiplier = sheet.investigation,
|
||||
modifier = intelligence.modifier + alterations[Property.INVESTIGATION].sum + sheet.investigation * proficiency,
|
||||
modifier = intelligence.modifier + status[Property.INVESTIGATION].sum + sheet.investigation * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.MEDICINE,
|
||||
multiplier = sheet.medicine,
|
||||
modifier = wisdom.modifier + alterations[Property.MEDICINE].sum + sheet.medicine * proficiency,
|
||||
modifier = wisdom.modifier + status[Property.MEDICINE].sum + sheet.medicine * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.NATURE,
|
||||
multiplier = sheet.nature,
|
||||
modifier = intelligence.modifier + alterations[Property.NATURE].sum + sheet.nature * proficiency,
|
||||
modifier = intelligence.modifier + status[Property.NATURE].sum + sheet.nature * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERCEPTION,
|
||||
multiplier = sheet.perception,
|
||||
modifier = wisdom.modifier + alterations[Property.PERCEPTION].sum + sheet.perception * proficiency,
|
||||
modifier = wisdom.modifier + status[Property.PERCEPTION].sum + sheet.perception * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERSUASION,
|
||||
multiplier = sheet.persuasion,
|
||||
modifier = charisma.modifier + alterations[Property.PERSUASION].sum + sheet.persuasion * proficiency,
|
||||
modifier = charisma.modifier + status[Property.PERSUASION].sum + sheet.persuasion * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.RELIGION,
|
||||
multiplier = sheet.religion,
|
||||
modifier = intelligence.modifier + alterations[Property.RELIGION].sum + sheet.religion * proficiency,
|
||||
modifier = intelligence.modifier + status[Property.RELIGION].sum + sheet.religion * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERFORMANCE,
|
||||
multiplier = sheet.performance,
|
||||
modifier = charisma.modifier + alterations[Property.PERFORMANCE].sum + sheet.performance * proficiency,
|
||||
modifier = charisma.modifier + status[Property.PERFORMANCE].sum + sheet.performance * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.SURVIVAL,
|
||||
multiplier = sheet.survival,
|
||||
modifier = wisdom.modifier + alterations[Property.SURVIVAL].sum + sheet.survival * proficiency,
|
||||
modifier = wisdom.modifier + status[Property.SURVIVAL].sum + sheet.survival * proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.DECEPTION,
|
||||
multiplier = sheet.deception,
|
||||
modifier = charisma.modifier + alterations[Property.DECEPTION].sum + sheet.deception * proficiency,
|
||||
modifier = charisma.modifier + status[Property.DECEPTION].sum + sheet.deception * proficiency,
|
||||
),
|
||||
),
|
||||
passives = PassivesUio(
|
||||
speed = sheet.speed,
|
||||
perception = alterations[Property.PERCEPTION].let {
|
||||
val advantage = if (it.advantage) 5 else 0
|
||||
val disadvantage = if (it.disadvantage) 5 else 0
|
||||
10 + wisdom.modifier + it.sum + sheet.perception * proficiency + advantage - disadvantage
|
||||
perception = status[Property.PERCEPTION].let {
|
||||
10 + wisdom.modifier + it.sum + sheet.perception * proficiency + it.passivesBonus
|
||||
},
|
||||
investigation = alterations[Property.INVESTIGATION].let {
|
||||
val advantage = if (it.advantage) 5 else 0
|
||||
val disadvantage = if (it.disadvantage) 5 else 0
|
||||
10 + intelligence.modifier + it.sum + sheet.investigation * proficiency + advantage - disadvantage
|
||||
investigation = status[Property.INVESTIGATION].let {
|
||||
10 + intelligence.modifier + it.sum + sheet.investigation * proficiency + it.passivesBonus
|
||||
},
|
||||
insight = alterations[Property.INSIGHT].let {
|
||||
val advantage = if (it.advantage) 5 else 0
|
||||
val disadvantage = if (it.disadvantage) 5 else 0
|
||||
10 + wisdom.modifier + it.sum + sheet.insight * proficiency + advantage - disadvantage
|
||||
insight = status[Property.INSIGHT].let {
|
||||
10 + wisdom.modifier + it.sum + sheet.insight * proficiency + it.passivesBonus
|
||||
},
|
||||
),
|
||||
masteries = MasteriesUio(
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ fun ProficiencyPageContent(
|
|||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
textAlign = TextAlign.Center,
|
||||
text = "Passives",
|
||||
text = stringResource(id = R.string.character_sheet_title_passive),
|
||||
)
|
||||
},
|
||||
masteries = {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class ProficiencyViewModel @Inject constructor(
|
|||
val alterations = alterationRepository.getActiveAlterationsStatus(character)
|
||||
val sheet = characterSheetFactory.convert(
|
||||
sheet = characterSheet,
|
||||
alterations = alterations,
|
||||
status = alterations,
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
_sheet.value = sheet
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Arrangement
|
|||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
|
|
@ -158,7 +159,10 @@ fun LexiconItem(
|
|||
}
|
||||
|
||||
if (item.isPlayingCharacter) {
|
||||
IconButton(onClick = { item.let(onCharacterSheet) }) {
|
||||
IconButton(
|
||||
modifier = Modifier.offset(x = 4.dp),
|
||||
onClick = { item.let(onCharacterSheet) }
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_d20_24),
|
||||
contentDescription = null
|
||||
|
|
|
|||
|
|
@ -0,0 +1,598 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary
|
||||
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.data.model.CharacterSheet
|
||||
import com.pixelized.rplexicon.data.model.CharacterSheetFire
|
||||
import com.pixelized.rplexicon.data.model.Property
|
||||
import com.pixelized.rplexicon.data.repository.authentication.FirebaseRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.AlterationRepository
|
||||
import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.AttributesSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.CharacteristicsSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ClassHeaderSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.PassivesSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ProficiencySummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SavingThrowsSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SpellSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.label
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.maxLabel
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.none
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.proficiency
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.highestSpellLevel
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.passivesBonus
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.spell
|
||||
import com.pixelized.rplexicon.utilitary.extentions.local.sum
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier
|
||||
import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val ENTER_ANIMATION_INITIAL_DELAY = 250L
|
||||
private const val ENTER_ANIMATION_DELAY = 100L
|
||||
|
||||
class SummaryFactory @Inject constructor(
|
||||
private val characterSheetRepository: CharacterSheetRepository,
|
||||
private val alterationRepository: AlterationRepository,
|
||||
private val firebaseRepository: FirebaseRepository,
|
||||
) {
|
||||
fun fetchSummary(scope: CoroutineScope): SummaryUio {
|
||||
val headerVisibility = mutableStateOf(false)
|
||||
val statsVisibility = mutableStateOf(false)
|
||||
val characteristicsVisibility = mutableStateOf(false)
|
||||
val savingThrowsVisibility = mutableStateOf(false)
|
||||
val proficienciesVisibility = mutableStateOf(false)
|
||||
val passivesVisibility = mutableStateOf(false)
|
||||
val spellsVisibility = mutableStateOf(false)
|
||||
|
||||
val header = ClassHeaderSummaryUio(
|
||||
c1 = mutableStateOf(ClassHeaderSummaryUio.Header()),
|
||||
c2 = mutableStateOf(ClassHeaderSummaryUio.Header()),
|
||||
c3 = mutableStateOf(ClassHeaderSummaryUio.Header()),
|
||||
c4 = mutableStateOf(ClassHeaderSummaryUio.Header()),
|
||||
c5 = mutableStateOf(ClassHeaderSummaryUio.Header()),
|
||||
)
|
||||
val stats = AttributesSummaryUio(
|
||||
hp = SummaryRowUio(label = R.string.character_sheet_title_hp),
|
||||
ac = SummaryRowUio(label = R.string.character_sheet_title_ca),
|
||||
dc = SummaryRowUio(label = R.string.character_sheet_title_dc),
|
||||
speed = SummaryRowUio(label = R.string.character_sheet_title_speed),
|
||||
)
|
||||
val characteristics = CharacteristicsSummaryUio(
|
||||
strength = SummaryRowUio(label = R.string.character_sheet_stat_strength),
|
||||
dexterity = SummaryRowUio(label = R.string.character_sheet_stat_dexterity),
|
||||
constitution = SummaryRowUio(label = R.string.character_sheet_stat_constitution),
|
||||
intelligence = SummaryRowUio(label = R.string.character_sheet_stat_intelligence),
|
||||
wisdom = SummaryRowUio(label = R.string.character_sheet_stat_wisdom),
|
||||
charisma = SummaryRowUio(label = R.string.character_sheet_stat_charisma),
|
||||
)
|
||||
val savingThrows = SavingThrowsSummaryUio(
|
||||
strength = SummaryRowUio(label = R.string.character_sheet_stat_strength),
|
||||
dexterity = SummaryRowUio(label = R.string.character_sheet_stat_dexterity),
|
||||
constitution = SummaryRowUio(label = R.string.character_sheet_stat_constitution),
|
||||
intelligence = SummaryRowUio(label = R.string.character_sheet_stat_intelligence),
|
||||
wisdom = SummaryRowUio(label = R.string.character_sheet_stat_wisdom),
|
||||
charisma = SummaryRowUio(label = R.string.character_sheet_stat_charisma),
|
||||
)
|
||||
val proficiencies = ProficiencySummaryUio(
|
||||
acrobatics = SummaryRowUio(label = R.string.character_sheet_proficiency_acrobatics),
|
||||
animalHandling = SummaryRowUio(label = R.string.character_sheet_proficiency_animal_handling),
|
||||
arcana = SummaryRowUio(label = R.string.character_sheet_proficiency_arcana),
|
||||
athletics = SummaryRowUio(label = R.string.character_sheet_proficiency_athletics),
|
||||
deception = SummaryRowUio(label = R.string.character_sheet_proficiency_deception),
|
||||
history = SummaryRowUio(label = R.string.character_sheet_proficiency_history),
|
||||
insight = SummaryRowUio(label = R.string.character_sheet_proficiency_insight),
|
||||
intimidation = SummaryRowUio(label = R.string.character_sheet_proficiency_intimidation),
|
||||
investigation = SummaryRowUio(label = R.string.character_sheet_proficiency_investigation),
|
||||
medicine = SummaryRowUio(label = R.string.character_sheet_proficiency_medicine),
|
||||
nature = SummaryRowUio(label = R.string.character_sheet_proficiency_nature),
|
||||
perception = SummaryRowUio(label = R.string.character_sheet_proficiency_perception),
|
||||
performance = SummaryRowUio(label = R.string.character_sheet_proficiency_performance),
|
||||
persuasion = SummaryRowUio(label = R.string.character_sheet_proficiency_persuasion),
|
||||
religion = SummaryRowUio(label = R.string.character_sheet_proficiency_religion),
|
||||
sleightOfHand = SummaryRowUio(label = R.string.character_sheet_proficiency_sleight_of_hand),
|
||||
stealth = SummaryRowUio(label = R.string.character_sheet_proficiency_stealth),
|
||||
survival = SummaryRowUio(label = R.string.character_sheet_proficiency_survival),
|
||||
)
|
||||
val passives = PassivesSummaryUio(
|
||||
perception = SummaryRowUio(label = R.string.character_sheet_proficiency_perception),
|
||||
investigation = SummaryRowUio(label = R.string.character_sheet_proficiency_investigation),
|
||||
insight = SummaryRowUio(label = R.string.character_sheet_proficiency_insight),
|
||||
)
|
||||
val maxSpellSlot = mutableIntStateOf(0)
|
||||
val spells = SpellSummaryUio(
|
||||
extra = SummaryRowUio(label = R.string.character_sheet_title_skills),
|
||||
slot1 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_1),
|
||||
slot2 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_2),
|
||||
slot3 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_3),
|
||||
slot4 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_4),
|
||||
slot5 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_5),
|
||||
slot6 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_6),
|
||||
slot7 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_7),
|
||||
slot8 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_8),
|
||||
slot9 = SummaryRowUio(label = R.string.character_sheet_title_spell_slot_9),
|
||||
max = maxSpellSlot
|
||||
)
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val data = DataStruct()
|
||||
characterSheetRepository.data
|
||||
.combine(alterationRepository.assignedAlterations) { sheets, _ ->
|
||||
data.sheets = sheets
|
||||
}
|
||||
.combine(firebaseRepository.getCharacter()) { _, fire ->
|
||||
data.fires = fire.characters
|
||||
}
|
||||
.collect {
|
||||
val (sheets, fires) = data
|
||||
val characters = sheets.keys.sorted()
|
||||
|
||||
// Update the max spell slot card.
|
||||
val highestSpellSlot = sheets.values.maxOf { it.highestSpellLevel() }
|
||||
withContext(Dispatchers.Main) {
|
||||
maxSpellSlot.intValue = highestSpellSlot
|
||||
}
|
||||
|
||||
// extension function to root a character to a column property.
|
||||
fun ClassHeaderSummaryUio.get(sheet: CharacterSheet?) = when (sheet) {
|
||||
sheets[characters.getOrNull(0)] -> c1
|
||||
sheets[characters.getOrNull(1)] -> c2
|
||||
sheets[characters.getOrNull(2)] -> c3
|
||||
sheets[characters.getOrNull(3)] -> c4
|
||||
sheets[characters.getOrNull(4)] -> c5
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun SummaryRowUio.get(sheet: CharacterSheet?) = when (sheet) {
|
||||
sheets[characters.getOrNull(0)] -> c1
|
||||
sheets[characters.getOrNull(1)] -> c2
|
||||
sheets[characters.getOrNull(2)] -> c3
|
||||
sheets[characters.getOrNull(3)] -> c4
|
||||
sheets[characters.getOrNull(4)] -> c5
|
||||
else -> null
|
||||
}
|
||||
|
||||
// Update the header
|
||||
sheets.values.forEach { sheet ->
|
||||
val clazz = ClassHeaderSummaryUio.Header(
|
||||
label = sheet.name,
|
||||
icon = sheet.characterClass.firstOrNull()?.icon ?: R.drawable.ic_d20_24,
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
header.get(sheet)?.value = clazz
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (headerVisibility.value.not()) delay(ENTER_ANIMATION_INITIAL_DELAY)
|
||||
headerVisibility.value = true
|
||||
}
|
||||
|
||||
// Update the attributes
|
||||
sheets.values.forEach { sheet ->
|
||||
val status = alterationRepository.getActiveAlterationsStatus(sheet.name)
|
||||
val fire = fires[sheet.name]
|
||||
|
||||
val hitPoint = label(
|
||||
label = fire?.hitPoint?.let {
|
||||
when (it.additional) {
|
||||
null, 0 -> "${it.value}"
|
||||
else -> "${it.value}+${it.additional}"
|
||||
}
|
||||
} ?: "?",
|
||||
)
|
||||
val armorClass = label(
|
||||
label = "${sheet.armorClass + status[Property.ARMOR_CLASS].sum}",
|
||||
)
|
||||
val dC = label(
|
||||
label = sheet.dC?.let { "$it" } ?: "",
|
||||
)
|
||||
val speed = label(
|
||||
label = "${sheet.speed}",
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
stats.hp.get(sheet)?.value = hitPoint
|
||||
stats.ac.get(sheet)?.value = armorClass
|
||||
stats.dc.get(sheet)?.value = dC
|
||||
stats.speed.get(sheet)?.value = speed
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (statsVisibility.value.not()) delay(ENTER_ANIMATION_DELAY)
|
||||
statsVisibility.value = true
|
||||
}
|
||||
|
||||
// Update the Characteristics
|
||||
sheets.values.forEach { sheet ->
|
||||
val status = alterationRepository.getActiveAlterationsStatus(sheet.name)
|
||||
// Update the Characteristics
|
||||
val strengthLabel = label(
|
||||
label = "${sheet.strength + status[Property.STRENGTH].sum}",
|
||||
)
|
||||
val dexterityLabel = label(
|
||||
label = "${sheet.dexterity + status[Property.DEXTERITY].sum}",
|
||||
)
|
||||
val constitutionLabel = label(
|
||||
label = "${sheet.constitution + status[Property.CONSTITUTION].sum}",
|
||||
)
|
||||
val intelligenceLabel = label(
|
||||
label = "${sheet.intelligence + status[Property.INTELLIGENCE].sum}",
|
||||
)
|
||||
val wisdomLabel = label(
|
||||
label = "${sheet.wisdom + status[Property.WISDOM].sum}",
|
||||
)
|
||||
val charismaLabel = label(
|
||||
label = "${sheet.charisma + status[Property.CHARISMA].sum}",
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
characteristics.strength.get(sheet)?.value = strengthLabel
|
||||
characteristics.dexterity.get(sheet)?.value = dexterityLabel
|
||||
characteristics.constitution.get(sheet)?.value = constitutionLabel
|
||||
characteristics.intelligence.get(sheet)?.value = intelligenceLabel
|
||||
characteristics.wisdom.get(sheet)?.value = wisdomLabel
|
||||
characteristics.charisma.get(sheet)?.value = charismaLabel
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (characteristicsVisibility.value.not()) delay(ENTER_ANIMATION_DELAY)
|
||||
characteristicsVisibility.value = true
|
||||
}
|
||||
|
||||
// Update the SavingThrows
|
||||
sheets.values.forEach { sheet ->
|
||||
val status = alterationRepository.getActiveAlterationsStatus(sheet.name)
|
||||
|
||||
val proficiency = (sheet.proficiency + status[Property.PROFICIENCY].sum)
|
||||
val strength = sheet.strength + status[Property.STRENGTH].sum
|
||||
val dexterity = sheet.dexterity + status[Property.DEXTERITY].sum
|
||||
val constitution = sheet.constitution + status[Property.CONSTITUTION].sum
|
||||
val intelligence = sheet.intelligence + status[Property.INTELLIGENCE].sum
|
||||
val wisdom = sheet.wisdom + status[Property.WISDOM].sum
|
||||
val charisma = sheet.charisma + status[Property.CHARISMA].sum
|
||||
|
||||
val strengthSavingThrows = proficiency(
|
||||
multiplier = sheet.strengthSavingThrows,
|
||||
label = status[Property.STRENGTH_SAVING_THROW].let {
|
||||
strength.modifier + it.sum + sheet.strengthSavingThrows * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val dexteritySavingThrows = proficiency(
|
||||
multiplier = sheet.dexteritySavingThrows,
|
||||
label = status[Property.DEXTERITY_SAVING_THROW].let {
|
||||
dexterity.modifier + it.sum + sheet.dexteritySavingThrows * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val constitutionSavingThrows = proficiency(
|
||||
multiplier = sheet.constitutionSavingThrows,
|
||||
label = status[Property.CONSTITUTION_SAVING_THROW].let {
|
||||
constitution.modifier + it.sum + sheet.constitutionSavingThrows * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val intelligenceSavingThrows = proficiency(
|
||||
multiplier = sheet.intelligenceSavingThrows,
|
||||
label = status[Property.INTELLIGENCE_SAVING_THROW].let {
|
||||
intelligence.modifier + it.sum + sheet.intelligenceSavingThrows * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val wisdomSavingThrows = proficiency(
|
||||
multiplier = sheet.wisdomSavingThrows,
|
||||
label = status[Property.WISDOM_SAVING_THROW].let {
|
||||
wisdom.modifier + it.sum + sheet.wisdomSavingThrows * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val charismaSavingThrows = proficiency(
|
||||
multiplier = sheet.charismaSavingThrows,
|
||||
label = status[Property.CHARISMA_SAVING_THROW].let {
|
||||
charisma.modifier + it.sum + sheet.charismaSavingThrows * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
savingThrows.strength.get(sheet)?.value = strengthSavingThrows
|
||||
savingThrows.dexterity.get(sheet)?.value = dexteritySavingThrows
|
||||
savingThrows.constitution.get(sheet)?.value = constitutionSavingThrows
|
||||
savingThrows.intelligence.get(sheet)?.value = intelligenceSavingThrows
|
||||
savingThrows.wisdom.get(sheet)?.value = wisdomSavingThrows
|
||||
savingThrows.charisma.get(sheet)?.value = charismaSavingThrows
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (savingThrowsVisibility.value.not()) delay(ENTER_ANIMATION_DELAY)
|
||||
savingThrowsVisibility.value = true
|
||||
}
|
||||
|
||||
// Update proficiencies
|
||||
sheets.values.forEach { sheet ->
|
||||
val status = alterationRepository.getActiveAlterationsStatus(sheet.name)
|
||||
|
||||
val proficiency = (sheet.proficiency + status[Property.PROFICIENCY].sum)
|
||||
val strength = sheet.strength + status[Property.STRENGTH].sum
|
||||
val dexterity = sheet.dexterity + status[Property.DEXTERITY].sum
|
||||
val intelligence = sheet.intelligence + status[Property.INTELLIGENCE].sum
|
||||
val wisdom = sheet.wisdom + status[Property.WISDOM].sum
|
||||
val charisma = sheet.charisma + status[Property.CHARISMA].sum
|
||||
|
||||
val acrobatics = proficiency(
|
||||
multiplier = sheet.acrobatics,
|
||||
label = status[Property.ACROBATICS].let {
|
||||
dexterity.modifier + it.sum + sheet.acrobatics * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val arcana = proficiency(
|
||||
multiplier = sheet.arcana,
|
||||
label = status[Property.ARCANA].let {
|
||||
intelligence.modifier + it.sum + sheet.arcana * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val athletics = proficiency(
|
||||
multiplier = sheet.athletics,
|
||||
label = status[Property.ATHLETICS].let {
|
||||
strength.modifier + it.sum + sheet.athletics * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val stealth = proficiency(
|
||||
multiplier = sheet.stealth,
|
||||
label = status[Property.STEALTH].let {
|
||||
dexterity.modifier + it.sum + sheet.stealth * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val animalHandling = proficiency(
|
||||
multiplier = sheet.animalHandling,
|
||||
label = status[Property.ANIMAL_HANDLING].let {
|
||||
wisdom.modifier + it.sum + sheet.animalHandling * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val sleightOfHand = proficiency(
|
||||
multiplier = sheet.sleightOfHand,
|
||||
label = status[Property.SLEIGHT_OF_HAND].let {
|
||||
dexterity.modifier + it.sum + sheet.sleightOfHand * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val history = proficiency(
|
||||
multiplier = sheet.history,
|
||||
label = status[Property.HISTORY].let {
|
||||
intelligence.modifier + it.sum + sheet.history * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val intimidation = proficiency(
|
||||
multiplier = sheet.intimidation,
|
||||
label = status[Property.INTIMIDATION].let {
|
||||
charisma.modifier + it.sum + sheet.intimidation * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val insight = proficiency(
|
||||
multiplier = sheet.insight,
|
||||
label = status[Property.INSIGHT].let {
|
||||
wisdom.modifier + it.sum + sheet.insight * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val investigation = proficiency(
|
||||
multiplier = sheet.investigation,
|
||||
label = status[Property.INVESTIGATION].let {
|
||||
intelligence.modifier + it.sum + sheet.investigation * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val medicine = proficiency(
|
||||
multiplier = sheet.medicine,
|
||||
label = status[Property.MEDICINE].let {
|
||||
wisdom.modifier + it.sum + sheet.medicine * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val nature = proficiency(
|
||||
multiplier = sheet.nature,
|
||||
label = status[Property.NATURE].let {
|
||||
intelligence.modifier + it.sum + sheet.nature * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val perception = proficiency(
|
||||
multiplier = sheet.perception,
|
||||
label = status[Property.PERCEPTION].let {
|
||||
wisdom.modifier + it.sum + sheet.perception * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val persuasion = proficiency(
|
||||
multiplier = sheet.persuasion,
|
||||
label = status[Property.PERSUASION].let {
|
||||
charisma.modifier + it.sum + sheet.persuasion * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val religion = proficiency(
|
||||
multiplier = sheet.religion,
|
||||
label = status[Property.RELIGION].let {
|
||||
intelligence.modifier + it.sum + sheet.religion * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val performance = proficiency(
|
||||
multiplier = sheet.performance,
|
||||
label = status[Property.PERFORMANCE].let {
|
||||
charisma.modifier + it.sum + sheet.performance * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val survival = proficiency(
|
||||
multiplier = sheet.survival,
|
||||
label = status[Property.SURVIVAL].let {
|
||||
wisdom.modifier + it.sum + sheet.survival * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
val deception = proficiency(
|
||||
multiplier = sheet.deception,
|
||||
label = status[Property.DECEPTION].let {
|
||||
charisma.modifier + it.sum + sheet.deception * proficiency
|
||||
}.toLabel(),
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
proficiencies.acrobatics.get(sheet)?.value = acrobatics
|
||||
proficiencies.arcana.get(sheet)?.value = arcana
|
||||
proficiencies.athletics.get(sheet)?.value = athletics
|
||||
proficiencies.stealth.get(sheet)?.value = stealth
|
||||
proficiencies.animalHandling.get(sheet)?.value = animalHandling
|
||||
proficiencies.sleightOfHand.get(sheet)?.value = sleightOfHand
|
||||
proficiencies.history.get(sheet)?.value = history
|
||||
proficiencies.intimidation.get(sheet)?.value = intimidation
|
||||
proficiencies.insight.get(sheet)?.value = insight
|
||||
proficiencies.investigation.get(sheet)?.value = investigation
|
||||
proficiencies.medicine.get(sheet)?.value = medicine
|
||||
proficiencies.nature.get(sheet)?.value = nature
|
||||
proficiencies.perception.get(sheet)?.value = perception
|
||||
proficiencies.persuasion.get(sheet)?.value = persuasion
|
||||
proficiencies.religion.get(sheet)?.value = religion
|
||||
proficiencies.performance.get(sheet)?.value = performance
|
||||
proficiencies.survival.get(sheet)?.value = survival
|
||||
proficiencies.deception.get(sheet)?.value = deception
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (proficienciesVisibility.value.not()) delay(ENTER_ANIMATION_DELAY)
|
||||
proficienciesVisibility.value = true
|
||||
}
|
||||
|
||||
// Update passives
|
||||
sheets.values.forEach { sheet ->
|
||||
val status = alterationRepository.getActiveAlterationsStatus(sheet.name)
|
||||
|
||||
val proficiency = (sheet.proficiency + status[Property.PROFICIENCY].sum)
|
||||
val intelligence = sheet.intelligence + status[Property.INTELLIGENCE].sum
|
||||
val wisdom = sheet.wisdom + status[Property.WISDOM].sum
|
||||
|
||||
val passiveInsight = label(
|
||||
label = status[Property.INSIGHT].let {
|
||||
wisdom.modifier + it.sum + sheet.insight * proficiency + it.passivesBonus
|
||||
}.let { "${10 + it}" },
|
||||
)
|
||||
val passiveInvestigation = label(
|
||||
label = status[Property.INVESTIGATION].let {
|
||||
intelligence.modifier + it.sum + sheet.investigation * proficiency + it.passivesBonus
|
||||
}.let { "${10 + it}" },
|
||||
)
|
||||
val passivePerception = label(
|
||||
label = status[Property.PERCEPTION].let {
|
||||
wisdom.modifier + it.sum + sheet.perception * proficiency + it.passivesBonus
|
||||
}.let { "${10 + it}" }
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
passives.insight.get(sheet)?.value = passiveInsight
|
||||
passives.investigation.get(sheet)?.value = passiveInvestigation
|
||||
passives.perception.get(sheet)?.value = passivePerception
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (passivesVisibility.value.not()) delay(ENTER_ANIMATION_DELAY)
|
||||
passivesVisibility.value = true
|
||||
}
|
||||
|
||||
sheets.values.forEach { sheet ->
|
||||
val fire = fires[sheet.name]
|
||||
|
||||
// Update the extra skill.
|
||||
val slot1 = sheet.spell(level = 1)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 1)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
|
||||
// Update spells
|
||||
val skill = sheet.characterClass.firstOrNull()?.resource?.let { skill ->
|
||||
fire?.skills?.get(skill)
|
||||
}?.let { skill ->
|
||||
label(label = "$skill")
|
||||
} ?: none()
|
||||
val slot2 = sheet.spell(level = 2)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 2)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot3 = sheet.spell(level = 3)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 3)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot4 = sheet.spell(level = 4)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 4)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot5 = sheet.spell(level = 5)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 5)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot6 = sheet.spell(level = 6)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 6)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot7 = sheet.spell(level = 7)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 7)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot8 = sheet.spell(level = 8)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 8)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
val slot9 = sheet.spell(level = 9)?.let { max ->
|
||||
maxLabel(
|
||||
label = fire?.spell(level = 9)?.let { "$it" } ?: "",
|
||||
max = "$max",
|
||||
)
|
||||
} ?: none()
|
||||
withContext(Dispatchers.Main) {
|
||||
spells.extra.get(sheet = sheet)?.value = skill
|
||||
spells.slot1.get(sheet = sheet)?.value = slot1
|
||||
spells.slot2.get(sheet = sheet)?.value = slot2
|
||||
spells.slot3.get(sheet = sheet)?.value = slot3
|
||||
spells.slot4.get(sheet = sheet)?.value = slot4
|
||||
spells.slot5.get(sheet = sheet)?.value = slot5
|
||||
spells.slot6.get(sheet = sheet)?.value = slot6
|
||||
spells.slot7.get(sheet = sheet)?.value = slot7
|
||||
spells.slot8.get(sheet = sheet)?.value = slot8
|
||||
spells.slot9.get(sheet = sheet)?.value = slot9
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
if (spellsVisibility.value.not()) delay(ENTER_ANIMATION_DELAY)
|
||||
spellsVisibility.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SummaryUio(
|
||||
headerVisibility = headerVisibility,
|
||||
header = header,
|
||||
statsVisibility = statsVisibility,
|
||||
stats = stats,
|
||||
characteristicsVisibility = characteristicsVisibility,
|
||||
characteristics = characteristics,
|
||||
savingThrowsVisibility = savingThrowsVisibility,
|
||||
savingThrows = savingThrows,
|
||||
proficienciesVisibility = proficienciesVisibility,
|
||||
proficiencies = proficiencies,
|
||||
passivesVisibility = passivesVisibility,
|
||||
passives = passives,
|
||||
spellsVisibility = spellsVisibility,
|
||||
spells = spells,
|
||||
)
|
||||
}
|
||||
|
||||
private class DataStruct {
|
||||
lateinit var sheets: Map<String, CharacterSheet>
|
||||
lateinit var fires: Map<String, CharacterSheetFire>
|
||||
|
||||
operator fun component1() = sheets
|
||||
operator fun component2() = fires
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.EnterTransition
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.zIndex
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.composable.KeepOnScreen
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToCharacterSheet
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.AttributesSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.AttributesSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.CharacteristicsSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.CharacteristicsSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ClassHeaderSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ClassHeaderSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.PassivesSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.PassivesSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ProficiencySummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ProficiencySummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SavingThrowsSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SavingThrowsSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SpellSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SpellSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberCharacteristicsSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberClassHeaderSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberPassivesSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberProficienciesSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberSavingThrowsSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberSpellsSummary
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberStatsSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
|
||||
@Stable
|
||||
data class SummaryUio(
|
||||
val headerVisibility: State<Boolean>,
|
||||
val header: ClassHeaderSummaryUio,
|
||||
val statsVisibility: State<Boolean>,
|
||||
val stats: AttributesSummaryUio,
|
||||
val characteristicsVisibility: State<Boolean>,
|
||||
val characteristics: CharacteristicsSummaryUio,
|
||||
val savingThrowsVisibility: State<Boolean>,
|
||||
val savingThrows: SavingThrowsSummaryUio,
|
||||
val proficienciesVisibility: State<Boolean>,
|
||||
val proficiencies: ProficiencySummaryUio,
|
||||
val passivesVisibility: State<Boolean>,
|
||||
val passives: PassivesSummaryUio,
|
||||
val spellsVisibility: State<Boolean>,
|
||||
val spells: SpellSummaryUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SummaryScreen(
|
||||
viewModel: SummaryViewModel = hiltViewModel(),
|
||||
) {
|
||||
val screen = LocalScreenNavHost.current
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
SummaryContent(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.systemBarsPadding(),
|
||||
summary = viewModel.summary,
|
||||
onBack = {
|
||||
screen.popBackStack()
|
||||
},
|
||||
onHeader = {
|
||||
screen.navigateToCharacterSheet(name = it.label)
|
||||
}
|
||||
)
|
||||
|
||||
KeepOnScreen()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SummaryContent(
|
||||
modifier: Modifier = Modifier,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
summary: SummaryUio,
|
||||
onBack: () -> Unit,
|
||||
onHeader: (ClassHeaderSummaryUio.Header) -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
containerColor = Color.Transparent,
|
||||
topBar = {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 4.dp, vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_arrow_back_ios_new_24),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = stringResource(id = R.string.character_sheet_summary_title),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(state = scrollState)
|
||||
.padding(paddingValues = paddingValues)
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
modifier = Modifier
|
||||
.zIndex(zIndex = 1f)
|
||||
.fillMaxWidth()
|
||||
.offset { IntOffset(x = 0, y = scrollState.value) }
|
||||
.background(brush = rememberHeaderBackgroundGradient())
|
||||
.padding(bottom = 16.dp, end = 3.dp),
|
||||
visible = summary.headerVisibility.value,
|
||||
enter = fadeIn(),
|
||||
) {
|
||||
ClassHeaderSummary(
|
||||
header = summary.header,
|
||||
onClick = onHeader,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = summary.statsVisibility.value,
|
||||
enter = enterTransition(),
|
||||
) {
|
||||
AttributesSummary(
|
||||
attributes = summary.stats,
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = summary.characteristicsVisibility.value,
|
||||
enter = enterTransition(),
|
||||
) {
|
||||
CharacteristicsSummary(
|
||||
characteristics = summary.characteristics,
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = summary.savingThrowsVisibility.value,
|
||||
enter = enterTransition(),
|
||||
) {
|
||||
SavingThrowsSummary(
|
||||
savingThrows = summary.savingThrows,
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = summary.proficienciesVisibility.value,
|
||||
enter = enterTransition(),
|
||||
) {
|
||||
ProficiencySummary(
|
||||
proficiencies = summary.proficiencies,
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = summary.passivesVisibility.value,
|
||||
enter = enterTransition(),
|
||||
) {
|
||||
PassivesSummary(
|
||||
passives = summary.passives,
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = summary.spellsVisibility.value,
|
||||
enter = enterTransition(),
|
||||
) {
|
||||
SpellSummary(
|
||||
spells = summary.spells,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun enterTransition(
|
||||
density: Density = LocalDensity.current,
|
||||
): EnterTransition {
|
||||
return fadeIn() + slideInVertically { with(density) { 24.dp.roundToPx() } }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberHeaderBackgroundGradient(): Brush {
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
return remember {
|
||||
Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
colorScheme.surface.copy(alpha = 1.0f),
|
||||
colorScheme.surface.copy(alpha = 1.0f),
|
||||
colorScheme.surface.copy(alpha = 0.5f),
|
||||
colorScheme.surface.copy(alpha = 0.0f),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, heightDp = 1680)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, heightDp = 1680)
|
||||
private fun SummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
val header = rememberClassHeaderSummary()
|
||||
val stats = rememberStatsSummary()
|
||||
val characteristics = rememberCharacteristicsSummary()
|
||||
val savingThrows = rememberSavingThrowsSummary()
|
||||
val proficiencies = rememberProficienciesSummary()
|
||||
val passives = rememberPassivesSummary()
|
||||
val spells = rememberSpellsSummary()
|
||||
|
||||
SummaryContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
summary = remember {
|
||||
SummaryUio(
|
||||
headerVisibility = mutableStateOf(true),
|
||||
header = header,
|
||||
statsVisibility = mutableStateOf(true),
|
||||
stats = stats,
|
||||
characteristicsVisibility = mutableStateOf(true),
|
||||
characteristics = characteristics,
|
||||
savingThrowsVisibility = mutableStateOf(true),
|
||||
savingThrows = savingThrows,
|
||||
proficienciesVisibility = mutableStateOf(true),
|
||||
proficiencies = proficiencies,
|
||||
passivesVisibility = mutableStateOf(true),
|
||||
passives = passives,
|
||||
spellsVisibility = mutableStateOf(true),
|
||||
spells = spells,
|
||||
)
|
||||
},
|
||||
onBack = { },
|
||||
onHeader = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SummaryViewModel @Inject constructor(
|
||||
factory: SummaryFactory,
|
||||
) : ViewModel() {
|
||||
val summary = factory.fetchSummary(viewModelScope)
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRow
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberStatsSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
data class AttributesSummaryUio(
|
||||
val hp: SummaryRowUio,
|
||||
val ac: SummaryRowUio,
|
||||
val dc: SummaryRowUio,
|
||||
val speed: SummaryRowUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun AttributesSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
attributes: AttributesSummaryUio,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp)
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SummaryRow(
|
||||
row = attributes.hp,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
SummaryRow(
|
||||
row = attributes.ac,
|
||||
)
|
||||
SummaryRow(
|
||||
row = attributes.dc,
|
||||
)
|
||||
SummaryRow(
|
||||
row = attributes.speed,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_attribute)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun StatsSummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
AttributesSummary(
|
||||
attributes = rememberStatsSummary()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRow
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberCharacteristicsSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
data class CharacteristicsSummaryUio(
|
||||
val strength: SummaryRowUio,
|
||||
val dexterity: SummaryRowUio,
|
||||
val constitution: SummaryRowUio,
|
||||
val intelligence: SummaryRowUio,
|
||||
val wisdom: SummaryRowUio,
|
||||
val charisma: SummaryRowUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun CharacteristicsSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
padding: PaddingValues = PaddingValues(start = 8.dp, top = 4.dp, bottom = 4.dp),
|
||||
characteristics: CharacteristicsSummaryUio,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.padding(paddingValues = padding)
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SummaryRow(
|
||||
row = characteristics.strength,
|
||||
)
|
||||
SummaryRow(
|
||||
row = characteristics.dexterity,
|
||||
)
|
||||
SummaryRow(
|
||||
row = characteristics.constitution,
|
||||
)
|
||||
SummaryRow(
|
||||
row = characteristics.intelligence,
|
||||
)
|
||||
SummaryRow(
|
||||
row = characteristics.wisdom,
|
||||
)
|
||||
SummaryRow(
|
||||
row = characteristics.charisma,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_characteristic)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun CharacteristicsSummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
CharacteristicsSummary(
|
||||
characteristics = rememberCharacteristicsSummary(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberClassHeaderSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
|
||||
@Stable
|
||||
data class ClassHeaderSummaryUio(
|
||||
val c1: MutableState<Header>,
|
||||
val c2: MutableState<Header>,
|
||||
val c3: MutableState<Header>,
|
||||
val c4: MutableState<Header>,
|
||||
val c5: MutableState<Header>,
|
||||
) {
|
||||
@Stable
|
||||
data class Header(
|
||||
val label: String = "",
|
||||
@DrawableRes val icon: Int = R.drawable.ic_d20_24,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ClassHeaderSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
header: ClassHeaderSummaryUio,
|
||||
onClick: (ClassHeaderSummaryUio.Header) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 1.dp, alignment = Alignment.End),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
IconButton(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
onClick = { onClick(header.c1.value) },
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
painter = painterResource(id = header.c1.value.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
onClick = { onClick(header.c2.value) },
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
painter = painterResource(id = header.c2.value.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
onClick = { onClick(header.c3.value) },
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
painter = painterResource(id = header.c3.value.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
onClick = { onClick(header.c4.value) },
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
painter = painterResource(id = header.c4.value.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
onClick = { onClick(header.c5.value) },
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.width(MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
painter = painterResource(id = header.c5.value.icon),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun ClassHeaderSummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
ClassHeaderSummary(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
header = rememberClassHeaderSummary(),
|
||||
onClick = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRow
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberPassivesSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
data class PassivesSummaryUio(
|
||||
val perception: SummaryRowUio,
|
||||
val investigation: SummaryRowUio,
|
||||
val insight: SummaryRowUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun PassivesSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
passives: PassivesSummaryUio,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp)
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SummaryRow(
|
||||
row = passives.perception,
|
||||
)
|
||||
SummaryRow(
|
||||
row = passives.investigation,
|
||||
)
|
||||
SummaryRow(
|
||||
row = passives.insight,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_passive)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun PassivesSummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
PassivesSummary(
|
||||
passives = rememberPassivesSummary(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRow
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberProficienciesSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
data class ProficiencySummaryUio(
|
||||
val acrobatics: SummaryRowUio,
|
||||
val animalHandling: SummaryRowUio,
|
||||
val arcana: SummaryRowUio,
|
||||
val athletics: SummaryRowUio,
|
||||
val deception: SummaryRowUio,
|
||||
val history: SummaryRowUio,
|
||||
val insight: SummaryRowUio,
|
||||
val intimidation: SummaryRowUio,
|
||||
val investigation: SummaryRowUio,
|
||||
val medicine: SummaryRowUio,
|
||||
val nature: SummaryRowUio,
|
||||
val perception: SummaryRowUio,
|
||||
val performance: SummaryRowUio,
|
||||
val persuasion: SummaryRowUio,
|
||||
val religion: SummaryRowUio,
|
||||
val sleightOfHand: SummaryRowUio,
|
||||
val stealth: SummaryRowUio,
|
||||
val survival: SummaryRowUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun ProficiencySummary(
|
||||
modifier: Modifier = Modifier,
|
||||
proficiencies: ProficiencySummaryUio,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp)
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SummaryRow(
|
||||
row = proficiencies.acrobatics,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.arcana,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.athletics,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.stealth,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.animalHandling,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.sleightOfHand,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.history,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.intimidation,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.insight,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.investigation,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.medicine,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.nature,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.perception,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.persuasion,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.religion,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.performance,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.survival,
|
||||
)
|
||||
SummaryRow(
|
||||
row = proficiencies.deception,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_proficiencies)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun ProficiencySummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
ProficiencySummary(
|
||||
proficiencies = rememberProficienciesSummary(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRow
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberSavingThrowsSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
data class SavingThrowsSummaryUio(
|
||||
val strength: SummaryRowUio,
|
||||
val dexterity: SummaryRowUio,
|
||||
val constitution: SummaryRowUio,
|
||||
val intelligence: SummaryRowUio,
|
||||
val wisdom: SummaryRowUio,
|
||||
val charisma: SummaryRowUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SavingThrowsSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
savingThrows: SavingThrowsSummaryUio
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp)
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SummaryRow(
|
||||
row = savingThrows.strength,
|
||||
)
|
||||
SummaryRow(
|
||||
row = savingThrows.dexterity,
|
||||
)
|
||||
SummaryRow(
|
||||
row = savingThrows.constitution,
|
||||
)
|
||||
SummaryRow(
|
||||
row = savingThrows.intelligence,
|
||||
)
|
||||
SummaryRow(
|
||||
row = savingThrows.wisdom,
|
||||
)
|
||||
SummaryRow(
|
||||
row = savingThrows.charisma,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_saving_throws)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SavingThrowsSummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
SavingThrowsSummary(
|
||||
savingThrows = rememberSavingThrowsSummary(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRow
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.preview.rememberSpellsSummary
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
data class SpellSummaryUio(
|
||||
val extra: SummaryRowUio,
|
||||
val slot1: SummaryRowUio,
|
||||
val slot2: SummaryRowUio,
|
||||
val slot3: SummaryRowUio,
|
||||
val slot4: SummaryRowUio,
|
||||
val slot5: SummaryRowUio,
|
||||
val slot6: SummaryRowUio,
|
||||
val slot7: SummaryRowUio,
|
||||
val slot8: SummaryRowUio,
|
||||
val slot9: SummaryRowUio,
|
||||
val max: State<Int>,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SpellSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = MaterialTheme.colorScheme.primary,
|
||||
spells: SpellSummaryUio,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp)
|
||||
.then(other = modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SummaryRow(
|
||||
row = spells.extra,
|
||||
color = color,
|
||||
)
|
||||
if (1 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot1,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (2 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot2,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (3 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot3,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (4 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot4,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (5 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot5,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (6 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot6,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (7 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot7,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (8 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot8,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
if (9 <= spells.max.value) {
|
||||
SummaryRow(
|
||||
row = spells.slot9,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_spells)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SpellSummaryPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
SpellSummary(
|
||||
spells = rememberSpellsSummary(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.common
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||
import androidx.compose.animation.ContentTransform
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
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.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.MasteryCircle
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryCellUio.Mode
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
|
||||
@Stable
|
||||
data class SummaryCellUio(
|
||||
val mode: Mode = Mode.None,
|
||||
) {
|
||||
@Stable
|
||||
sealed class Mode {
|
||||
data object None : Mode()
|
||||
|
||||
@Stable
|
||||
data class Label(
|
||||
val label: String,
|
||||
) : Mode()
|
||||
|
||||
@Stable
|
||||
data class Proficiency(
|
||||
val label: String,
|
||||
val multiplier: Int,
|
||||
) : Mode()
|
||||
|
||||
@Stable
|
||||
data class LabelMax(
|
||||
val label: String,
|
||||
val max: String,
|
||||
) : Mode()
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
fun none() = SummaryCellUio(Mode.None)
|
||||
|
||||
@Stable
|
||||
fun label(
|
||||
label: String,
|
||||
): SummaryCellUio {
|
||||
return SummaryCellUio(
|
||||
Mode.Label(label),
|
||||
)
|
||||
}
|
||||
|
||||
@Stable
|
||||
fun maxLabel(
|
||||
label: String,
|
||||
max: String,
|
||||
): SummaryCellUio {
|
||||
return SummaryCellUio(
|
||||
Mode.LabelMax(
|
||||
label = label,
|
||||
max = max,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Stable
|
||||
fun proficiency(
|
||||
label: String,
|
||||
multiplier: Int,
|
||||
): SummaryCellUio {
|
||||
return SummaryCellUio(
|
||||
Mode.Proficiency(
|
||||
label = label,
|
||||
multiplier = multiplier,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SummaryValue(
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = MaterialTheme.typography.titleMedium,
|
||||
color: Color = MaterialTheme.colorScheme.onSurface,
|
||||
cell: State<SummaryCellUio>,
|
||||
) {
|
||||
when (val value = cell.value.mode) {
|
||||
Mode.None -> Box(
|
||||
modifier = Modifier
|
||||
.size(size = MaterialTheme.lexicon.dimens.summary.cell)
|
||||
.then(other = modifier)
|
||||
)
|
||||
|
||||
is Mode.Label -> SummaryLabel(
|
||||
modifier = modifier,
|
||||
style = style,
|
||||
color = color,
|
||||
value = value,
|
||||
)
|
||||
|
||||
is Mode.LabelMax -> SummaryMaxLabel(
|
||||
modifier = modifier,
|
||||
style = style,
|
||||
color = color,
|
||||
value = value,
|
||||
)
|
||||
|
||||
is Mode.Proficiency -> SummaryProficiency(
|
||||
modifier = modifier,
|
||||
style = style,
|
||||
color = color,
|
||||
value = value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SummaryLabel(
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = MaterialTheme.typography.titleMedium,
|
||||
color: Color = MaterialTheme.colorScheme.onSurface,
|
||||
value: Mode.Label,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(size = MaterialTheme.lexicon.dimens.summary.cell)
|
||||
.then(other = modifier),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = value,
|
||||
label = "SummaryLabelAnimation",
|
||||
transitionSpec = animationSpec(),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.width(width = MaterialTheme.lexicon.dimens.summary.cell.width),
|
||||
text = it.label,
|
||||
style = style,
|
||||
color = color,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SummaryMaxLabel(
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = MaterialTheme.typography.titleMedium,
|
||||
color: Color = MaterialTheme.colorScheme.onSurface,
|
||||
value: Mode.LabelMax,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(size = MaterialTheme.lexicon.dimens.summary.cell)
|
||||
.then(other = modifier),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = value.label,
|
||||
label = "SummaryMaxLabelAnimation",
|
||||
transitionSpec = animationSpec(),
|
||||
) {
|
||||
Text(
|
||||
text = it,
|
||||
style = style,
|
||||
color = color,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 3.dp),
|
||||
text = "/${value.max}",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = FontWeight.Normal,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SummaryProficiency(
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = MaterialTheme.typography.titleMedium,
|
||||
color: Color = MaterialTheme.colorScheme.onSurface,
|
||||
value: Mode.Proficiency,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.size(size = MaterialTheme.lexicon.dimens.summary.cell)
|
||||
.padding(start = 4.dp)
|
||||
.then(other = modifier),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
MasteryCircle(
|
||||
size = MaterialTheme.lexicon.dimens.summary.mastery,
|
||||
multiplier = value.multiplier,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
text = value.label,
|
||||
style = style,
|
||||
color = color,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
private fun animationSpec(): AnimatedContentTransitionScope<*>.() -> ContentTransform = {
|
||||
slideInVertically { it } + fadeIn() togetherWith
|
||||
slideOutVertically { -it } + fadeOut() using
|
||||
SizeTransform(clip = false)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun SummaryValuePreview(
|
||||
@PreviewParameter(SummaryValueProvider::class) preview: State<SummaryCellUio>,
|
||||
) {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
SummaryValue(cell = preview)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryValueProvider : PreviewParameterProvider<State<SummaryCellUio>> {
|
||||
override val values: Sequence<State<SummaryCellUio>> = sequenceOf(
|
||||
mutableStateOf(SummaryCellUio(Mode.None)),
|
||||
mutableStateOf(SummaryCellUio(Mode.Label(label = "16"))),
|
||||
mutableStateOf(SummaryCellUio(Mode.LabelMax(label = "16", max = "25"))),
|
||||
mutableStateOf(SummaryCellUio(Mode.Proficiency(label = "+5", multiplier = 1))),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.common
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.verticalDivider
|
||||
|
||||
@Stable
|
||||
data class SummaryRowUio(
|
||||
@StringRes val label: Int,
|
||||
val c1: MutableState<SummaryCellUio> = mutableStateOf(none()),
|
||||
val c2: MutableState<SummaryCellUio> = mutableStateOf(none()),
|
||||
val c3: MutableState<SummaryCellUio> = mutableStateOf(none()),
|
||||
val c4: MutableState<SummaryCellUio> = mutableStateOf(none()),
|
||||
val c5: MutableState<SummaryCellUio> = mutableStateOf(none()),
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SummaryRow(
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = MaterialTheme.typography.titleMedium,
|
||||
color: Color = MaterialTheme.colorScheme.onSurface,
|
||||
row: SummaryRowUio,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(weight = 1f, fill = false),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = stringResource(id = row.label),
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.height(intrinsicSize = IntrinsicSize.Min),
|
||||
) {
|
||||
Divider(
|
||||
modifier = Modifier.verticalDivider(),
|
||||
)
|
||||
SummaryValue(
|
||||
cell = row.c1,
|
||||
style = style,
|
||||
color = color,
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.verticalDivider(),
|
||||
)
|
||||
SummaryValue(
|
||||
cell = row.c2,
|
||||
style = style,
|
||||
color = color,
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.verticalDivider(),
|
||||
)
|
||||
SummaryValue(
|
||||
cell = row.c3,
|
||||
style = style,
|
||||
color = color,
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.verticalDivider(),
|
||||
)
|
||||
SummaryValue(
|
||||
cell = row.c4,
|
||||
style = style,
|
||||
color = color,
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.verticalDivider(),
|
||||
)
|
||||
SummaryValue(
|
||||
cell = row.c5,
|
||||
style = style,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun SummaryRowPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
SummaryRow(
|
||||
row = remember {
|
||||
SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_perception,
|
||||
c1 = mutableStateOf(proficiency("+6", 1)),
|
||||
c2 = mutableStateOf(proficiency("+2", 0)),
|
||||
c3 = mutableStateOf(proficiency("+4", 1)),
|
||||
c4 = mutableStateOf(proficiency("-1", 0)),
|
||||
c5 = mutableStateOf(proficiency("-1", 0)),
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.CharacteristicsSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.label
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberCharacteristicsSummary(): CharacteristicsSummaryUio {
|
||||
return remember {
|
||||
CharacteristicsSummaryUio(
|
||||
strength = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
c1 = mutableStateOf(label(label = "16")),
|
||||
c2 = mutableStateOf(label(label = "14")),
|
||||
c3 = mutableStateOf(label(label = "14")),
|
||||
c4 = mutableStateOf(label(label = "8")),
|
||||
c5 = mutableStateOf(label(label = "8")),
|
||||
),
|
||||
dexterity = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
c1 = mutableStateOf(label(label = "11")),
|
||||
c2 = mutableStateOf(label(label = "8")),
|
||||
c3 = mutableStateOf(label(label = "16")),
|
||||
c4 = mutableStateOf(label(label = "14")),
|
||||
c5 = mutableStateOf(label(label = "14")),
|
||||
),
|
||||
constitution = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
c1 = mutableStateOf(label(label = "16")),
|
||||
c2 = mutableStateOf(label(label = "15")),
|
||||
c3 = mutableStateOf(label(label = "12")),
|
||||
c4 = mutableStateOf(label(label = "10")),
|
||||
c5 = mutableStateOf(label(label = "14")),
|
||||
),
|
||||
intelligence = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
c1 = mutableStateOf(label(label = "8")),
|
||||
c2 = mutableStateOf(label(label = "11")),
|
||||
c3 = mutableStateOf(label(label = "10")),
|
||||
c4 = mutableStateOf(label(label = "14")),
|
||||
c5 = mutableStateOf(label(label = "12")),
|
||||
),
|
||||
wisdom = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
c1 = mutableStateOf(label(label = "14")),
|
||||
c2 = mutableStateOf(label(label = "16")),
|
||||
c3 = mutableStateOf(label(label = "15")),
|
||||
c4 = mutableStateOf(label(label = "12")),
|
||||
c5 = mutableStateOf(label(label = "10")),
|
||||
),
|
||||
charisma = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
c1 = mutableStateOf(label(label = "10")),
|
||||
c2 = mutableStateOf(label(label = "14")),
|
||||
c3 = mutableStateOf(label(label = "8")),
|
||||
c4 = mutableStateOf(label(label = "17")),
|
||||
c5 = mutableStateOf(label(label = "18")),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ClassHeaderSummaryUio
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberClassHeaderSummary(): ClassHeaderSummaryUio {
|
||||
return remember {
|
||||
ClassHeaderSummaryUio(
|
||||
c1 = mutableStateOf(
|
||||
ClassHeaderSummaryUio.Header(
|
||||
label = "Brulkai",
|
||||
icon = R.drawable.ic_class_barbarian_24,
|
||||
)
|
||||
),
|
||||
c2 = mutableStateOf(
|
||||
ClassHeaderSummaryUio.Header(
|
||||
label = "Léandre",
|
||||
icon = R.drawable.ic_class_cleric_24,
|
||||
)
|
||||
),
|
||||
c3 = mutableStateOf(
|
||||
ClassHeaderSummaryUio.Header(
|
||||
label = "Nélia",
|
||||
icon = R.drawable.ic_class_ranger_24,
|
||||
)
|
||||
),
|
||||
c4 = mutableStateOf(
|
||||
ClassHeaderSummaryUio.Header(
|
||||
label = "Tigrane",
|
||||
icon = R.drawable.ic_class_warlock_24,
|
||||
)
|
||||
),
|
||||
c5 = mutableStateOf(
|
||||
ClassHeaderSummaryUio.Header(
|
||||
label = "Unathana",
|
||||
icon = R.drawable.ic_class_bard_24,
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.PassivesSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.label
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberPassivesSummary(): PassivesSummaryUio {
|
||||
return remember {
|
||||
PassivesSummaryUio(
|
||||
perception = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_perception,
|
||||
c1 = mutableStateOf(label(label = "14")),
|
||||
c2 = mutableStateOf(label(label = "13")),
|
||||
c3 = mutableStateOf(label(label = "14")),
|
||||
c4 = mutableStateOf(label(label = "11")),
|
||||
c5 = mutableStateOf(label(label = "11")),
|
||||
),
|
||||
investigation = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_investigation,
|
||||
c1 = mutableStateOf(label(label = "9")),
|
||||
c2 = mutableStateOf(label(label = "10")),
|
||||
c3 = mutableStateOf(label(label = "10")),
|
||||
c4 = mutableStateOf(label(label = "14")),
|
||||
c5 = mutableStateOf(label(label = "13")),
|
||||
),
|
||||
insight = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_insight,
|
||||
c1 = mutableStateOf(label(label = "14")),
|
||||
c2 = mutableStateOf(label(label = "17")),
|
||||
c3 = mutableStateOf(label(label = "14")),
|
||||
c4 = mutableStateOf(label(label = "11")),
|
||||
c5 = mutableStateOf(label(label = "11")),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.ProficiencySummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryCellUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.proficiency
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberProficienciesSummary(): ProficiencySummaryUio {
|
||||
return remember {
|
||||
ProficiencySummaryUio(
|
||||
acrobatics = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_acrobatics,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+6", multiplier = 2)),
|
||||
),
|
||||
animalHandling = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_animal_handling,
|
||||
c1 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
),
|
||||
arcana = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_arcana,
|
||||
c1 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c5 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
),
|
||||
athletics = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_athletics,
|
||||
c1 = mutableStateOf(proficiency(label = "+5", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
),
|
||||
deception = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_deception,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+3", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+5", multiplier = 1)),
|
||||
c5 = mutableStateOf(proficiency(label = "+5", multiplier = 0)),
|
||||
),
|
||||
history = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_history,
|
||||
c1 = mutableStateOf(proficiency(label = "+1", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+2", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+3", multiplier = 1)),
|
||||
),
|
||||
insight = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_insight,
|
||||
c1 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+7", multiplier = 1)),
|
||||
c3 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
),
|
||||
intimidation = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_intimidation,
|
||||
c1 = mutableStateOf(proficiency(label = "+2", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+5", multiplier = 0)),
|
||||
),
|
||||
investigation = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_investigation,
|
||||
c1 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c5 = mutableStateOf(proficiency(label = "+3", multiplier = 1)),
|
||||
),
|
||||
medicine = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_medicine,
|
||||
c1 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+7", multiplier = 1)),
|
||||
c3 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
),
|
||||
nature = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_nature,
|
||||
c1 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
),
|
||||
perception = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_perception,
|
||||
c1 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
),
|
||||
performance = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_performance,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+8", multiplier = 2)),
|
||||
),
|
||||
persuasion = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_persuasion,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+6", multiplier = 1)),
|
||||
c3 = mutableStateOf(proficiency(label = "+3", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+6", multiplier = 1)),
|
||||
),
|
||||
religion = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_religion,
|
||||
c1 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c3 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
),
|
||||
sleightOfHand = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_sleight_of_hand,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c5 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
),
|
||||
stealth = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_stealth,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+5", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
),
|
||||
survival = SummaryRowUio(
|
||||
label = R.string.character_sheet_proficiency_survival,
|
||||
c1 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+2", multiplier = 1)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SavingThrowsSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.proficiency
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberSavingThrowsSummary(): SavingThrowsSummaryUio {
|
||||
return remember {
|
||||
SavingThrowsSummaryUio(
|
||||
strength = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
c1 = mutableStateOf(proficiency(label = "+6", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
),
|
||||
dexterity = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
c1 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+5", multiplier = 1)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+4", multiplier = 1)),
|
||||
),
|
||||
constitution = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
c1 = mutableStateOf(proficiency(label = "+6", multiplier = 1)),
|
||||
c2 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
),
|
||||
intelligence = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
c1 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c3 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c5 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
),
|
||||
wisdom = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
c1 = mutableStateOf(proficiency(label = "+3", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+7", multiplier = 1)),
|
||||
c3 = mutableStateOf(proficiency(label = "+2", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+3", multiplier = 1)),
|
||||
c5 = mutableStateOf(proficiency(label = "+0", multiplier = 0)),
|
||||
),
|
||||
charisma = SummaryRowUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
c1 = mutableStateOf(proficiency(label = "+1", multiplier = 0)),
|
||||
c2 = mutableStateOf(proficiency(label = "+6", multiplier = 1)),
|
||||
c3 = mutableStateOf(proficiency(label = "-1", multiplier = 0)),
|
||||
c4 = mutableStateOf(proficiency(label = "+5", multiplier = 1)),
|
||||
c5 = mutableStateOf(proficiency(label = "+6", multiplier = 1)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.SpellSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.label
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.maxLabel
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberSpellsSummary(): SpellSummaryUio {
|
||||
return remember {
|
||||
SpellSummaryUio(
|
||||
extra = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_skills,
|
||||
c1 = mutableStateOf(label(label = "2")),
|
||||
c2 = mutableStateOf(label(label = "1")),
|
||||
c5 = mutableStateOf(label(label = "4")),
|
||||
),
|
||||
slot1 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_1,
|
||||
c2 = mutableStateOf(maxLabel(label = "3", max = "4")),
|
||||
c3 = mutableStateOf(maxLabel(label = "3", max = "3")),
|
||||
c5 = mutableStateOf(maxLabel(label = "2", max = "4")),
|
||||
),
|
||||
slot2 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_2,
|
||||
c2 = mutableStateOf(maxLabel(label = "1", max = "2")),
|
||||
c4 = mutableStateOf(maxLabel(label = "2", max = "2")),
|
||||
c5 = mutableStateOf(maxLabel(label = "1", max = "2")),
|
||||
),
|
||||
slot3 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_3,
|
||||
),
|
||||
slot4 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_4,
|
||||
),
|
||||
slot5 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_5,
|
||||
),
|
||||
slot6 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_6,
|
||||
),
|
||||
slot7 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_7,
|
||||
),
|
||||
slot8 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_8,
|
||||
),
|
||||
slot9 = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_spell_slot_9,
|
||||
),
|
||||
max = mutableIntStateOf(2),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.pixelized.rplexicon.ui.screens.summary.composable.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.AttributesSummaryUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.SummaryRowUio
|
||||
import com.pixelized.rplexicon.ui.screens.summary.composable.common.label
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberStatsSummary(): AttributesSummaryUio {
|
||||
return remember {
|
||||
AttributesSummaryUio(
|
||||
hp = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_hp,
|
||||
c1 = mutableStateOf(label(label = "25")),
|
||||
c2 = mutableStateOf(label(label = "21")),
|
||||
c3 = mutableStateOf(label(label = "25")),
|
||||
c4 = mutableStateOf(label(label = "20")),
|
||||
c5 = mutableStateOf(label(label = "23")),
|
||||
),
|
||||
ac = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_ca,
|
||||
c1 = mutableStateOf(label(label = "16")),
|
||||
c2 = mutableStateOf(label(label = "15")),
|
||||
c3 = mutableStateOf(label(label = "15")),
|
||||
c4 = mutableStateOf(label(label = "13")),
|
||||
c5 = mutableStateOf(label(label = "13")),
|
||||
),
|
||||
dc = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_dc,
|
||||
c1 = mutableStateOf(label(label = "")),
|
||||
c2 = mutableStateOf(label(label = "15")),
|
||||
c3 = mutableStateOf(label(label = "12")),
|
||||
c4 = mutableStateOf(label(label = "13")),
|
||||
c5 = mutableStateOf(label(label = "14")),
|
||||
),
|
||||
speed = SummaryRowUio(
|
||||
label = R.string.character_sheet_title_speed,
|
||||
c1 = mutableStateOf(label(label = "10m")),
|
||||
c2 = mutableStateOf(label(label = "10m")),
|
||||
c3 = mutableStateOf(label(label = "13m")),
|
||||
c4 = mutableStateOf(label(label = "10m")),
|
||||
c5 = mutableStateOf(label(label = "10m")),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ 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.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlin.math.sqrt
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ data class LexiconDimens(
|
|||
val itemListPadding: PaddingValues,
|
||||
val handle: Handle,
|
||||
val map: Map,
|
||||
val summary: Summary,
|
||||
) {
|
||||
@Stable
|
||||
@Immutable
|
||||
|
|
@ -34,6 +36,15 @@ data class LexiconDimens(
|
|||
val crossStrokePx: Int,
|
||||
val shadowDropPx: Int,
|
||||
)
|
||||
|
||||
@Stable
|
||||
@Immutable
|
||||
data class Summary(
|
||||
val cell: DpSize,
|
||||
val mastery: Dp,
|
||||
val label: Dp,
|
||||
val space: Dp,
|
||||
)
|
||||
}
|
||||
|
||||
fun lexiconDimen(
|
||||
|
|
@ -56,10 +67,17 @@ fun lexiconDimen(
|
|||
crossStrokePx = with(density) { 2.dp.roundToPx() },
|
||||
shadowDropPx = with(density) { 2.dp.roundToPx() },
|
||||
),
|
||||
summary: LexiconDimens.Summary = LexiconDimens.Summary(
|
||||
cell = DpSize(width = 52.dp, height = 32.dp),
|
||||
mastery = 12.dp,
|
||||
label = 32.dp,
|
||||
space = 4.dp,
|
||||
),
|
||||
) = LexiconDimens(
|
||||
item = itemHeight,
|
||||
detailPadding = detailPadding,
|
||||
itemListPadding = itemListPadding,
|
||||
handle = handle,
|
||||
map = map,
|
||||
summary = summary,
|
||||
)
|
||||
|
|
@ -10,10 +10,12 @@ import androidx.compose.foundation.clickable
|
|||
import androidx.compose.foundation.gestures.detectTransformGestures
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.DividerDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -172,3 +174,7 @@ fun Modifier.lexiconShadow() = composed {
|
|||
shadow(elevation = 4.dp)
|
||||
}
|
||||
}
|
||||
|
||||
fun Modifier.verticalDivider() = this
|
||||
.fillMaxHeight()
|
||||
.width(1.dp)
|
||||
|
|
@ -25,6 +25,9 @@ val List<Alteration.Status>?.disadvantage: Boolean
|
|||
val List<Alteration.Status>?.fail: Boolean
|
||||
get() = this?.any { it.fail } ?: false
|
||||
|
||||
val List<Alteration.Status>?.passivesBonus: Int
|
||||
get() = (if (advantage) 5 else 0) - (if (disadvantage) 5 else 0)
|
||||
|
||||
// force a roll to hit a 20
|
||||
val List<Alteration.Status>?.critical: Boolean
|
||||
get() = this?.any { it.critical } ?: false
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
<string name="map_destination">Destinations :</string>
|
||||
<string name="map_illustrations">Illustrations :</string>
|
||||
|
||||
<string name="character_sheet_summary_title">Détails des personnages</string>
|
||||
<string name="character_sheet_refresh_label">Rafraichir</string>
|
||||
<string name="character_sheet_tab_proficiency">Talents</string>
|
||||
<string name="character_sheet_tab_inventory">Inventaire</string>
|
||||
|
|
@ -100,6 +101,10 @@
|
|||
<string name="character_sheet_title_inspiration">Inspiration</string>
|
||||
<string name="character_sheet_title_conduit">Conduit Divin</string>
|
||||
<string name="character_sheet_title_initiative">Initiative</string>
|
||||
<string name="character_sheet_title_characteristic">Caractéristiques</string>
|
||||
<string name="character_sheet_title_attribute">Attributs</string>
|
||||
<string name="character_sheet_title_passive">Talents passifs</string>
|
||||
<string name="character_sheet_title_spells">Sortilèges</string>
|
||||
<string name="character_sheet_title_saving_throws">Jet de sauvegarde</string>
|
||||
<string name="character_sheet_title_proficiencies">Talents</string>
|
||||
<string name="character_sheet_martial_masteries">Maîtrises martiales :</string>
|
||||
|
|
@ -110,6 +115,15 @@
|
|||
<string name="character_sheet_title_objects">Objets</string>
|
||||
<string name="character_sheet_title_inventory">Inventaire</string>
|
||||
<string name="character_sheet_title_equipment">Equipement</string>
|
||||
<string name="character_sheet_title_spell_slot_1">Sort de niveau 1</string>
|
||||
<string name="character_sheet_title_spell_slot_2">Sort de niveau 2</string>
|
||||
<string name="character_sheet_title_spell_slot_3">Sort de niveau 3</string>
|
||||
<string name="character_sheet_title_spell_slot_4">Sort de niveau 4</string>
|
||||
<string name="character_sheet_title_spell_slot_5">Sort de niveau 5</string>
|
||||
<string name="character_sheet_title_spell_slot_6">Sort de niveau 6</string>
|
||||
<string name="character_sheet_title_spell_slot_7">Sort de niveau 7</string>
|
||||
<string name="character_sheet_title_spell_slot_8">Sort de niveau 8</string>
|
||||
<string name="character_sheet_title_spell_slot_9">Sort de niveau 9</string>
|
||||
<string name="character_sheet_stat_level">Niveau</string>
|
||||
<string name="character_sheet_stat_strength">Force</string>
|
||||
<string name="character_sheet_stat_strength_short">FOR</string>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
<string name="map_destination">Destinations:</string>
|
||||
<string name="map_illustrations">Illustrations:</string>
|
||||
|
||||
<string name="character_sheet_summary_title">Characters sheets details</string>
|
||||
<string name="character_sheet_refresh_label">Refresh</string>
|
||||
<string name="character_sheet_tab_proficiency">Proficiencies</string>
|
||||
<string name="character_sheet_tab_inventory">Inventory</string>
|
||||
|
|
@ -102,6 +103,10 @@
|
|||
<string name="character_sheet_title_initiative">Initiative</string>
|
||||
<string name="character_sheet_title_saving_throws">Saving Throws</string>
|
||||
<string name="character_sheet_title_proficiencies">Proficiencies</string>
|
||||
<string name="character_sheet_title_characteristic">Characteristics</string>
|
||||
<string name="character_sheet_title_attribute">Attributes</string>
|
||||
<string name="character_sheet_title_passive">Passives proficiencies</string>
|
||||
<string name="character_sheet_title_spells">Spells</string>
|
||||
<string name="character_sheet_martial_masteries">Martial masteries:</string>
|
||||
<string name="character_sheet_languages_masteries">Languages masteries:</string>
|
||||
<string name="character_sheet_others_masteries">Others masteries:</string>
|
||||
|
|
@ -110,6 +115,15 @@
|
|||
<string name="character_sheet_title_skills">Skills</string>
|
||||
<string name="character_sheet_title_inventory">Inventory</string>
|
||||
<string name="character_sheet_title_equipment">Equipment</string>
|
||||
<string name="character_sheet_title_spell_slot_1">Spell slot 1</string>
|
||||
<string name="character_sheet_title_spell_slot_2">Spell slot 2</string>
|
||||
<string name="character_sheet_title_spell_slot_3">Spell slot 3</string>
|
||||
<string name="character_sheet_title_spell_slot_4">Spell slot 4</string>
|
||||
<string name="character_sheet_title_spell_slot_5">Spell slot 5</string>
|
||||
<string name="character_sheet_title_spell_slot_6">Spell slot 6</string>
|
||||
<string name="character_sheet_title_spell_slot_7">Spell slot 7</string>
|
||||
<string name="character_sheet_title_spell_slot_8">Spell slot 8</string>
|
||||
<string name="character_sheet_title_spell_slot_9">Spell slot 9</string>
|
||||
<string name="character_sheet_stat_level">Level</string>
|
||||
<string name="character_sheet_stat_strength">Strength</string>
|
||||
<string name="character_sheet_stat_strength_short">STR</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue