Add id + levelUp + base expression to the charactersheet edition.
This commit is contained in:
		
							parent
							
								
									e2b3b54f88
								
							
						
					
					
						commit
						50ed975913
					
				
					 11 changed files with 352 additions and 89 deletions
				
			
		| 
						 | 
				
			
			@ -62,22 +62,55 @@
 | 
			
		|||
    <string name="character_sheet_edit__skills__bonus_label">Bonus</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__level_label">Niveau</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__title">Compétences</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__combat">Bagarre</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__dodge">Esquive</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__grab">Saisie</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__throw">Lancer</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__athletics">Athlétisme</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__acrobatics">Acrobatie</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__perception">Perception</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__search">Recherche</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__empathy">Empathie</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__persuasion">Persuasion</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__intimidation">Intimidation</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__spiel">Baratin</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__bargain">Marchandage</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__discretion">Discrétion</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__sleight_of_hand">Escamotage</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__aid">Premiers soins</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__combat_label">Bagarre</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__combat_description">Attaque en combat à mains nues. Une attaque réussie inflige 1D3 + BDGT.\n\n- Base : DEX * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__combat_base">floor5(DEX*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__dodge_label">Esquive</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__dodge_description">Éviter une attaque, un projectile, etc.\n\n- Base : DEX*2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__dodge_base">floor5(DEX*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__grab_label">Saisie</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__grab_description">Maitriser/immobiliser un adversaire.\n\n- Base : STR + HEI</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__grab_base">floor5(STR+HEI)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__throw_label">Lancer</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__throw_description">Viser et lancer quelque chose à travers les airs et vers une cible.\n\n- Base : STR + DEX</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__throw_base">floor5(STR+DEX)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__athletics_label">Athlétisme</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__athletics_description">Réaliser un mouvement nécessitant une certaine force (Enfoncer une porte, nager à contre-courant, etc.).\n\n- Base : STR + CON * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__athletics_base">floor5(STR+CON*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__acrobatics_label">Acrobatie</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__acrobatics_description">Réaliser un mouvement nécessitant une certaine agilité (Marcher sur une corde, courir sur la glace, etc.).\n\n- Base : DEX + CON * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__acrobatics_base">floor5(DEX+CON*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__perception_label">Perception</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__perception_description">Aptitude à percevoir via ses sens ou à percevoir un détail difficile à remarquer.\n\n- Base : 10 + INT * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__perception_base">floor5(10+INT*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__search_label">Recherche</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__search_description">Aptitude à trouver des indices et à émettre des suppositions sur la base de ceux-ci.\n\n- Base : 10 + INT * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__search_base">floor5(10+INT*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__empathy_label">Empathie</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__empathy_description">Évaluer les pensées et/ou les motivations cachées d’un autre personnage en se basant sur des signaux subliminaux.\n\n- Base : CHA + INT</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__empathy_base">floor5(CHA+INT)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__persuasion_label">Persuasion</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__persuasion_description">Influencer quelqu'un ou un groupe de personnes avec tact, grâce, ou de bonnes manières.\n\n- Base : CHA * 3</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__persuasion_base">floor5(CHA*3)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__intimidation_label">Intimidation</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__intimidation_description">Influencer quelqu'un ou un groupe de personnes par des menaces, des actions hostiles, ou de la violence physique.\n\n- Base : CHA + max(HEI + POW) * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__intimidation_base">floor5(CHA+max(HEI,POW)*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__spiel_label">Baratin</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__spiel_description">Mentir ou cacher la vérité avec efficacité, soit verbalement, soit par vos actions.\n\n- Base : CHA * 2 + INT</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__spiel_base">floor5(CHA*2+INT)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__bargain_label">Marchandage</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__bargain_description">Négocier les prix.\n\n- Base : CHA * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__bargain_base">floor5(CHA*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__discretion_label">Discrétion</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__discretion_description">Passer inaperçu.\n\n- Base : CHA + DEX * 2 - HEI</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__discretion_base">floor5(CHA+DEX*2-HEI)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__sleight_of_hand_label">Escamotage</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__sleight_of_hand_description">Réaliser une manipulation ou une fourberie, comme prendre quelque chose à quelqu'un ou dissimuler un objet sur vous-même.\n\n- Base : DEX * 2</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__sleight_of_hand_base">floor5(DEX*2)</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__aid_label">Premiers soins</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__aid_description">Traiter les blessures légères. Une réussite rétablit 1D3 points de vie. Une réussite spéciale restaure 1D3+3 points de vie.\n\n- Base : INT + DEX</string>
 | 
			
		||||
    <string name="character_sheet_edit__skills__aid_base">floor5(INT+DEX)</string>
 | 
			
		||||
    <string name="character_sheet_edit__level_up">Level Up</string>
 | 
			
		||||
    <string name="character_sheet_edit__occupation__title">Occupations</string>
 | 
			
		||||
    <string name="character_sheet_edit__occupation__add_action">Ajouter une occupation</string>
 | 
			
		||||
    <string name="character_sheet_edit__actions__name_label">Nom</string>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,10 +99,15 @@ class CharacterSheetStore(
 | 
			
		|||
 | 
			
		||||
    private suspend fun handleMessage(message: Message) {
 | 
			
		||||
        when (val payload = message.value) {
 | 
			
		||||
            is RestSynchronisation.CharacterUpdate -> getCharacterSheet(
 | 
			
		||||
                characterSheetId = payload.id,
 | 
			
		||||
                forceUpdate = true
 | 
			
		||||
            )
 | 
			
		||||
            is RestSynchronisation.CharacterUpdate -> {
 | 
			
		||||
                getCharacterSheet(
 | 
			
		||||
                    characterSheetId = payload.id,
 | 
			
		||||
                    forceUpdate = true,
 | 
			
		||||
                )
 | 
			
		||||
                if (_previewFlow.value.firstOrNull { it.characterSheetId == payload.id } == null) {
 | 
			
		||||
                    charactersPreview()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            is RestSynchronisation.CharacterDelete -> {
 | 
			
		||||
                _previewFlow.value = previewFlow.value.toMutableList()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,14 @@ package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit
 | 
			
		|||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.derivedStateOf
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.occupation
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.LevelUpWrapperUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SimpleFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.utils.extention.unAccent
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
 | 
			
		||||
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
| 
						 | 
				
			
			@ -20,29 +23,61 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ch
 | 
			
		|||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__int
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__pow
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__str
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__level_up
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__name_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bonus_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__level_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_title
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_title
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_base
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_description
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_label
 | 
			
		||||
import org.jetbrains.compose.resources.getString
 | 
			
		||||
import java.util.UUID
 | 
			
		||||
import kotlin.math.max
 | 
			
		||||
 | 
			
		||||
class CharacterSheetEditFactory(
 | 
			
		||||
| 
						 | 
				
			
			@ -78,12 +113,12 @@ class CharacterSheetEditFactory(
 | 
			
		|||
            ?: 0
 | 
			
		||||
 | 
			
		||||
        return CharacterSheet(
 | 
			
		||||
            id = editedSheet.id,
 | 
			
		||||
            id = editedSheet.id.value,
 | 
			
		||||
            name = editedSheet.name.value.value,
 | 
			
		||||
            portrait = currentSheet?.portrait,
 | 
			
		||||
            thumbnail = currentSheet?.thumbnail,
 | 
			
		||||
            level = level,
 | 
			
		||||
            shouldLevelUp = currentSheet?.shouldLevelUp ?: false,
 | 
			
		||||
            shouldLevelUp = editedSheet.levelUp.checked.value,
 | 
			
		||||
            strength = strength,
 | 
			
		||||
            dexterity = dexterity,
 | 
			
		||||
            constitution = constitution,
 | 
			
		||||
| 
						 | 
				
			
			@ -100,8 +135,10 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                CharacterSheet.Skill(
 | 
			
		||||
                    id = editedSkill.id,
 | 
			
		||||
                    label = editedSkill.label,
 | 
			
		||||
                    description = currentSkill?.description,
 | 
			
		||||
                    base = "${editedSkill.base.value}",
 | 
			
		||||
                    description = currentSkill?.description
 | 
			
		||||
                        ?: commonSkillDescription(skillId = editedSkill.id),
 | 
			
		||||
                    base = currentSkill?.base
 | 
			
		||||
                        ?: commonSkillBase(skillId = editedSkill.id),
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    level = editedSkill.level.value.value.toIntOrNull() ?: 0,
 | 
			
		||||
                    occupation = editedSkill.option.checked.value,
 | 
			
		||||
| 
						 | 
				
			
			@ -216,12 +253,16 @@ class CharacterSheetEditFactory(
 | 
			
		|||
        val magicSkillsLabel = getString(Res.string.character_sheet_edit__skills__magic_title)
 | 
			
		||||
 | 
			
		||||
        return with(characterSheetUseCase) {
 | 
			
		||||
            val name = skillFieldFactory.createWrapper(
 | 
			
		||||
                label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
 | 
			
		||||
                value = sheet?.name ?: ""
 | 
			
		||||
            )
 | 
			
		||||
            CharacterSheetEditPageUio(
 | 
			
		||||
                id = sheet?.id ?: UUID.randomUUID().toString(),
 | 
			
		||||
                name = skillFieldFactory.createWrapper(
 | 
			
		||||
                    label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
 | 
			
		||||
                    value = sheet?.name ?: ""
 | 
			
		||||
                ),
 | 
			
		||||
                id = derivedStateOf {
 | 
			
		||||
                    sheet?.id ?: name.value.value.unAccent().replace(" ", "_")
 | 
			
		||||
                },
 | 
			
		||||
                levelUp = createLevelUpWrapper(shouldLevelUp = sheet?.shouldLevelUp ?: false),
 | 
			
		||||
                name = name,
 | 
			
		||||
                strength = str,
 | 
			
		||||
                dexterity = dex,
 | 
			
		||||
                constitution = con,
 | 
			
		||||
| 
						 | 
				
			
			@ -233,97 +274,113 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.COMBAT_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__combat),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__combat_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__combat_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(dex() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.DODGE_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__dodge),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__dodge_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__dodge_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(dex() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.GRAB_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__grab),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__grab_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__grab_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(str() + hei()) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.THROW_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__throw),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__throw_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__throw_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(str() + dex()) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.ATHLETICS_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__athletics),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__athletics_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__athletics_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(str() + con() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.ACROBATICS_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__acrobatics),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__acrobatics_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__acrobatics_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(dex() + con() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.PERCEPTION_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__perception),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__perception_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__perception_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(10 + int() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.SEARCH_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__search),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__search_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__search_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(10 + int() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.EMPATHY_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__empathy),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__empathy_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__empathy_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(cha() + int()) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.PERSUASION_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__persuasion),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__persuasion_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__persuasion_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(cha() * 3) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.INTIMIDATION_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__intimidation),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__intimidation_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__intimidation_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(cha() + max(pow(), hei()) * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.SPIEL_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__spiel),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__spiel_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__spiel_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(cha() * 2 + int()) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.BARGAIN_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__bargain),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__bargain_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__bargain_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(cha() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.DISCRETION_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__discretion),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__discretion_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__discretion_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(cha() + dex() * 2 - hei()) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__sleight_of_hand),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__sleight_of_hand_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__sleight_of_hand_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(dex() * 2) },
 | 
			
		||||
                    ),
 | 
			
		||||
                    createBaseSkill(
 | 
			
		||||
                        sheet = sheet,
 | 
			
		||||
                        id = CharacterSheet.CommonSkillId.AID_ID,
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__aid),
 | 
			
		||||
                        label = getString(Res.string.character_sheet_edit__skills__aid_label),
 | 
			
		||||
                        description = getString(Res.string.character_sheet_edit__skills__aid_description),
 | 
			
		||||
                        base = derivedStateOf { normalize(int() + dex()) },
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
| 
						 | 
				
			
			@ -383,10 +440,22 @@ class CharacterSheetEditFactory(
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun createLevelUpWrapper(
 | 
			
		||||
        shouldLevelUp: Boolean,
 | 
			
		||||
    ): LevelUpWrapperUio {
 | 
			
		||||
        val field = mutableStateOf(shouldLevelUp)
 | 
			
		||||
        return LevelUpWrapperUio(
 | 
			
		||||
            label = getString(Res.string.character_sheet_edit__level_up),
 | 
			
		||||
            checked = field,
 | 
			
		||||
            onCheck = { field.value = it },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun createBaseSkill(
 | 
			
		||||
        sheet: CharacterSheet?,
 | 
			
		||||
        id: String,
 | 
			
		||||
        label: String,
 | 
			
		||||
        description: String,
 | 
			
		||||
        base: State<Int>,
 | 
			
		||||
    ): BaseSkillFieldUio {
 | 
			
		||||
        val skill = sheet?.commonSkills?.firstOrNull { it.id == id }
 | 
			
		||||
| 
						 | 
				
			
			@ -404,10 +473,80 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                value = skill?.level?.takeIf { it > 0 }?.toString() ?: "",
 | 
			
		||||
            ),
 | 
			
		||||
            option = skillFieldFactory.occupationOption(skill?.occupation ?: false),
 | 
			
		||||
            tooltip = TooltipUio(
 | 
			
		||||
                title = label,
 | 
			
		||||
                description = description,
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun SimpleFieldUio.unpack(): String? {
 | 
			
		||||
        return value.value.value.ifBlank { value.placeholder.value }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun commonSkillBase(skillId: String): String {
 | 
			
		||||
        return when (skillId) {
 | 
			
		||||
            CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.character_sheet_edit__skills__combat_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.character_sheet_edit__skills__dodge_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.character_sheet_edit__skills__grab_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.character_sheet_edit__skills__throw_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.character_sheet_edit__skills__athletics_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.character_sheet_edit__skills__acrobatics_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.character_sheet_edit__skills__perception_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.character_sheet_edit__skills__search_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.character_sheet_edit__skills__empathy_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.character_sheet_edit__skills__persuasion_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.character_sheet_edit__skills__intimidation_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.character_sheet_edit__skills__spiel_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.character_sheet_edit__skills__bargain_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.character_sheet_edit__skills__discretion_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.character_sheet_edit__skills__sleight_of_hand_base)
 | 
			
		||||
            CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.character_sheet_edit__skills__aid_base)
 | 
			
		||||
            else -> ""
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun commonSkillLabel(skillId: String): String {
 | 
			
		||||
        return when (skillId) {
 | 
			
		||||
            CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.character_sheet_edit__skills__combat_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.character_sheet_edit__skills__dodge_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.character_sheet_edit__skills__grab_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.character_sheet_edit__skills__throw_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.character_sheet_edit__skills__athletics_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.character_sheet_edit__skills__acrobatics_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.character_sheet_edit__skills__perception_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.character_sheet_edit__skills__search_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.character_sheet_edit__skills__empathy_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.character_sheet_edit__skills__persuasion_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.character_sheet_edit__skills__intimidation_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.character_sheet_edit__skills__spiel_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.character_sheet_edit__skills__bargain_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.character_sheet_edit__skills__discretion_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.character_sheet_edit__skills__sleight_of_hand_label)
 | 
			
		||||
            CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.character_sheet_edit__skills__aid_label)
 | 
			
		||||
            else -> ""
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private suspend fun commonSkillDescription(skillId: String): String {
 | 
			
		||||
        return when (skillId) {
 | 
			
		||||
            CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.character_sheet_edit__skills__combat_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.character_sheet_edit__skills__dodge_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.character_sheet_edit__skills__grab_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.character_sheet_edit__skills__throw_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.character_sheet_edit__skills__athletics_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.character_sheet_edit__skills__acrobatics_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.character_sheet_edit__skills__perception_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.character_sheet_edit__skills__search_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.character_sheet_edit__skills__empathy_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.character_sheet_edit__skills__persuasion_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.character_sheet_edit__skills__intimidation_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.character_sheet_edit__skills__spiel_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.character_sheet_edit__skills__bargain_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.character_sheet_edit__skills__discretion_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.character_sheet_edit__skills__sleight_of_hand_description)
 | 
			
		||||
            CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.character_sheet_edit__skills__aid_description)
 | 
			
		||||
            else -> ""
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ import androidx.compose.material.icons.Icons
 | 
			
		|||
import androidx.compose.material.icons.filled.Add
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.rememberCoroutineScope
 | 
			
		||||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
| 
						 | 
				
			
			@ -34,12 +35,15 @@ import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.Action
 | 
			
		|||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillForm
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.LevelUpField
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.LevelUpWrapperUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SimpleField
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SimpleFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SkillFieldUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SkillForm
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.theme.lwa
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__common_title
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +54,6 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ch
 | 
			
		|||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__save_action
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_action
 | 
			
		||||
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 org.jetbrains.compose.resources.painterResource
 | 
			
		||||
import org.jetbrains.compose.resources.stringResource
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +61,8 @@ import org.koin.compose.viewmodel.koinViewModel
 | 
			
		|||
 | 
			
		||||
@Stable
 | 
			
		||||
data class CharacterSheetEditPageUio(
 | 
			
		||||
    val id: String,
 | 
			
		||||
    val id: State<String>,
 | 
			
		||||
    val levelUp: LevelUpWrapperUio,
 | 
			
		||||
    val name: TextFieldWrapperUio,
 | 
			
		||||
    val strength: SimpleFieldUio,
 | 
			
		||||
    val dexterity: SimpleFieldUio,
 | 
			
		||||
| 
						 | 
				
			
			@ -168,6 +172,19 @@ fun CharacterSheetEdit(
 | 
			
		|||
                    .padding(all = 16.dp),
 | 
			
		||||
                verticalArrangement = Arrangement.spacedBy(space = 16.dp)
 | 
			
		||||
            ) {
 | 
			
		||||
                Row(
 | 
			
		||||
                    verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
                ) {
 | 
			
		||||
                    Text(
 | 
			
		||||
                        modifier = Modifier.weight(1f),
 | 
			
		||||
                        style = MaterialTheme.lwa.typography.base.caption,
 | 
			
		||||
                        text = form.id.value
 | 
			
		||||
                    )
 | 
			
		||||
                    LevelUpField(
 | 
			
		||||
                        field = form.levelUp,
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                TextFieldWrapper(
 | 
			
		||||
                    modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                    wrapper = form.name,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ class CharacterSheetEditViewModel(
 | 
			
		|||
 | 
			
		||||
    suspend fun save() {
 | 
			
		||||
        val updatedSheet = sheetFactory.updateCharacterSheet(
 | 
			
		||||
            currentSheet = characterSheetRepository.characterDetail(characterSheetId = _characterSheet.value.id),
 | 
			
		||||
            currentSheet = characterSheetRepository.characterDetail(characterSheetId = _characterSheet.value.id.value),
 | 
			
		||||
            editedSheet = _characterSheet.value,
 | 
			
		||||
        )
 | 
			
		||||
        characterSheetRepository.updateCharacter(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.ExperimentalFoundationApi
 | 
			
		||||
import androidx.compose.foundation.layout.Arrangement
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +25,8 @@ 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.ui.composable.tooltip.TooltipLayout
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.CheckedOption
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.DropDownCheckedMenuItem
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
 | 
			
		||||
| 
						 | 
				
			
			@ -40,8 +43,10 @@ class BaseSkillFieldUio(
 | 
			
		|||
    val bonus: TextFieldWrapperUio,
 | 
			
		||||
    val level: TextFieldWrapperUio,
 | 
			
		||||
    val option: CheckedOption,
 | 
			
		||||
    val tooltip: TooltipUio,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@OptIn(ExperimentalFoundationApi::class)
 | 
			
		||||
@Composable
 | 
			
		||||
fun BaseSkillForm(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
| 
						 | 
				
			
			@ -75,24 +80,27 @@ fun BaseSkillForm(
 | 
			
		|||
            maxLines = 1,
 | 
			
		||||
            text = field.label,
 | 
			
		||||
        )
 | 
			
		||||
        Column(
 | 
			
		||||
        TooltipLayout(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .width(width = 96.dp)
 | 
			
		||||
                .padding(start = 16.dp),
 | 
			
		||||
            tooltip = field.tooltip,
 | 
			
		||||
        ) {
 | 
			
		||||
            Text(
 | 
			
		||||
                style = MaterialTheme.typography.caption,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                maxLines = 1,
 | 
			
		||||
                color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
 | 
			
		||||
                text = baseLabel.value,
 | 
			
		||||
            )
 | 
			
		||||
            Text(
 | 
			
		||||
                style = MaterialTheme.typography.body1,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                maxLines = 1,
 | 
			
		||||
                text = "+${field.base.value}",
 | 
			
		||||
            )
 | 
			
		||||
            Column {
 | 
			
		||||
                Text(
 | 
			
		||||
                    style = MaterialTheme.typography.caption,
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
                    color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
 | 
			
		||||
                    text = baseLabel.value,
 | 
			
		||||
                )
 | 
			
		||||
                Text(
 | 
			
		||||
                    style = MaterialTheme.typography.body1,
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
                    text = "+${field.base.value}",
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        TextFieldWrapper(
 | 
			
		||||
            modifier = Modifier.width(width = 96.dp),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.layout.Row
 | 
			
		||||
import androidx.compose.material.Checkbox
 | 
			
		||||
import androidx.compose.material.MaterialTheme
 | 
			
		||||
import androidx.compose.material.Text
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.ui.Alignment
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.theme.lwa
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
class LevelUpWrapperUio(
 | 
			
		||||
    val label: String,
 | 
			
		||||
    val checked: State<Boolean>,
 | 
			
		||||
    val onCheck: (Boolean) -> Unit,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun LevelUpField(
 | 
			
		||||
    modifier: Modifier = Modifier,
 | 
			
		||||
    field: LevelUpWrapperUio,
 | 
			
		||||
) {
 | 
			
		||||
    Row(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
    ) {
 | 
			
		||||
        Text(
 | 
			
		||||
            style = MaterialTheme.lwa.typography.base.body1,
 | 
			
		||||
            text = field.label,
 | 
			
		||||
        )
 | 
			
		||||
        Checkbox(
 | 
			
		||||
            checked = field.checked.value,
 | 
			
		||||
            onCheckedChange = field.onCheck,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -17,9 +17,15 @@ sealed class ActionOption(
 | 
			
		|||
    val label: String,
 | 
			
		||||
    onOption: () -> Unit,
 | 
			
		||||
) : OptionUio(onOption = onOption) {
 | 
			
		||||
 | 
			
		||||
    class DeleteOptionUio(icon: ImageVector, label: String, onOption: () -> Unit) :
 | 
			
		||||
        ActionOption(icon = icon, label = label, onOption = onOption)
 | 
			
		||||
    class DeleteOptionUio(
 | 
			
		||||
        icon: ImageVector,
 | 
			
		||||
        label: String,
 | 
			
		||||
        onOption: () -> Unit,
 | 
			
		||||
    ) : ActionOption(
 | 
			
		||||
        icon = icon,
 | 
			
		||||
        label = label,
 | 
			
		||||
        onOption = onOption,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,8 +19,15 @@ sealed class CheckedOption(
 | 
			
		|||
    val checked: State<Boolean>,
 | 
			
		||||
    onOption: () -> Unit,
 | 
			
		||||
) : OptionUio(onOption = onOption) {
 | 
			
		||||
    class OccupationOption(label: String, checked: State<Boolean>, onOption: () -> Unit) :
 | 
			
		||||
        CheckedOption(label = label, checked = checked, onOption = onOption)
 | 
			
		||||
    class OccupationOption(
 | 
			
		||||
        label: String,
 | 
			
		||||
        checked: State<Boolean>,
 | 
			
		||||
        onOption: () -> Unit,
 | 
			
		||||
    ) : CheckedOption(
 | 
			
		||||
        label = label,
 | 
			
		||||
        checked = checked,
 | 
			
		||||
        onOption = onOption,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,15 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.ui.screen.gamemaster
 | 
			
		||||
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio.Action
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTagUio
 | 
			
		||||
import com.pixelized.desktop.lwa.utils.extention.unAccent
 | 
			
		||||
import com.pixelized.shared.lwa.model.campaign.Campaign
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.game_master__character_tag__character_label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.game_master__character_tag__npc_label
 | 
			
		||||
import org.jetbrains.compose.resources.getString
 | 
			
		||||
import java.text.Normalizer
 | 
			
		||||
 | 
			
		||||
class GameMasterFactory {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ class GameMasterFactory {
 | 
			
		|||
        filter: String,
 | 
			
		||||
        tags: Map<GMTagUio.TagId, Boolean>,
 | 
			
		||||
    ): List<GMCharacterUio> {
 | 
			
		||||
        val normalizedFilter = Normalizer.normalize(filter, Normalizer.Form.NFD)
 | 
			
		||||
        val normalizedFilter = filter.unAccent()
 | 
			
		||||
 | 
			
		||||
        return characters.mapNotNull {
 | 
			
		||||
            convertToGMCharacterPreviewUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ class GameMasterFactory {
 | 
			
		|||
        }
 | 
			
		||||
        // Filter process : Name.
 | 
			
		||||
        if (filter.isNotEmpty()) {
 | 
			
		||||
            val normalizedName = Normalizer.normalize(character.name, Normalizer.Form.NFD)
 | 
			
		||||
            val normalizedName = character.name.unAccent()
 | 
			
		||||
            // If the filter is not empty and the character is not
 | 
			
		||||
            val nameHighlight = normalizedName.contains(other = filter, ignoreCase = true)
 | 
			
		||||
            if (nameHighlight.not()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,12 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.utils.extention
 | 
			
		||||
 | 
			
		||||
val String.ARG: String get() = "$this={$this}"
 | 
			
		||||
import java.text.Normalizer
 | 
			
		||||
 | 
			
		||||
private val REGEX_UN_ACCENT = "\\p{InCombiningDiacriticalMarks}+".toRegex()
 | 
			
		||||
 | 
			
		||||
val String.ARG: String get() = "$this={$this}"
 | 
			
		||||
 | 
			
		||||
fun CharSequence.unAccent(): String {
 | 
			
		||||
    val temp = Normalizer.normalize(this, Normalizer.Form.NFD)
 | 
			
		||||
    return REGEX_UN_ACCENT.replace(temp, "")
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue