diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 550afe3..dce0aee 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -63,6 +63,8 @@
Premiers soins
Occupations
Ajouter une occupation
+ Nom
+ Bonus
Compétences magiques
Ajouter une compétence magique
Supprimer
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt
index 366ed01..3f46a28 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt
@@ -43,7 +43,7 @@ class SkillValueComputationUseCase(
baseSum
}
- return max(base + skill.bonus + skill.level - diminished, 0)
+ return max(base + (skill.bonus ?: 0) + (skill.level ?: 0) - diminished, 0)
}
fun computeRoll(
@@ -83,8 +83,8 @@ class SkillValueComputationUseCase(
if (damageBonusInstructions is Instruction.Dice) {
RollUseCase.roll(
quantity = damageBonusInstructions.quantity,
- faces = damageBonusInstructions.faces
- ) / 2
+ faces = damageBonusInstructions.faces / 2,
+ )
} else {
0
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheet.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheet.kt
index 2ad8a68..3a4b615 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheet.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheet.kt
@@ -35,8 +35,8 @@ data class CharacterSheet(
val id: String,
val label: String,
val base: String,
- val bonus: Int,
- val level: Int,
+ val bonus: Int?,
+ val level: Int?,
val occupation: Boolean,
val used: Boolean,
)
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheetJsonV1.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheetJsonV1.kt
index 3219c2e..559625c 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheetJsonV1.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/model/CharacterSheetJsonV1.kt
@@ -36,8 +36,8 @@ data class CharacterSheetJsonV1(
val id: String,
val label: String,
val base: String,
- val bonus: Int,
- val level: Int,
+ val bonus: Int?,
+ val level: Int?,
val occupation: Boolean,
val used: Boolean,
)
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
index 9529b19..f1f21f6 100644
--- 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
@@ -4,13 +4,15 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
-import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
import com.pixelized.desktop.lwa.screen.characterSheet.common.SkillFieldFactory
import com.pixelized.desktop.lwa.screen.characterSheet.common.occupation
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__action_label
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label
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
@@ -53,7 +55,6 @@ import kotlin.math.min
class CharacterSheetEditFactory(
private val bonusDamageUseCase: DamageBonusUseCase,
private val skillFactory: SkillFieldFactory,
- private val parser: ArithmeticParser,
) {
fun updateCharacterSheet(
currentSheet: CharacterSheet?,
@@ -92,9 +93,9 @@ class CharacterSheetEditFactory(
CharacterSheet.Skill(
id = editedSkill.id,
label = editedSkill.label,
- base = "${editedSkill.base}",
- bonus = editedSkill.bonus.value.value.toIntOrNull() ?: 0,
- level = editedSkill.level.value.value.toIntOrNull() ?: 0,
+ base = "${editedSkill.base.value}",
+ bonus = editedSkill.bonus.value.value.toIntOrNull(),
+ level = editedSkill.level.value.value.toIntOrNull(),
occupation = editedSkill.option.checked.value,
used = currentSkill?.used ?: false,
)
@@ -107,8 +108,8 @@ class CharacterSheetEditFactory(
id = editedSkill.id,
label = editedSkill.label.value.value,
base = editedSkill.base.value.value,
- bonus = editedSkill.bonus.value.value.toIntOrNull() ?: 0,
- level = editedSkill.level.value.value.toIntOrNull() ?: 0,
+ bonus = editedSkill.bonus.value.value.toIntOrNull(),
+ level = editedSkill.level.value.value.toIntOrNull(),
occupation = editedSkill.options.occupation,
used = currentSkill?.used ?: false,
)
@@ -121,17 +122,17 @@ class CharacterSheetEditFactory(
id = editedSkill.id,
label = editedSkill.label.value.value,
base = editedSkill.base.value.value,
- bonus = editedSkill.bonus.value.value.toIntOrNull() ?: 0,
- level = editedSkill.level.value.value.toIntOrNull() ?: 0,
+ bonus = editedSkill.bonus.value.value.toIntOrNull(),
+ level = editedSkill.level.value.value.toIntOrNull(),
occupation = editedSkill.options.occupation,
used = currentSkill?.used ?: false,
)
},
actions = editedSheet.actions.map {
CharacterSheet.Roll(
- id = "", // TODO
- label = it.label.value,
- roll = it.unpack(),
+ id = it.id,
+ label = it.label.value.value,
+ roll = it.action.value.value,
)
},
)
@@ -139,7 +140,7 @@ class CharacterSheetEditFactory(
suspend fun convertToUio(
sheet: CharacterSheet?,
- onDeleteSkill: (skillId: String) -> Unit,
+ onDeleteSkill: (id: String) -> Unit,
): CharacterSheetEditPageUio {
val str = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__str),
@@ -149,27 +150,27 @@ class CharacterSheetEditFactory(
val dex = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__dex),
initialValue = sheet?.dexterity?.toString() ?: "",
- valuePlaceHolder = { "11" }
+ valuePlaceHolder = { "10" }
)
val con = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__con),
initialValue = sheet?.constitution?.toString() ?: "",
- valuePlaceHolder = { "15" }
+ valuePlaceHolder = { "10" }
)
val hei = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__hei),
initialValue = sheet?.height?.toString() ?: "",
- valuePlaceHolder = { "13" }
+ valuePlaceHolder = { "10" }
)
val int = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__int),
initialValue = sheet?.intelligence?.toString() ?: "",
- valuePlaceHolder = { "9" }
+ valuePlaceHolder = { "10" }
)
val pow = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__pow),
initialValue = sheet?.power?.toString() ?: "",
- valuePlaceHolder = { "15" }
+ valuePlaceHolder = { "10" }
)
val cha = FieldUio.create(
initialLabel = getString(Res.string.character_sheet_edit__characteristics__cha),
@@ -339,8 +340,8 @@ class CharacterSheetEditFactory(
label = specialSkillsLabel,
labelValue = skill.label,
baseValue = skill.base,
- bonusValue = skill.bonus.takeIf { it > 0 }?.toString() ?: "",
- levelValue = skill.level.takeIf { it > 0 }?.toString() ?: "",
+ bonusValue = skill.bonus?.toString() ?: "",
+ levelValue = skill.level?.toString() ?: "",
options = run {
val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
listOf(
@@ -356,8 +357,8 @@ class CharacterSheetEditFactory(
label = magicSkillsLabel,
labelValue = skill.label,
baseValue = skill.base,
- bonusValue = skill.bonus.takeIf { it > 0 }?.toString() ?: "",
- levelValue = skill.level.takeIf { it > 0 }?.toString() ?: "",
+ bonusValue = skill.bonus?.toString() ?: "",
+ levelValue = skill.level?.toString() ?: "",
options = run {
val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
listOf(
@@ -367,7 +368,20 @@ class CharacterSheetEditFactory(
},
)
} ?: emptyList(),
- actions = emptyList(),
+ actions = sheet?.actions?.map { action ->
+ ActionFieldUio(
+ id = action.id,
+ label = skillFactory.createWrapper(
+ label = getString(Res.string.character_sheet_edit__actions__name_label),
+ value = action.label,
+ ),
+ action = skillFactory.createWrapper(
+ label = getString(Res.string.character_sheet_edit__actions__action_label),
+ value = action.roll,
+ ),
+ option = skillFactory.deleteOption { onDeleteSkill(action.id) },
+ )
+ } ?: emptyList(),
)
}
@@ -385,17 +399,16 @@ class CharacterSheetEditFactory(
base = base,
bonus = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__skills__bonus_label),
- value = skill?.bonus?.takeIf { it > 0 }?.toString() ?: "",
+ value = skill?.bonus?.toString() ?: "",
),
level = skillFactory.createWrapper(
label = getString(Res.string.character_sheet_edit__skills__level_label),
- value = skill?.level?.takeIf { it > 0 }?.toString() ?: "",
+ value = skill?.level?.toString() ?: "",
),
option = skillFactory.occupationOption(skill?.occupation ?: false),
)
}
-
private inline fun FieldUio.unpack(): T {
val tmp = value.value.ifBlank { valuePlaceHolder.value }
return when (T::class) {
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 50f6c06..a584de3 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
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Icon
@@ -32,6 +33,8 @@ import com.pixelized.desktop.lwa.LocalWindowController
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.navigation.window.LocalWindow
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionField
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillForm
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
@@ -74,7 +77,7 @@ data class CharacterSheetEditPageUio(
val commonSkills: List,
val specialSkills: List,
val magicSkills: List,
- val actions: List,
+ val actions: List,
) {
val characteristics
get() = listOf(
@@ -340,12 +343,15 @@ fun CharacterSheetEdit(
}
}
- form.actions.forEach {
- Form(
- modifier = Modifier.fillMaxWidth(),
- valueWidth = 120.dp,
- field = it,
- )
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ form.actions.forEach {
+ ActionField(
+ modifier = Modifier.fillMaxWidth().padding(end = (4 + 2).dp),
+ action = it
+ )
+ }
}
Row(
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 88f5470..7f46e1a 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
@@ -7,9 +7,11 @@ import androidx.lifecycle.ViewModel
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetEditDestination
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.screen.characterSheet.common.SkillFieldFactory
-import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__action_label
+import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_title
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_title
import org.jetbrains.compose.resources.getString
@@ -73,10 +75,16 @@ class CharacterSheetEditViewModel(
}
suspend fun onNewAction() {
- val field = FieldUio.create(
- initialLabel = "",
- isLabelEditable = true,
- valuePlaceHolder = { "" },
+ val id = UUID.randomUUID().toString()
+ val field = ActionFieldUio(
+ id = id,
+ label = skillFactory.createWrapper(
+ label = getString(Res.string.character_sheet_edit__actions__name_label),
+ ),
+ action = skillFactory.createWrapper(
+ label = getString(Res.string.character_sheet_edit__actions__action_label),
+ ),
+ option = skillFactory.deleteOption { deleteSkill(id) },
)
val actions = _characterSheet.value.actions.toMutableList().also {
it.add(field)
@@ -94,6 +102,9 @@ class CharacterSheetEditViewModel(
magicSkills = _characterSheet.value.magicSkills.toMutableList().also { skills ->
skills.removeIf { it.id == skillId }
},
+ actions = _characterSheet.value.actions.toMutableList().also { actions ->
+ actions.removeIf { it.id == skillId }
+ }
)
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/ActionField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/ActionField.kt
new file mode 100644
index 0000000..39ea6ab
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/ActionField.kt
@@ -0,0 +1,77 @@
+package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.DropdownMenu
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.MoreVert
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.DropDownActionMenuItem
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
+import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
+
+@Stable
+data class ActionFieldUio(
+ val id: String,
+ val label: TextFieldWrapperUio,
+ val action: TextFieldWrapperUio,
+ val option: ActionOption.DeleteOptionUio,
+)
+
+@Composable
+fun ActionField(
+ modifier: Modifier = Modifier,
+ action: ActionFieldUio,
+) {
+ val showMenu = remember { mutableStateOf(false) }
+
+ Row(
+ modifier = modifier,
+ horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ TextFieldWrapper(
+ modifier = Modifier.weight(weight = 1f),
+ wrapper = action.label,
+ )
+ TextFieldWrapper(
+ modifier = Modifier.width(width = (192+4).dp),
+ wrapper = action.action,
+ )
+ Box {
+ IconButton(
+ onClick = { showMenu.value = showMenu.value.not() },
+ ) {
+ Icon(
+ imageVector = Icons.Default.MoreVert,
+ tint = MaterialTheme.colors.primary,
+ contentDescription = null,
+ )
+ }
+ DropdownMenu(
+ expanded = showMenu.value,
+ onDismissRequest = { showMenu.value = false }
+ ) {
+ DropDownActionMenuItem(
+ wrapper = action.option,
+ onClick = {
+ showMenu.value = false
+ action.option.onOption()
+ }
+ )
+ }
+ }
+ }
+}
\ No newline at end of file