diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
new file mode 100644
index 0000000..0d81a5f
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -0,0 +1,68 @@
+
+
+ Créer une feuille de personnage
+
+ Réussite critique
+ Réussite spéciale
+ Réussite
+ Échec
+ Échec critique
+
+ Création de personnage
+ Nom
+ Ajouter un lancé
+ Sauvegarder
+ Charactéristiques
+ Force
+ Dextérité
+ Constitution
+ Taille
+ Intelligence
+ Pouvoir
+ Charisme
+ Charactéristiques dérivées
+ Déplacement
+ Points de vie
+ Points de pouvoir
+ Bonus aux dégats
+ Armure
+ Compétances
+ Ajouter une compétance
+ Bagarre
+ Esquive
+ Saisie
+ Lancer
+ Athlétisme
+ Acrobatie
+ Perception
+ Recherche
+ Empathie
+ Persuasion
+ Intimidation
+ Baratin
+ Marchandage
+ Discrétion
+ Escamotage
+ Premiers soins
+ Occupations
+ Ajouter une occupation
+ Compétences magiques
+ Ajouter une compétence magique
+
+ Force
+ Dextérité
+ Constitution
+ Taille
+ Intelligence
+ Pouvoir
+ Charisme
+ Charactéristiques dérivées
+ Déplacement
+ Points de vie
+ Points de pouvoir
+ Bonus aux dégats
+ Armure
+ Compétences
+ Occupations
+ Compétences magiques
+
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/DamageBonusUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/DamageBonusUseCase.kt
new file mode 100644
index 0000000..553aa76
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/DamageBonusUseCase.kt
@@ -0,0 +1,19 @@
+package com.pixelized.desktop.lwa.business
+
+object DamageBonusUseCase {
+
+ fun bonusDamage(strength: Int, height: Int): String {
+ return bonusDamage(stat = strength + height)
+ }
+
+ fun bonusDamage(stat: Int): String {
+ return when {
+ stat < 12 -> "-1d6"
+ stat in 12..17 -> "-1d4"
+ stat in 18..22 -> "+0"
+ stat in 23..29 -> "+1d4"
+ stat in 30..39 -> "+1d6"
+ else -> "+2d6"
+ }
+ }
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt
index 20ecb1b..a0a67ec 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt
@@ -3,27 +3,33 @@ package com.pixelized.desktop.lwa.business
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheet
object RollUseCase {
- private val d100 = (1..100)
private val diceParser = Regex(
- """(?[+-])?\h*(?[ade])?(?\d+)d(?\d+)"""
+ """(?[+-])?\s*(?[ade])?(?\d+)[dD](?\d+)"""
)
private val flatParser = Regex(
- """(?[+-])?\h(?\d+)\b"""
+ """(?[+-])?\s*[^a-zA-Z](?\d+)\b"""
)
private val paramParser = Regex(
- """(?[+-])?\h(?BDGT)\b"""
+ """(?[+-])?\s*(?BDGT)\b"""
)
fun rollD100(): Int {
- return d100.random()
+ return roll(quantity = 1, faces = 100)
+ }
+
+ fun roll(quantity: Int, faces: Int): Int {
+ return sum(count = quantity) { (Math.random() * faces.toDouble() + 1).toInt() }
}
fun roll(characterSheet: CharacterSheet, roll: String): Int {
println(roll)
return diceParser.findAll(roll).sumOf {
val (sign, modifier, quantity, faces) = it.destructured
- ((if (sign == "-") -1 else 1) * quantity.toInt() * (Math.random() * faces.toDouble() + 1).toInt()).also {
+ ((if (sign == "-") -1 else 1) * roll(
+ quantity = quantity.toInt(),
+ faces = faces.toInt()
+ )).also {
println("roll ${sign}${quantity}d${faces} -> $it")
}
} + flatParser.findAll(roll).sumOf {
@@ -36,7 +42,10 @@ object RollUseCase {
(if (sign == "-") -1 else 1) * when (param) {
"BDGT" -> diceParser.findAll(characterSheet.damageBonus).sumOf {
val (sign, modifier, quantity, faces) = it.destructured
- ((if (sign == "-") -1 else 1) * quantity.toInt() * (Math.random() * faces.toDouble() + 1).toInt()).also {
+ ((if (sign == "-") -1 else 1) * roll(
+ quantity = quantity.toInt(),
+ faces = faces.toInt()
+ )).also {
println("param: ${sign}${param} -> $it")
}
}
@@ -45,4 +54,12 @@ object RollUseCase {
}
}
}
+
+ private fun sum(count: Int, block: () -> Int): Int {
+ return if (count > 1) {
+ block() + sum(count - 1, block)
+ } else {
+ block()
+ }
+ }
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetFactory.kt
index 2566a44..7733d68 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetFactory.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetFactory.kt
@@ -3,34 +3,68 @@ package com.pixelized.desktop.lwa.screen.characterSheet.detail
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheet
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Node
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.*
+import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__str
+import org.jetbrains.compose.resources.getString
class CharacterSheetFactory {
- fun convertToUio(model: CharacterSheet): CharacterSheetPageUio {
+ suspend fun convertToUio(model: CharacterSheet): CharacterSheetPageUio {
return CharacterSheetPageUio(
id = model.id,
name = model.name,
characteristics = listOf(
- Characteristic(label = "Force", value = "${model.strength}"),
- Characteristic(label = "Dextérité", value = "${model.dexterity}"),
- Characteristic(label = "Constitution", value = "${model.constitution}"),
- Characteristic(label = "Taille", value = "${model.height}"),
- Characteristic(label = "Intelligence", value = "${model.intelligence}"),
- Characteristic(label = "Pouvoir", value = "${model.power}"),
- Characteristic(label = "Charisme", value = "${model.charisma}"),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__str),
+ value = "${model.strength}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__dex),
+ value = "${model.dexterity}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__con),
+ value = "${model.constitution}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__hei),
+ value = "${model.height}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__int),
+ value = "${model.intelligence}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__pow),
+ value = "${model.power}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__characteristics__cha),
+ value = "${model.charisma}",
+ ),
),
subCharacteristics = listOf(
- Characteristic(label = "Déplacement ", value = "${model.movement}"),
Characteristic(
- label = "Points de vie",
- value = "${model.currentHp}/${model.maxHp}"
+ label = getString(Res.string.character_sheet__sub_characteristics__movement),
+ value = "${model.movement}",
),
Characteristic(
- label = "Points de pouvoir",
- value = "${model.currentPP}/${model.maxPP}"
+ label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
+ value = "${model.currentHp}/${model.maxHp}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__sub_characteristics__power_point),
+ value = "${model.currentPP}/${model.maxPP}",
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
+ value = model.damageBonus,
+ ),
+ Characteristic(
+ label = getString(Res.string.character_sheet__sub_characteristics__armor),
+ value = "${model.armor}",
),
- Characteristic(label = "Bonus aux dégâts", value = model.damageBonus),
- Characteristic(label = "Armure", value = "${model.armor}"),
),
skills = model.skills.mapNotNull {
if (it.value > 0) {
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt
index 227f2b5..cb3f03d 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetPage.kt
@@ -49,8 +49,13 @@ import com.pixelized.desktop.lwa.screen.roll.RollPage
import com.pixelized.desktop.lwa.screen.roll.RollViewModel
import kotlinx.coroutines.launch
import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.character_sheet__magics__title
+import lwacharactersheet.composeapp.generated.resources.character_sheet__occupations_title
+import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__title
+import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
@Stable
data class CharacterSheetPageUio(
@@ -122,7 +127,10 @@ fun CharacterSheetPage(
}
},
onCharacteristic = { characteristic ->
- rollViewModel.prepareRoll(sheet = sheet, characteristic = characteristic)
+ rollViewModel.prepareRoll(
+ sheet = sheet,
+ characteristic = characteristic
+ )
overlayViewModel.show()
},
onSkill = { node ->
@@ -228,7 +236,7 @@ fun CharacterSheetPageContent(
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
style = MaterialTheme.typography.caption,
textAlign = TextAlign.Center,
- text = "Charactéristiques dérivées"
+ text = stringResource(Res.string.character_sheet__sub_characteristics__title),
)
characterSheet.subCharacteristics.forEach {
Characteristics(
@@ -246,7 +254,7 @@ fun CharacterSheetPageContent(
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
style = MaterialTheme.typography.caption,
textAlign = TextAlign.Center,
- text = "Compétences",
+ text = stringResource(Res.string.character_sheet__skills__title),
)
characterSheet.skills.forEach {
Skill(
@@ -266,7 +274,7 @@ fun CharacterSheetPageContent(
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
style = MaterialTheme.typography.caption,
textAlign = TextAlign.Center,
- text = "Occupations"
+ text = stringResource(Res.string.character_sheet__occupations_title),
)
characterSheet.occupations.forEach {
Skill(
@@ -286,7 +294,7 @@ fun CharacterSheetPageContent(
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
style = MaterialTheme.typography.caption,
textAlign = TextAlign.Center,
- text = "Compétences magiques"
+ text = stringResource(Res.string.character_sheet__magics__title),
)
characterSheet.magics.forEach {
Skill(
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt
index 11ec376..6f4a380 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/detail/CharacterSheetViewModel.kt
@@ -8,6 +8,7 @@ import androidx.lifecycle.ViewModel
import com.pixelized.desktop.lwa.navigation.destination.CharacterSheetDestination
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.utils.extention.collectAsState
+import kotlinx.coroutines.runBlocking
class CharacterSheetViewModel(
savedStateHandle: SavedStateHandle,
@@ -23,7 +24,9 @@ class CharacterSheetViewModel(
get() = repository
.characterSheetFlow(id = argument.id)
.collectAsState { sheet ->
- sheet?.let { model -> factory.convertToUio(model = model) }
+ sheet?.let { model ->
+ runBlocking { factory.convertToUio(model = model) }
+ }
}
suspend fun deleteCharacter(id: String) {
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditFactory.kt
new file mode 100644
index 0000000..3514e80
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditFactory.kt
@@ -0,0 +1,309 @@
+package com.pixelized.desktop.lwa.screen.characterSheet.edit
+
+import com.pixelized.desktop.lwa.business.DamageBonusUseCase.bonusDamage
+import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
+import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheet
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditPageUio.SkillGroup
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__cha
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__con
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__dex
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__hei
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__int
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__pow
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__str
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__title
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__magic__add_action
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__magic__title
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__name_placeholder
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__occupation__add_action
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__occupation__title
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__add_action
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__title
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__armor
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__damage_bonus
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__movement
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__title
+import org.jetbrains.compose.resources.getString
+import java.util.UUID
+import kotlin.math.ceil
+import kotlin.math.max
+
+class CharacterSheetEditFactory {
+
+ fun convertToModel(sheet: CharacterSheetEditPageUio): CharacterSheet {
+ return CharacterSheet(
+ id = sheet.id,
+ name = sheet.name.value.value,
+ strength = sheet.skills[0].fields[0].unpack(),
+ dexterity = sheet.skills[0].fields[1].unpack(),
+ constitution = sheet.skills[0].fields[2].unpack(),
+ height = sheet.skills[0].fields[3].unpack(),
+ intelligence = sheet.skills[0].fields[4].unpack(),
+ power = sheet.skills[0].fields[5].unpack(),
+ charisma = sheet.skills[0].fields[6].unpack(),
+ movement = sheet.skills[1].fields[0].unpack(),
+ currentHp = sheet.skills[1].fields[1].unpack(),
+ maxHp = sheet.skills[1].fields[1].unpack(),
+ currentPP = sheet.skills[1].fields[2].unpack(),
+ maxPP = sheet.skills[1].fields[2].unpack(),
+ damageBonus = sheet.skills[1].fields[3].unpack(),
+ armor = sheet.skills[1].fields[4].unpack(),
+ skills = sheet.skills[2].fields.map {
+ CharacterSheet.Skill(
+ label = it.label.value,
+ value = it.unpack(),
+ used = false,
+ )
+ },
+ occupations = sheet.skills[3].fields.map {
+ CharacterSheet.Skill(
+ label = it.label.value,
+ value = it.unpack(),
+ used = false,
+ )
+ },
+ magics = sheet.skills[4].fields.map {
+ CharacterSheet.Skill(
+ label = it.label.value,
+ value = it.unpack(),
+ used = false,
+ )
+ },
+ rolls = sheet.rolls.map {
+ CharacterSheet.Roll(
+ label = it.label.value,
+ roll = it.unpack(),
+ )
+ },
+ )
+ }
+
+ suspend fun convertToUio(
+ sheet: CharacterSheet?,
+ ): CharacterSheetEditPageUio {
+ val str = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__str),
+ initialValue = sheet?.strength?.toString() ?: "",
+ valuePlaceHolder = { "0" },
+ )
+ val dex = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__dex),
+ initialValue = sheet?.dexterity?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ )
+ val con = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__con),
+ initialValue = sheet?.constitution?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ )
+ val hei = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__hei),
+ initialValue = sheet?.height?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ )
+ val int = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__int),
+ initialValue = sheet?.intelligence?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ )
+ val pow = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__pow),
+ initialValue = sheet?.power?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ )
+ val cha = FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__characteristics__cha),
+ initialValue = sheet?.charisma?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ )
+
+ fun str(): Int = str.unpack() ?: 0
+ fun dex(): Int = dex.unpack() ?: 0
+ fun con(): Int = con.unpack() ?: 0
+ fun hei(): Int = hei.unpack() ?: 0
+ fun int(): Int = int.unpack() ?: 0
+ fun pow(): Int = pow.unpack() ?: 0
+ fun cha(): Int = cha.unpack() ?: 0
+
+ return CharacterSheetEditPageUio(
+ id = sheet?.id ?: UUID.randomUUID().toString(),
+ name = FieldUio.create(
+ isLabelDisplayed = false,
+ initialLabel = getString(Res.string.character_sheet_edit__name_placeholder),
+ initialValue = sheet?.name ?: ""
+ ),
+ skills = listOf(
+ SkillGroup(
+ type = SkillGroup.Type.CHARACTERISTICS,
+ title = getString(Res.string.character_sheet_edit__characteristics__title),
+ fields = listOf(str, dex, con, hei, int, pow, cha),
+ ),
+ SkillGroup(
+ type = SkillGroup.Type.SUB_CHARACTERISTICS,
+ title = getString(Res.string.character_sheet_edit__sub_characteristics__title),
+ fields = listOf(
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__movement),
+ initialValue = sheet?.movement?.toString() ?: "",
+ valuePlaceHolder = { "10" }
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point),
+ initialValue = sheet?.maxHp?.toString() ?: "",
+ valuePlaceHolder = { "${ceil((con() + hei()) / 2f).toInt()}" }
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__power_point),
+ initialValue = sheet?.maxPP?.toString() ?: "",
+ valuePlaceHolder = { "${pow()}" }
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus),
+ initialValue = sheet?.damageBonus ?: "",
+ valuePlaceHolder = { bonusDamage(strength = str(), height = hei()) }
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__armor),
+ initialValue = sheet?.armor?.toString() ?: "",
+ valuePlaceHolder = { "0" }
+ ),
+ ),
+ ),
+ SkillGroup(
+ type = SkillGroup.Type.SKILLS,
+ title = getString(Res.string.character_sheet_edit__skills__title),
+ action = getString(Res.string.character_sheet_edit__skills__add_action),
+ fields = sheet?.skills?.map {
+ FieldUio.create(
+ initialLabel = it.label,
+ initialValue = it.value.toString(),
+ )
+ } ?: listOf(
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__combat),
+ valuePlaceHolder = { "${normalize(dex() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__dodge),
+ valuePlaceHolder = { "${normalize(dex() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__grab),
+ valuePlaceHolder = { "${normalize(str() + hei())}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__throw),
+ valuePlaceHolder = { "${normalize(str() + dex())}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__athletics),
+ valuePlaceHolder = { "${normalize(str() + con() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__acrobatics),
+ valuePlaceHolder = { "${normalize(dex() + con() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__perception),
+ valuePlaceHolder = { "${normalize(10 + int() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__search),
+ valuePlaceHolder = { "${normalize(10 + int() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__empathy),
+ valuePlaceHolder = { "${normalize(cha() + int())}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__persuasion),
+ valuePlaceHolder = { "${normalize(cha() * 3)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__intimidation),
+ valuePlaceHolder = { "${normalize(cha() + max(pow(), hei()) * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__spiel),
+ valuePlaceHolder = { "${normalize(cha() * 2 + int())}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__bargain),
+ valuePlaceHolder = { "${normalize(cha() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__discretion),
+ valuePlaceHolder = { "${normalize(cha() + dex() * 2 - hei())}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__sleight_of_hand),
+ valuePlaceHolder = { "${normalize(dex() * 2)}" },
+ ),
+ FieldUio.create(
+ initialLabel = getString(Res.string.character_sheet_edit__skills__aid),
+ valuePlaceHolder = { "${normalize(int() + dex())}" },
+ ),
+ ),
+ ),
+ SkillGroup(
+ type = SkillGroup.Type.OCCUPATIONS,
+ title = getString(Res.string.character_sheet_edit__occupation__title),
+ action = getString(Res.string.character_sheet_edit__occupation__add_action),
+ fields = sheet?.occupations?.map {
+ FieldUio.create(
+ initialLabel = it.label,
+ initialValue = it.value.toString(),
+ valuePlaceHolder = { "40" }
+ )
+ } ?: emptyList(),
+ ),
+ SkillGroup(
+ type = SkillGroup.Type.MAGICS,
+ title = getString(Res.string.character_sheet_edit__magic__title),
+ action = getString(Res.string.character_sheet_edit__magic__add_action),
+ fields = sheet?.magics?.map {
+ FieldUio.create(
+ initialLabel = it.label,
+ initialValue = it.value.toString()
+ )
+ } ?: emptyList(),
+ ),
+ ),
+ rolls = sheet?.rolls?.map {
+ FieldUio.create(
+ isLabelEditable = true,
+ initialLabel = it.label,
+ initialValue = it.roll,
+ )
+ } ?: emptyList()
+ )
+ }
+
+ private inline fun FieldUio.unpack(): T {
+ val tmp = value.value.ifBlank { valuePlaceHolder.value }
+ return when (T::class) {
+ Int::class -> (tmp.toIntOrNull() ?: 0) as T
+ else -> tmp as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt
index 330cf15..fdf9161 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditPage.kt
@@ -34,6 +34,11 @@ import com.pixelized.desktop.lwa.navigation.LocalScreen
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.Form
import kotlinx.coroutines.launch
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__add_roll_action
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__save_action
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__title
+import org.jetbrains.compose.resources.stringResource
@Stable
data class CharacterSheetEditPageUio(
@@ -46,7 +51,7 @@ data class CharacterSheetEditPageUio(
data class SkillGroup(
val title: String,
val type: Type,
- val editable: Boolean = false,
+ val action: String? = null,
val fields: List,
) {
@Stable
@@ -106,7 +111,7 @@ fun CharacterSheetEdit(
Text(
overflow = TextOverflow.Ellipsis,
maxLines = 1,
- text = "Création de personnage",
+ text = stringResource(Res.string.character_sheet_edit__title),
)
},
navigationIcon = {
@@ -152,7 +157,7 @@ fun CharacterSheetEdit(
field = it,
)
}
- if (it.editable) {
+ it.action?.let { label ->
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
@@ -169,7 +174,7 @@ fun CharacterSheetEdit(
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
) {
Text(
- text = "Ajouter une ligne",
+ text = label,
)
Icon(
imageVector = Icons.Default.Add,
@@ -186,6 +191,7 @@ fun CharacterSheetEdit(
form.rolls.forEach {
Form(
modifier = Modifier.fillMaxWidth(),
+ valueWidth = 120.dp,
field = it,
)
}
@@ -197,7 +203,7 @@ fun CharacterSheetEdit(
TextButton(
onClick = onNewCategory,
) {
- Text(text = "Ajouter un lancé")
+ Text(text = stringResource(Res.string.character_sheet_edit__add_roll_action))
}
}
@@ -208,7 +214,7 @@ fun CharacterSheetEdit(
TextButton(
onClick = onSave,
) {
- Text(text = "Sauvegarder")
+ Text(text = stringResource(Res.string.character_sheet_edit__save_action))
}
}
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt
index 55711e5..823f529 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetEditViewModel.kt
@@ -8,6 +8,7 @@ import com.pixelized.desktop.lwa.navigation.destination.CharacterSheetEditDestin
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditPageUio.SkillGroup
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
+import kotlinx.coroutines.runBlocking
class CharacterSheetEditViewModel(
savedStateHandle: SavedStateHandle,
@@ -15,11 +16,13 @@ class CharacterSheetEditViewModel(
private val argument = CharacterSheetEditDestination.Argument(savedStateHandle)
private val repository = CharacterSheetRepository
- private val factory = CharacterSheetFactory()
+ private val factory = CharacterSheetEditFactory()
- private val _characterSheet = repository
- .characterSheetFlow(id = argument.id).value
- .let { sheet -> mutableStateOf(factory.convertToUio(sheet = sheet)) }
+ private val _characterSheet = mutableStateOf(
+ repository.characterSheetFlow(id = argument.id).value.let {
+ runBlocking { factory.convertToUio(it) }
+ }
+ )
val characterSheet: State get() = _characterSheet
fun onSkill(skill: SkillGroup) {
@@ -32,8 +35,8 @@ class CharacterSheetEditViewModel(
addAll(group.fields)
add(
FieldUio.create(
- label = "",
isLabelEditable = true,
+ initialLabel = "",
valuePlaceHolder = {
when (group.type) {
SkillGroup.Type.CHARACTERISTICS -> ""
@@ -61,7 +64,7 @@ class CharacterSheetEditViewModel(
rolls = sheet.rolls.toMutableList().apply {
add(
FieldUio.create(
- label = "",
+ initialLabel = "",
isLabelEditable = true,
valuePlaceHolder = { "" },
)
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetFactory.kt
deleted file mode 100644
index 471392e..0000000
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/CharacterSheetFactory.kt
+++ /dev/null
@@ -1,279 +0,0 @@
-package com.pixelized.desktop.lwa.screen.characterSheet.edit
-
-import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
-import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheet
-import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditPageUio.SkillGroup
-import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
-import java.util.UUID
-import kotlin.math.ceil
-import kotlin.math.max
-
-class CharacterSheetFactory {
-
- fun convertToModel(sheet: CharacterSheetEditPageUio): CharacterSheet {
- return CharacterSheet(
- id = sheet.id,
- name = sheet.name.value.value,
- strength = sheet.skills[0].fields[0].unpack(),
- dexterity = sheet.skills[0].fields[1].unpack(),
- constitution = sheet.skills[0].fields[2].unpack(),
- height = sheet.skills[0].fields[3].unpack(),
- intelligence = sheet.skills[0].fields[4].unpack(),
- power = sheet.skills[0].fields[5].unpack(),
- charisma = sheet.skills[0].fields[6].unpack(),
- movement = sheet.skills[1].fields[0].unpack(),
- currentHp = sheet.skills[1].fields[1].unpack(),
- maxHp = sheet.skills[1].fields[1].unpack(),
- currentPP = sheet.skills[1].fields[2].unpack(),
- maxPP = sheet.skills[1].fields[2].unpack(),
- damageBonus = sheet.skills[1].fields[3].unpack(),
- armor = sheet.skills[1].fields[4].unpack(),
- skills = sheet.skills[2].fields.map {
- CharacterSheet.Skill(
- label = it.label.value,
- value = it.unpack(),
- used = false,
- )
- },
- occupations = sheet.skills[3].fields.map {
- CharacterSheet.Skill(
- label = it.label.value,
- value = it.unpack(),
- used = false,
- )
- },
- magics = sheet.skills[4].fields.map {
- CharacterSheet.Skill(
- label = it.label.value,
- value = it.unpack(),
- used = false,
- )
- },
- rolls = sheet.rolls.map {
- CharacterSheet.Roll(
- label = it.label.value,
- roll = it.unpack(),
- )
- },
- )
- }
-
- fun convertToUio(
- sheet: CharacterSheet?,
- ): CharacterSheetEditPageUio {
- val str = FieldUio.create(
- label = "Force",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.strength?.toString() ?: ""
- )
- val dex = FieldUio.create(
- label = "Dextérité",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.dexterity?.toString() ?: ""
- )
- val con = FieldUio.create(
- label = "Constitution",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.constitution?.toString() ?: ""
- )
- val hei = FieldUio.create(
- label = "Taille",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.height?.toString() ?: ""
- )
- val int = FieldUio.create(
- label = "Intelligence",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.intelligence?.toString() ?: ""
- )
- val pow = FieldUio.create(
- label = "Pouvoir",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.power?.toString() ?: ""
- )
- val cha = FieldUio.create(
- label = "Charisme",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.charisma?.toString() ?: ""
- )
-
- fun str(): Int = str.unpack() ?: 0
- fun dex(): Int = dex.unpack() ?: 0
- fun con(): Int = con.unpack() ?: 0
- fun hei(): Int = hei.unpack() ?: 0
- fun int(): Int = int.unpack() ?: 0
- fun pow(): Int = pow.unpack() ?: 0
- fun cha(): Int = cha.unpack() ?: 0
-
- return CharacterSheetEditPageUio(
- id = sheet?.id ?: UUID.randomUUID().toString(),
- name = FieldUio.create(
- useLabelAsPlaceholder = true,
- label = "Name",
- initialValue = sheet?.name ?: ""
- ),
- skills = listOf(
- SkillGroup(
- title = "Charactéristiques",
- type = SkillGroup.Type.CHARACTERISTICS,
- fields = listOf(str, dex, con, hei, int, pow, cha),
- ),
- SkillGroup(
- title = "Charactéristiques dérivées",
- type = SkillGroup.Type.SUB_CHARACTERISTICS,
- fields = listOf(
- FieldUio.create(
- label = "Déplacement",
- valuePlaceHolder = { "10" },
- initialValue = sheet?.movement?.toString() ?: ""
- ),
- FieldUio.create(
- label = "Points de vie",
- valuePlaceHolder = { "${ceil((con() + hei()) / 2f).toInt()}" },
- initialValue = sheet?.maxHp?.toString() ?: ""
- ),
- FieldUio.create(
- label = "Points de pouvoir",
- valuePlaceHolder = { "${pow()}" },
- initialValue = sheet?.maxPP?.toString() ?: ""
- ),
- FieldUio.create(
- label = "Bonus aux dégats",
- valuePlaceHolder = {
- val bonus = str() + hei()
- when {
- bonus < 12 -> "-1d6"
- bonus in 12..17 -> "-1d4"
- bonus in 18..22 -> "-0"
- bonus in 23..29 -> "1d4"
- bonus in 30..39 -> "1d6"
- else -> "2d6"
- }
- },
- initialValue = sheet?.damageBonus ?: ""
- ),
- FieldUio.create(
- label = "Armure",
- valuePlaceHolder = { "0" },
- initialValue = sheet?.armor?.toString() ?: ""
- ),
- ),
- ),
- SkillGroup(
- title = "Compétances",
- type = SkillGroup.Type.SKILLS,
- editable = true,
- fields = sheet?.skills?.map {
- FieldUio.create(
- label = it.label,
- initialValue = it.value.toString(),
- )
- } ?: listOf(
- FieldUio.create(
- label = "Bagarre",
- valuePlaceHolder = { "${normalize(dex() * 2)}" },
- ),
- FieldUio.create(
- label = "Esquive",
- valuePlaceHolder = { "${normalize(dex() * 2)}" },
- ),
- FieldUio.create(
- label = "Saisie",
- valuePlaceHolder = { "${normalize(str() + hei())}" },
- ),
- FieldUio.create(
- label = "Lancer",
- valuePlaceHolder = { "${normalize(str() + dex())}" },
- ),
- FieldUio.create(
- label = "Athlétisme",
- valuePlaceHolder = { "${normalize(str() + con() * 2)}" },
- ),
- FieldUio.create(
- label = "Acrobatie",
- valuePlaceHolder = { "${normalize(dex() + con() * 2)}" },
- ),
- FieldUio.create(
- label = "Perception",
- valuePlaceHolder = { "${normalize(10 + int() * 2)}" },
- ),
- FieldUio.create(
- label = "Recherche",
- valuePlaceHolder = { "${normalize(10 + int() * 2)}" },
- ),
- FieldUio.create(
- label = "Empathie",
- valuePlaceHolder = { "${normalize(cha() + int())}" },
- ),
- FieldUio.create(
- label = "Persuasion",
- valuePlaceHolder = { "${normalize(cha() * 3)}" },
- ),
- FieldUio.create(
- label = "Intimidation",
- valuePlaceHolder = { "${normalize(cha() + max(pow(), hei()) * 2)}" },
- ),
- FieldUio.create(
- label = "Baratin",
- valuePlaceHolder = { "${normalize(cha() * 2 + int())}" },
- ),
- FieldUio.create(
- label = "Marchandage",
- valuePlaceHolder = { "${normalize(cha() * 2)}" },
- ),
- FieldUio.create(
- label = "Discrétion",
- valuePlaceHolder = { "${normalize(cha() + dex() * 2 - hei())}" },
- ),
- FieldUio.create(
- label = "Escamotage",
- valuePlaceHolder = { "${normalize(dex() * 2)}" },
- ),
- FieldUio.create(
- label = "Premiers soins",
- valuePlaceHolder = { "${normalize(int() + dex())}" },
- ),
- ),
- ),
- SkillGroup(
- title = "Occupations",
- type = SkillGroup.Type.OCCUPATIONS,
- editable = true,
- fields = sheet?.occupations?.map {
- FieldUio.create(
- label = it.label,
- valuePlaceHolder = { "40" },
- initialValue = it.value.toString()
- )
- } ?: emptyList(),
- ),
- SkillGroup(
- title = "Compétences magiques",
- type = SkillGroup.Type.MAGICS,
- editable = true,
- fields = sheet?.magics?.map {
- FieldUio.create(
- label = it.label,
- initialValue = it.value.toString()
- )
- } ?: emptyList(),
- ),
- ),
- rolls = sheet?.rolls?.map {
- FieldUio.create(
- label = it.label,
- isLabelEditable = true,
- initialValue = it.roll,
- )
- } ?: emptyList()
- )
- }
-
- private inline fun FieldUio.unpack(): T {
- val tmp = value.value.ifBlank { valuePlaceHolder.value }
- return when (T::class) {
- Int::class -> (tmp.toIntOrNull() ?: 0) as T
- else -> tmp as T
- }
- }
-}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/FieldUio.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/FieldUio.kt
index e03e31b..cfe360c 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/FieldUio.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/FieldUio.kt
@@ -22,37 +22,41 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Stable
open class FieldUio(
- val useLabelAsPlaceholder: Boolean,
+ val isLabelDisplayed: Boolean,
val isLabelEditable: Boolean,
val label: State,
+ val labelPlaceHolder: State,
val onLabelChange: (String) -> Unit,
- val valuePlaceHolder: State,
val value: State,
+ val valuePlaceHolder: State,
val onValueChange: (String) -> Unit,
) {
companion object {
@Stable
fun create(
- useLabelAsPlaceholder: Boolean = false,
+ isLabelDisplayed: Boolean = true,
isLabelEditable: Boolean = false,
- label: String = "",
+ initialLabel: String = "",
+ labelPlaceHolder: () -> String = { "" },
initialValue: String = "",
valuePlaceHolder: () -> String = { "" },
): FieldUio {
- val labelState = mutableStateOf(label)
- val valueState = mutableStateOf(initialValue)
+ val label = mutableStateOf(initialLabel)
+ val value = mutableStateOf(initialValue)
return FieldUio(
- useLabelAsPlaceholder = useLabelAsPlaceholder,
- isLabelEditable = useLabelAsPlaceholder.not() && isLabelEditable,
- label = labelState,
- onLabelChange = { labelState.value = it },
+ isLabelDisplayed = isLabelDisplayed,
+ isLabelEditable = isLabelEditable,
+ label = label,
+ labelPlaceHolder = derivedStateOf(labelPlaceHolder),
+ onLabelChange = { label.value = it },
+ value = value,
valuePlaceHolder = derivedStateOf(valuePlaceHolder),
- value = valueState,
- onValueChange = { valueState.value = it },
+ onValueChange = { value.value = it },
)
}
}
@@ -61,27 +65,17 @@ open class FieldUio(
@Composable
fun Form(
modifier: Modifier = Modifier,
+ valueWidth: Dp = 80.dp,
field: FieldUio,
) {
val focus = LocalFocusManager.current
AnimatedContent(
- targetState = field.useLabelAsPlaceholder,
+ targetState = field.isLabelDisplayed,
transitionSpec = { fadeIn() togetherWith fadeOut() }
) {
when (it) {
true -> {
- TextField(
- modifier = modifier,
- value = field.value.value,
- label = { Text(text = field.label.value) },
- singleLine = true,
- keyboardActions = KeyboardActions { focus.moveFocus(FocusDirection.Next) },
- onValueChange = field.onValueChange,
- )
- }
-
- else -> {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
@@ -94,32 +88,43 @@ fun Form(
) { editable ->
when (editable) {
true -> TextField(
- value = field.label.value,
- placeholder = { Text(text = "Nom") },
- singleLine = true,
keyboardActions = KeyboardActions { focus.moveFocus(FocusDirection.Next) },
+ singleLine = true,
+ placeholder = { Text(text = field.labelPlaceHolder.value) },
onValueChange = field.onLabelChange,
+ value = field.label.value,
)
else -> Text(
modifier = Modifier.padding(horizontal = 16.dp),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.body1,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
text = field.label.value
)
}
}
TextField(
- modifier = Modifier.width(width = 80.dp),
- value = field.value.value,
- placeholder = { Text(text = field.valuePlaceHolder.value) },
- singleLine = true,
+ modifier = Modifier.width(width = valueWidth),
keyboardActions = KeyboardActions { focus.moveFocus(FocusDirection.Next) },
+ singleLine = true,
+ placeholder = { Text(text = field.valuePlaceHolder.value) },
onValueChange = field.onValueChange,
+ value = field.value.value,
)
}
}
+
+ else -> {
+ TextField(
+ modifier = modifier,
+ keyboardActions = KeyboardActions { focus.moveFocus(FocusDirection.Next) },
+ singleLine = true,
+ label = { Text(text = field.label.value) },
+ onValueChange = field.onValueChange,
+ value = field.value.value,
+ )
+ }
}
}
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt
index 6030c66..a8bcbaa 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/main/MainPage.kt
@@ -12,7 +12,6 @@ import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
-import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
@@ -22,6 +21,9 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.pixelized.desktop.lwa.navigation.LocalScreen
import com.pixelized.desktop.lwa.navigation.destination.navigateToCharacterSheet
import com.pixelized.desktop.lwa.navigation.destination.navigateToCharacterSheetEdit
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.main_page__create_action
+import org.jetbrains.compose.resources.stringResource
@Stable
data class CharacterUio(
@@ -67,13 +69,13 @@ fun MainPageContent(
Column {
characters.value.forEach { sheet ->
TextButton(
- onClick = { onCharacter(sheet) }
+ onClick = { onCharacter(sheet) },
) {
Text(
modifier = Modifier.fillMaxWidth(),
- maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Start,
+ maxLines = 1,
text = sheet.name,
)
}
@@ -88,7 +90,7 @@ fun MainPageContent(
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Start,
- text = "Créer une feuille de personnage",
+ text = stringResource(Res.string.main_page__create_action),
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt
index 3365441..60bcf17 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/roll/RollViewModel.kt
@@ -16,6 +16,13 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.roll_page__critical_failure
+import lwacharactersheet.composeapp.generated.resources.roll_page__critical_success
+import lwacharactersheet.composeapp.generated.resources.roll_page__failure
+import lwacharactersheet.composeapp.generated.resources.roll_page__special_success
+import lwacharactersheet.composeapp.generated.resources.roll_page__success
+import org.jetbrains.compose.resources.getString
class RollViewModel : ViewModel() {
private val _roll = mutableStateOf(RollUio(label = "", value = 0))
@@ -117,12 +124,11 @@ class RollViewModel : ViewModel() {
_result.value = RollResultUio(
label = rollStep?.let { rollStep ->
when (roll) {
- // TODO wording
- in rollStep.criticalSuccessRange -> "Réussite critique"
- in rollStep.specialSuccessRange -> "Réussite spéciale"
- in rollStep.successRange -> "Réussite"
- in rollStep.failureRange -> "Échec"
- in rollStep.criticalFailureRange -> "Échec critique"
+ in rollStep.criticalSuccessRange -> getString(resource = Res.string.roll_page__critical_success)
+ in rollStep.specialSuccessRange -> getString(resource = Res.string.roll_page__special_success)
+ in rollStep.successRange -> getString(resource = Res.string.roll_page__success)
+ in rollStep.failureRange -> getString(resource = Res.string.roll_page__failure)
+ in rollStep.criticalFailureRange -> getString(resource = Res.string.roll_page__critical_failure)
else -> ""
}
} ?: "",
diff --git a/composeApp/src/commonTest/kotlin/com/pixelized/desktop/lwa/business/DamageBonusUseCaseTest.kt b/composeApp/src/commonTest/kotlin/com/pixelized/desktop/lwa/business/DamageBonusUseCaseTest.kt
new file mode 100644
index 0000000..28d8bfe
--- /dev/null
+++ b/composeApp/src/commonTest/kotlin/com/pixelized/desktop/lwa/business/DamageBonusUseCaseTest.kt
@@ -0,0 +1,52 @@
+package com.pixelized.desktop.lwa.business
+
+import org.junit.Test
+
+class DamageBonusUseCaseTest {
+
+ @Test
+ fun testBonusDamage() {
+ (0 until 12).forEach {
+ val result = DamageBonusUseCase.bonusDamage(stat = it)
+ val expected = "-1d6"
+ assert(result == expected) {
+ "Expected:'$expected' bonus damage for stat:'$it' but was:'$result'"
+ }
+ }
+ (12 until 18).forEach {
+ val result = DamageBonusUseCase.bonusDamage(stat = it)
+ val expected = "-1d4"
+ assert(result == expected) {
+ "Expected:'$expected' bonus damage for stat:'$it' but was:'$result'"
+ }
+ }
+ (18 until 23).forEach {
+ val result = DamageBonusUseCase.bonusDamage(stat = it)
+ val expected = "+0"
+ assert(result == expected) {
+ "Expected:'$expected' bonus damage for stat:'$it' but was:'$result'"
+ }
+ }
+ (23 until 30).forEach {
+ val result = DamageBonusUseCase.bonusDamage(stat = it)
+ val expected = "+1d4"
+ assert(result == expected) {
+ "Expected:'$expected' bonus damage for stat:'$it' but was:'$result'"
+ }
+ }
+ (30 until 40).forEach {
+ val result = DamageBonusUseCase.bonusDamage(stat = it)
+ val expected = "+1d6"
+ assert(result == expected) {
+ "Expected:'$expected' bonus damage for stat:'$it' but was:'$result'"
+ }
+ }
+ (40 until 100).forEach {
+ val result = DamageBonusUseCase.bonusDamage(stat = it)
+ val expected = "+2d6"
+ assert(result == expected) {
+ "Expected:'$expected' bonus damage for stat:'$it' but was:'$result'"
+ }
+ }
+ }
+}