Rework the UI of the character sheet to fit the paper one.
This commit is contained in:
parent
f840777929
commit
5fe6cd0c01
16 changed files with 1024 additions and 1100 deletions
|
|
@ -5,14 +5,12 @@ import com.pixelized.rplexicon.model.CharacterSheet
|
|||
import com.pixelized.rplexicon.ui.screens.character.CharacterSheetUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.LabelPointUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.SavingsThrowsUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.modifier
|
||||
import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConvertCharacterSheetIntoDisplayableFactory @Inject constructor() {
|
||||
|
||||
fun toUio(sheet: CharacterSheet): CharacterSheetUio {
|
||||
return CharacterSheetUio(
|
||||
armorClass = LabelPointUio(
|
||||
|
|
@ -20,183 +18,176 @@ class ConvertCharacterSheetIntoDisplayableFactory @Inject constructor() {
|
|||
value = "${sheet.armorClass}",
|
||||
max = null,
|
||||
),
|
||||
speed = LabelPointUio(
|
||||
label = R.string.character_sheet_title_speed,
|
||||
value = "${sheet.speed}",
|
||||
max = "m",
|
||||
),
|
||||
hitPoint = LabelPointUio(
|
||||
label = R.string.character_sheet_title_hp,
|
||||
value = "${sheet.hitPoint}",
|
||||
max = "${sheet.maxHitPoint}",
|
||||
max = "/ ${sheet.maxHitPoint}",
|
||||
),
|
||||
initiative = LabelPointUio(
|
||||
label = R.string.character_sheet_title_initiative,
|
||||
value = sheet.dexterity.modifier.toLabel(),
|
||||
max = null,
|
||||
),
|
||||
strength = StatUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
value = sheet.strength,
|
||||
modifier = sheet.strength.modifier,
|
||||
stats = listOf(
|
||||
StatUio(
|
||||
id = StatUio.ID.STRENGTH,
|
||||
value = sheet.strength,
|
||||
modifier = sheet.strength.modifier,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.DEXTERITY,
|
||||
value = sheet.dexterity,
|
||||
modifier = sheet.dexterity.modifier,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.CONSTITUTION,
|
||||
value = sheet.constitution,
|
||||
modifier = sheet.constitution.modifier,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.INTELLIGENCE,
|
||||
value = sheet.intelligence,
|
||||
modifier = sheet.intelligence.modifier,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.WISDOM,
|
||||
value = sheet.wisdom,
|
||||
modifier = sheet.wisdom.modifier,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.CHARISMA,
|
||||
value = sheet.charisma,
|
||||
modifier = sheet.charisma.modifier,
|
||||
),
|
||||
),
|
||||
dexterity = StatUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
value = sheet.dexterity,
|
||||
modifier = sheet.dexterity.modifier,
|
||||
savingThrows = listOf(
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.STRENGTH_SAVING_THROW,
|
||||
multiplier = sheet.strengthSavingThrows,
|
||||
modifier = sheet.strength.modifier + sheet.strengthSavingThrows * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.DEXTERITY_SAVING_THROW,
|
||||
multiplier = sheet.dexteritySavingThrows,
|
||||
modifier = sheet.dexterity.modifier + sheet.dexteritySavingThrows * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.CONSTITUTION_SAVING_THROW,
|
||||
multiplier = sheet.constitutionSavingThrows,
|
||||
modifier = sheet.constitution.modifier + sheet.constitutionSavingThrows * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INTELLIGENCE_SAVING_THROW,
|
||||
multiplier = sheet.intelligenceSavingThrows,
|
||||
modifier = sheet.intelligence.modifier + sheet.intelligenceSavingThrows * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.WISDOM_SAVING_THROW,
|
||||
multiplier = sheet.wisdomSavingThrows,
|
||||
modifier = sheet.wisdom.modifier + sheet.wisdomSavingThrows * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.CHARISMA_SAVING_THROW,
|
||||
multiplier = sheet.charismaSavingThrows,
|
||||
modifier = sheet.charisma.modifier + sheet.charismaSavingThrows * sheet.proficiency,
|
||||
),
|
||||
),
|
||||
constitution = StatUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
value = sheet.constitution,
|
||||
modifier = sheet.constitution.modifier,
|
||||
),
|
||||
intelligence = StatUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
value = sheet.intelligence,
|
||||
modifier = sheet.intelligence.modifier,
|
||||
),
|
||||
wisdom = StatUio(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
value = sheet.wisdom,
|
||||
modifier = sheet.wisdom.modifier,
|
||||
),
|
||||
charisma = StatUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
value = sheet.charisma,
|
||||
modifier = sheet.charisma.modifier,
|
||||
),
|
||||
strengthSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
multiplier = sheet.strengthSavingThrows,
|
||||
modifier = sheet.strength.modifier + sheet.strengthSavingThrows * sheet.proficiency,
|
||||
),
|
||||
dexteritySavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
multiplier = sheet.dexteritySavingThrows,
|
||||
modifier = sheet.dexterity.modifier + sheet.dexteritySavingThrows * sheet.proficiency,
|
||||
),
|
||||
constitutionSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
multiplier = sheet.constitutionSavingThrows,
|
||||
modifier = sheet.constitution.modifier + sheet.constitutionSavingThrows * sheet.proficiency,
|
||||
),
|
||||
intelligenceSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
multiplier = sheet.intelligenceSavingThrows,
|
||||
modifier = sheet.intelligence.modifier + sheet.intelligenceSavingThrows * sheet.proficiency,
|
||||
),
|
||||
wisdomSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
multiplier = sheet.wisdomSavingThrows,
|
||||
modifier = sheet.wisdom.modifier + sheet.wisdomSavingThrows * sheet.proficiency,
|
||||
),
|
||||
charismaSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
multiplier = sheet.charismaSavingThrows,
|
||||
modifier = sheet.charisma.modifier + sheet.charismaSavingThrows * sheet.proficiency,
|
||||
),
|
||||
acrobatics = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_acrobatics,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
multiplier = sheet.acrobatics,
|
||||
modifier = sheet.dexterity.modifier + sheet.acrobatics * sheet.proficiency,
|
||||
),
|
||||
animalHandling = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_animal_handling,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = sheet.animalHandling,
|
||||
modifier = sheet.wisdom.modifier + sheet.animalHandling * sheet.proficiency,
|
||||
),
|
||||
arcana = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_arcana,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = sheet.arcana,
|
||||
modifier = sheet.intelligence.modifier + sheet.arcana * sheet.proficiency,
|
||||
),
|
||||
athletics = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_athletics,
|
||||
related = R.string.character_sheet_stat_strength_short,
|
||||
multiplier = sheet.athletics,
|
||||
modifier = sheet.strength.modifier + sheet.athletics * sheet.proficiency,
|
||||
),
|
||||
deception = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_deception,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = sheet.deception,
|
||||
modifier = sheet.charisma.modifier + sheet.deception * sheet.proficiency,
|
||||
),
|
||||
history = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_history,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = sheet.history,
|
||||
modifier = sheet.intelligence.modifier + sheet.history * sheet.proficiency,
|
||||
),
|
||||
insight = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_insight,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = sheet.insight,
|
||||
modifier = sheet.wisdom.modifier + sheet.insight * sheet.proficiency,
|
||||
),
|
||||
intimidation = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_intimidation,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = sheet.intimidation,
|
||||
modifier = sheet.charisma.modifier + sheet.intimidation * sheet.proficiency,
|
||||
),
|
||||
investigation = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_investigation,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = sheet.investigation,
|
||||
modifier = sheet.intelligence.modifier + sheet.investigation * sheet.proficiency,
|
||||
),
|
||||
medicine = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_medicine,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = sheet.medicine,
|
||||
modifier = sheet.wisdom.modifier + sheet.medicine * sheet.proficiency,
|
||||
),
|
||||
nature = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_nature,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = sheet.nature,
|
||||
modifier = sheet.intelligence.modifier + sheet.nature * sheet.proficiency,
|
||||
),
|
||||
perception = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_perception,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = sheet.perception,
|
||||
modifier = sheet.wisdom.modifier + sheet.perception * sheet.proficiency,
|
||||
),
|
||||
performance = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_performance,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = sheet.performance,
|
||||
modifier = sheet.charisma.modifier + sheet.performance * sheet.proficiency,
|
||||
),
|
||||
persuasion = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_persuasion,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = sheet.persuasion,
|
||||
modifier = sheet.charisma.modifier + sheet.persuasion * sheet.proficiency,
|
||||
),
|
||||
religion = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_religion,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = sheet.religion,
|
||||
modifier = sheet.intelligence.modifier + sheet.religion * sheet.proficiency,
|
||||
),
|
||||
sleightOfHand = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_sleight_of_hand,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
multiplier = sheet.sleightOfHand,
|
||||
modifier = sheet.dexterity.modifier + sheet.sleightOfHand * sheet.proficiency,
|
||||
),
|
||||
stealth = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_stealth,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
multiplier = sheet.stealth,
|
||||
modifier = sheet.dexterity.modifier + sheet.stealth * sheet.proficiency,
|
||||
),
|
||||
survival = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_survival,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = sheet.survival,
|
||||
modifier = sheet.wisdom.modifier + sheet.survival * sheet.proficiency,
|
||||
proficiencies = listOf(
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ACROBATICS,
|
||||
multiplier = sheet.acrobatics,
|
||||
modifier = sheet.dexterity.modifier + sheet.acrobatics * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ARCANA,
|
||||
multiplier = sheet.arcana,
|
||||
modifier = sheet.intelligence.modifier + sheet.arcana * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ATHLETICS,
|
||||
multiplier = sheet.athletics,
|
||||
modifier = sheet.strength.modifier + sheet.athletics * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.STEALTH,
|
||||
multiplier = sheet.stealth,
|
||||
modifier = sheet.dexterity.modifier + sheet.stealth * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ANIMAL_HANDLING,
|
||||
multiplier = sheet.animalHandling,
|
||||
modifier = sheet.wisdom.modifier + sheet.animalHandling * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.SLEIGHT_OF_HAND,
|
||||
multiplier = sheet.sleightOfHand,
|
||||
modifier = sheet.dexterity.modifier + sheet.sleightOfHand * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.HISTORY,
|
||||
multiplier = sheet.history,
|
||||
modifier = sheet.intelligence.modifier + sheet.history * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INTIMIDATION,
|
||||
multiplier = sheet.intimidation,
|
||||
modifier = sheet.charisma.modifier + sheet.intimidation * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INSIGHT,
|
||||
multiplier = sheet.insight,
|
||||
modifier = sheet.wisdom.modifier + sheet.insight * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INVESTIGATION,
|
||||
multiplier = sheet.investigation,
|
||||
modifier = sheet.intelligence.modifier + sheet.investigation * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.MEDICINE,
|
||||
multiplier = sheet.medicine,
|
||||
modifier = sheet.wisdom.modifier + sheet.medicine * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.NATURE,
|
||||
multiplier = sheet.nature,
|
||||
modifier = sheet.intelligence.modifier + sheet.nature * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERCEPTION,
|
||||
multiplier = sheet.perception,
|
||||
modifier = sheet.wisdom.modifier + sheet.perception * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERSUASION,
|
||||
multiplier = sheet.persuasion,
|
||||
modifier = sheet.charisma.modifier + sheet.persuasion * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.RELIGION,
|
||||
multiplier = sheet.religion,
|
||||
modifier = sheet.intelligence.modifier + sheet.religion * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERFORMANCE,
|
||||
multiplier = sheet.performance,
|
||||
modifier = sheet.charisma.modifier + sheet.performance * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.SURVIVAL,
|
||||
multiplier = sheet.survival,
|
||||
modifier = sheet.wisdom.modifier + sheet.survival * sheet.proficiency,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.DECEPTION,
|
||||
multiplier = sheet.deception,
|
||||
modifier = sheet.charisma.modifier + sheet.deception * sheet.proficiency,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,12 @@ class CharacterSheetParser @Inject constructor() {
|
|||
|
||||
// prepare a hash on the structure & function to get index in it.
|
||||
lateinit var structure: Map<String, Int>
|
||||
fun List<*>.parse(key: String): Int =
|
||||
fun List<*>.parseInt(key: String): Int =
|
||||
(getOrNull(structure.getValue(key)) as? String)?.toIntOrNull() ?: 0
|
||||
|
||||
fun List<*>.parseString(key: String): String? =
|
||||
(getOrNull(structure.getValue(key)) as? String)
|
||||
|
||||
// parse the sheet
|
||||
return sheet?.mapIndexedNotNull { index, item ->
|
||||
when (index) {
|
||||
|
|
@ -34,44 +37,45 @@ class CharacterSheetParser @Inject constructor() {
|
|||
}
|
||||
|
||||
else -> {
|
||||
val name = item.getOrNull(structure.getValue(NAME)) as String?
|
||||
val name = item.parseString(NAME)
|
||||
if (name != null) {
|
||||
CharacterSheet(
|
||||
name = name,
|
||||
hitPoint = item.parse(HIT_POINT),
|
||||
maxHitPoint = item.parse(MAX_HIT_POINT),
|
||||
armorClass = item.parse(ARMOR_CLASS),
|
||||
proficiency = item.parse(MASTERY),
|
||||
strength = item.parse(STRENGTH),
|
||||
dexterity = item.parse(DEXTERITY),
|
||||
constitution = item.parse(CONSTITUTION),
|
||||
intelligence = item.parse(INTELLIGENCE),
|
||||
wisdom = item.parse(WISDOM),
|
||||
charisma = item.parse(CHARISMA),
|
||||
strengthSavingThrows = item.parse(STRENGTH_SAVING_THROW),
|
||||
dexteritySavingThrows = item.parse(DEXTERITY_SAVING_THROW),
|
||||
constitutionSavingThrows = item.parse(CONSTITUTION_SAVING_THROW),
|
||||
intelligenceSavingThrows = item.parse(INTELLIGENCE_SAVING_THROW),
|
||||
wisdomSavingThrows = item.parse(WISDOM_SAVING_THROW),
|
||||
charismaSavingThrows = item.parse(CHARISMA_SAVING_THROW),
|
||||
acrobatics = item.parse(ACROBATICS),
|
||||
animalHandling = item.parse(ANIMAL_HANDLING),
|
||||
arcana = item.parse(ARCANA),
|
||||
athletics = item.parse(ATHLETICS),
|
||||
deception = item.parse(DECEPTION),
|
||||
history = item.parse(HISTORY),
|
||||
insight = item.parse(INSIGHT),
|
||||
intimidation = item.parse(INTIMIDATION),
|
||||
investigation = item.parse(INVESTIGATION),
|
||||
medicine = item.parse(MEDICINE),
|
||||
nature = item.parse(NATURE),
|
||||
perception = item.parse(PERCEPTION),
|
||||
performance = item.parse(PERFORMANCE),
|
||||
persuasion = item.parse(PERSUASION),
|
||||
religion = item.parse(RELIGION),
|
||||
sleightOfHand = item.parse(SLEIGHT_OF_HAND),
|
||||
stealth = item.parse(STEALTH),
|
||||
survival = item.parse(SURVIVAL),
|
||||
hitPoint = item.parseString(HIT_POINT) ?: "1",
|
||||
maxHitPoint = item.parseString(MAX_HIT_POINT) ?: "1",
|
||||
armorClass = item.parseString(ARMOR_CLASS) ?: "0",
|
||||
speed = item.parseInt(SPEED),
|
||||
proficiency = item.parseInt(MASTERY),
|
||||
strength = item.parseInt(STRENGTH),
|
||||
dexterity = item.parseInt(DEXTERITY),
|
||||
constitution = item.parseInt(CONSTITUTION),
|
||||
intelligence = item.parseInt(INTELLIGENCE),
|
||||
wisdom = item.parseInt(WISDOM),
|
||||
charisma = item.parseInt(CHARISMA),
|
||||
strengthSavingThrows = item.parseInt(STRENGTH_SAVING_THROW),
|
||||
dexteritySavingThrows = item.parseInt(DEXTERITY_SAVING_THROW),
|
||||
constitutionSavingThrows = item.parseInt(CONSTITUTION_SAVING_THROW),
|
||||
intelligenceSavingThrows = item.parseInt(INTELLIGENCE_SAVING_THROW),
|
||||
wisdomSavingThrows = item.parseInt(WISDOM_SAVING_THROW),
|
||||
charismaSavingThrows = item.parseInt(CHARISMA_SAVING_THROW),
|
||||
acrobatics = item.parseInt(ACROBATICS),
|
||||
animalHandling = item.parseInt(ANIMAL_HANDLING),
|
||||
arcana = item.parseInt(ARCANA),
|
||||
athletics = item.parseInt(ATHLETICS),
|
||||
deception = item.parseInt(DECEPTION),
|
||||
history = item.parseInt(HISTORY),
|
||||
insight = item.parseInt(INSIGHT),
|
||||
intimidation = item.parseInt(INTIMIDATION),
|
||||
investigation = item.parseInt(INVESTIGATION),
|
||||
medicine = item.parseInt(MEDICINE),
|
||||
nature = item.parseInt(NATURE),
|
||||
perception = item.parseInt(PERCEPTION),
|
||||
performance = item.parseInt(PERFORMANCE),
|
||||
persuasion = item.parseInt(PERSUASION),
|
||||
religion = item.parseInt(RELIGION),
|
||||
sleightOfHand = item.parseInt(SLEIGHT_OF_HAND),
|
||||
stealth = item.parseInt(STEALTH),
|
||||
survival = item.parseInt(SURVIVAL),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
|
@ -86,6 +90,7 @@ class CharacterSheetParser @Inject constructor() {
|
|||
private const val HIT_POINT = "Point de vie"
|
||||
private const val MAX_HIT_POINT = "Point de vie MAX"
|
||||
private const val ARMOR_CLASS = "Classe d'armure"
|
||||
private const val SPEED = "Vitesse"
|
||||
private const val MASTERY = "Bonus de maîtrise"
|
||||
private const val STRENGTH = "Force"
|
||||
private const val DEXTERITY = "Dextérité"
|
||||
|
|
@ -124,6 +129,7 @@ class CharacterSheetParser @Inject constructor() {
|
|||
HIT_POINT,
|
||||
MAX_HIT_POINT,
|
||||
ARMOR_CLASS,
|
||||
SPEED,
|
||||
MASTERY,
|
||||
STRENGTH,
|
||||
DEXTERITY,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ package com.pixelized.rplexicon.model
|
|||
|
||||
data class CharacterSheet(
|
||||
val name: String,
|
||||
val hitPoint: Int, // Point de vie
|
||||
val maxHitPoint: Int,
|
||||
val armorClass: Int, // Classe d'armure
|
||||
val hitPoint: String, // Point de vie
|
||||
val maxHitPoint: String,
|
||||
val armorClass: String, // Classe d'armure
|
||||
val speed: Int,
|
||||
val proficiency: Int, // Bonus de maîtrise
|
||||
val strength: Int, // Force
|
||||
val dexterity: Int, // Dextérité
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ fun BlurredOverlayHost(
|
|||
Box(
|
||||
modifier = Modifier
|
||||
.clickableInterceptor()
|
||||
.background(brush = MaterialTheme.lexicon.colorScheme.rollOverlayBrush)
|
||||
.background(color = MaterialTheme.lexicon.colorScheme.rollOverlayBrush)
|
||||
.fillMaxSize()
|
||||
.systemBarsPadding(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.pixelized.rplexicon.ui.screens.character
|
|||
|
||||
import android.content.res.Configuration
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
|
@ -61,11 +60,7 @@ import com.pixelized.rplexicon.ui.screens.character.composable.Counter
|
|||
import com.pixelized.rplexicon.ui.screens.character.composable.CounterUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.LabelPoint
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.LabelPointUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.Proficiency
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.SavingsThrows
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.SavingsThrowsUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.Stat
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
|
@ -74,38 +69,12 @@ import kotlinx.coroutines.launch
|
|||
@Stable
|
||||
data class CharacterSheetUio(
|
||||
val armorClass: LabelPointUio,
|
||||
val speed: LabelPointUio,
|
||||
val hitPoint: LabelPointUio,
|
||||
val initiative: LabelPointUio,
|
||||
val strength: StatUio,
|
||||
val dexterity: StatUio,
|
||||
val constitution: StatUio,
|
||||
val intelligence: StatUio,
|
||||
val wisdom: StatUio,
|
||||
val charisma: StatUio,
|
||||
val strengthSavingThrows: SavingsThrowsUio,
|
||||
val dexteritySavingThrows: SavingsThrowsUio,
|
||||
val constitutionSavingThrows: SavingsThrowsUio,
|
||||
val intelligenceSavingThrows: SavingsThrowsUio,
|
||||
val wisdomSavingThrows: SavingsThrowsUio,
|
||||
val charismaSavingThrows: SavingsThrowsUio,
|
||||
val acrobatics: ProficiencyUio,
|
||||
val animalHandling: ProficiencyUio,
|
||||
val arcana: ProficiencyUio,
|
||||
val athletics: ProficiencyUio,
|
||||
val deception: ProficiencyUio,
|
||||
val history: ProficiencyUio,
|
||||
val insight: ProficiencyUio,
|
||||
val intimidation: ProficiencyUio,
|
||||
val investigation: ProficiencyUio,
|
||||
val medicine: ProficiencyUio,
|
||||
val nature: ProficiencyUio,
|
||||
val perception: ProficiencyUio,
|
||||
val performance: ProficiencyUio,
|
||||
val persuasion: ProficiencyUio,
|
||||
val religion: ProficiencyUio,
|
||||
val sleightOfHand: ProficiencyUio,
|
||||
val stealth: ProficiencyUio,
|
||||
val survival: ProficiencyUio,
|
||||
val stats: List<StatUio>,
|
||||
val savingThrows: List<ProficiencyUio>,
|
||||
val proficiencies: List<ProficiencyUio>,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
|
|
@ -146,153 +115,45 @@ fun CharacterSheetScreen(
|
|||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onStrength = {
|
||||
val roll = viewModel.strengthRoll()
|
||||
onStats = { stat ->
|
||||
val roll = when (stat.id) {
|
||||
StatUio.ID.STRENGTH -> viewModel.strengthRoll()
|
||||
StatUio.ID.DEXTERITY -> viewModel.dexterityRoll()
|
||||
StatUio.ID.CONSTITUTION -> viewModel.constitutionRoll()
|
||||
StatUio.ID.INTELLIGENCE -> viewModel.intelligenceRoll()
|
||||
StatUio.ID.WISDOM -> viewModel.wisdomRoll()
|
||||
StatUio.ID.CHARISMA -> viewModel.charismaRoll()
|
||||
}
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onDexterity = {
|
||||
val roll = viewModel.dexterityRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onConstitution = {
|
||||
val roll = viewModel.constitutionRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onIntelligence = {
|
||||
val roll = viewModel.intelligenceRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onWisdom = {
|
||||
val roll = viewModel.wisdomRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onCharisma = {
|
||||
val roll = viewModel.charismaRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onStrengthSavingThrows = {
|
||||
val roll = viewModel.strengthSavingThrowsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onDexteritySavingThrows = {
|
||||
val roll = viewModel.dexteritySavingThrowsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onConstitutionSavingThrows = {
|
||||
val roll = viewModel.constitutionSavingThrowsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onIntelligenceSavingThrows = {
|
||||
val roll = viewModel.intelligenceSavingThrowsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onWisdomSavingThrows = {
|
||||
val roll = viewModel.wisdomSavingThrowsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onCharismaSavingThrows = {
|
||||
val roll = viewModel.charismaSavingThrowsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onAcrobatics = {
|
||||
val roll = viewModel.acrobaticsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onAnimalHandling = {
|
||||
val roll = viewModel.animalHandlingRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onArcana = {
|
||||
val roll = viewModel.arcanaRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onAthletics = {
|
||||
val roll = viewModel.athleticsRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onDeception = {
|
||||
val roll = viewModel.deceptionRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onHistory = {
|
||||
val roll = viewModel.historyRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onInsight = {
|
||||
val roll = viewModel.insightRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onIntimidation = {
|
||||
val roll = viewModel.intimidationRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onInvestigation = {
|
||||
val roll = viewModel.investigationRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onMedicine = {
|
||||
val roll = viewModel.medicineRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onNature = {
|
||||
val roll = viewModel.natureRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onPerception = {
|
||||
val roll = viewModel.perceptionRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onPerformance = {
|
||||
val roll = viewModel.performanceRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onPersuasion = {
|
||||
val roll = viewModel.persuasionRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onReligion = {
|
||||
val roll = viewModel.religionRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onSleightOfHand = {
|
||||
val roll = viewModel.sleightOfHandRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onStealth = {
|
||||
val roll = viewModel.stealthRoll()
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onSurvival = {
|
||||
val roll = viewModel.survivalRoll()
|
||||
onProficiencies = { proficiency ->
|
||||
val roll = when (proficiency.id) {
|
||||
ProficiencyUio.ID.STRENGTH_SAVING_THROW -> viewModel.strengthRoll()
|
||||
ProficiencyUio.ID.DEXTERITY_SAVING_THROW -> viewModel.dexterityRoll()
|
||||
ProficiencyUio.ID.CONSTITUTION_SAVING_THROW -> viewModel.constitutionRoll()
|
||||
ProficiencyUio.ID.INTELLIGENCE_SAVING_THROW -> viewModel.intelligenceRoll()
|
||||
ProficiencyUio.ID.WISDOM_SAVING_THROW -> viewModel.wisdomRoll()
|
||||
ProficiencyUio.ID.CHARISMA_SAVING_THROW -> viewModel.charismaRoll()
|
||||
ProficiencyUio.ID.ACROBATICS -> viewModel.acrobaticsRoll()
|
||||
ProficiencyUio.ID.ANIMAL_HANDLING -> viewModel.animalHandlingRoll()
|
||||
ProficiencyUio.ID.ARCANA -> viewModel.arcanaRoll()
|
||||
ProficiencyUio.ID.ATHLETICS -> viewModel.athleticsRoll()
|
||||
ProficiencyUio.ID.DECEPTION -> viewModel.deceptionRoll()
|
||||
ProficiencyUio.ID.HISTORY -> viewModel.historyRoll()
|
||||
ProficiencyUio.ID.INSIGHT -> viewModel.insightRoll()
|
||||
ProficiencyUio.ID.INTIMIDATION -> viewModel.intimidationRoll()
|
||||
ProficiencyUio.ID.INVESTIGATION -> viewModel.investigationRoll()
|
||||
ProficiencyUio.ID.MEDICINE -> viewModel.medicineRoll()
|
||||
ProficiencyUio.ID.NATURE -> viewModel.natureRoll()
|
||||
ProficiencyUio.ID.PERCEPTION -> viewModel.perceptionRoll()
|
||||
ProficiencyUio.ID.PERFORMANCE -> viewModel.performanceRoll()
|
||||
ProficiencyUio.ID.PERSUASION -> viewModel.persuasionRoll()
|
||||
ProficiencyUio.ID.RELIGION -> viewModel.religionRoll()
|
||||
ProficiencyUio.ID.SLEIGHT_OF_HAND -> viewModel.sleightOfHandRoll()
|
||||
ProficiencyUio.ID.STEALTH -> viewModel.stealthRoll()
|
||||
ProficiencyUio.ID.SURVIVAL -> viewModel.survivalRoll()
|
||||
}
|
||||
overlay.prepareRoll(roll = roll)
|
||||
overlay.showOverlay()
|
||||
},
|
||||
|
|
@ -328,37 +189,9 @@ private fun CharacterSheetContent(
|
|||
counter: State<List<CounterUio>>,
|
||||
alterations: State<List<String>>,
|
||||
onBack: () -> Unit,
|
||||
onStats: (StatUio) -> Unit,
|
||||
onProficiencies: (ProficiencyUio) -> Unit,
|
||||
onInitiative: () -> Unit,
|
||||
onStrength: () -> Unit,
|
||||
onDexterity: () -> Unit,
|
||||
onConstitution: () -> Unit,
|
||||
onIntelligence: () -> Unit,
|
||||
onWisdom: () -> Unit,
|
||||
onCharisma: () -> Unit,
|
||||
onStrengthSavingThrows: () -> Unit,
|
||||
onDexteritySavingThrows: () -> Unit,
|
||||
onConstitutionSavingThrows: () -> Unit,
|
||||
onIntelligenceSavingThrows: () -> Unit,
|
||||
onWisdomSavingThrows: () -> Unit,
|
||||
onCharismaSavingThrows: () -> Unit,
|
||||
onAcrobatics: () -> Unit,
|
||||
onAnimalHandling: () -> Unit,
|
||||
onArcana: () -> Unit,
|
||||
onAthletics: () -> Unit,
|
||||
onDeception: () -> Unit,
|
||||
onHistory: () -> Unit,
|
||||
onInsight: () -> Unit,
|
||||
onIntimidation: () -> Unit,
|
||||
onInvestigation: () -> Unit,
|
||||
onMedicine: () -> Unit,
|
||||
onNature: () -> Unit,
|
||||
onPerception: () -> Unit,
|
||||
onPerformance: () -> Unit,
|
||||
onPersuasion: () -> Unit,
|
||||
onReligion: () -> Unit,
|
||||
onSleightOfHand: () -> Unit,
|
||||
onStealth: () -> Unit,
|
||||
onSurvival: () -> Unit,
|
||||
onHit: (id: String) -> Unit,
|
||||
onDamage: (id: String) -> Unit,
|
||||
) {
|
||||
|
|
@ -407,200 +240,24 @@ private fun CharacterSheetContent(
|
|||
.padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
16.dp,
|
||||
Alignment.CenterHorizontally
|
||||
space = 16.dp,
|
||||
alignment = Alignment.CenterHorizontally
|
||||
),
|
||||
) {
|
||||
LabelPoint(
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
hp = sheet.armorClass,
|
||||
)
|
||||
LabelPoint(
|
||||
hp = sheet.hitPoint,
|
||||
)
|
||||
LabelPoint(
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
hp = sheet.initiative,
|
||||
onClick = onInitiative,
|
||||
)
|
||||
LabelPoint(label = sheet.armorClass)
|
||||
LabelPoint(label = sheet.hitPoint)
|
||||
LabelPoint(label = sheet.speed)
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Stat(
|
||||
modifier = Modifier.weight(1f),
|
||||
stat = sheet.strength,
|
||||
onClick = onStrength,
|
||||
)
|
||||
Stat(
|
||||
modifier = Modifier.weight(1f),
|
||||
stat = sheet.dexterity,
|
||||
onClick = onDexterity,
|
||||
)
|
||||
Stat(
|
||||
modifier = Modifier.weight(1f),
|
||||
stat = sheet.constitution,
|
||||
onClick = onConstitution,
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Stat(
|
||||
modifier = Modifier.weight(1f),
|
||||
stat = sheet.intelligence,
|
||||
onClick = onIntelligence,
|
||||
)
|
||||
Stat(
|
||||
modifier = Modifier.weight(1f),
|
||||
stat = sheet.wisdom,
|
||||
onClick = onWisdom,
|
||||
)
|
||||
Stat(
|
||||
modifier = Modifier.weight(1f),
|
||||
stat = sheet.charisma,
|
||||
onClick = onCharisma,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SectionTitle(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
title = R.string.character_sheet_title_saving_throws,
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
SavingsThrows(
|
||||
savingsThrows = sheet.strengthSavingThrows,
|
||||
onClick = onStrengthSavingThrows,
|
||||
)
|
||||
SavingsThrows(
|
||||
savingsThrows = sheet.dexteritySavingThrows,
|
||||
onClick = onDexteritySavingThrows,
|
||||
)
|
||||
SavingsThrows(
|
||||
savingsThrows = sheet.constitutionSavingThrows,
|
||||
onClick = onConstitutionSavingThrows,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
SavingsThrows(
|
||||
savingsThrows = sheet.intelligenceSavingThrows,
|
||||
onClick = onIntelligenceSavingThrows,
|
||||
)
|
||||
SavingsThrows(
|
||||
savingsThrows = sheet.wisdomSavingThrows,
|
||||
onClick = onWisdomSavingThrows,
|
||||
)
|
||||
SavingsThrows(
|
||||
savingsThrows = sheet.charismaSavingThrows,
|
||||
onClick = onCharismaSavingThrows,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SectionTitle(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
title = R.string.character_sheet_title_proficiencies,
|
||||
)
|
||||
|
||||
Column(
|
||||
ProficiencyPage(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
),
|
||||
) {
|
||||
Proficiency(
|
||||
proficiency = sheet.acrobatics,
|
||||
onClick = onAcrobatics,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.animalHandling,
|
||||
onClick = onAnimalHandling,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.arcana,
|
||||
onClick = onArcana,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.athletics,
|
||||
onClick = onAthletics,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.deception,
|
||||
onClick = onDeception,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.history,
|
||||
onClick = onHistory,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.insight,
|
||||
onClick = onInsight,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.intimidation,
|
||||
onClick = onIntimidation,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.investigation,
|
||||
onClick = onInvestigation,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.medicine,
|
||||
onClick = onMedicine,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.nature,
|
||||
onClick = onNature,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.perception,
|
||||
onClick = onPerception,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.performance,
|
||||
onClick = onPerformance,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.persuasion,
|
||||
onClick = onPersuasion,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.religion,
|
||||
onClick = onReligion,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.sleightOfHand,
|
||||
onClick = onSleightOfHand,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.stealth,
|
||||
onClick = onStealth,
|
||||
)
|
||||
Proficiency(
|
||||
proficiency = sheet.survival,
|
||||
onClick = onSurvival,
|
||||
)
|
||||
}
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
sheet = sheet,
|
||||
onInitiative = onInitiative,
|
||||
onStats = onStats,
|
||||
onProficiencies = onProficiencies,
|
||||
)
|
||||
|
||||
if (actions.value.isNotEmpty() || counter.value.isNotEmpty()) {
|
||||
Row(
|
||||
|
|
@ -657,11 +314,6 @@ private fun CharacterSheetContent(
|
|||
}
|
||||
|
||||
if (alterations.value.isNotEmpty()) {
|
||||
SectionTitle(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
title = R.string.character_sheet_title_alteration,
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
|
|
@ -697,45 +349,6 @@ private fun CharacterSheetContent(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SectionTitle(
|
||||
modifier: Modifier = Modifier,
|
||||
@StringRes title: Int
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.graphicsLayer { rotationY = 180f },
|
||||
painter = painterResource(id = R.drawable.art_clip_1),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
alignment = Alignment.Center,
|
||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface),
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(weight = 1f, fill = false)
|
||||
.padding(horizontal = 8.dp),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = stringResource(title),
|
||||
)
|
||||
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.art_clip_1),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
alignment = Alignment.Center,
|
||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSurface),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, heightDp = 2000)
|
||||
|
|
@ -747,185 +360,176 @@ private fun CharacterScreenPreview() {
|
|||
armorClass = LabelPointUio(
|
||||
label = R.string.character_sheet_title_ca,
|
||||
value = "15",
|
||||
max = null,
|
||||
),
|
||||
hitPoint = LabelPointUio(
|
||||
label = R.string.character_sheet_title_hp,
|
||||
value = "13",
|
||||
max = "15",
|
||||
value = "125",
|
||||
max = "/ 150",
|
||||
),
|
||||
speed = LabelPointUio(
|
||||
label = R.string.character_sheet_title_speed,
|
||||
value = "30",
|
||||
max = "m",
|
||||
),
|
||||
initiative = LabelPointUio(
|
||||
label = R.string.character_sheet_title_initiative,
|
||||
value = "+2",
|
||||
max = null,
|
||||
),
|
||||
strength = StatUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
value = 16,
|
||||
modifier = 3,
|
||||
stats = listOf(
|
||||
StatUio(
|
||||
id = StatUio.ID.STRENGTH,
|
||||
value = 16,
|
||||
modifier = 3,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.DEXTERITY,
|
||||
value = 10,
|
||||
modifier = 0,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.CONSTITUTION,
|
||||
value = 16,
|
||||
modifier = 3,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.INTELLIGENCE,
|
||||
value = 8,
|
||||
modifier = 1,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.WISDOM,
|
||||
value = 14,
|
||||
modifier = 2,
|
||||
),
|
||||
StatUio(
|
||||
id = StatUio.ID.CHARISMA,
|
||||
value = 10,
|
||||
modifier = 0,
|
||||
),
|
||||
),
|
||||
dexterity = StatUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
value = 10,
|
||||
modifier = 0,
|
||||
savingThrows = listOf(
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.STRENGTH_SAVING_THROW,
|
||||
multiplier = 1,
|
||||
modifier = 5,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.DEXTERITY_SAVING_THROW,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.CONSTITUTION_SAVING_THROW,
|
||||
multiplier = 1,
|
||||
modifier = +5,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INTELLIGENCE_SAVING_THROW,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.WISDOM_SAVING_THROW,
|
||||
multiplier = 0,
|
||||
modifier = +2,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.CHARISMA_SAVING_THROW,
|
||||
multiplier = 0,
|
||||
modifier = +0,
|
||||
),
|
||||
),
|
||||
constitution = StatUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
value = 16,
|
||||
modifier = 3,
|
||||
),
|
||||
intelligence = StatUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
value = 8,
|
||||
modifier = 1,
|
||||
),
|
||||
wisdom = StatUio(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
value = 14,
|
||||
modifier = 2,
|
||||
),
|
||||
charisma = StatUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
value = 10,
|
||||
modifier = 0
|
||||
),
|
||||
strengthSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
multiplier = 1,
|
||||
modifier = 5,
|
||||
),
|
||||
dexteritySavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
constitutionSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
multiplier = 1,
|
||||
modifier = +5,
|
||||
),
|
||||
intelligenceSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
wisdomSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
multiplier = 0,
|
||||
modifier = +2,
|
||||
),
|
||||
charismaSavingThrows = SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
multiplier = 0,
|
||||
modifier = +0,
|
||||
),
|
||||
acrobatics = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_acrobatics,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
multiplier = 0,
|
||||
modifier = +0,
|
||||
),
|
||||
animalHandling = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_animal_handling,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = 0,
|
||||
modifier = 2,
|
||||
),
|
||||
arcana = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_arcana,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
athletics = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_athletics,
|
||||
related = R.string.character_sheet_stat_strength_short,
|
||||
multiplier = 1,
|
||||
modifier = 5,
|
||||
),
|
||||
deception = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_deception,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
history = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_history,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
insight = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_insight,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = 1,
|
||||
modifier = 4,
|
||||
),
|
||||
intimidation = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_intimidation,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = 1,
|
||||
modifier = 2,
|
||||
),
|
||||
investigation = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_investigation,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
medicine = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_medicine,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = 0,
|
||||
modifier = 2,
|
||||
),
|
||||
nature = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_nature,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
perception = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_perception,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = 1,
|
||||
modifier = 4,
|
||||
),
|
||||
performance = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_performance,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
persuasion = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_persuasion,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
religion = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_religion,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
sleightOfHand = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_sleight_of_hand,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
stealth = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_stealth,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
survival = ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_survival,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
multiplier = 1,
|
||||
modifier = 4,
|
||||
proficiencies = listOf(
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ACROBATICS,
|
||||
multiplier = 0,
|
||||
modifier = +0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ANIMAL_HANDLING,
|
||||
multiplier = 0,
|
||||
modifier = 2,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ARCANA,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.ATHLETICS,
|
||||
multiplier = 1,
|
||||
modifier = 5,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.DECEPTION,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.HISTORY,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INSIGHT,
|
||||
multiplier = 1,
|
||||
modifier = 4,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INTIMIDATION,
|
||||
multiplier = 1,
|
||||
modifier = 2,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.INVESTIGATION,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.MEDICINE,
|
||||
multiplier = 0,
|
||||
modifier = 2,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.NATURE,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERCEPTION,
|
||||
multiplier = 1,
|
||||
modifier = 4,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERFORMANCE,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.PERSUASION,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.RELIGION,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.SLEIGHT_OF_HAND,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.STEALTH,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
ProficiencyUio(
|
||||
id = ProficiencyUio.ID.SURVIVAL,
|
||||
multiplier = 1,
|
||||
modifier = 4,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -970,36 +574,8 @@ private fun CharacterScreenPreview() {
|
|||
},
|
||||
onBack = { },
|
||||
onInitiative = { },
|
||||
onStrength = { },
|
||||
onDexterity = { },
|
||||
onConstitution = { },
|
||||
onIntelligence = { },
|
||||
onWisdom = { },
|
||||
onCharisma = { },
|
||||
onStrengthSavingThrows = { },
|
||||
onDexteritySavingThrows = { },
|
||||
onConstitutionSavingThrows = { },
|
||||
onIntelligenceSavingThrows = { },
|
||||
onWisdomSavingThrows = { },
|
||||
onCharismaSavingThrows = { },
|
||||
onAcrobatics = { },
|
||||
onAnimalHandling = { },
|
||||
onArcana = { },
|
||||
onAthletics = { },
|
||||
onDeception = { },
|
||||
onHistory = { },
|
||||
onInsight = { },
|
||||
onIntimidation = { },
|
||||
onInvestigation = { },
|
||||
onMedicine = { },
|
||||
onNature = { },
|
||||
onPerception = { },
|
||||
onPerformance = { },
|
||||
onPersuasion = { },
|
||||
onReligion = { },
|
||||
onSleightOfHand = { },
|
||||
onStealth = { },
|
||||
onSurvival = { },
|
||||
onStats = { },
|
||||
onProficiencies = { },
|
||||
onHit = { },
|
||||
onDamage = { },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.Measurable
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.Proficiency
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.ProficiencyUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.Stat
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.StatUio
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Composable
|
||||
fun ProficiencyPage(
|
||||
modifier: Modifier = Modifier,
|
||||
inner: Shape = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline: Shape = remember { CutCornerShape(size = 16.dp) },
|
||||
sheet: CharacterSheetUio,
|
||||
onInitiative: () -> Unit,
|
||||
onStats: (StatUio) -> Unit,
|
||||
onProficiencies: (ProficiencyUio) -> Unit,
|
||||
) {
|
||||
ProficiencyLayout(
|
||||
modifier = modifier,
|
||||
inner = inner,
|
||||
outline = outline,
|
||||
stats = {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.sizeIn(minWidth = 100.dp, minHeight = 116.dp)
|
||||
.ddBorder(outline = outline, inner = inner)
|
||||
.clickable(onClick = onInitiative)
|
||||
.padding(all = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = sheet.initiative.label?.let { stringResource(id = it) } ?: ""
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.displayMedium,
|
||||
text = sheet.initiative.value ?: ""
|
||||
)
|
||||
}
|
||||
sheet.stats.forEach {
|
||||
Stat(
|
||||
modifier = Modifier.ddBorder(inner = inner, outline = outline),
|
||||
stat = it,
|
||||
onClick = onStats,
|
||||
)
|
||||
}
|
||||
},
|
||||
savingThrows = {
|
||||
sheet.savingThrows.forEach {
|
||||
Proficiency(
|
||||
proficiency = it,
|
||||
onClick = onProficiencies,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_saving_throws)
|
||||
)
|
||||
},
|
||||
proficiencies = {
|
||||
sheet.proficiencies.forEach {
|
||||
Proficiency(
|
||||
proficiency = it,
|
||||
onClick = onProficiencies,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = R.string.character_sheet_title_proficiencies)
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ProficiencyLayout(
|
||||
modifier: Modifier = Modifier,
|
||||
spacing: Dp = 16.dp,
|
||||
inner: Shape,
|
||||
outline: Shape,
|
||||
stats: @Composable ColumnScope.() -> Unit,
|
||||
savingThrows: @Composable ColumnScope.() -> Unit,
|
||||
proficiencies: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
Layout(
|
||||
modifier = modifier,
|
||||
content = {
|
||||
Column(
|
||||
modifier = Modifier.layoutId("StatsId"),
|
||||
content = stats,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.layoutId("SavingThrowsId")
|
||||
.ddBorder(inner = inner, outline = outline),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
content = savingThrows,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.layoutId("ProficienciesId")
|
||||
.ddBorder(inner = inner, outline = outline),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
content = proficiencies,
|
||||
)
|
||||
},
|
||||
measurePolicy = { measurables, constraints ->
|
||||
val spacingPx = with(density) { spacing.toPx().toInt() }
|
||||
val statsWidth = with(density) { 100.dp.toPx().toInt() }
|
||||
|
||||
val proficienciesWidth = constraints.maxWidth - statsWidth - spacingPx
|
||||
val savingThrowsMeasure = measurables.savingThrows.measure(
|
||||
constraints.copy(
|
||||
minWidth = proficienciesWidth,
|
||||
maxWidth = proficienciesWidth,
|
||||
)
|
||||
)
|
||||
val proficienciesMeasure = measurables.proficiencies.measure(
|
||||
constraints.copy(
|
||||
minWidth = proficienciesWidth,
|
||||
maxWidth = proficienciesWidth,
|
||||
)
|
||||
)
|
||||
|
||||
val statsHeight = savingThrowsMeasure.height + proficienciesMeasure.height + spacingPx
|
||||
val statsMeasure = measurables.stats.measure(
|
||||
constraints.copy(
|
||||
minWidth = statsWidth,
|
||||
maxWidth = statsWidth,
|
||||
minHeight = statsHeight,
|
||||
maxHeight = statsHeight,
|
||||
)
|
||||
)
|
||||
|
||||
layout(width = constraints.maxWidth, height = statsMeasure.height) {
|
||||
statsMeasure.place(
|
||||
x = 0,
|
||||
y = 0,
|
||||
)
|
||||
savingThrowsMeasure.place(
|
||||
x = statsWidth + spacingPx,
|
||||
y = 0,
|
||||
)
|
||||
proficienciesMeasure.place(
|
||||
x = statsWidth + spacingPx,
|
||||
y = savingThrowsMeasure.height + spacingPx,
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val List<Measurable>.stats get() = first { it.layoutId == "StatsId" }
|
||||
val List<Measurable>.savingThrows get() = first { it.layoutId == "SavingThrowsId" }
|
||||
val List<Measurable>.proficiencies get() = first { it.layoutId == "ProficienciesId" }
|
||||
|
|
@ -2,22 +2,16 @@ package com.pixelized.rplexicon.ui.screens.character.composable
|
|||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
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.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -26,65 +20,49 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
|
||||
@Stable
|
||||
class LabelPointUio(
|
||||
val label: Int?,
|
||||
val value: String?,
|
||||
val max: String?,
|
||||
val max: String? = null,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun LabelPoint(
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = MaterialTheme.typography.displayMedium,
|
||||
hp: LabelPointUio,
|
||||
onClick: (() -> Unit)? = null
|
||||
titleStyle: TextStyle = MaterialTheme.typography.labelSmall,
|
||||
valueStyle: TextStyle = MaterialTheme.typography.headlineMedium,
|
||||
labelStyle: TextStyle = MaterialTheme.typography.titleMedium,
|
||||
label: LabelPointUio,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.sizeIn(minWidth = 96.dp, minHeight = 80.dp)
|
||||
.ddBorder(
|
||||
horizontalSpacing = 4.dp,
|
||||
verticalSpacing = 4.dp,
|
||||
outline = remember {
|
||||
CutCornerShape(
|
||||
topStart = 16.dp,
|
||||
topEnd = 16.dp,
|
||||
bottomEnd = 38.dp,
|
||||
bottomStart = 38.dp
|
||||
)
|
||||
},
|
||||
inner = remember {
|
||||
CutCornerShape(
|
||||
topStart = 14.dp,
|
||||
topEnd = 14.dp,
|
||||
bottomEnd = 36.dp,
|
||||
bottomStart = 36.dp
|
||||
)
|
||||
},
|
||||
)
|
||||
.clickable(enabled = onClick != null) { onClick?.let { it() } }
|
||||
.padding(all = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = modifier.padding(all = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = hp.label?.let { stringResource(id = it) } ?: ""
|
||||
)
|
||||
Text(
|
||||
style = style,
|
||||
text = hp.value ?: ""
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.width(width = 32.dp),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = hp.max ?: ""
|
||||
)
|
||||
label.label?.let {
|
||||
Text(
|
||||
style = titleStyle,
|
||||
text = stringResource(id = it)
|
||||
)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = valueStyle,
|
||||
text = label.value ?: "0"
|
||||
)
|
||||
label.max?.let {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = labelStyle,
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,26 +78,24 @@ private fun LabelPointPreview() {
|
|||
horizontalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterHorizontally),
|
||||
) {
|
||||
LabelPoint(
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
hp = LabelPointUio(
|
||||
label = R.string.character_sheet_title_hp,
|
||||
label = LabelPointUio(
|
||||
label = R.string.character_sheet_title_ca,
|
||||
value = "15",
|
||||
max = null
|
||||
),
|
||||
)
|
||||
LabelPoint(
|
||||
hp = LabelPointUio(
|
||||
label = R.string.character_sheet_title_ca,
|
||||
label = LabelPointUio(
|
||||
label = R.string.character_sheet_title_hp,
|
||||
value = "13",
|
||||
max = "15"
|
||||
max = "/ 15"
|
||||
),
|
||||
)
|
||||
LabelPoint(
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
hp = LabelPointUio(
|
||||
label = R.string.character_sheet_title_initiative,
|
||||
value = "+0",
|
||||
max = null
|
||||
label = LabelPointUio(
|
||||
label = R.string.character_sheet_title_speed,
|
||||
value = "10",
|
||||
max = "m"
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.utilitary.extentions.dashedBorder
|
||||
|
||||
@Composable
|
||||
fun MasteryCircle(
|
||||
|
|
@ -22,17 +23,22 @@ fun MasteryCircle(
|
|||
0 -> Box(
|
||||
modifier = modifier
|
||||
.size(size = size)
|
||||
.border(
|
||||
.dashedBorder(
|
||||
width = 1.dp,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
shape = CircleShape
|
||||
shape = CircleShape,
|
||||
on = 2.dp,
|
||||
off = 1.dp
|
||||
)
|
||||
)
|
||||
|
||||
1 -> Box(
|
||||
modifier = modifier
|
||||
.size(size = size)
|
||||
.background(color = MaterialTheme.colorScheme.onSurface, shape = CircleShape)
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
shape = CircleShape,
|
||||
)
|
||||
)
|
||||
|
||||
else -> Box(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Arrangement
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -18,6 +17,7 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
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
|
||||
|
|
@ -28,60 +28,162 @@ import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
|||
|
||||
@Stable
|
||||
data class ProficiencyUio(
|
||||
@StringRes val label: Int, // the proficiency label
|
||||
@StringRes val related: Int, // the related stat to the proficiency
|
||||
val id: ID,
|
||||
val multiplier: Int, // the multiplier (use for the circle) 0 -> None 1 -> Mastery 2 -> Expertise
|
||||
val modifier: Int, // the proficiency value. (stats + mastery)
|
||||
)
|
||||
) {
|
||||
enum class ID(
|
||||
@StringRes val label: Int, // the proficiency label
|
||||
@StringRes val related: Int?, // the related stat to the proficiency
|
||||
) {
|
||||
STRENGTH_SAVING_THROW(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
related = null,
|
||||
),
|
||||
DEXTERITY_SAVING_THROW(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
related = null,
|
||||
),
|
||||
CONSTITUTION_SAVING_THROW(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
related = null,
|
||||
),
|
||||
INTELLIGENCE_SAVING_THROW(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
related = null,
|
||||
),
|
||||
WISDOM_SAVING_THROW(
|
||||
label = R.string.character_sheet_stat_wisdom,
|
||||
related = null,
|
||||
),
|
||||
CHARISMA_SAVING_THROW(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
related = null,
|
||||
),
|
||||
ACROBATICS(
|
||||
label = R.string.character_sheet_proficiency_acrobatics,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
),
|
||||
ANIMAL_HANDLING(
|
||||
label = R.string.character_sheet_proficiency_animal_handling,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
),
|
||||
ARCANA(
|
||||
label = R.string.character_sheet_proficiency_arcana,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
),
|
||||
ATHLETICS(
|
||||
label = R.string.character_sheet_proficiency_athletics,
|
||||
related = R.string.character_sheet_stat_strength_short,
|
||||
),
|
||||
DECEPTION(
|
||||
label = R.string.character_sheet_proficiency_deception,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
),
|
||||
HISTORY(
|
||||
label = R.string.character_sheet_proficiency_history,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
),
|
||||
INSIGHT(
|
||||
label = R.string.character_sheet_proficiency_insight,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
),
|
||||
INTIMIDATION(
|
||||
label = R.string.character_sheet_proficiency_intimidation,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
),
|
||||
INVESTIGATION(
|
||||
label = R.string.character_sheet_proficiency_investigation,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
),
|
||||
MEDICINE(
|
||||
label = R.string.character_sheet_proficiency_medicine,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
),
|
||||
NATURE(
|
||||
label = R.string.character_sheet_proficiency_nature,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
),
|
||||
PERCEPTION(
|
||||
label = R.string.character_sheet_proficiency_perception,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
),
|
||||
PERFORMANCE(
|
||||
label = R.string.character_sheet_proficiency_performance,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
),
|
||||
PERSUASION(
|
||||
label = R.string.character_sheet_proficiency_persuasion,
|
||||
related = R.string.character_sheet_stat_charisma_short,
|
||||
),
|
||||
RELIGION(
|
||||
label = R.string.character_sheet_proficiency_religion,
|
||||
related = R.string.character_sheet_stat_intelligence_short,
|
||||
),
|
||||
SLEIGHT_OF_HAND(
|
||||
label = R.string.character_sheet_proficiency_sleight_of_hand,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
),
|
||||
STEALTH(
|
||||
label = R.string.character_sheet_proficiency_stealth,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
),
|
||||
SURVIVAL(
|
||||
label = R.string.character_sheet_proficiency_survival,
|
||||
related = R.string.character_sheet_stat_wisdom_short,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Proficiency(
|
||||
modifier: Modifier = Modifier,
|
||||
padding: PaddingValues = PaddingValues(horizontal = 8.dp),
|
||||
padding: PaddingValues = PaddingValues(top = 8.dp, bottom = 8.dp, start = 4.dp, end = 8.dp),
|
||||
proficiency: ProficiencyUio,
|
||||
onClick: () -> Unit,
|
||||
onClick: (ProficiencyUio) -> Unit,
|
||||
) {
|
||||
Box(
|
||||
Row(
|
||||
modifier = modifier
|
||||
.heightIn(48.dp)
|
||||
.clickable(onClick = onClick),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
.clickable { onClick(proficiency) }
|
||||
.padding(paddingValues = padding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(paddingValues = padding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
Box(
|
||||
modifier = Modifier.size(size = 24.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.size(size = 24.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
MasteryCircle(
|
||||
multiplier = proficiency.multiplier,
|
||||
)
|
||||
}
|
||||
MasteryCircle(
|
||||
multiplier = proficiency.multiplier,
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = stringResource(id = proficiency.label),
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = stringResource(id = proficiency.id.label),
|
||||
)
|
||||
proficiency.id.related?.let { res ->
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = "(${stringResource(proficiency.related)})",
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = "(${stringResource(res)})",
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
text = proficiency.modifier.toLabel(),
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
text = proficiency.modifier.toLabel(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,20 +206,17 @@ private fun ProficiencyPreview(
|
|||
private class ProficiencyPreviewProvider : PreviewParameterProvider<ProficiencyUio> {
|
||||
override val values: Sequence<ProficiencyUio> = sequenceOf(
|
||||
ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_acrobatics,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
id = ProficiencyUio.ID.ACROBATICS,
|
||||
multiplier = 0,
|
||||
modifier = -1
|
||||
modifier = -1,
|
||||
),
|
||||
ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_athletics,
|
||||
related = R.string.character_sheet_stat_strength_short,
|
||||
id = ProficiencyUio.ID.ATHLETICS,
|
||||
multiplier = 1,
|
||||
modifier = 5,
|
||||
),
|
||||
ProficiencyUio(
|
||||
label = R.string.character_sheet_proficiency_sleight_of_hand,
|
||||
related = R.string.character_sheet_stat_dexterity_short,
|
||||
id = ProficiencyUio.ID.SLEIGHT_OF_HAND,
|
||||
multiplier = 2,
|
||||
modifier = 8,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.composable
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
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.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.R
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ddBorder
|
||||
import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
||||
|
||||
@Stable
|
||||
data class SavingsThrowsUio(
|
||||
@StringRes val label: Int, // the proficiency label
|
||||
val multiplier: Int, // the multiplier (use for the circle) 0 -> None 1 -> Mastery 2 -> Expertise
|
||||
val modifier: Int, // the proficiency value. (stats + mastery)
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SavingsThrows(
|
||||
modifier: Modifier = Modifier,
|
||||
padding: PaddingValues = PaddingValues(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 8.dp),
|
||||
savingsThrows: SavingsThrowsUio,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.ddBorder(
|
||||
horizontalSpacing = 3.dp,
|
||||
outline = remember { CutCornerShape(size = 24.dp) },
|
||||
inner = remember { RoundedCornerShape(size = 24.dp) },
|
||||
)
|
||||
.clickable(onClick = onClick)
|
||||
.padding(paddingValues = padding),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.size(size = 24.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
MasteryCircle(
|
||||
multiplier = savingsThrows.multiplier,
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier.weight(weight = 1f, fill = true),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
text = stringResource(id = savingsThrows.label),
|
||||
)
|
||||
|
||||
Text(
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
text = savingsThrows.modifier.toLabel(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
fun SavingsThrowsPreview(
|
||||
@PreviewParameter(SavingsThrowsPreviewProvider::class) preview: SavingsThrowsUio,
|
||||
) {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
SavingsThrows(
|
||||
modifier = Modifier.padding(all = 8.dp),
|
||||
savingsThrows = preview,
|
||||
onClick = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SavingsThrowsPreviewProvider : PreviewParameterProvider<SavingsThrowsUio> {
|
||||
override val values: Sequence<SavingsThrowsUio> = sequenceOf(
|
||||
SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_strength,
|
||||
multiplier = 0,
|
||||
modifier = 0,
|
||||
),
|
||||
SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_intelligence,
|
||||
multiplier = 1,
|
||||
modifier = 5,
|
||||
),
|
||||
SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_dexterity,
|
||||
multiplier = 2,
|
||||
modifier = 8,
|
||||
),
|
||||
SavingsThrowsUio(
|
||||
label = R.string.character_sheet_stat_charisma,
|
||||
multiplier = 0,
|
||||
modifier = -1,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.clickable
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CutCornerShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
|
@ -29,31 +30,39 @@ import com.pixelized.rplexicon.utilitary.extentions.toLabel
|
|||
|
||||
@Stable
|
||||
data class StatUio(
|
||||
@StringRes val label: Int,
|
||||
val id: ID,
|
||||
val value: Int,
|
||||
val modifier: Int,
|
||||
)
|
||||
) {
|
||||
enum class ID(
|
||||
@StringRes val label: Int,
|
||||
) {
|
||||
STRENGTH(label = R.string.character_sheet_stat_strength),
|
||||
DEXTERITY(label = R.string.character_sheet_stat_dexterity),
|
||||
CONSTITUTION(label = R.string.character_sheet_stat_constitution),
|
||||
INTELLIGENCE(label = R.string.character_sheet_stat_intelligence),
|
||||
WISDOM(label = R.string.character_sheet_stat_wisdom),
|
||||
CHARISMA(label = R.string.character_sheet_stat_charisma),
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Stat(
|
||||
modifier: Modifier = Modifier,
|
||||
stat: StatUio,
|
||||
onClick: () -> Unit
|
||||
onClick: (StatUio) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
)
|
||||
.clickable(onClick = onClick)
|
||||
.sizeIn(minWidth = 100.dp, minHeight = 130.dp)
|
||||
.clickable { onClick(stat) }
|
||||
.padding(all = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = stringResource(id = stat.label),
|
||||
text = stringResource(id = stat.id.label),
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.displayMedium,
|
||||
|
|
@ -76,9 +85,14 @@ private fun StatPreview() {
|
|||
LexiconTheme {
|
||||
Surface {
|
||||
Stat(
|
||||
modifier = Modifier.padding(all = 8.dp),
|
||||
modifier = Modifier
|
||||
.padding(all = 8.dp)
|
||||
.ddBorder(
|
||||
inner = remember { RoundedCornerShape(size = 8.dp) },
|
||||
outline = remember { CutCornerShape(size = 16.dp) },
|
||||
),
|
||||
stat = StatUio(
|
||||
label = R.string.character_sheet_stat_constitution,
|
||||
id = StatUio.ID.CONSTITUTION,
|
||||
value = 16,
|
||||
modifier = 3,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class LexiconColors(
|
|||
val status: Color,
|
||||
val navigation: Color,
|
||||
val handle: Color,
|
||||
val rollOverlayBrush: Brush,
|
||||
val rollOverlayBrush: Color,
|
||||
val dice: Dice,
|
||||
val characterSheet: CharacterSheet,
|
||||
) {
|
||||
|
|
@ -82,12 +82,7 @@ fun colorScheme(
|
|||
shadow: Color = ShadowPalette.shadow,
|
||||
status: Color = Color.Transparent,
|
||||
navigation: Color = Color.Transparent,
|
||||
rollOverlayBrush: Brush = Brush.radialGradient(
|
||||
colors = listOf(
|
||||
base.surface.copy(alpha = 0.75f),
|
||||
base.surface.copy(alpha = 0.25f),
|
||||
),
|
||||
),
|
||||
rollOverlayBrush: Color = base.surface.copy(alpha = 0.5f),
|
||||
dice: LexiconColors.Dice = LexiconColors.Dice(
|
||||
tint = base.primary,
|
||||
value = base.onSurface,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
|
|
|
|||
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.pixelized.rplexicon.utilitary.extentions
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawWithCache
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.geometry.isSimple
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.graphics.drawscope.withTransform
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
|
||||
/**
|
||||
* Modify element to add border with appearance specified with a [border] and a [shape], pad the
|
||||
* content by the [BorderStroke.width] and clip it.
|
||||
*
|
||||
* @sample androidx.compose.foundation.samples.BorderSample()
|
||||
*
|
||||
* @param border [BorderStroke] class that specifies border appearance, such as size and color
|
||||
* @param shape shape of the border
|
||||
*/
|
||||
fun Modifier.dashedBorder(border: BorderStroke, shape: Shape = RectangleShape, on: Dp, off: Dp) =
|
||||
dashedBorder(width = border.width, brush = border.brush, shape = shape, on, off)
|
||||
|
||||
/**
|
||||
* Returns a [Modifier] that adds border with appearance specified with [width], [color] and a
|
||||
* [shape], pads the content by the [width] and clips it.
|
||||
*
|
||||
* @sample androidx.compose.foundation.samples.BorderSampleWithDataClass()
|
||||
*
|
||||
* @param width width of the border. Use [Dp.Hairline] for a hairline border.
|
||||
* @param color color to paint the border with
|
||||
* @param shape shape of the border
|
||||
* @param on the size of the solid part of the dashes
|
||||
* @param off the size of the space between dashes
|
||||
*/
|
||||
fun Modifier.dashedBorder(width: Dp, color: Color, shape: Shape = RectangleShape, on: Dp, off: Dp) =
|
||||
dashedBorder(width, SolidColor(color), shape, on, off)
|
||||
|
||||
/**
|
||||
* Returns a [Modifier] that adds border with appearance specified with [width], [brush] and a
|
||||
* [shape], pads the content by the [width] and clips it.
|
||||
*
|
||||
* @sample androidx.compose.foundation.samples.BorderSampleWithBrush()
|
||||
*
|
||||
* @param width width of the border. Use [Dp.Hairline] for a hairline border.
|
||||
* @param brush brush to paint the border with
|
||||
* @param shape shape of the border
|
||||
*/
|
||||
fun Modifier.dashedBorder(width: Dp, brush: Brush, shape: Shape, on: Dp, off: Dp): Modifier =
|
||||
this.then(
|
||||
Modifier.drawWithCache {
|
||||
val outline: Outline = shape.createOutline(size, layoutDirection, this)
|
||||
val borderSize = if (width == Dp.Hairline) 1f else width.toPx()
|
||||
|
||||
var insetOutline: Outline? = null // outline used for roundrect/generic shapes
|
||||
var stroke: Stroke? = null // stroke to draw border for all outline types
|
||||
var pathClip: Path? = null // path to clip roundrect/generic shapes
|
||||
var inset = 0f // inset to translate before drawing the inset outline
|
||||
// path to draw generic shapes or roundrects with different corner radii
|
||||
var insetPath: Path? = null
|
||||
if (borderSize > 0 && size.minDimension > 0f) {
|
||||
if (outline is Outline.Rectangle) {
|
||||
stroke = Stroke(
|
||||
borderSize, pathEffect = PathEffect.dashPathEffect(
|
||||
floatArrayOf(on.toPx(), off.toPx())
|
||||
)
|
||||
)
|
||||
} else {
|
||||
// Multiplier to apply to the border size to get a stroke width that is
|
||||
// large enough to cover the corners while not being too large to overly
|
||||
// square off the internal shape. The resultant shape will be
|
||||
// clipped to the desired shape. Any value lower will show artifacts in
|
||||
// the corners of shapes. A value too large will always square off
|
||||
// the internal shape corners. For example, for a rounded rect border
|
||||
// a large multiplier will always have squared off edges within the
|
||||
// inner section of the stroke, however, having a smaller multiplier
|
||||
// will still keep the rounded effect for the inner section of the
|
||||
// border
|
||||
val strokeWidth = 1.2f * borderSize
|
||||
inset = borderSize - strokeWidth / 2
|
||||
val insetSize = Size(
|
||||
size.width - inset * 2,
|
||||
size.height - inset * 2
|
||||
)
|
||||
insetOutline = shape.createOutline(insetSize, layoutDirection, this)
|
||||
stroke = Stroke(
|
||||
strokeWidth, pathEffect = PathEffect.dashPathEffect(
|
||||
floatArrayOf(on.toPx(), off.toPx())
|
||||
)
|
||||
)
|
||||
pathClip = when (outline) {
|
||||
is Outline.Rounded -> {
|
||||
Path().apply { addRoundRect(outline.roundRect) }
|
||||
}
|
||||
|
||||
is Outline.Generic -> {
|
||||
outline.path
|
||||
}
|
||||
// should not get here because we check for Outline.Rectangle above
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
insetPath = when {
|
||||
// Rounded rect with non equal corner radii needs a path to be pre-translated
|
||||
insetOutline is Outline.Rounded && !insetOutline.roundRect.isSimple -> {
|
||||
Path().apply {
|
||||
addRoundRect(insetOutline.roundRect)
|
||||
translate(Offset(inset, inset))
|
||||
}
|
||||
}
|
||||
// Generic paths must be created and pre-translated
|
||||
insetOutline is Outline.Generic -> {
|
||||
|
||||
Path().apply {
|
||||
addPath(insetOutline.path, Offset(inset, inset))
|
||||
}
|
||||
}
|
||||
// Drawing a round rect with equal corner radii without usage of a path
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDrawWithContent {
|
||||
drawContent()
|
||||
// Only draw the border if a have a valid stroke parameter. If we have
|
||||
// an invalid border size we will just draw the content
|
||||
if (stroke != null) {
|
||||
if (insetOutline != null && pathClip != null) {
|
||||
val isSimpleRoundRect =
|
||||
insetOutline is Outline.Rounded && insetOutline.roundRect.isSimple
|
||||
withTransform({
|
||||
clipPath(pathClip)
|
||||
// we are drawing the round rect not as a path so we must
|
||||
// translate ourselves othe
|
||||
if (isSimpleRoundRect) {
|
||||
translate(inset, inset)
|
||||
}
|
||||
}) {
|
||||
if (isSimpleRoundRect) {
|
||||
// If we don't have an insetPath then we are drawing
|
||||
// a simple round rect with the corner radii all identical
|
||||
val rrect = (insetOutline as Outline.Rounded).roundRect
|
||||
drawRoundRect(
|
||||
brush = brush,
|
||||
topLeft = Offset(rrect.left, rrect.top),
|
||||
size = Size(rrect.width, rrect.height),
|
||||
cornerRadius = rrect.topLeftCornerRadius,
|
||||
style = stroke
|
||||
)
|
||||
} else if (insetPath != null) {
|
||||
drawPath(insetPath, brush, style = stroke)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Rectangular border fast path
|
||||
val strokeWidth = stroke.width
|
||||
val halfStrokeWidth = strokeWidth / 2
|
||||
drawRect(
|
||||
brush = brush,
|
||||
topLeft = Offset(halfStrokeWidth, halfStrokeWidth),
|
||||
size = Size(
|
||||
size.width - strokeWidth,
|
||||
size.height - strokeWidth
|
||||
),
|
||||
style = stroke
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue