diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 39eea3a..dd625a6 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -62,22 +62,55 @@
Bonus
Niveau
Compétences
- Bagarre
- Esquive
- Saisie
- Lancer
- Athlétisme
- Acrobatie
- Perception
- Recherche
- Empathie
- Persuasion
- Intimidation
- Baratin
- Marchandage
- Discrétion
- Escamotage
- Premiers soins
+ Bagarre
+ Attaque en combat à mains nues. Une attaque réussie inflige 1D3 + BDGT.\n\n- Base : DEX * 2
+ floor5(DEX*2)
+ Esquive
+ Éviter une attaque, un projectile, etc.\n\n- Base : DEX*2
+ floor5(DEX*2)
+ Saisie
+ Maitriser/immobiliser un adversaire.\n\n- Base : STR + HEI
+ floor5(STR+HEI)
+ Lancer
+ Viser et lancer quelque chose à travers les airs et vers une cible.\n\n- Base : STR + DEX
+ floor5(STR+DEX)
+ Athlétisme
+ Réaliser un mouvement nécessitant une certaine force (Enfoncer une porte, nager à contre-courant, etc.).\n\n- Base : STR + CON * 2
+ floor5(STR+CON*2)
+ Acrobatie
+ Réaliser un mouvement nécessitant une certaine agilité (Marcher sur une corde, courir sur la glace, etc.).\n\n- Base : DEX + CON * 2
+ floor5(DEX+CON*2)
+ Perception
+ Aptitude à percevoir via ses sens ou à percevoir un détail difficile à remarquer.\n\n- Base : 10 + INT * 2
+ floor5(10+INT*2)
+ Recherche
+ Aptitude à trouver des indices et à émettre des suppositions sur la base de ceux-ci.\n\n- Base : 10 + INT * 2
+ floor5(10+INT*2)
+ Empathie
+ É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
+ floor5(CHA+INT)
+ Persuasion
+ Influencer quelqu'un ou un groupe de personnes avec tact, grâce, ou de bonnes manières.\n\n- Base : CHA * 3
+ floor5(CHA*3)
+ Intimidation
+ 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
+ floor5(CHA+max(HEI,POW)*2)
+ Baratin
+ Mentir ou cacher la vérité avec efficacité, soit verbalement, soit par vos actions.\n\n- Base : CHA * 2 + INT
+ floor5(CHA*2+INT)
+ Marchandage
+ Négocier les prix.\n\n- Base : CHA * 2
+ floor5(CHA*2)
+ Discrétion
+ Passer inaperçu.\n\n- Base : CHA + DEX * 2 - HEI
+ floor5(CHA+DEX*2-HEI)
+ Escamotage
+ 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
+ floor5(DEX*2)
+ Premiers soins
+ 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
+ floor5(INT+DEX)
+ Level Up
Occupations
Ajouter une occupation
Nom
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt
index 129fe50..b0cbb03 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt
@@ -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()
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt
index ac12afc..807581f 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt
@@ -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,
): 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 -> ""
+ }
+ }
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt
index 16d5eb1..9c24d1e 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt
@@ -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,
+ 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,
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt
index 9be7f37..bbe9da5 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt
@@ -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(
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt
index 6f96d51..5965f79 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt
@@ -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),
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt
new file mode 100644
index 0000000..cd5eb2e
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt
@@ -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,
+ 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,
+ )
+ }
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt
index 66c0811..14d4e01 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt
@@ -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
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt
index 6425f3b..c0b657e 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt
@@ -19,8 +19,15 @@ sealed class CheckedOption(
val checked: State,
onOption: () -> Unit,
) : OptionUio(onOption = onOption) {
- class OccupationOption(label: String, checked: State, onOption: () -> Unit) :
- CheckedOption(label = label, checked = checked, onOption = onOption)
+ class OccupationOption(
+ label: String,
+ checked: State,
+ onOption: () -> Unit,
+ ) : CheckedOption(
+ label = label,
+ checked = checked,
+ onOption = onOption,
+ )
}
@Composable
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterFactory.kt
index f760711..2a35d02 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterFactory.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterFactory.kt
@@ -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,
): List {
- 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()) {
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/StringExt.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/StringExt.kt
index 3975d9a..81dce9c 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/StringExt.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/utils/extention/StringExt.kt
@@ -1,3 +1,12 @@
package com.pixelized.desktop.lwa.utils.extention
-val String.ARG: String get() = "$this={$this}"
\ No newline at end of file
+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, "")
+}
\ No newline at end of file