From d1a98b90750c3b9d4cfe10d56b87527cd7694f87 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Wed, 27 Nov 2024 17:24:17 +0100 Subject: [PATCH] Update the last character sheet formfield. --- .../com/pixelized/desktop/lwa/Module.kt | 2 +- .../CharacterSheetJsonFactory.kt | 4 +- .../characterSheet/model/CharacterSheet.kt | 2 +- .../detail/CharacterSheetFactory.kt | 5 +- .../detail/CharacterSheetViewModel.kt | 4 +- .../edit/CharacterSheetEditFactory.kt | 237 ++++++++++-------- .../edit/CharacterSheetEditPage.kt | 57 ++--- .../edit/CharacterSheetEditViewModel.kt | 2 +- .../{ => edit}/common/SkillFieldFactory.kt | 10 +- .../characterSheet/edit/composable/Field.kt | 153 ----------- .../edit/composable/SimpleField.kt | 49 ++++ .../edit/composable/SpecialSkillField.kt | 159 +----------- .../edit/composable/textfield/FormWrapper.kt | 27 +- 13 files changed, 248 insertions(+), 463 deletions(-) rename composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/{ => edit}/common/SkillFieldFactory.kt (93%) delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/Field.kt create mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SimpleField.kt diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt index 2f6a53f..2988f06 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt @@ -8,7 +8,7 @@ import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetReposit import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetStore import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository -import com.pixelized.desktop.lwa.screen.characterSheet.common.SkillFieldFactory +import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetViewModel import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditFactory diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetJsonFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetJsonFactory.kt index 96b280e..16edad1 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetJsonFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetJsonFactory.kt @@ -29,7 +29,7 @@ class CharacterSheetJsonFactory( currentHp = sheet.currentHp, maxHp = if (sheet.overrideMaxHp) sheet.maxHp else null, currentPP = sheet.currentPp, - maxPP = if (sheet.overrideMaxPP) sheet.maxPP else null, + maxPP = if (sheet.overrideMaxPP) sheet.maxPp else null, damageBonus = if (sheet.overrideDamageBonus) sheet.damageBonus else null, armor = if (sheet.overrideArmor) sheet.armor else null, skills = sheet.commonSkills.map { @@ -104,7 +104,7 @@ class CharacterSheetJsonFactory( maxHp = json.maxHp ?: (ceil((json.constitution + json.height) / 2f).toInt()), currentPp = json.currentPP, overrideMaxPP = json.maxPP != null, - maxPP = json.maxPP ?: json.power, + maxPp = json.maxPP ?: json.power, overrideDamageBonus = json.damageBonus != null, damageBonus = json.damageBonus ?: bonusDamageUseCase.bonusDamage( 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 3a4b615..2080ade 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 @@ -19,7 +19,7 @@ data class CharacterSheet( val maxHp: Int, val currentPp: Int, val overrideMaxPP: Boolean, - val maxPP: Int, + val maxPp: Int, val overrideDamageBonus: Boolean, val damageBonus: String, val overrideArmor: Boolean, 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 7db79a6..fb9b02c 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 @@ -2,7 +2,6 @@ package com.pixelized.desktop.lwa.screen.characterSheet.detail import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio -import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CommonSkillId import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic @@ -52,9 +51,7 @@ import org.jetbrains.compose.resources.getString class CharacterSheetFactory( private val skillUseCase: SkillValueComputationUseCase, - private val arithmeticParser: ArithmeticParser, ) { - companion object { const val HP = "HP" const val PP = "PP" @@ -163,7 +160,7 @@ class CharacterSheetFactory( Characteristic( id = PP, label = getString(Res.string.character_sheet__sub_characteristics__power_point), - value = "${sheet.currentPp}/${sheet.maxPP}", + value = "${sheet.currentPp}/${sheet.maxPp}", tooltips = TooltipUio( title = getString(Res.string.character_sheet__sub_characteristics__power_point), description = getString(Res.string.tooltip__sub_characteristics__power_point), 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 6bc3d7e..4310063 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 @@ -146,7 +146,7 @@ class CharacterSheetViewModel( label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__power_point), value = { value.value }, onValueChange = { value.value = it }, - maxValue = "${sheet.maxPP}", + maxValue = "${sheet.maxPp}", ) } @@ -166,7 +166,7 @@ class CharacterSheetViewModel( val sheet = repository.characterSheetFlow(id = argument.id).value val updated = when (characteristicId) { CharacterSheetFactory.HP -> sheet?.copy(currentHp = max(0, min(sheet.maxHp, value))) - CharacterSheetFactory.PP -> sheet?.copy(currentPp = max(0, min(sheet.maxPP, value))) + CharacterSheetFactory.PP -> sheet?.copy(currentPp = max(0, min(sheet.maxPp, value))) else -> null } updated?.let { 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 f1f21f6..374185d 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 @@ -2,14 +2,15 @@ package com.pixelized.desktop.lwa.screen.characterSheet.edit import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.mutableStateOf import com.pixelized.desktop.lwa.business.DamageBonusUseCase import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize 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.common.SkillFieldFactory +import com.pixelized.desktop.lwa.screen.characterSheet.edit.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 com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SimpleFieldUio 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 @@ -60,32 +61,54 @@ class CharacterSheetEditFactory( currentSheet: CharacterSheet?, editedSheet: CharacterSheetEditPageUio, ): CharacterSheet { + val maxHp = editedSheet.maxHp.unpack()?.toIntOrNull() + ?: currentSheet?.maxHp + ?: 0 + val maxPp = editedSheet.maxPp.unpack()?.toIntOrNull() + ?: currentSheet?.maxPp + ?: 0 return CharacterSheet( id = editedSheet.id, name = editedSheet.name.value.value, - strength = editedSheet.strength.unpack(), - dexterity = editedSheet.dexterity.unpack(), - constitution = editedSheet.constitution.unpack(), - height = editedSheet.height.unpack(), - intelligence = editedSheet.intelligence.unpack(), - power = editedSheet.power.unpack(), - charisma = editedSheet.charisma.unpack(), - overrideMovement = editedSheet.movement.value.value.isNotBlank(), - movement = editedSheet.movement.unpack(), - overrideMaxHp = editedSheet.maxHp.value.value.isNotBlank(), - maxHp = editedSheet.maxHp.unpack(), - currentHp = editedSheet.maxHp.unpack().let { - max(0, min(it, currentSheet?.currentHp ?: it)) - }, - overrideMaxPP = editedSheet.maxPP.value.value.isNotBlank(), - maxPP = editedSheet.maxPP.unpack(), - currentPp = editedSheet.maxPP.unpack().let { - max(0, min(it, currentSheet?.currentPp ?: it)) - }, - overrideDamageBonus = editedSheet.damageBonus.value.value.isNotBlank(), - damageBonus = editedSheet.damageBonus.unpack(), - overrideArmor = editedSheet.armor.value.value.isNotBlank(), - armor = editedSheet.armor.unpack(), + strength = editedSheet.strength.unpack()?.toIntOrNull() + ?: currentSheet?.strength + ?: 0, + dexterity = editedSheet.dexterity.unpack()?.toIntOrNull() + ?: currentSheet?.dexterity + ?: 0, + constitution = editedSheet.constitution.unpack()?.toIntOrNull() + ?: currentSheet?.constitution + ?: 0, + height = editedSheet.height.unpack()?.toIntOrNull() + ?: currentSheet?.height + ?: 0, + intelligence = editedSheet.intelligence.unpack()?.toIntOrNull() + ?: currentSheet?.intelligence + ?: 0, + power = editedSheet.power.unpack()?.toIntOrNull() + ?: currentSheet?.power + ?: 0, + charisma = editedSheet.charisma.unpack()?.toIntOrNull() + ?: currentSheet?.charisma + ?: 0, + overrideMovement = editedSheet.movement.value.value.value.isNotBlank(), + movement = editedSheet.movement.unpack()?.toIntOrNull() + ?: currentSheet?.movement + ?: 10, + overrideMaxHp = editedSheet.maxHp.value.value.value.isNotBlank(), + maxHp = maxHp, + currentHp = max(0, min(maxHp, currentSheet?.currentHp ?: maxHp)), + overrideMaxPP = editedSheet.maxPp.value.value.value.isNotBlank(), + maxPp = maxPp, + currentPp = max(0, min(maxPp, currentSheet?.currentPp ?: maxPp)), + overrideDamageBonus = editedSheet.damageBonus.value.value.value.isNotBlank(), + damageBonus = editedSheet.damageBonus.unpack() + ?: currentSheet?.damageBonus + ?: "", + overrideArmor = editedSheet.armor.value.value.value.isNotBlank(), + armor = editedSheet.armor.unpack()?.toIntOrNull() + ?: currentSheet?.armor + ?: 0, commonSkills = editedSheet.commonSkills.map { editedSkill -> val currentSkill = currentSheet?.commonSkills?.firstOrNull { it.id == editedSkill.id @@ -142,59 +165,72 @@ class CharacterSheetEditFactory( sheet: CharacterSheet?, onDeleteSkill: (id: String) -> Unit, ): CharacterSheetEditPageUio { - val str = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__str), - initialValue = sheet?.strength?.toString() ?: "", - valuePlaceHolder = { "10" }, + val str = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__str), + value = skillFactory.createWrapper( + value = sheet?.strength?.toString() ?: "", + placeholder = mutableStateOf("10") + ), ) - val dex = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__dex), - initialValue = sheet?.dexterity?.toString() ?: "", - valuePlaceHolder = { "10" } + val dex = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__dex), + value = skillFactory.createWrapper( + value = sheet?.dexterity?.toString() ?: "", + placeholder = mutableStateOf("10"), + ), ) - val con = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__con), - initialValue = sheet?.constitution?.toString() ?: "", - valuePlaceHolder = { "10" } + val con = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__con), + value = skillFactory.createWrapper( + value = sheet?.constitution?.toString() ?: "", + placeholder = mutableStateOf("10"), + ) ) - val hei = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__hei), - initialValue = sheet?.height?.toString() ?: "", - valuePlaceHolder = { "10" } + val hei = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__hei), + value = skillFactory.createWrapper( + value = sheet?.height?.toString() ?: "", + placeholder = mutableStateOf("10"), + ) ) - val int = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__int), - initialValue = sheet?.intelligence?.toString() ?: "", - valuePlaceHolder = { "10" } + val int = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__int), + value = skillFactory.createWrapper( + value = sheet?.intelligence?.toString() ?: "", + placeholder = mutableStateOf("10"), + ) ) - val pow = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__pow), - initialValue = sheet?.power?.toString() ?: "", - valuePlaceHolder = { "10" } + val pow = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__pow), + value = skillFactory.createWrapper( + value = sheet?.power?.toString() ?: "", + placeholder = mutableStateOf("10"), + ) ) - val cha = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__characteristics__cha), - initialValue = sheet?.charisma?.toString() ?: "", - valuePlaceHolder = { "7" } + val cha = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__characteristics__cha), + value = skillFactory.createWrapper( + value = sheet?.charisma?.toString() ?: "", + placeholder = mutableStateOf("10"), + ) ) - 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 + fun str(): Int = str.unpack()?.toIntOrNull() ?: 0 + fun dex(): Int = dex.unpack()?.toIntOrNull() ?: 0 + fun con(): Int = con.unpack()?.toIntOrNull() ?: 0 + fun hei(): Int = hei.unpack()?.toIntOrNull() ?: 0 + fun int(): Int = int.unpack()?.toIntOrNull() ?: 0 + fun pow(): Int = pow.unpack()?.toIntOrNull() ?: 0 + fun cha(): Int = cha.unpack()?.toIntOrNull() ?: 0 val specialSkillsLabel = getString(Res.string.character_sheet_edit__skills__special_title) val magicSkillsLabel = getString(Res.string.character_sheet_edit__skills__magic_title) 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 ?: "" + name = skillFactory.createWrapper( + label = getString(Res.string.character_sheet_edit__name_placeholder), + value = sheet?.name ?: "" ), strength = str, dexterity = dex, @@ -203,38 +239,45 @@ class CharacterSheetEditFactory( intelligence = int, power = pow, charisma = cha, - movement = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__movement), - initialValue = (if (sheet?.overrideMovement == true) "${sheet.movement}" else null) - ?: "", - valuePlaceHolder = { "10" } + movement = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__sub_characteristics__movement), + value = skillFactory.createWrapper( + value = if (sheet?.overrideMovement == true) "${sheet.movement}" else "", + placeholder = mutableStateOf("10"), + ) ), - maxHp = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point), - initialValue = (if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else null) ?: "", - valuePlaceHolder = { "${ceil((con() + hei()) / 2f).toInt()}" } + maxHp = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point), + value = skillFactory.createWrapper( + value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "", + placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" }, + ) ), - maxPP = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__power_point), - initialValue = (if (sheet?.overrideMaxPP == true) "${sheet.maxPP}" else null) ?: "", - valuePlaceHolder = { "${pow()}" } + maxPp = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point), + value = skillFactory.createWrapper( + value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "", + placeholder = derivedStateOf { "${pow()}" }, + ) ), - damageBonus = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus), - initialValue = (if (sheet?.overrideDamageBonus == true) sheet.damageBonus else null) - ?: "", - valuePlaceHolder = { - bonusDamageUseCase.bonusDamage( - strength = str(), - height = hei() - ) - } + damageBonus = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__sub_characteristics__damage_bonus), + value = skillFactory.createWrapper( + value = if (sheet?.overrideDamageBonus == true) sheet.damageBonus else "", + placeholder = derivedStateOf { + bonusDamageUseCase.bonusDamage( + strength = str(), + height = hei() + ) + }, + ) ), - armor = FieldUio.create( - initialLabel = getString(Res.string.character_sheet_edit__sub_characteristics__armor), - initialValue = (if (sheet?.overrideArmor == true) sheet.armor.toString() else null) - ?: "", - valuePlaceHolder = { "0" } + armor = SimpleFieldUio( + label = getString(Res.string.character_sheet_edit__sub_characteristics__armor), + value = skillFactory.createWrapper( + value = if (sheet?.overrideArmor == true) "${sheet.armor}" else "", + placeholder = mutableStateOf("0"), + ) ), commonSkills = listOf( createBaseSkill( @@ -409,11 +452,7 @@ class CharacterSheetEditFactory( ) } - 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 - } + private fun SimpleFieldUio.unpack(): String? { + return value.value.value.ifBlank { value.placeholder.value } } } \ 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 a584de3..12b497a 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,7 +7,6 @@ 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 @@ -19,11 +18,9 @@ import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable -import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -37,10 +34,12 @@ import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFie 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 -import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.Form +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SimpleField +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SimpleFieldUio import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SkillFieldUio import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SkillForm +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio import kotlinx.coroutines.launch import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__common_title @@ -53,7 +52,6 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sk import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_action import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__title import lwacharactersheet.composeapp.generated.resources.ic_save_24dp -import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.koin.compose.viewmodel.koinViewModel @@ -61,19 +59,19 @@ import org.koin.compose.viewmodel.koinViewModel @Stable data class CharacterSheetEditPageUio( val id: String, - val name: FieldUio, - val strength: FieldUio, - val dexterity: FieldUio, - val constitution: FieldUio, - val height: FieldUio, - val intelligence: FieldUio, - val power: FieldUio, - val charisma: FieldUio, - val movement: FieldUio, - val maxHp: FieldUio, - val maxPP: FieldUio, - val damageBonus: FieldUio, - val armor: FieldUio, + val name: TextFieldWrapperUio, + val strength: SimpleFieldUio, + val dexterity: SimpleFieldUio, + val constitution: SimpleFieldUio, + val height: SimpleFieldUio, + val intelligence: SimpleFieldUio, + val power: SimpleFieldUio, + val charisma: SimpleFieldUio, + val movement: SimpleFieldUio, + val maxHp: SimpleFieldUio, + val maxPp: SimpleFieldUio, + val damageBonus: SimpleFieldUio, + val armor: SimpleFieldUio, val commonSkills: List, val specialSkills: List, val magicSkills: List, @@ -94,7 +92,7 @@ data class CharacterSheetEditPageUio( get() = listOf( movement, maxHp, - maxPP, + maxPp, damageBonus, armor, ) @@ -184,9 +182,9 @@ fun CharacterSheetEdit( .padding(all = 16.dp), verticalArrangement = Arrangement.spacedBy(space = 16.dp) ) { - Form( + TextFieldWrapper( modifier = Modifier.fillMaxWidth(), - field = form.name, + wrapper = form.name, ) DecoratedBox( @@ -203,7 +201,7 @@ fun CharacterSheetEdit( text = stringResource(Res.string.character_sheet_edit__characteristics__title), ) form.characteristics.forEach { - Form( + SimpleField( modifier = Modifier.fillMaxWidth(), field = it, ) @@ -225,7 +223,7 @@ fun CharacterSheetEdit( text = stringResource(Res.string.character_sheet_edit__sub_characteristics__title), ) form.subCharacteristics.forEach { - Form( + SimpleField( modifier = Modifier.fillMaxWidth(), field = it, ) @@ -344,7 +342,9 @@ fun CharacterSheetEdit( } Column( - horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxWidth() + .animateContentSize(), ) { form.actions.forEach { ActionField( @@ -352,13 +352,8 @@ fun CharacterSheetEdit( action = it ) } - } - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End, - ) { TextButton( + modifier = Modifier.align(alignment = Alignment.End), onClick = onNewAction, ) { Text( 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 7f46e1a..0fa00e2 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 @@ -6,7 +6,7 @@ import androidx.lifecycle.SavedStateHandle 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.common.SkillFieldFactory import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.ActionFieldUio import kotlinx.coroutines.runBlocking import lwacharactersheet.composeapp.generated.resources.Res diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/common/SkillFieldFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/common/SkillFieldFactory.kt similarity index 93% rename from composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/common/SkillFieldFactory.kt rename to composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/common/SkillFieldFactory.kt index eb1dbbb..3d97ca1 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/common/SkillFieldFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/common/SkillFieldFactory.kt @@ -1,13 +1,14 @@ -package com.pixelized.desktop.lwa.screen.characterSheet.common +package com.pixelized.desktop.lwa.screen.characterSheet.edit.common import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete +import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.SkillFieldUio -import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.CheckedOption import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.OptionUio +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__delete__label import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__occupation__label @@ -19,7 +20,6 @@ import java.util.UUID class SkillFieldFactory { - suspend fun createSkill( id: String = UUID.randomUUID().toString(), label: String, @@ -53,7 +53,8 @@ class SkillFieldFactory { fun createWrapper( enable: Boolean = true, - label: String = "", + label: String? = null, + placeholder: State = mutableStateOf(null), value: String = "", ): TextFieldWrapperUio { val state = mutableStateOf(value) @@ -61,6 +62,7 @@ class SkillFieldFactory { enable = enable, label = label, value = state, + placeholder = placeholder, onValueChange = { state.value = it }, ) } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/Field.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/Field.kt deleted file mode 100644 index fdaf53e..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/Field.kt +++ /dev/null @@ -1,153 +0,0 @@ -package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable - -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.togetherWith -import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.ui.Alignment -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 -import com.pixelized.desktop.lwa.utils.preview.ContentPreview - -@Deprecated("redo") -@Stable -open class FieldUio( - val isLabelDisplayed: Boolean, - val isLabelEditable: Boolean, - val label: State, - val labelPlaceHolder: State, - val onLabelChange: (String) -> Unit, - val value: State, - val valuePlaceHolder: State, - val onValueChange: (String) -> Unit, -) { - companion object { - @Stable - fun create( - isLabelDisplayed: Boolean = true, - isLabelEditable: Boolean = false, - initialLabel: String = "", - labelPlaceHolder: () -> String = { "" }, - initialValue: String = "", - valuePlaceHolder: () -> String = { "" }, - ): FieldUio { - val label = mutableStateOf(initialLabel) - val value = mutableStateOf(initialValue) - return FieldUio( - isLabelDisplayed = isLabelDisplayed, - isLabelEditable = isLabelEditable, - label = label, - labelPlaceHolder = derivedStateOf(labelPlaceHolder), - onLabelChange = { label.value = it }, - value = value, - valuePlaceHolder = derivedStateOf(valuePlaceHolder), - onValueChange = { value.value = it }, - ) - } - } -} - -@Composable -fun Form( - modifier: Modifier = Modifier, - valueWidth: Dp = 80.dp, - field: FieldUio, -) { - val focus = LocalFocusManager.current - - AnimatedContent( - targetState = field.isLabelDisplayed, - transitionSpec = { fadeIn() togetherWith fadeOut() } - ) { - when (it) { - true -> { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(space = 8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - AnimatedContent( - modifier = Modifier.weight(weight = 1f), - targetState = field.isLabelEditable, - transitionSpec = { fadeIn() togetherWith fadeOut() }, - ) { editable -> - when (editable) { - true -> TextField( - 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), - style = MaterialTheme.typography.body1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = field.label.value - ) - } - } - TextField( - 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, - ) - } - } - } -} - -@Composable -@Preview -private fun Preview() { - ContentPreview( - paddingValues = PaddingValues(all = 16.dp) - ) { - Form( - field = FieldUio.create( - isLabelDisplayed = true, - isLabelEditable = true, - initialLabel = "label", - labelPlaceHolder = { "labelPlaceholder" }, - initialValue = "value", - valuePlaceHolder = { "valuePlaceholder" }, - ) - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SimpleField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SimpleField.kt new file mode 100644 index 0000000..469c97b --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SimpleField.kt @@ -0,0 +1,49 @@ +package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper +import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio + +@Stable +class SimpleFieldUio( + val label: String, + val value: TextFieldWrapperUio, +) + +@Composable +fun SimpleField( + modifier: Modifier = Modifier, + field: SimpleFieldUio, +) { + Row( + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + modifier = Modifier + .weight(1f) + .padding(start = 16.dp, bottom = 12.dp) + .align(alignment = Alignment.Bottom), + style = MaterialTheme.typography.body1, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + text = field.label, + ) + TextFieldWrapper( + modifier = Modifier.width(width = 96.dp), + wrapper = field.value, + ) + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SpecialSkillField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SpecialSkillField.kt index 9dbc3fa..1810f2e 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SpecialSkillField.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/SpecialSkillField.kt @@ -97,161 +97,4 @@ fun SkillForm( } } } -} - -// PREVIEW - -@Composable -@Preview -private fun Preview() { - ContentPreview( - modifier = Modifier.width(width = 1000.dp), - paddingValues = PaddingValues(all = 16.dp), - ) { - SkillForm( - field = skillFieldUio( - labelLabel = "compétence", - labelValue = "Bagarre", - baseLabel = "Base", - baseValue = "Stat(DEX*2)", - bonusLabel = "Bonus", - bonusValue = "50", - levelLabel = "Niveau", - levelValue = "5", - ), - ) - } -} - -fun main() = singleWindowApplication(title = "Context menu") { - ContentPreview( - modifier = Modifier.width(1000.dp), - paddingValues = PaddingValues(all = 16.dp), - ) { - Column( - verticalArrangement = Arrangement.spacedBy(space = 8.dp) - ) { - SkillForm( - field = skillFieldUio( - labelLabel = "compétence", - labelValue = "Bagarre", - baseLabel = "Base", - baseValue = "Stat(DEX*2)", - bonusLabel = "Bonus", - bonusValue = "55", - levelLabel = "Niveau", - levelValue = "0", - options = listOf( - CheckedOption.OccupationOption( - label = "Base minimum 40", - checked = mutableStateOf(true), - onOption = { }, - ), - ActionOption.DeleteOptionUio( - icon = Icons.Default.Delete, - label = "Supprimer", - onOption = { }, - ), - ) - ), - ) - SkillForm( - field = skillFieldUio( - labelLabel = "compétence", - labelValue = "Esquive", - baseLabel = "Base", - baseValue = "Stat(DEX*2)", - bonusLabel = "Bonus", - bonusValue = "40", - levelLabel = "Niveau", - levelValue = "0", - options = listOf( - CheckedOption.OccupationOption( - label = "Base minimum 40", - checked = mutableStateOf(true), - onOption = { }, - ), - ActionOption.DeleteOptionUio( - icon = Icons.Default.Delete, - label = "Supprimer", - onOption = { }, - ), - ) - ), - ) - SkillForm( - field = skillFieldUio( - labelLabel = "compétence", - labelValue = "Saisie", - baseLabel = "Base", - baseValue = "Stat(FOR+TAI)", - bonusLabel = "Bonus", - bonusValue = "0", - levelLabel = "Niveau", - levelValue = "0", - options = listOf( - CheckedOption.OccupationOption( - label = "Base minimum 40", - checked = mutableStateOf(true), - onOption = { }, - ), - ActionOption.DeleteOptionUio( - icon = Icons.Default.Delete, - label = "Supprimer", - onOption = { }, - ), - ) - ), - ) - } - } -} - -private fun skillFieldUio( - labelLabel: String, - labelValue: String, - baseLabel: String, - baseValue: String, - bonusLabel: String, - bonusValue: String, - levelLabel: String, - levelValue: String, - options: List = emptyList(), -): SkillFieldUio { - return SkillFieldUio( - id = UUID.randomUUID().toString(), - label = mutableStateOf(labelValue).let { state -> - TextFieldWrapperUio( - enable = true, - label = labelLabel, - value = state, - onValueChange = { state.value = it }, - ) - }, - base = mutableStateOf(baseValue).let { state -> - TextFieldWrapperUio( - enable = true, - label = baseLabel, - value = state, - onValueChange = { state.value = it }, - ) - }, - bonus = mutableStateOf(bonusValue).let { state -> - TextFieldWrapperUio( - enable = true, - label = bonusLabel, - value = state, - onValueChange = { state.value = it }, - ) - }, - level = mutableStateOf(levelValue).let { state -> - TextFieldWrapperUio( - enable = true, - label = levelLabel, - value = state, - onValueChange = { state.value = it }, - ) - }, - options = options, - ) -} +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/textfield/FormWrapper.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/textfield/FormWrapper.kt index f7cd5be..e40142f 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/textfield/FormWrapper.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/screen/characterSheet/edit/composable/textfield/FormWrapper.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.Stable import androidx.compose.runtime.State import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.style.TextOverflow import com.pixelized.desktop.lwa.utils.rememberKeyboardActions @@ -16,8 +17,9 @@ import com.pixelized.desktop.lwa.utils.rememberKeyboardActions @Stable data class TextFieldWrapperUio( val enable: Boolean, - val label: String, + val label: String?, val value: State, + val placeholder: State, val onValueChange: (String) -> Unit, ) @@ -38,12 +40,23 @@ fun TextFieldWrapper( }, enabled = wrapper.enable, singleLine = true, - label = { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = wrapper.label - ) + placeholder = wrapper.placeholder.value?.let { + { + Text( + overflow = TextOverflow.Ellipsis, + maxLines = 1, + text = it + ) + } + }, + label = wrapper.label?.let { + { + Text( + overflow = TextOverflow.Ellipsis, + maxLines = 1, + text = it + ) + } }, onValueChange = { wrapper.onValueChange(it) }, value = wrapper.value.value,