Update the last character sheet formfield.
This commit is contained in:
		
							parent
							
								
									d93ffd9499
								
							
						
					
					
						commit
						d1a98b9075
					
				
					 13 changed files with 248 additions and 463 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<Int>().let {
 | 
			
		||||
                max(0, min(it, currentSheet?.currentHp ?: it))
 | 
			
		||||
            },
 | 
			
		||||
            overrideMaxPP = editedSheet.maxPP.value.value.isNotBlank(),
 | 
			
		||||
            maxPP = editedSheet.maxPP.unpack(),
 | 
			
		||||
            currentPp = editedSheet.maxPP.unpack<Int>().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 <reified T> 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 }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<BaseSkillFieldUio>,
 | 
			
		||||
    val specialSkills: List<SkillFieldUio>,
 | 
			
		||||
    val magicSkills: List<SkillFieldUio>,
 | 
			
		||||
| 
						 | 
				
			
			@ -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(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<String?> = 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 },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -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<String>,
 | 
			
		||||
    val labelPlaceHolder: State<String>,
 | 
			
		||||
    val onLabelChange: (String) -> Unit,
 | 
			
		||||
    val value: State<String>,
 | 
			
		||||
    val valuePlaceHolder: State<String>,
 | 
			
		||||
    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" },
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<OptionUio> = 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,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<String>,
 | 
			
		||||
    val placeholder: State<String?>,
 | 
			
		||||
    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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue